You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by sd...@apache.org on 2016/04/14 03:58:02 UTC

[6/6] sentry git commit: SENTRY-711: Implement grant user to role (Colin Ma, reviewed by Dapeng Sun)

SENTRY-711: Implement grant user to role (Colin Ma, reviewed by Dapeng Sun)


Project: http://git-wip-us.apache.org/repos/asf/sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/68949951
Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/68949951
Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/68949951

Branch: refs/heads/master
Commit: 68949951e97b206766bf3e07d24399d80799e7af
Parents: 04881fa
Author: Colin Ma <co...@apache.org>
Authored: Wed Apr 13 15:03:56 2016 +0800
Committer: Colin Ma <co...@apache.org>
Committed: Thu Apr 14 09:21:55 2016 +0800

----------------------------------------------------------------------
 .../binding/hive/HiveAuthzBindingHookBase.java  |    8 +-
 .../hive/ql/exec/SentryGrantRevokeTask.java     |   29 +-
 .../SentryHiveAuthorizationTaskFactoryImpl.java |    4 +-
 .../TestSentryHiveAuthorizationTaskFactory.java |   50 +-
 .../sentry/policy/common/PolicyEngine.java      |   29 +
 .../sentry/policy/db/SimpleDBPolicyEngine.java  |   21 +
 .../indexer/SimpleIndexerPolicyEngine.java      |   21 +-
 .../policy/kafka/SimpleKafkaPolicyEngine.java   |   20 +
 .../policy/search/SimpleSearchPolicyEngine.java |   21 +-
 .../policy/sqoop/SimpleSqoopPolicyEngine.java   |   19 +
 .../sentry/provider/cache/PrivilegeCache.java   |    7 +
 .../cache/SimpleCacheProviderBackend.java       |   11 +
 .../provider/cache/SimplePrivilegeCache.java    |    8 +
 .../provider/cache/PrivilegeCacheTestImpl.java  |    5 +
 .../sentry/provider/common/ProviderBackend.java |    8 +-
 .../common/ResourceAuthorizationProvider.java   |   13 +-
 .../provider/common/TestGetGroupMapping.java    |   19 +-
 .../db/service/thrift/SentryPolicyService.java  | 2564 +++++++++++++++++-
 .../thrift/TAlterSentryRoleAddUsersRequest.java |  740 +++++
 .../TAlterSentryRoleAddUsersResponse.java       |  390 +++
 .../TAlterSentryRoleDeleteGroupsRequest.java    |   36 +-
 .../TAlterSentryRoleDeleteUsersRequest.java     |  740 +++++
 .../TAlterSentryRoleDeleteUsersResponse.java    |  390 +++
 .../TAlterSentryRoleGrantPrivilegeRequest.java  |   36 +-
 .../TAlterSentryRoleGrantPrivilegeResponse.java |   36 +-
 .../TAlterSentryRoleRevokePrivilegeRequest.java |   36 +-
 .../TListSentryPrivilegesByAuthRequest.java     |   68 +-
 .../TListSentryPrivilegesByAuthResponse.java    |   52 +-
 ...TListSentryPrivilegesForProviderRequest.java |  198 +-
 ...ListSentryPrivilegesForProviderResponse.java |   32 +-
 .../thrift/TListSentryPrivilegesResponse.java   |   36 +-
 .../thrift/TListSentryRolesForUserRequest.java  |  587 ++++
 .../thrift/TListSentryRolesResponse.java        |   36 +-
 .../db/service/thrift/TSentryActiveRoleSet.java |   32 +-
 .../db/service/thrift/TSentryMappingData.java   |  148 +-
 .../db/service/thrift/TSentryPrivilegeMap.java  |   76 +-
 .../provider/db/service/thrift/TSentryRole.java |   36 +-
 .../provider/db/SimpleDBProviderBackend.java    |   15 +-
 .../generic/SentryGenericProviderBackend.java   |    7 +
 .../db/log/entity/JsonLogEntityFactory.java     |   40 +
 .../provider/db/log/util/CommandUtil.java       |   28 +-
 .../sentry/provider/db/log/util/Constants.java  |   22 +-
 .../provider/db/service/model/MSentryRole.java  |   29 +-
 .../provider/db/service/model/MSentryUser.java  |  116 +
 .../provider/db/service/model/package.jdo       |   78 +-
 .../db/service/persistent/SentryStore.java      |  254 +-
 .../db/service/thrift/NotificationHandler.java  |    8 +
 .../thrift/NotificationHandlerInvoker.java      |   30 +
 .../thrift/SentryPolicyServiceClient.java       |   19 +-
 .../SentryPolicyServiceClientDefaultImpl.java   |   79 +-
 .../thrift/SentryPolicyStoreProcessor.java      |  155 +-
 .../main/resources/sentry_policy_service.thrift |   37 +-
 .../provider/db/log/util/TestCommandUtil.java   |   42 +-
 .../db/service/persistent/TestSentryStore.java  |  461 +++-
 .../TestSentryServerForHaWithoutKerberos.java   |   60 +-
 .../thrift/TestSentryServerWithoutKerberos.java |   59 +-
 .../thrift/TestSentryServiceIntegration.java    |  226 ++
 .../file/SimpleFileProviderBackend.java         |    7 +
 .../tests/e2e/dbprovider/TestDbDDLAuditLog.java |   18 +
 .../e2e/dbprovider/TestGrantUserToRole.java     |  237 ++
 60 files changed, 7938 insertions(+), 651 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java
