You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/03/31 22:30:42 UTC
incubator-ranger git commit: RANGER-238 Filter database and table
listing per users permissions.
Repository: incubator-ranger
Updated Branches:
refs/heads/master d804499ae -> ff347709c
RANGER-238 Filter database and table listing per users permissions.
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/ff347709
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/ff347709
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/ff347709
Branch: refs/heads/master
Commit: ff347709cfc04f1d90f1744fec89762d736698f7
Parents: d804499
Author: Alok Lal <al...@hortonworks.com>
Authored: Thu Mar 19 19:01:59 2015 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Tue Mar 31 13:11:31 2015 -0700
----------------------------------------------------------------------
.../RangerDefaultPolicyEvaluator.java | 99 ++++----
.../policyengine/test_policyengine_hive.json | 47 ++++
hbase-agent/pom.xml | 3 +-
hdfs-agent/pom.xml | 3 +-
hive-agent/pom.xml | 3 +-
.../authorizer/RangerHiveAccessRequest.java | 18 +-
.../hive/authorizer/RangerHiveAuditHandler.java | 149 +++++++-----
.../hive/authorizer/RangerHiveAuthorizer.java | 238 +++++++++++++++----
ranger-util/.gitignore | 1 +
ranger_solrj/pom.xml | 1 -
ugsync/pom.xml | 3 +-
unixauthclient/pom.xml | 3 +-
unixauthservice/pom.xml | 3 +-
13 files changed, 415 insertions(+), 156 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/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 76e50cb..fb80675 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
@@ -19,7 +19,14 @@
package org.apache.ranger.plugin.policyevaluator;
-import com.google.common.base.Strings;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+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;
@@ -35,13 +42,14 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
-import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher;
import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
-import java.util.*;
+import com.google.common.base.Strings;
+import com.google.common.collect.Sets;
public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator {
@@ -271,7 +279,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
protected void evaluatePolicyItemsForAccess(RangerAccessRequest request, RangerAccessResult result) {
if(LOG.isDebugEnabled()) {
- LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItemsForAccess()");
+ LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItemsForAccess(" + request + ", " + result + ")");
}
String accessType = request.getAccessType();
if (StringUtils.isEmpty(accessType)) {
@@ -333,7 +341,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
break;
}
if(LOG.isDebugEnabled()) {
- LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItemsForAccess()");
+ LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItemsForAccess(" + request + ", " + result + ")");
}
}
@@ -437,46 +445,53 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ")");
}
-
- boolean ret = false;
-
- RangerServiceDef serviceDef = getServiceDef();
-
- if(serviceDef != null && serviceDef.getResources() != null) {
- int numMatched = 0;
- int numUnmatched = 0;
-
- for(RangerResourceDef resourceDef : serviceDef.getResources()) {
- String resourceName = resourceDef.getName();
- String resourceValue = resource == null ? null : resource.getValue(resourceName);
- RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName);
-
- if(numUnmatched > 0) { // no further values are expected in the resource
- if(! StringUtils.isEmpty(resourceValue)) {
- break;
- }
-
- numUnmatched++;
- continue;
- } else {
- boolean isMatch = false;
-
- // when no value exists for a resourceName, consider it a match only if (policy doesn't have a matcher OR matcher allows no-value resource)
- if(StringUtils.isEmpty(resourceValue)) {
- isMatch = matcher == null || matcher.isMatch(resourceValue);
- } else {
- isMatch = matcher != null && matcher.isMatch(resourceValue);
- }
-
- if(isMatch) {
- numMatched++;
- } else {
- numUnmatched++;
+ boolean ret;
+
+ if (resource == null || CollectionUtils.isEmpty(resource.getKeys())) { // sanity-check, firewalling
+ LOG.debug("matchResourceHead: resource was null/empty!");
+ ret = true; // null resource matches anything
+ } else if (getServiceDef() == null) { // sanity-check, firewalling
+ LOG.debug("matchResourceHead: service-def was null!");
+ ret = false; // null policy can never match a non-empty resource
+ } else if (getPolicy() == null || getPolicy().getResources() == null) {
+ LOG.debug("matchResourceHead: policy or its resources were null!");
+ ret = false; // null policy can never match a non-empty resource
+ } else if (matchers == null || matchers.size() != getPolicy().getResources().size()) { // sanity-check, firewalling
+ LOG.debug("matchResourceHead: matchers could be found for some of the policy resources");
+ ret = false; // empty policy can never match a non-empty resources and can't be evaluated meaningfully in matchers are absent
+ } else {
+ if (!Sets.difference(resource.getKeys(), matchers.keySet()).isEmpty()) { // e.g. avoid using udf policy for resource that has more than db specified and vice-versa
+ LOG.debug("matchResourceHead: resource/policy resource-keys mismatch. policy is incompatible with resource; can't match.");
+ ret = false;
+ } else {
+ Set<String> policyResourceNames = matchers.keySet();
+ boolean skipped = false;
+ boolean matched = true;
+ Iterator<RangerResourceDef> iterator = getServiceDef().getResources().iterator();
+ while (iterator.hasNext() && matched) {
+ RangerResourceDef resourceDef = iterator.next();
+ String resourceName = resourceDef.getName();
+ // we only work with resources that are relevant to this policy
+ if (policyResourceNames.contains(resourceName)) {
+ String resourceValue = resource.getValue(resourceName);
+ if (StringUtils.isEmpty(resourceValue)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Skipping matching for " + resourceName + " since it is null/empty on resource");
+ }
+ skipped = true; // once we skip a level all lower levels must be skippable, too
+ } else if (skipped == true) {
+ LOG.debug("matchResourceHead: found a lower level resource when a higer level resource was absent!");
+ matched = false;
+ } else if (!matchers.get(resourceName).isMatch(resourceValue)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("matchResourceHead: matcher for " + resourceName + " failed");
+ }
+ matched = false;
+ }
}
}
+ ret = matched;
}
-
- ret = (numMatched > 0) && serviceDef.getResources().size() == (numMatched + numUnmatched);
}
if(LOG.isDebugEnabled()) {
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_hive.json b/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
index 8ca7071..9cf20b9 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
@@ -38,6 +38,13 @@
{"accesses":[{"type":"create","isAllowed":true},{"type":"drop","isAllowed":true}],"users":["admin"],"groups":["admin"],"delegateAdmin":true}
]
}
+ ,
+ {"id":3,"name":"db=db1; table=tbl*; column=*","isEnabled":true,"isAuditEnabled":true,
+ "resources":{"database":{"values":["db1"]},"table":{"values":["tbl*"]},"column":{"values":["*"]}},
+ "policyItems":[
+ {"accesses":[{"type":"select","isAllowed":true}],"users":["user1","user2"],"groups":["group1","group2"],"delegateAdmin":false}
+ ]
+ }
],
"tests":[
@@ -256,6 +263,46 @@
},
"result":{"isAudited":true,"isAllowed":false,"policyId":-1}
}
+ ,
+ {"name":"DENY '_any access to db1/table1' for user1: table-level mismatch",
+ "request":{
+ "resource":{"elements":{"database":"db1", "table":"table1"}},
+ "accessType":"","user":"user1","userGroups":["users"],"requestData":"show columns in table1 from db1;"
+ },
+ "result":{"isAudited":false,"isAllowed":false,"policyId":-1}
+ }
+ ,
+ {"name":"DENY '_any access to db1/_/col1' for user1: table not specified but column was specified",
+ "request":{
+ "resource":{"elements":{"database":"db1", "column":"col1"}},
+ "accessType":"","user":"user1","userGroups":["users"],"requestData":"fictional use case when request specified a lower level resource by skipping intermediate resource"
+ },
+ "result":{"isAudited":false,"isAllowed":false,"policyId":-1}
+ }
+ ,
+ {"name":"ALLOW '_any access to db1' for user1: match when request has less levels than policy",
+ "request":{
+ "resource":{"elements":{"database":"db1"}},
+ "accessType":"","user":"user1","userGroups":["users"],"requestData":"use db1"
+ },
+ "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+ }
+ ,
+ {"name":"ALLOW '_any access to db1/table1' for user1: match when request has same levels as policy",
+ "request":{
+ "resource":{"elements":{"database":"db1", "table":"tbl1"}},
+ "accessType":"","user":"user1","userGroups":["users"],"requestData":"describe db1.tbl1"
+ },
+ "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+ }
+ ,
+ {"name":"ALLOW '_any access to db1/tbl1/col1' for user1: match when request has more specific levels than policy",
+ "request":{
+ "resource":{"elements":{"database":"db1", "table":"tbl1", "column":"col1"}},
+ "accessType":"","user":"user1","userGroups":["users"],"requestData":"fictional case: request for any match today happens only at a higher levels"
+ },
+ "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+ }
]
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/hbase-agent/pom.xml
----------------------------------------------------------------------
diff --git a/hbase-agent/pom.xml b/hbase-agent/pom.xml
index 5c74b94..b4664f3 100644
--- a/hbase-agent/pom.xml
+++ b/hbase-agent/pom.xml
@@ -55,8 +55,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>${gson.version}</version>
- </dependency>
+ </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/hdfs-agent/pom.xml
----------------------------------------------------------------------
diff --git a/hdfs-agent/pom.xml b/hdfs-agent/pom.xml
index 6ebf633..d1f42a7 100644
--- a/hdfs-agent/pom.xml
+++ b/hdfs-agent/pom.xml
@@ -35,8 +35,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>${gson.version}</version>
- </dependency>
+ </dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/hive-agent/pom.xml
----------------------------------------------------------------------
diff --git a/hive-agent/pom.xml b/hive-agent/pom.xml
index 1c556db..752b37b 100644
--- a/hive-agent/pom.xml
+++ b/hive-agent/pom.xml
@@ -90,8 +90,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>${gson.version}</version>
- </dependency>
+ </dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-metastore</artifactId>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/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 39f5773..1f7ae4d 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
@@ -39,7 +39,7 @@ public class RangerHiveAccessRequest extends RangerAccessRequestImpl {
public RangerHiveAccessRequest(RangerHiveResource resource,
String user,
Set<String> userGroups,
- HiveOperationType hiveOpType,
+ String hiveOpTypeName,
HiveAccessType accessType,
HiveAuthzContext context,
HiveAuthzSessionContext sessionContext) {
@@ -47,7 +47,7 @@ public class RangerHiveAccessRequest extends RangerAccessRequestImpl {
this.setUser(user);
this.setUserGroups(userGroups);
this.setAccessTime(StringUtil.getUTCDate());
- this.setAction(hiveOpType.name());
+ this.setAction(hiveOpTypeName);
if(context != null) {
this.setClientIPAddress(context.getIpAddress());
@@ -70,6 +70,20 @@ public class RangerHiveAccessRequest extends RangerAccessRequestImpl {
}
}
+ public RangerHiveAccessRequest(RangerHiveResource resource,
+ String user,
+ Set<String> userGroups,
+ HiveOperationType hiveOpType,
+ HiveAccessType accessType,
+ HiveAuthzContext context,
+ HiveAuthzSessionContext sessionContext) {
+ this(resource, user, userGroups, hiveOpType.name(), accessType, context, sessionContext);
+ }
+
+ public RangerHiveAccessRequest(RangerHiveResource resource, String user, Set<String> groups, HiveAuthzContext context, HiveAuthzSessionContext sessionContext) {
+ this(resource, user, groups, "OTHER", HiveAccessType.USE, context, sessionContext);
+ }
+
public HiveAccessType getHiveAccessType() {
return accessType;
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/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 7110861..4d2d40f 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
@@ -22,8 +22,11 @@ package org.apache.ranger.authorization.hive.authorizer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
+import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType;
import org.apache.ranger.audit.model.AuthzAuditEvent;
import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
import org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants;
@@ -31,6 +34,8 @@ import org.apache.ranger.authorization.utils.StringUtil;
import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import com.google.common.collect.Lists;
+
public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
private static final String RangerModuleName = RangerConfiguration.getInstance().get(RangerHadoopConstants.AUDITLOG_RANGER_MODULE_ACL_NAME_PROP , RangerHadoopConstants.DEFAULT_RANGER_MODULE_ACL_NAME) ;
@@ -40,18 +45,12 @@ public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
public RangerHiveAuditHandler() {
super();
}
-
- @Override
- public void logAudit(RangerAccessResult result) {
- if(! result.getIsAudited()) {
- return;
- }
-
- AuthzAuditEvent auditEvent = new AuthzAuditEvent();
-
+
+ AuthzAuditEvent createAuditEvent(RangerAccessResult result, String accessType, String resourcePath) {
RangerHiveAccessRequest request = (RangerHiveAccessRequest)result.getAccessRequest();
RangerHiveResource resource = (RangerHiveResource)request.getResource();
+ AuthzAuditEvent auditEvent = new AuthzAuditEvent();
auditEvent.setAclEnforcer(RangerModuleName);
auditEvent.setSessionId(request.getSessionId());
auditEvent.setResourceType("@" + StringUtil.toLower(resource.getObjectType().name())); // to be consistent with earlier release
@@ -67,66 +66,108 @@ public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
auditEvent.setRepositoryName(result.getServiceName()) ;
auditEvent.setRequestData(request.getRequestData());
auditEvent.setResourcePath(resource != null ? resource.getAsString(result.getServiceDef()) : null);
+
+ return auditEvent;
+ }
+
+ AuthzAuditEvent createAuditEvent(RangerAccessResult result) {
+
+ RangerHiveAccessRequest request = (RangerHiveAccessRequest)result.getAccessRequest();
+ RangerHiveResource resource = (RangerHiveResource)request.getResource();
+ String accessType = request.getHiveAccessType().toString();
+ String resourcePath = resource != null ? resource.getAsString(result.getServiceDef()) : null;
+ return createAuditEvent(result, accessType, resourcePath);
+ }
+
+ public List<AuthzAuditEvent> createAuditEvents(Collection<RangerAccessResult> results) {
+ Map<Long, AuthzAuditEvent> auditEvents = new HashMap<Long, AuthzAuditEvent>();
+ Iterator<RangerAccessResult> iterator = results.iterator();
+ AuthzAuditEvent deniedAuditEvent = null;
+ while (iterator.hasNext() && deniedAuditEvent == null) {
+ RangerAccessResult result = iterator.next();
+ if(result.getIsAudited()) {
+ if (!result.getIsAllowed()) {
+ deniedAuditEvent = createAuditEvent(result);
+ } else {
+ long policyId = result.getPolicyId();
+ if (auditEvents.containsKey(policyId)) { // add this result to existing event by updating column values
+ AuthzAuditEvent auditEvent = auditEvents.get(policyId);
+ RangerHiveAccessRequest request = (RangerHiveAccessRequest)result.getAccessRequest();
+ RangerHiveResource resource = (RangerHiveResource)request.getResource();
+ String resourcePath = auditEvent.getResourcePath() + "," + resource.getColumn();
+ auditEvent.setResourcePath(resourcePath);
+ } else { // new event as this approval was due to a different policy.
+ AuthzAuditEvent auditEvent = createAuditEvent(result);
+ auditEvents.put(policyId, auditEvent);
+ }
+ }
+ }
+ }
+ List<AuthzAuditEvent> result;
+ if (deniedAuditEvent == null) {
+ result = new ArrayList<>(auditEvents.values());
+ } else {
+ result = Lists.newArrayList(deniedAuditEvent);
+ }
+
+ return result;
+ }
+
+ @Override
+ public void logAudit(RangerAccessResult result) {
+ if(! result.getIsAudited()) {
+ return;
+ }
+ AuthzAuditEvent auditEvent = createAuditEvent(result);
addAuthzAuditEvent(auditEvent);
}
- /*
+ /**
* This method is expected to be called ONLY to process the results for multiple-columns in a table.
* To ensure this, RangerHiveAuthorizer should call isAccessAllowed(Collection<requests>) only for this condition
*/
@Override
public void logAudit(Collection<RangerAccessResult> results) {
- Map<Long, AuthzAuditEvent> auditEvents = new HashMap<Long, AuthzAuditEvent>();
-
- for(RangerAccessResult result : results) {
- if(! result.getIsAudited()) {
- continue;
- }
-
- RangerHiveAccessRequest request = (RangerHiveAccessRequest)result.getAccessRequest();
- RangerHiveResource resource = (RangerHiveResource)request.getResource();
- AuthzAuditEvent auditEvent = auditEvents.get(result.getPolicyId());
-
- if(auditEvent == null) {
- auditEvent = new AuthzAuditEvent();
- auditEvents.put(result.getPolicyId(), auditEvent);
-
- auditEvent.setAclEnforcer(RangerModuleName);
- auditEvent.setSessionId(request.getSessionId());
- auditEvent.setResourceType("@" + StringUtil.toLower(resource.getObjectType().name())); // to be consistent with earlier release
- auditEvent.setAccessType(request.getHiveAccessType().toString());
- auditEvent.setAction(request.getAction());
- auditEvent.setUser(request.getUser());
- auditEvent.setAccessResult((short)(result.getIsAllowed() ? 1 : 0));
- auditEvent.setPolicyId(result.getPolicyId());
- auditEvent.setClientIP(request.getClientIPAddress());
- auditEvent.setClientType(request.getClientType());
- auditEvent.setEventTime(request.getAccessTime());
- auditEvent.setRepositoryType(result.getServiceType());
- auditEvent.setRepositoryName(result.getServiceName()) ;
- auditEvent.setRequestData(request.getRequestData());
-
- auditEvent.setResourcePath(resource != null ? resource.getAsString(result.getServiceDef()) : null);
- } else if(result.getIsAllowed()){
- auditEvent.setResourcePath(auditEvent.getResourcePath() + "," + resource.getColumn());
- } else {
- auditEvent.setResourcePath(resource != null ? resource.getAsString(result.getServiceDef()) : null);
- }
-
- if(!result.getIsAllowed()) {
- auditEvent.setResourcePath(resource != null ? resource.getAsString(result.getServiceDef()) : null);
+ List<AuthzAuditEvent> auditEvents = createAuditEvents(results);
+ for(AuthzAuditEvent auditEvent : auditEvents) {
+ addAuthzAuditEvent(auditEvent);
+ }
+ }
- break;
- }
+ 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);
- for(AuthzAuditEvent auditEvent : auditEvents.values()) {
- addAuthzAuditEvent(auditEvent);
+ 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) {
+ public void logAuditEventForDfs(String userName, String dfsCommand, boolean accessGranted, int repositoryType, String repositoryName) {
AuthzAuditEvent auditEvent = new AuthzAuditEvent();
auditEvent.setAclEnforcer(RangerModuleName);
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/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 121177d..bca8858 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
@@ -283,51 +283,73 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
}
}
- 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);
-
- for(String column : columns) {
- if (column != null) {
- column = column.trim();
- }
- if(StringUtils.isEmpty(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;
+ 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(result.getServiceDef());
+ 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));
+ }
+ if (result.getIsAudited()) {
+ auditHandler.logAuditEventForFiltering(result, hiveOpType);
+ }
+ }
+ } 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);
+
+ for(String column : columns) {
+ if (column != null) {
+ column = column.trim();
+ }
+ if(StringUtils.isEmpty(column.trim())) {
+ continue;
}
+
+ RangerHiveResource colResource = new RangerHiveResource(HiveObjectType.COLUMN, resource.getDatabase(), resource.getTable(), column);
+
+ RangerHiveAccessRequest colRequest = request.copy();
+ colRequest.setResource(colResource);
+
+ colRequests.add(colRequest);
}
- }
- } else {
- result = hivePlugin.isAccessAllowed(request, auditHandler);
- }
-
- if(result != null && !result.getIsAllowed()) {
- String path = resource != null ? resource.getAsString(result.getServiceDef()) : null;
- throw new HiveAccessControlException(String.format("Permission denied: user [%s] does not have [%s] privilege on [%s]",
- user, request.getHiveAccessType().name(), path));
+ 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 != null ? resource.getAsString(result.getServiceDef()) : null;
+
+ throw new HiveAccessControlException(String.format("Permission denied: user [%s] does not have [%s] privilege on [%s]",
+ user, request.getHiveAccessType().name(), path));
+ }
}
}
} finally {
@@ -335,6 +357,29 @@ 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
@@ -347,13 +392,116 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
public List<HivePrivilegeObject> filterListCmdObjects(List<HivePrivilegeObject> objs,
HiveAuthzContext context)
throws HiveAuthzPluginException, HiveAccessControlException {
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("==> filterListCmdObjects(%s, %s)", objs, context));
+ }
+
List<HivePrivilegeObject> ret = null;
- // TODO: only the objects the user has access-to should be added to 'ret'
- ret = objs;
-
+ // bail out early if nothing is there to validate!
+ if (objs == null) {
+ LOG.debug("filterListCmdObjects: meta objects list was null!");
+ } else if (objs.isEmpty()) {
+ LOG.debug("filterListCmdObjects: meta objects list was empty!");
+ ret = objs;
+ } else if (getCurrentUserGroupInfo() == null) {
+ /*
+ * This is null for metastore and there doesn't seem to be a way to tell if one is running as metastore or hiveserver2!
+ */
+ LOG.warn("filterListCmdObjects: user information not available");
+ ret = objs;
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("filterListCmdObjects: number of input objects[" + objs.size() + "]");
+ }
+ // get user/group info
+ UserGroupInformation ugi = getCurrentUserGroupInfo(); // we know this can't be null since we checked it above!
+ HiveAuthzSessionContext sessionContext = getHiveAuthzSessionContext();
+ String user = ugi.getShortUserName();
+ Set<String> groups = Sets.newHashSet(ugi.getGroupNames());
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("filterListCmdObjects: user[%s], groups%s", user, groups));
+ }
+
+ if (ret == null) { // if we got any items to filter then we can't return back a null. We must return back a list even if its empty.
+ ret = new ArrayList<HivePrivilegeObject>(objs.size());
+ }
+ for (HivePrivilegeObject privilegeObject : objs) {
+ if (LOG.isDebugEnabled()) {
+ HivePrivObjectActionType actionType = privilegeObject.getActionType();
+ HivePrivilegeObjectType objectType = privilegeObject.getType();
+ String objectName = privilegeObject.getObjectName();
+ String dbName = privilegeObject.getDbname();
+ List<String> columns = privilegeObject.getColumns();
+ List<String> partitionKeys = privilegeObject.getPartKeys();
+ String commandString = context.getCommandString();
+ String ipAddress = context.getIpAddress();
+
+ final String format = "filterListCmdObjects: actionType[%s], objectType[%s], objectName[%s], dbName[%s], columns[%s], partitionKeys[%s]; context: commandString[%s], ipAddress[%s]";
+ LOG.debug(String.format(format, actionType, objectType, objectName, dbName, columns, partitionKeys, commandString, ipAddress));
+ }
+
+ RangerHiveResource resource = createHiveResource(privilegeObject);
+ RangerHiveAccessRequest request = new RangerHiveAccessRequest(resource, user, groups, context, sessionContext);
+ RangerAccessResult result = hivePlugin.isAccessAllowed(request);
+ if (result == null) {
+ LOG.error("filterListCmdObjects: Internal error: null RangerAccessResult object received back from isAccessAllowed()!");
+ } else if (!result.getIsAllowed()) {
+ if (!LOG.isDebugEnabled()) {
+ String path = resource.getAsString(result.getServiceDef());
+ LOG.debug(String.format("filterListCmdObjects: Permission denied: user [%s] does not have [%s] privilege on [%s]", user, request.getHiveAccessType().name(), path));
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(String.format("filterListCmdObjects: resource[%s]: allowed!: 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));
+ }
+
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;
+
+ HivePrivilegeObjectType objectType = privilegeObject.getType();
+ String objectName = privilegeObject.getObjectName();
+ String dbName = privilegeObject.getDbname();
+
+ switch(objectType) {
+ case DATABASE:
+ resource = new RangerHiveResource(HiveObjectType.DATABASE, objectName);
+ break;
+ case TABLE_OR_VIEW:
+ resource = new RangerHiveResource(HiveObjectType.TABLE, dbName, objectName);
+ break;
+ default:
+ LOG.warn("RangerHiveAuthorizer.getHiveResource: unexpected objectType:" + objectType);
+ }
+ return resource;
+ }
+
private RangerHiveResource getHiveResource(HiveOperationType hiveOpType,
HivePrivilegeObject hiveObj) {
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/ranger-util/.gitignore
----------------------------------------------------------------------
diff --git a/ranger-util/.gitignore b/ranger-util/.gitignore
index ffdf566..88be44f 100644
--- a/ranger-util/.gitignore
+++ b/ranger-util/.gitignore
@@ -2,3 +2,4 @@
/target/
/bin/
.settings/
+gen/
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/ranger_solrj/pom.xml
----------------------------------------------------------------------
diff --git a/ranger_solrj/pom.xml b/ranger_solrj/pom.xml
index 1924e87..58527f4 100644
--- a/ranger_solrj/pom.xml
+++ b/ranger_solrj/pom.xml
@@ -7,7 +7,6 @@
<artifactId>ranger</artifactId>
<version>0.5.0</version>
</parent>
- <groupId>org.apache.ranger</groupId>
<artifactId>ranger_solrj</artifactId>
<version>0.5.0</version>
<name>ranger_solrj</name>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/ugsync/pom.xml
----------------------------------------------------------------------
diff --git a/ugsync/pom.xml b/ugsync/pom.xml
index aee6e7a..55bc4c3 100644
--- a/ugsync/pom.xml
+++ b/ugsync/pom.xml
@@ -42,8 +42,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>${gson.version}</version>
- </dependency>
+ </dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/unixauthclient/pom.xml
----------------------------------------------------------------------
diff --git a/unixauthclient/pom.xml b/unixauthclient/pom.xml
index b296d33..721cf0f 100644
--- a/unixauthclient/pom.xml
+++ b/unixauthclient/pom.xml
@@ -43,8 +43,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>${gson.version}</version>
- </dependency>
+ </dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ff347709/unixauthservice/pom.xml
----------------------------------------------------------------------
diff --git a/unixauthservice/pom.xml b/unixauthservice/pom.xml
index 920b2cd..89c0a81 100644
--- a/unixauthservice/pom.xml
+++ b/unixauthservice/pom.xml
@@ -49,8 +49,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>${gson.version}</version>
- </dependency>
+ </dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>