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 <[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/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 <[email protected]>
Authored: Thu Mar 19 19:01:59 2015 -0700
Committer: Madhan Neethiraj <[email protected]>
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>

Reply via email to