index 6df939f..a00f2d5 100644
--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java
+++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/HiveAuthzBindingHookBase.java
@@ -75,6 +75,7 @@ import org.slf4j.LoggerFactory;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
 
 public abstract class HiveAuthzBindingHookBase extends AbstractSemanticAnalyzerHook {
   private static final Logger LOG = LoggerFactory
@@ -747,9 +748,10 @@ public abstract class HiveAuthzBindingHookBase extends AbstractSemanticAnalyzerH
       String userName) throws SemanticException {
     // get the original HiveAuthzBinding, and get the user's privileges by AuthorizationProvider
     AuthorizationProvider authProvider = hiveAuthzBinding.getCurrentAuthProvider();
-    Set<String> userPrivileges = authProvider.getPolicyEngine().getPrivileges(
-            authProvider.getGroupMapping().getGroups(userName), hiveAuthzBinding.getActiveRoleSet(),
-            hiveAuthzBinding.getAuthServer());
+    Set<String> userPrivileges =
+        authProvider.getPolicyEngine().getPrivileges(
+            authProvider.getGroupMapping().getGroups(userName), Sets.newHashSet(userName),
+            hiveAuthzBinding.getActiveRoleSet(), hiveAuthzBinding.getAuthServer());
 
     // create PrivilegeCache using user's privileges
     PrivilegeCache privilegeCache = new SimplePrivilegeCache(userPrivileges);

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java
index cd8352a..217b7b3 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/hadoop/hive/ql/exec/SentryGrantRevokeTask.java
@@ -237,11 +237,14 @@ public class SentryGrantRevokeTask extends Task<DDLWork> implements Serializable
       } else if (operation.equals(RoleDDLDesc.RoleOperation.SHOW_ROLE_GRANT)) {
         Set<TSentryRole> roles;
         PrincipalType principalType = desc.getPrincipalType();
-        if (principalType != PrincipalType.GROUP) {
+        if (principalType == PrincipalType.GROUP) {
+          roles = sentryClient.listRolesByGroupName(subject, name);
+        } else if (principalType == PrincipalType.USER) {
+          roles = sentryClient.listRolesByUserName(subject, name);
+        } else {
           String msg = SentryHiveConstants.GRANT_REVOKE_NOT_SUPPORTED_FOR_PRINCIPAL + principalType;
           throw new HiveException(msg);
         }
-        roles = sentryClient.listRolesByGroupName(subject, desc.getName() );
         writeToFile(writeRoleGrantsInfo(roles), desc.getResFile());
         return RETURN_CODE_SUCCESS;
       } else if(operation.equals(RoleDDLDesc.RoleOperation.SHOW_ROLES)) {
@@ -407,21 +410,35 @@ public class SentryGrantRevokeTask extends Task<DDLWork> implements Serializable
       List<String> roles = desc.getRoles();
       // get principals
       Set<String> groups = Sets.newHashSet();
+      Set<String> users = Sets.newHashSet();
       for (PrincipalDesc principal : principals) {
-        if (principal.getType() != PrincipalType.GROUP) {
+        if (principal.getType() == PrincipalType.GROUP) {
+          groups.add(principal.getName());
+        } else if (principal.getType() == PrincipalType.USER) {
+          users.add(principal.getName());
+        } else {
           String msg = SentryHiveConstants.GRANT_REVOKE_NOT_SUPPORTED_FOR_PRINCIPAL +
               principal.getType();
           throw new HiveException(msg);
         }
-        groups.add(principal.getName());
       }
 
       // grant/revoke role to/from principals
       for (String roleName : roles) {
         if (grantRole) {
-          sentryClient.grantRoleToGroups(subject, roleName, groups);
+          if (groups.size() > 0) {
+            sentryClient.grantRoleToGroups(subject, roleName, groups);
+          }
+          if (users.size() > 0) {
+            sentryClient.grantRoleToUsers(subject, roleName, users);
+          }
         } else {
-          sentryClient.revokeRoleFromGroups(subject, roleName, groups);
+          if (groups.size() > 0) {
+            sentryClient.revokeRoleFromGroups(subject, roleName, groups);
+          }
+          if (users.size() > 0) {
+            sentryClient.revokeRoleFromUsers(subject, roleName, users);
+          }
         }
       }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
index caf32cf..0d1db89 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
@@ -102,7 +102,7 @@ public class SentryHiveAuthorizationTaskFactoryImpl implements HiveAuthorization
       principalType = PrincipalType.ROLE;
       break;
     }
-    if (principalType != PrincipalType.GROUP) {
+    if (principalType != PrincipalType.GROUP  && principalType != PrincipalType.USER) {
       String msg = SentryHiveConstants.GRANT_REVOKE_NOT_SUPPORTED_FOR_PRINCIPAL + principalType;
       throw new SemanticException(msg);
     }
@@ -241,7 +241,7 @@ public class SentryHiveAuthorizationTaskFactoryImpl implements HiveAuthorization
       roleOwnerName = SessionState.get().getAuthenticator().getUserName();
     }
     for (PrincipalDesc princ : principalDesc) {
-      if (princ.getType() != PrincipalType.GROUP) {
+      if (princ.getType() != PrincipalType.GROUP && princ.getType() != PrincipalType.USER) {
         String msg = SentryHiveConstants.GRANT_REVOKE_NOT_SUPPORTED_ON_OBJECT + princ.getType();
         throw new SemanticException(msg);
       }

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java
index dfe93a5..4fcb71c 100644
--- a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryHiveAuthorizationTaskFactory.java
@@ -17,6 +17,11 @@
  */
 package org.apache.sentry.binding.hive;
 
+import java.io.File;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+
 import org.junit.Assert;
 
 import org.apache.commons.io.FileUtils;
@@ -54,11 +59,6 @@ import org.mockito.Mockito;
 
 import com.google.common.io.Files;
 
-import java.io.File;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.List;
-
 public class TestSentryHiveAuthorizationTaskFactory {
 
   private static final String ALL = "ALL";
@@ -237,8 +237,20 @@ public class TestSentryHiveAuthorizationTaskFactory {
    */
   @Test
   public void testGrantRoleUser() throws Exception {
-    expectSemanticException("GRANT ROLE " + ROLE + " TO USER " + USER,
-        SentryHiveConstants.GRANT_REVOKE_NOT_SUPPORTED_ON_OBJECT + "USER");
+    DDLWork work = analyze(parse("GRANT ROLE " + ROLE + " TO USER " + USER));
+    GrantRevokeRoleDDL grantDesc = work.getGrantRevokeRoleDDL();
+    Assert.assertNotNull("Grant should not be null", grantDesc);
+    Assert.assertTrue("Expected grant ", grantDesc.getGrant());
+    Assert.assertFalse("Grant option should be false", grantDesc.isGrantOption());
+    Assert.assertEquals(currentUser, grantDesc.getGrantor());
+    Assert.assertEquals(PrincipalType.USER, grantDesc.getGrantorType());
+    for (String role : assertSize(1, grantDesc.getRoles())) {
+      Assert.assertEquals(ROLE, role);
+    }
+    for (PrincipalDesc principal : assertSize(1, grantDesc.getPrincipalDesc())) {
+      Assert.assertEquals(PrincipalType.USER, principal.getType());
+      Assert.assertEquals(USER, principal.getName());
+    }
   }
 
   /**
@@ -277,8 +289,20 @@ public class TestSentryHiveAuthorizationTaskFactory {
    */
   @Test
   public void testRevokeRoleUser() throws Exception {
-    expectSemanticException("REVOKE ROLE " + ROLE + " FROM USER " + USER,
-        SentryHiveConstants.GRANT_REVOKE_NOT_SUPPORTED_ON_OBJECT + "USER");
+    DDLWork work = analyze(parse("REVOKE ROLE " + ROLE + " FROM USER " + USER));
+    GrantRevokeRoleDDL grantDesc = work.getGrantRevokeRoleDDL();
+    Assert.assertNotNull("Grant should not be null", grantDesc);
+    Assert.assertFalse("Did not expect grant ", grantDesc.getGrant());
+    Assert.assertFalse("Grant option is always true ", grantDesc.isGrantOption());
+    Assert.assertEquals(currentUser, grantDesc.getGrantor());
+    Assert.assertEquals(PrincipalType.USER, grantDesc.getGrantorType());
+    for (String role : assertSize(1, grantDesc.getRoles())) {
+      Assert.assertEquals(ROLE, role);
+    }
+    for (PrincipalDesc principal : assertSize(1, grantDesc.getPrincipalDesc())) {
+      Assert.assertEquals(PrincipalType.USER, principal.getType());
+      Assert.assertEquals(USER, principal.getName());
+    }
   }
 
   /**
@@ -316,8 +340,12 @@ public class TestSentryHiveAuthorizationTaskFactory {
    */
   @Test
   public void testShowRoleGrantUser() throws Exception {
-    expectSemanticException("SHOW ROLE GRANT USER " + USER,
-        SentryHiveConstants.GRANT_REVOKE_NOT_SUPPORTED_FOR_PRINCIPAL + "USER");
+    DDLWork work = analyze(parse("SHOW ROLE GRANT USER " + USER));
+    RoleDDLDesc roleDesc = work.getRoleDDLDesc();
+    Assert.assertNotNull("Role should not be null", roleDesc);
+    Assert.assertEquals(RoleOperation.SHOW_ROLE_GRANT, roleDesc.getOperation());
+    Assert.assertEquals(PrincipalType.USER, roleDesc.getPrincipalType());
+    Assert.assertEquals(USER, roleDesc.getName());
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyEngine.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyEngine.java
index bbb009c..b7d8c32 100644
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyEngine.java
+++ b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyEngine.java
@@ -53,6 +53,20 @@ public interface PolicyEngine {
       throws SentryConfigurationException;
 
   /**
+   * Get privileges associated with groups and users. Returns Strings which can be resolved by the
+   * caller. Strings are returned to separate the PolicyFile class from the type of privileges used
+   * in a policy file. Additionally it is possible further processing of the privileges is needed
+   * before resolving to a privilege object.
+   *
+   * @param group name
+   * @param user name
+   * @param active role-set
+   * @return non-null immutable set of privileges
+   */
+  ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users, ActiveRoleSet roleSet)
+      throws SentryConfigurationException;
+
+  /**
    * Get privileges associated with a group. Returns Strings which can be resolved
    * by the caller. Strings are returned to separate the PolicyFile class from the
    * type of privileges used in a policy file. Additionally it is possible further
@@ -65,6 +79,21 @@ public interface PolicyEngine {
   ImmutableSet<String> getPrivileges(Set<String> groups, ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
       throws SentryConfigurationException;
 
+  /**
+   * Get privileges associated with groups and users. Returns Strings which can be resolved by the
+   * caller. Strings are returned to separate the PolicyFile class from the type of privileges used
+   * in a policy file. Additionally it is possible further processing of the privileges is needed
+   * before resolving to a privilege object.
+   *
+   * @param group name
+   * @param user name
+   * @param active role-set
+   * @param authorizable Hierarchy (Can be null)
+   * @return non-null immutable set of privileges
+   */
+  ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users, ActiveRoleSet roleSet,
+      Authorizable... authorizableHierarchy) throws SentryConfigurationException;
+
   void close();
 
   void validatePolicy(boolean strictValidation) throws SentryConfigurationException;

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/SimpleDBPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/SimpleDBPolicyEngine.java b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/SimpleDBPolicyEngine.java
index b5b584f..9d25592 100644
--- a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/SimpleDBPolicyEngine.java
+++ b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/SimpleDBPolicyEngine.java
@@ -65,6 +65,12 @@ public class SimpleDBPolicyEngine implements PolicyEngine {
     return getPrivileges(groups, roleSet);
   }
 
+  @Override
+  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet) throws SentryConfigurationException {
+    return getPrivileges(groups, users, roleSet);
+  }
+
   /**
    * {@inheritDoc}
    */
@@ -82,6 +88,21 @@ public class SimpleDBPolicyEngine implements PolicyEngine {
   }
 
   @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
+      throws SentryConfigurationException {
+    if (LOGGER.isDebugEnabled()) {
+      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
+    }
+    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet,
+        authorizableHierarchy);
+    if (LOGGER.isDebugEnabled()) {
+      LOGGER.debug("result = " + result);
+    }
+    return result;
+  }
+
+  @Override
   public void validatePolicy(boolean strictValidation) throws SentryConfigurationException {
     this.providerBackend.validatePolicy(strictValidation);
   }

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java
index 2f4bc1d..8914319 100644
--- a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java
+++ b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java
@@ -21,8 +21,8 @@ import java.util.Set;
 import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.policy.common.PrivilegeFactory;
 import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.policy.common.PrivilegeFactory;
 import org.apache.sentry.policy.common.PrivilegeValidator;
 import org.apache.sentry.provider.common.ProviderBackend;
 import org.apache.sentry.provider.common.ProviderBackendContext;
@@ -67,6 +67,12 @@ public class SimpleIndexerPolicyEngine implements PolicyEngine {
     return getPrivileges(groups, roleSet);
   }
 
+  @Override
+  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet) throws SentryConfigurationException {
+    return getPrivileges(groups, users, roleSet);
+  }
+
   /**
    * {@inheritDoc}
    */
@@ -83,6 +89,19 @@ public class SimpleIndexerPolicyEngine implements PolicyEngine {
   }
 
   @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet, Authorizable... authorizationHierarchy) {
+    if(LOGGER.isDebugEnabled()) {
+      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
+    }
+    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet);
+    if(LOGGER.isDebugEnabled()) {
+      LOGGER.debug("result = " + result);
+    }
+    return result;
+  }
+
+  @Override
   public void validatePolicy(boolean strictValidation)
       throws SentryConfigurationException {
     throw new SentryConfigurationException("Not implemented yet");

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/SimpleKafkaPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/SimpleKafkaPolicyEngine.java b/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/SimpleKafkaPolicyEngine.java
index 7e043e1..4d90544 100644
--- a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/SimpleKafkaPolicyEngine.java
+++ b/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/SimpleKafkaPolicyEngine.java
@@ -84,4 +84,24 @@ public class SimpleKafkaPolicyEngine implements PolicyEngine {
     }
   }
 
+  @Override
+  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet) throws SentryConfigurationException {
+    return getPrivileges(groups, users, roleSet);
+  }
+
+  @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
+      throws SentryConfigurationException {
+    if(LOGGER.isDebugEnabled()) {
+      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
+    }
+    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet);
+    if(LOGGER.isDebugEnabled()) {
+      LOGGER.debug("result = " + result);
+    }
+    return result;
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SimpleSearchPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SimpleSearchPolicyEngine.java b/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SimpleSearchPolicyEngine.java
index bc518fb..c71036e 100644
--- a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SimpleSearchPolicyEngine.java
+++ b/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SimpleSearchPolicyEngine.java
@@ -21,8 +21,8 @@ import java.util.Set;
 import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.policy.common.PrivilegeFactory;
 import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.policy.common.PrivilegeFactory;
 import org.apache.sentry.policy.common.PrivilegeValidator;
 import org.apache.sentry.provider.common.ProviderBackend;
 import org.apache.sentry.provider.common.ProviderBackendContext;
