This is an automated email from the ASF dual-hosted git repository. abhay pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push: new 1368600 RANGER-2665: Policy engine for delegate-admin processing is not built correctly when policy-deltas are enabled and a zone policy is updated 1368600 is described below commit 1368600bc10ed31adbdf6e64530590ed1ad4c9f9 Author: Abhay Kulkarni <ab...@apache.org> AuthorDate: Sat Dec 7 17:14:51 2019 -0800 RANGER-2665: Policy engine for delegate-admin processing is not built correctly when policy-deltas are enabled and a zone policy is updated --- .../ranger/plugin/service/RangerBasePlugin.java | 42 ++++++++++-------- .../ranger/plugin/util/RangerPolicyDeltaUtil.java | 41 ++++++++++++++++++ .../apache/ranger/biz/RangerPolicyAdminCache.java | 50 +++++++++++++++------- 3 files changed, 99 insertions(+), 34 deletions(-) diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java index 6f1d9f9..75fbd64 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java @@ -176,39 +176,41 @@ public class RangerBasePlugin { ServicePolicies servicePolicies = null; boolean isValid = true; boolean usePolicyDeltas = false; + boolean updateRolesOnly = false; if (policies == null) { policies = getDefaultSvcPolicies(); if (policies == null) { LOG.error("Could not get default Service Policies"); - isValid = false; } } else { - if (policies.getPolicies() != null && policies.getPolicyDeltas() != null) { - LOG.error("Invalid servicePolicies: Both policies and policy-deltas cannot be null OR both of them cannot be non-null"); - - isValid = false; - } else if (policies.getPolicies() != null) { - usePolicyDeltas = false; - } else if (policies.getPolicyDeltas() != null) { - // Rebuild policies from deltas - RangerPolicyEngineImpl policyEngine = (RangerPolicyEngineImpl) oldPolicyEngine; + Boolean hasPolicyDeltas = RangerPolicyDeltaUtil.hasPolicyDeltas(policies); - servicePolicies = ServicePolicies.applyDelta(policies, policyEngine); - - if (servicePolicies != null) { - usePolicyDeltas = true; + if (hasPolicyDeltas == null) { + if (roles != null) { + updateRolesOnly = true; } else { + LOG.error("Policies, policy-deltas and roles are all null, Should not get here!!"); isValid = false; - - LOG.error("Could not apply deltas=" + Arrays.toString(policies.getPolicyDeltas().toArray())); } } else { - LOG.error("Should not get here!!"); + if (hasPolicyDeltas.equals(Boolean.TRUE)) { + // Rebuild policies from deltas + RangerPolicyEngineImpl policyEngine = (RangerPolicyEngineImpl) oldPolicyEngine; - isValid = false; + servicePolicies = ServicePolicies.applyDelta(policies, policyEngine); + + if (servicePolicies != null) { + usePolicyDeltas = true; + } else { + LOG.error("Could not apply deltas=" + Arrays.toString(policies.getPolicyDeltas().toArray())); + isValid = false; + } + } else { + usePolicyDeltas = false; + } } } @@ -216,7 +218,9 @@ public class RangerBasePlugin { RangerPolicyEngine newPolicyEngine = null; boolean isPolicyEngineShared = false; - if (!usePolicyDeltas) { + if (updateRolesOnly) { + this.policyEngine.setRoles(roles); + } else if (!usePolicyDeltas) { if (LOG.isDebugEnabled()) { LOG.debug("policies are not null. Creating engine from policies"); } diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerPolicyDeltaUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerPolicyDeltaUtil.java index 4599997..241cf9d 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerPolicyDeltaUtil.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerPolicyDeltaUtil.java @@ -20,6 +20,7 @@ package org.apache.ranger.plugin.util; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ranger.plugin.model.RangerPolicy; @@ -153,4 +154,44 @@ public class RangerPolicyDeltaUtil { } return isValid; } + + public static Boolean hasPolicyDeltas(final ServicePolicies servicePolicies) { + if (LOG.isDebugEnabled()) { + LOG.debug("==> hasPolicyDeltas(servicePolicies:[" + servicePolicies + "]"); + } + final Boolean ret; + + if (servicePolicies == null) { + LOG.error("ServicePolicies are null!"); + ret = null; + } else { + Boolean isDeltasInSecurityZones = null; + + if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) { + for (ServicePolicies.SecurityZoneInfo element : servicePolicies.getSecurityZones().values()) { + if (CollectionUtils.isNotEmpty(element.getPolicies()) && CollectionUtils.isEmpty(element.getPolicyDeltas())) { + isDeltasInSecurityZones = false; + break; + } + if (CollectionUtils.isEmpty(element.getPolicies()) && CollectionUtils.isNotEmpty(element.getPolicyDeltas())) { + isDeltasInSecurityZones = true; + break; + } + } + } + + if (CollectionUtils.isNotEmpty(servicePolicies.getPolicies()) || (servicePolicies.getTagPolicies() != null && CollectionUtils.isNotEmpty(servicePolicies.getTagPolicies().getPolicies())) || (isDeltasInSecurityZones != null && isDeltasInSecurityZones.equals(Boolean.FALSE))) { + ret = false; + } else if (CollectionUtils.isNotEmpty(servicePolicies.getPolicyDeltas()) || (isDeltasInSecurityZones != null && isDeltasInSecurityZones.equals(Boolean.TRUE))) { + ret = true; + } else { + LOG.warn("ServicePolicies contain either both policies and policy-deltas or contain neither policies nor policy-deltas!"); + ret = null; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("<== hasPolicyDeltas(servicePolicies:[" + servicePolicies + "], ret:[" + ret + "]"); + } + return ret; + } } diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java index 76dabb4..266bfbb 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java @@ -40,6 +40,7 @@ import org.apache.ranger.plugin.policyengine.RangerPluginContext; import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; import org.apache.ranger.plugin.store.SecurityZoneStore; import org.apache.ranger.plugin.store.ServiceStore; +import org.apache.ranger.plugin.util.RangerPolicyDeltaUtil; import org.apache.ranger.plugin.util.RangerRoles; import org.apache.ranger.plugin.util.ServicePolicies; @@ -109,6 +110,9 @@ public class RangerPolicyAdminCache { } catch (Exception excp) { LOG.error("getPolicyAdmin(" + serviceName + "): failed to get latest policies from service-store", excp); } + if (ret == null) { + LOG.error("Policy-engine is not built! Returning null policy-engine!"); + } return ret; } @@ -118,27 +122,45 @@ public class RangerPolicyAdminCache { RangerPolicyAdminImpl oldPolicyAdmin = (RangerPolicyAdminImpl) policyAdmin; synchronized(this) { - if (oldPolicyAdmin == null || CollectionUtils.isEmpty(policies.getPolicyDeltas())) { - ret = addPolicyAdmin(policies, roles, options); - } else { - RangerPolicyAdmin updatedPolicyAdmin = RangerPolicyAdminImpl.getPolicyAdmin(oldPolicyAdmin, policies); - - if (updatedPolicyAdmin != null) { - updatedPolicyAdmin.setRoles(roles); - policyAdminCache.put(policies.getServiceName(), updatedPolicyAdmin); - - ret = updatedPolicyAdmin; + Boolean hasPolicyDeltas = RangerPolicyDeltaUtil.hasPolicyDeltas(policies); + + if (hasPolicyDeltas != null) { + if (hasPolicyDeltas.equals(Boolean.TRUE)) { + if (oldPolicyAdmin != null) { + ret = RangerPolicyAdminImpl.getPolicyAdmin(oldPolicyAdmin, policies); + if (ret != null) { + ret.setRoles(roles); + } + } else { + LOG.error("Old policy engine is null! Cannot apply deltas without old policy engine!"); + ret = null; + } } else { ret = addPolicyAdmin(policies, roles, options); } + } else { + LOG.warn("ServicePolicies contain neither policies nor policy-deltas !"); + ret = null; } - if (oldPolicyAdmin != null) { - oldPolicyAdmin.releaseResources(); + if (ret != null) { + if (LOG.isDebugEnabled()) { + if (oldPolicyAdmin == null) { + LOG.debug("Adding policy-engine to cache with serviceName:[" + policies.getServiceName() + "] as key"); + } else { + LOG.debug("Replacing policy-engine in cache with serviceName:[" + policies.getServiceName() + "] as key"); + } + } + policyAdminCache.put(policies.getServiceName(), ret); + if (oldPolicyAdmin != null) { + oldPolicyAdmin.releaseResources(); + } + } else { + LOG.warn("Could not build new policy-engine. Continuing with the old policy-engine, if any"); } } - return ret; + return ret != null ? ret : oldPolicyAdmin; } private RangerPolicyAdmin addPolicyAdmin(ServicePolicies policies, RangerRoles roles, RangerPolicyEngineOptions options) { @@ -147,8 +169,6 @@ public class RangerPolicyAdminCache { RangerPluginContext rangerPluginContext = new RangerPluginContext(new RangerPluginConfig(serviceType, null, "ranger-admin", null, null, options)); RangerPolicyAdmin ret = new RangerPolicyAdminImpl(policies, rangerPluginContext, roles); - policyAdminCache.put(policies.getServiceName(), ret); - return ret; }