@@ -83,6 +83,25 @@ public class SimpleSearchPolicyEngine implements PolicyEngine {
   }
 
   @Override
+  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet) throws SentryConfigurationException {
+    return getPrivileges(groups, users, roleSet);
+  }
+
+  @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet, Authorizable... authorizationHierarchy) {
+    if (LOGGER.isDebugEnabled()) {
+      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
+    }
+    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet);
+    if (LOGGER.isDebugEnabled()) {
+      LOGGER.debug("result = " + result);
+    }
+    return result;
+  }
+
+  @Override
   public void validatePolicy(boolean strictValidation)
       throws SentryConfigurationException {
     providerBackend.validatePolicy(strictValidation);

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SimpleSqoopPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SimpleSqoopPolicyEngine.java b/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SimpleSqoopPolicyEngine.java
index e8615a0..13f78c6 100644
--- a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SimpleSqoopPolicyEngine.java
+++ b/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SimpleSqoopPolicyEngine.java
@@ -69,6 +69,25 @@ public class SimpleSqoopPolicyEngine implements PolicyEngine {
   }
 
   @Override
+  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet) throws SentryConfigurationException {
+    return getPrivileges(groups, users, roleSet);
+  }
+
+  @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet, Authorizable... authorizationHierarchy) {
+    if(LOGGER.isDebugEnabled()) {
+      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
+    }
+    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet);
+    if(LOGGER.isDebugEnabled()) {
+      LOGGER.debug("result = " + result);
+    }
+    return result;
+  }
+
+  @Override
   public void close() {
     if (providerBackend != null) {
       providerBackend.close();

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java
index 811b931..28c5b76 100644
--- a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java
+++ b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/PrivilegeCache.java
@@ -29,5 +29,12 @@ public interface PrivilegeCache {
   Set<String> listPrivileges(Set<String> groups,
       ActiveRoleSet roleSet);
 
+  /**
+   * Get the privileges for the give set of groups and users with the give active
+   * roles from the cache.
+   */
+  Set<String> listPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet);
+
   void close();
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java
index 73ed6c2..d8b9063 100644
--- a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java
+++ b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimpleCacheProviderBackend.java
@@ -66,6 +66,17 @@ public class SimpleCacheProviderBackend implements ProviderBackend {
   }
 
   @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet, Authorizable... authorizableHierarchy) {
+    if (!initialized()) {
+      throw new IllegalStateException(
+          "Backend has not been properly initialized");
+    }
+    return ImmutableSet.copyOf(cacheHandle.listPrivileges(groups, users,
+        roleSet));
+  }
+
+  @Override
   public ImmutableSet<String> getRoles(Set<String> groups, ActiveRoleSet roleSet) {
     if (!initialized()) {
       throw new IllegalStateException(

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java
index 2643a32..dd0c39a 100644
--- a/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java
+++ b/sentry-provider/sentry-provider-cache/src/main/java/org/apache/sentry/provider/cache/SimplePrivilegeCache.java
@@ -48,4 +48,12 @@ public class SimplePrivilegeCache implements PrivilegeCache {
       cachedPrivileges.clear();
     }
   }
+
+  @Override
+  public Set<String> listPrivileges(Set<String> groups, Set<String> users, ActiveRoleSet roleSet) {
+    if (cachedPrivileges == null) {
+      cachedPrivileges = new HashSet<String>();
+    }
+    return cachedPrivileges;
+  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java b/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java
index a7566e7..79e047e 100644
--- a/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java
+++ b/sentry-provider/sentry-provider-cache/src/test/java/org/apache/sentry/provider/cache/PrivilegeCacheTestImpl.java
@@ -60,4 +60,9 @@ public class PrivilegeCacheTestImpl implements PrivilegeCache {
       FileUtils.deleteQuietly(baseDir);
     }
   }
+
+  @Override
+  public Set<String> listPrivileges(Set<String> groups, Set<String> users, ActiveRoleSet roleSet) {
+    return backend.getPrivileges(groups, users, roleSet);
+  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackend.java b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackend.java
index b19a170..ffd3af4 100644
--- a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackend.java
+++ b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackend.java
@@ -45,11 +45,17 @@ public interface ProviderBackend {
   void initialize(ProviderBackendContext context);
 
   /**
-   * Get the privileges from the backend.
+   * Get the privileges from the backend for groups.
    */
   ImmutableSet<String> getPrivileges(Set<String> groups, ActiveRoleSet roleSet, Authorizable... authorizableHierarchy);
 
   /**
+   * Get the privileges from the backend for users and groups.
+   */
+  ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet, Authorizable... authorizableHierarchy);
+
+  /**
    * Get the roles associated with the groups from the backend.
    */
   ImmutableSet<String> getRoles(Set<String> groups, ActiveRoleSet roleSet);

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java
index 0cf0b5d..b023c9a 100644
--- a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java
+++ b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java
@@ -95,12 +95,14 @@ public abstract class ResourceAuthorizationProvider implements AuthorizationProv
       List<? extends Authorizable> authorizables, Set<? extends Action> actions,
       ActiveRoleSet roleSet) {
     Set<String> groups =  getGroups(subject);
+    Set<String> users = Sets.newHashSet(subject.getName());
     Set<String> hierarchy = new HashSet<String>();
     for (Authorizable authorizable : authorizables) {
       hierarchy.add(KV_JOINER.join(authorizable.getTypeName(), authorizable.getName()));
     }
     List<String> requestPrivileges = buildPermissions(authorizables, actions);
-    Iterable<Privilege> privileges = getPrivileges(groups, roleSet, authorizables.toArray(new Authorizable[0]));
+    Iterable<Privilege> privileges = getPrivileges(groups, users, roleSet,
+        authorizables.toArray(new Authorizable[0]));
     lastFailedPrivileges.get().clear();
 
     for (String requestPrivilege : requestPrivileges) {
@@ -123,8 +125,10 @@ public abstract class ResourceAuthorizationProvider implements AuthorizationProv
     return false;
   }
 
-  private Iterable<Privilege> getPrivileges(Set<String> groups, ActiveRoleSet roleSet, Authorizable[] authorizables) {
-    return Iterables.transform(appendDefaultDBPriv(policy.getPrivileges(groups, roleSet, authorizables), authorizables),
+  private Iterable<Privilege> getPrivileges(Set<String> groups, Set<String> users,
+      ActiveRoleSet roleSet, Authorizable[] authorizables) {
+    ImmutableSet<String> privileges = policy.getPrivileges(groups, users, roleSet, authorizables);
+    return Iterables.transform(appendDefaultDBPriv(privileges, authorizables),
         new Function<String, Privilege>() {
       @Override
       public Privilege apply(String privilege) {
@@ -172,7 +176,8 @@ public abstract class ResourceAuthorizationProvider implements AuthorizationProv
 
   @Override
   public Set<String> listPrivilegesForSubject(Subject subject) throws SentryConfigurationException {
-    return policy.getPrivileges(getGroups(subject), ActiveRoleSet.ALL);
+    return policy.getPrivileges(getGroups(subject), Sets.newHashSet(subject.getName()),
+        ActiveRoleSet.ALL, (Authorizable[]) null);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/sentry/blob/68949951/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java b/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java
index 14af2d4..402574e 100644
--- a/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java
+++ b/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java
@@ -20,11 +20,11 @@ import static org.junit.Assert.assertSame;
 
 import java.util.Set;
 
+import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.policy.common.PrivilegeFactory;
 import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.policy.common.PrivilegeFactory;
 import org.junit.Test;
 
 import com.google.common.collect.ImmutableSet;
@@ -53,7 +53,7 @@ public class TestGetGroupMapping {
       @Override
       public ImmutableSet<String> getAllPrivileges(Set<String> groups,
           ActiveRoleSet roleSet) throws SentryConfigurationException {
-        return getPrivileges(groups, roleSet, null);
+        return getPrivileges(groups, roleSet);
       }
 
       @Override
@@ -67,6 +67,19 @@ public class TestGetGroupMapping {
       }
 
       @Override
+      public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
+          ActiveRoleSet roleSet) throws SentryConfigurationException {
+        return getPrivileges(groups, users, roleSet);
+      }
+
+      @Override
+      public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
+          ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
+          throws SentryConfigurationException {
+        return ImmutableSet.of();
+      }
+
+      @Override
       public void close() {}
     };