You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by gq...@apache.org on 2015/05/12 09:06:54 UTC

incubator-sentry git commit: SENTRY-612: Sqoop2 integration with sentry (Guoquan Shen, reviewed by Prasad Mujumdar)

Repository: incubator-sentry
Updated Branches:
  refs/heads/master 6498ce90d -> 357d83fbc


SENTRY-612: Sqoop2 integration with sentry (Guoquan Shen, reviewed by Prasad Mujumdar)


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

Branch: refs/heads/master
Commit: 357d83fbc619ba14bb63a6dce0200c5560e18376
Parents: 6498ce9
Author: Guoquan Shen <gu...@intel.com>
Authored: Tue May 12 14:43:06 2015 +0800
Committer: Guoquan Shen <gu...@intel.com>
Committed: Tue May 12 14:43:06 2015 +0800

----------------------------------------------------------------------
 pom.xml                                         |  26 ++
 sentry-binding/pom.xml                          |   1 +
 sentry-binding/sentry-binding-sqoop/pom.xml     |  80 ++++
 .../org/apache/sentry/sqoop/PrincipalDesc.java  |  50 +++
 .../apache/sentry/sqoop/SentrySqoopError.java   |  32 ++
 .../sqoop/authz/SentryAccessController.java     | 192 +++++++++
 .../sqoop/authz/SentryAuthorizationHander.java  | 117 ++++++
 .../authz/SentryAuthorizationValidator.java     |  63 +++
 .../sentry/sqoop/binding/SqoopAuthBinding.java  | 393 +++++++++++++++++++
 .../binding/SqoopAuthBindingSingleton.java      |  96 +++++
 .../sqoop/binding/SqoopProviderBackend.java     |  44 +++
 .../apache/sentry/sqoop/conf/SqoopAuthConf.java |  75 ++++
 .../sqoop/MockAuthenticationProvider.java       |  32 ++
 .../sqoop/TestSentryAuthorizationHander.java    |  74 ++++
 .../apache/sentry/sqoop/TestSqoopAuthConf.java  |  62 +++
 .../test/resources/no-configure-sentry-site.xml |  22 ++
 .../src/test/resources/sentry-site.xml          |  38 ++
 .../src/test/resources/test-authz-provider.ini  |  40 ++
 sentry-dist/pom.xml                             |   4 +
 .../provider/common/AuthorizationComponent.java |   1 +
 sentry-provider/sentry-provider-db/pom.xml      |   4 +
 .../generic/SentryGenericProviderBackend.java   | 153 ++++++++
 .../persistent/PrivilegeOperatePersistence.java |   2 +
 .../thrift/SentryGenericPolicyProcessor.java    |   9 +
 24 files changed, 1610 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 863f70c..8bcf1d0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,6 +94,7 @@ limitations under the License.
     <objenesis.version>1.2</objenesis.version>
     <cglib.version>2.2</cglib.version>
     <commons-pool2.version>2.2</commons-pool2.version>
+    <sqoop.version>1.99.6</sqoop.version>
   </properties>
 
   <dependencyManagement>
@@ -371,6 +372,11 @@ limitations under the License.
       </dependency>
       <dependency>
         <groupId>org.apache.sentry</groupId>
+        <artifactId>sentry-binding-sqoop</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.sentry</groupId>
         <artifactId>sentry-provider-common</artifactId>
         <version>${project.version}</version>
       </dependency>
@@ -531,6 +537,26 @@ limitations under the License.
         <artifactId>commons-pool2</artifactId>
         <version>${commons-pool2.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.sqoop</groupId>
+        <artifactId>sqoop-common</artifactId>
+        <version>${sqoop.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.sqoop</groupId>
+        <artifactId>sqoop-security</artifactId>
+        <version>${sqoop.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.sqoop</groupId>
+        <artifactId>sqoop-server</artifactId>
+        <version>${sqoop.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.sqoop</groupId>
+        <artifactId>test</artifactId>
+        <version>${sqoop.version}</version>
+      </dependency>
     </dependencies>
   </dependencyManagement>
 

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/pom.xml b/sentry-binding/pom.xml
index b903ab3..8e0256c 100644
--- a/sentry-binding/pom.xml
+++ b/sentry-binding/pom.xml
@@ -32,6 +32,7 @@ limitations under the License.
   <modules>
     <module>sentry-binding-hive</module>
     <module>sentry-binding-solr</module>
+    <module>sentry-binding-sqoop</module>
   </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/pom.xml b/sentry-binding/sentry-binding-sqoop/pom.xml
new file mode 100644
index 0000000..2d25d21
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.sentry</groupId>
+    <artifactId>sentry-binding</artifactId>
+    <version>1.6.0-incubating-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>sentry-binding-sqoop</artifactId>
+  <name>Sentry Binding for Sqoop</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-core-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-core-model-sqoop</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-provider-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-provider-file</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-provider-db</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-policy-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-policy-sqoop</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+	<dependency>
+        <groupId>org.apache.sqoop</groupId>
+        <artifactId>sqoop-common</artifactId>
+    </dependency>
+	<dependency>
+        <groupId>org.apache.sqoop</groupId>
+        <artifactId>sqoop-security</artifactId>
+    </dependency>
+  </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/PrincipalDesc.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/PrincipalDesc.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/PrincipalDesc.java
new file mode 100644
index 0000000..cc9096c
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/PrincipalDesc.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop;
+
+public class PrincipalDesc {
+  public static enum PrincipalType {
+    USER,
+    ROLE,
+    GROUP;
+  }
+
+  private String name;
+  private PrincipalType type;
+
+  public PrincipalDesc(String name, String type) {
+    this.name = name;
+    this.type = fromStr(type);
+  }
+
+  private PrincipalType fromStr(String str) {
+    return Enum.valueOf(PrincipalType.class, str.toUpperCase());
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public PrincipalType getType() {
+    return type;
+  }
+
+  public static PrincipalDesc fromStr(String name, String type) {
+    return new PrincipalDesc(name, type);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/SentrySqoopError.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/SentrySqoopError.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/SentrySqoopError.java
new file mode 100644
index 0000000..b86c59f
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/SentrySqoopError.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop;
+
+public class SentrySqoopError {
+  public static final String SHOW_GRANT_NOT_SUPPORTED_FOR_PRINCIPAL =
+      "Sentry does only support show roles on group, not supported on ";
+  public static final String AUTHORIZE_CHECK_NOT_SUPPORT_FOR_PRINCIPAL =
+      "Sentry does only support authorization check on user principal, not supported on ";
+  public static final String SHOW_PRIVILEGE_NOT_SUPPORTED_FOR_PRINCIPAL =
+      "Sentry does only support show privilege on role, not supported on ";
+  public static final String GRANT_REVOKE_PRIVILEGE_NOT_SUPPORT_FOR_PRINCIPAL =
+      "Sentry does only support grant/revoke privilege to/from role, not supported on ";
+  public static final String GRANT_REVOKE_ROLE_NOT_SUPPORT_FOR_PRINCIPAL =
+      "Sentry does only support grant/revoke role to/from group, not supported on ";
+  public static final String NOT_IMPLEMENT_YET =
+      "Sentry does not implement yet ";
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAccessController.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAccessController.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAccessController.java
new file mode 100644
index 0000000..7762f61
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAccessController.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop.authz;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.sqoop.PrincipalDesc;
+import org.apache.sentry.sqoop.PrincipalDesc.PrincipalType;
+import org.apache.sentry.sqoop.SentrySqoopError;
+import org.apache.sentry.sqoop.binding.SqoopAuthBinding;
+import org.apache.sentry.sqoop.binding.SqoopAuthBindingSingleton;
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MPrincipal;
+import org.apache.sqoop.model.MPrivilege;
+import org.apache.sqoop.model.MResource;
+import org.apache.sqoop.model.MRole;
+import org.apache.sqoop.security.AuthorizationAccessController;
+import org.apache.sqoop.security.SecurityError;
+
+public class SentryAccessController extends AuthorizationAccessController {
+  private static final Logger LOG = Logger.getLogger(SentryAccessController.class);
+  private final SqoopAuthBinding binding;
+
+  public SentryAccessController() throws Exception {
+    this.binding = SqoopAuthBindingSingleton.getInstance().getAuthBinding();
+  }
+
+  private Subject getSubject() {
+    return new Subject(SentryAuthorizationHander.getAuthenticator().getUserName());
+  }
+
+  @Override
+  public void createRole(MRole role) throws SqoopException {
+    binding.createRole(getSubject(), role.getName());
+  }
+
+  @Override
+  public void dropRole(MRole role) throws SqoopException {
+    binding.dropRole(getSubject(), role.getName());
+  }
+
+  @Override
+  public List<MRole> getAllRoles() throws SqoopException {
+    return binding.listAllRoles(getSubject());
+  }
+
+  @Override
+  public List<MPrincipal> getPrincipalsByRole(MRole role) throws SqoopException {
+    /**
+     * Sentry does not implement this function yet
+     */
+    throw new SqoopException(SecurityError.AUTH_0014, SentrySqoopError.NOT_IMPLEMENT_YET);
+  }
+
+  @Override
+  public List<MPrivilege> getPrivilegesByPrincipal(MPrincipal principal,
+      MResource resource) throws SqoopException {
+    /**
+     * Sentry Only supports get privilege by role
+     */
+    PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+    if (principalDesc.getType() != PrincipalType.ROLE) {
+      throw new SqoopException(SecurityError.AUTH_0014,
+          SentrySqoopError.SHOW_PRIVILEGE_NOT_SUPPORTED_FOR_PRINCIPAL
+              + principalDesc.getType().name());
+    }
+    return binding.listPrivilegeByRole(getSubject(), principalDesc.getName(), resource);
+  }
+
+  @Override
+  public List<MRole> getRolesByPrincipal(MPrincipal principal) throws SqoopException {
+    /**
+     * Sentry Only supports get privilege by role
+     */
+    PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+    if (principalDesc.getType() != PrincipalType.GROUP) {
+      throw new SqoopException(SecurityError.AUTH_0014,
+          SentrySqoopError.SHOW_GRANT_NOT_SUPPORTED_FOR_PRINCIPAL
+              + principalDesc.getType().name());
+    }
+    return binding.listRolesByGroup(getSubject(), principalDesc.getName());
+  }
+
+  @Override
+  public void grantPrivileges(List<MPrincipal> principals, List<MPrivilege> privileges)
+      throws SqoopException {
+    for (MPrincipal principal : principals) {
+      PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+      if (principalDesc.getType() != PrincipalType.ROLE) {
+        throw new SqoopException(SecurityError.AUTH_0014,
+            SentrySqoopError.GRANT_REVOKE_PRIVILEGE_NOT_SUPPORT_FOR_PRINCIPAL
+                + principalDesc.getType().name());
+      }
+
+      for (MPrivilege privilege : privileges) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Going to grant privilege : " + privilege +
+              " to principal: " + principal);
+        }
+        binding.grantPrivilege(getSubject(), principal.getName(), privilege);
+      }
+    }
+  }
+
+  @Override
+  public void grantRole(List<MPrincipal> principals, List<MRole> roles)
+      throws SqoopException {
+    for (MPrincipal principal : principals) {
+      PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+      if (principalDesc.getType() != PrincipalType.GROUP) {
+        throw new SqoopException(SecurityError.AUTH_0014,
+            SentrySqoopError.GRANT_REVOKE_ROLE_NOT_SUPPORT_FOR_PRINCIPAL
+                + principalDesc.getType().name());
+      }
+      for (MRole role : roles) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Going to grant role : " + role.getName() +
+              " to principal: " + principal);
+        }
+        binding.grantGroupToRole(getSubject(), principal.getName(), role);
+      }
+    }
+  }
+
+  @Override
+  public void removeResource(MResource resource) throws SqoopException {
+    binding.dropPrivilege(getSubject(), resource);
+  }
+
+  @Override
+  public void revokePrivileges(List<MPrincipal> principals, List<MPrivilege> privileges)
+      throws SqoopException {
+    for (MPrincipal principal : principals) {
+      PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+      if (principalDesc.getType() != PrincipalType.ROLE) {
+        throw new SqoopException(SecurityError.AUTH_0014,
+            SentrySqoopError.GRANT_REVOKE_PRIVILEGE_NOT_SUPPORT_FOR_PRINCIPAL
+                + principalDesc.getType().name());
+      }
+
+      for (MPrivilege privilege : privileges) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Going to revoke privilege : " + privilege +
+              " from principal: " + principal);
+        }
+        binding.revokePrivilege(getSubject(), principal.getName(), privilege);
+      }
+    }
+  }
+
+  @Override
+  public void revokeRole(List<MPrincipal> principals, List<MRole> roles)
+      throws SqoopException {
+    for (MPrincipal principal : principals) {
+      PrincipalDesc principalDesc = PrincipalDesc.fromStr(principal.getName(), principal.getType());
+      if (principalDesc.getType() != PrincipalType.GROUP) {
+        throw new SqoopException(SecurityError.AUTH_0014,
+            SentrySqoopError.GRANT_REVOKE_ROLE_NOT_SUPPORT_FOR_PRINCIPAL
+                + principalDesc.getType().name());
+      }
+      for (MRole role : roles) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Going to revoke role : " + role.getName() +
+              " from principal: " + principal);
+        }
+        binding.revokeGroupfromRole(getSubject(), principal.getName(), role);
+      }
+    }
+  }
+
+  @Override
+  public void updateResource(MResource srcResource, MResource dstResource)
+      throws SqoopException {
+    binding.renamePrivilege(getSubject(), srcResource, dstResource);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationHander.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationHander.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationHander.java
new file mode 100644
index 0000000..93bf3f3
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationHander.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop.authz;
+
+import java.util.List;
+
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MPrincipal;
+import org.apache.sqoop.model.MPrivilege;
+import org.apache.sqoop.model.MResource;
+import org.apache.sqoop.model.MRole;
+import org.apache.sqoop.security.AuthenticationProvider;
+import org.apache.sqoop.security.authorization.DefaultAuthorizationHandler;
+
+public class SentryAuthorizationHander extends DefaultAuthorizationHandler {
+  private static AuthenticationProvider authenticator;
+
+  public static AuthenticationProvider getAuthenticator() {
+    if (authenticator == null) {
+      throw new RuntimeException("authenticator can't be null");
+    }
+    return authenticator;
+  }
+  @Override
+  public void doInitialize(AuthenticationProvider authenticationProvider, String serverName)
+      throws ClassNotFoundException, IllegalAccessException,
+      InstantiationException {
+    super.doInitialize(authenticationProvider, serverName);
+    authenticator = authenticationProvider;
+  }
+
+  @Override
+  public void checkPrivileges(MPrincipal principal, List<MPrivilege> privileges)
+      throws SqoopException {
+    authorizationValidator.checkPrivileges(principal, privileges);
+  }
+
+  @Override
+  public void createRole(MRole role) throws SqoopException {
+    authorizationAccessController.createRole(role);
+  }
+
+  @Override
+  public void dropRole(MRole role) throws SqoopException {
+    authorizationAccessController.dropRole(role);
+  }
+
+  @Override
+  public List<MRole> getAllRoles() throws SqoopException {
+    return authorizationAccessController.getAllRoles();
+  }
+
+  @Override
+  public List<MPrincipal> getPrincipalsByRole(MRole role) throws SqoopException {
+    return authorizationAccessController.getPrincipalsByRole(role);
+  }
+
+  @Override
+  public List<MPrivilege> getPrivilegesByPrincipal(MPrincipal principal,
+      MResource resource) throws SqoopException {
+    return authorizationAccessController.getPrivilegesByPrincipal(principal, resource);
+  }
+
+  @Override
+  public List<MRole> getRolesByPrincipal(MPrincipal principal) throws SqoopException {
+    return authorizationAccessController.getRolesByPrincipal(principal);
+  }
+
+  @Override
+  public void grantPrivileges(List<MPrincipal> principals, List<MPrivilege> privileges)
+      throws SqoopException {
+    authorizationAccessController.grantPrivileges(principals, privileges);
+  }
+
+  @Override
+  public void grantRole(List<MPrincipal> principals, List<MRole> roles)
+      throws SqoopException {
+    authorizationAccessController.grantRole(principals, roles);
+  }
+
+  @Override
+  public void removeResource(MResource resource) throws SqoopException {
+    authorizationAccessController.removeResource(resource);
+  }
+
+  @Override
+  public void revokePrivileges(List<MPrincipal> principals, List<MPrivilege> privileges)
+      throws SqoopException {
+    authorizationAccessController.revokePrivileges(principals, privileges);
+  }
+
+  @Override
+  public void revokeRole(List<MPrincipal> principals, List<MRole> roles)
+      throws SqoopException {
+    authorizationAccessController.revokeRole(principals, roles);
+  }
+
+  @Override
+  public void updateResource(MResource srcResource, MResource dstResource)
+      throws SqoopException {
+    authorizationAccessController.updateResource(srcResource, dstResource);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationValidator.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationValidator.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationValidator.java
new file mode 100644
index 0000000..5f96767
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/authz/SentryAuthorizationValidator.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop.authz;
+
+import java.util.List;
+
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.sqoop.PrincipalDesc;
+import org.apache.sentry.sqoop.PrincipalDesc.PrincipalType;
+import org.apache.sentry.sqoop.SentrySqoopError;
+import org.apache.sentry.sqoop.binding.SqoopAuthBinding;
+import org.apache.sentry.sqoop.binding.SqoopAuthBindingSingleton;
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MPrincipal;
+import org.apache.sqoop.model.MPrivilege;
+import org.apache.sqoop.security.AuthorizationValidator;
+import org.apache.sqoop.security.SecurityError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SentryAuthorizationValidator extends AuthorizationValidator {
+  private static final Logger LOG = LoggerFactory.getLogger(SentryAuthorizationValidator.class);
+  private final SqoopAuthBinding binding;
+
+  public SentryAuthorizationValidator() throws Exception {
+    this.binding = SqoopAuthBindingSingleton.getInstance().getAuthBinding();
+  }
+
+  @Override
+  public void checkPrivileges(MPrincipal principal, List<MPrivilege> privileges) throws SqoopException {
+    if ((privileges == null) || privileges.isEmpty()) {
+      return;
+    }
+    PrincipalDesc principalDesc = new PrincipalDesc(principal.getName(), principal.getType());
+    if (principalDesc.getType() != PrincipalType.USER) {
+      throw new SqoopException(SecurityError.AUTH_0014,SentrySqoopError.AUTHORIZE_CHECK_NOT_SUPPORT_FOR_PRINCIPAL);
+    }
+    for (MPrivilege privilege : privileges) {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Going to authorize check on privilege : " + privilege +
+            " for principal: " + principal);
+      }
+      if (!binding.authorize(new Subject(principalDesc.getName()), privilege)) {
+        throw new SqoopException(SecurityError.AUTH_0014, "User " + principalDesc.getName() +
+            " does not have privileges for : " + privilege.toString());
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
new file mode 100644
index 0000000..86b157c
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
@@ -0,0 +1,393 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop.binding;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.sqoop.Server;
+import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
+import org.apache.sentry.core.model.sqoop.SqoopActionFactory;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.provider.common.AuthorizationComponent;
+import org.apache.sentry.provider.common.AuthorizationProvider;
+import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryRole;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+import org.apache.sqoop.common.SqoopException;
+import org.apache.sqoop.model.MPrivilege;
+import org.apache.sqoop.model.MResource;
+import org.apache.sqoop.model.MRole;
+import org.apache.sqoop.security.SecurityError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+public class SqoopAuthBinding {
+  private static final Logger LOG = LoggerFactory.getLogger(SqoopAuthBinding.class);
+  private static final String COMPONENT_TYPE = AuthorizationComponent.SQOOP;
+
+  private final Configuration authConf;
+  private final AuthorizationProvider authProvider;
+  private final Server sqoopServer;
+  private ProviderBackend providerBackend;
+
+  private final SqoopActionFactory actionFactory = new SqoopActionFactory();
+
+  public SqoopAuthBinding(Configuration authConf, String serverName) throws Exception {
+    this.authConf = authConf;
+    this.authConf.set(AuthzConfVars.AUTHZ_SERVER_NAME.getVar(), serverName);
+    this.sqoopServer = new Server(serverName);
+    this.authProvider = createAuthProvider();
+  }
+
+  /**
+   * Instantiate the configured authz provider
+   * @return {@link AuthorizationProvider}
+   */
+  private AuthorizationProvider createAuthProvider() throws Exception {
+    /**
+     * get the authProvider class, policyEngine class, providerBackend class and resources from the sqoopAuthConf config
+     */
+    String authProviderName = authConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar(),AuthzConfVars.AUTHZ_PROVIDER.getDefault());
+    String resourceName = authConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(), AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getDefault());
+    String providerBackendName = authConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar(), AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getDefault());
+    String policyEngineName = authConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(), AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault());
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Using authorization provider " + authProviderName +
+          " with resource " + resourceName + ", policy engine "
+          + policyEngineName + ", provider backend " + providerBackendName);
+    }
+
+    //Instantiate the configured providerBackend
+    Constructor<?> providerBackendConstructor =
+        Class.forName(providerBackendName).getDeclaredConstructor(Configuration.class, String.class);
+    providerBackendConstructor.setAccessible(true);
+    providerBackend =
+          (ProviderBackend) providerBackendConstructor.newInstance(new Object[] {authConf, resourceName});
+
+    //Instantiate the configured policyEngine
+    Constructor<?> policyConstructor =
+        Class.forName(policyEngineName).getDeclaredConstructor(String.class, ProviderBackend.class);
+    policyConstructor.setAccessible(true);
+    PolicyEngine policyEngine =
+        (PolicyEngine) policyConstructor.newInstance(new Object[] {sqoopServer.getName(), providerBackend});
+
+    //Instantiate the configured authProvider
+    Constructor<?> constrctor =
+        Class.forName(authProviderName).getDeclaredConstructor(Configuration.class, String.class, PolicyEngine.class);
+    constrctor.setAccessible(true);
+    return (AuthorizationProvider) constrctor.newInstance(new Object[] {authConf, resourceName, policyEngine});
+  }
+
+  /**
+   * Authorize access to a Sqoop privilege
+   * @param subject
+   * @param authorizable
+   * @param action
+   * @return true or false
+   */
+  public boolean authorize(Subject subject, MPrivilege privilege) {
+    List<Authorizable> authorizables = toAuthorizable(privilege.getResource());
+    if (!hasServerInclude(authorizables)) {
+      authorizables.add(0, sqoopServer);
+    }
+    return authProvider.hasAccess(subject,
+        authorizables,
+        Sets.newHashSet(actionFactory.getActionByName(privilege.getAction())), ActiveRoleSet.ALL);
+  }
+
+  public boolean hasServerInclude(List<Authorizable> authorizables) {
+    for (Authorizable authorizable : authorizables) {
+      if (authorizable.getTypeName().equalsIgnoreCase(sqoopServer.getTypeName())) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   *  The Sentry-296(generate client for connection pooling) has already finished development and reviewed by now. When it
+   *  was committed to master, the getClient method was needed to refactor using the connection pool
+   */
+  private SentryGenericServiceClient getClient() throws Exception {
+    return new SentryGenericServiceClient(authConf);
+  }
+
+  public void createRole(final Subject subject, final String role) throws SqoopException {
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        client.createRole(subject.getName(), role, COMPONENT_TYPE);
+        return null;
+      }
+    });
+  }
+
+  public void dropRole(final Subject subject, final String role) throws SqoopException {
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        client.dropRole(subject.getName(), role, COMPONENT_TYPE);
+        return null;
+      }
+    });
+  }
+
+  public List<MRole> listAllRoles(final Subject subject) throws SqoopException {
+    Set<TSentryRole> tSentryRoles = execute(new Command<Set<TSentryRole>>() {
+      @Override
+      public Set<TSentryRole> run(SentryGenericServiceClient client)
+          throws Exception {
+        return client.listAllRoles(subject.getName(), COMPONENT_TYPE);
+      }
+    });
+
+    List<MRole> roles = Lists.newArrayList();
+    for (TSentryRole tRole : tSentryRoles) {
+      roles.add(new MRole(tRole.getRoleName()));
+    }
+    return roles;
+  }
+
+  public List<MRole> listRolesByGroup(final Subject subject, final String groupName) throws SqoopException {
+    Set<TSentryRole> tSentryRoles = execute(new Command<Set<TSentryRole>>() {
+      @Override
+      public Set<TSentryRole> run(SentryGenericServiceClient client)
+          throws Exception {
+        return client.listRolesByGroupName(subject.getName(), groupName, COMPONENT_TYPE);
+      }
+    });
+
+    List<MRole> roles = Lists.newArrayList();
+    for (TSentryRole tSentryRole : tSentryRoles) {
+      roles.add(new MRole(tSentryRole.getRoleName()));
+    }
+    return roles;
+  }
+
+  public List<MPrivilege> listPrivilegeByRole(final Subject subject, final String role, final MResource resource) throws SqoopException {
+    Set<TSentryPrivilege> tSentryPrivileges = execute(new Command<Set<TSentryPrivilege>>() {
+      @Override
+      public Set<TSentryPrivilege> run(SentryGenericServiceClient client)
+          throws Exception {
+        if (resource == null) {
+          return client.listPrivilegesByRoleName(subject.getName(), role, COMPONENT_TYPE, sqoopServer.getName());
+        } else if (resource.getType().equalsIgnoreCase(MResource.TYPE.SERVER.name())) {
+          return client.listPrivilegesByRoleName(subject.getName(), role, COMPONENT_TYPE, resource.getName());
+        } else {
+          return client.listPrivilegesByRoleName(subject.getName(), role, COMPONENT_TYPE, sqoopServer.getName(), toAuthorizable(resource));
+        }
+      }
+    });
+
+    List<MPrivilege> privileges = Lists.newArrayList();
+    for (TSentryPrivilege tSentryPrivilege : tSentryPrivileges) {
+      privileges.add(toSqoopPrivilege(tSentryPrivilege));
+    }
+    return privileges;
+  }
+
+  public void grantPrivilege(final Subject subject, final String role, final MPrivilege privilege) throws SqoopException {
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        client.grantPrivilege(subject.getName(), role, COMPONENT_TYPE, toTSentryPrivilege(privilege));
+        return null;
+      }
+    });
+  }
+
+  public void revokePrivilege(final Subject subject, final String role, final MPrivilege privilege) throws SqoopException {
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        client.revokePrivilege(subject.getName(), role, COMPONENT_TYPE, toTSentryPrivilege(privilege));
+        return null;
+      }
+    });
+  }
+
+  public void grantGroupToRole(final Subject subject, final String group, final MRole role) throws SqoopException {
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        client.addRoleToGroups(subject.getName(), role.getName(), COMPONENT_TYPE, Sets.newHashSet(group));
+        return null;
+      }
+    });
+  }
+
+  public void revokeGroupfromRole(final Subject subject, final String group, final MRole role) throws SqoopException {
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        client.deleteRoleToGroups(subject.getName(), role.getName(), COMPONENT_TYPE, Sets.newHashSet(group));
+        return null;
+      }
+    });
+  }
+
+  public void renamePrivilege(final Subject subject, final MResource srcResource, final MResource dstResource) throws SqoopException {
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        client.renamePrivilege(subject.getName(), COMPONENT_TYPE, sqoopServer.getName(),
+            toAuthorizable(srcResource), toAuthorizable(dstResource));
+        return null;
+      }
+    });
+  }
+
+  public void dropPrivilege(final Subject subject, final MResource resource) throws SqoopException {
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        TSentryPrivilege privilege = new TSentryPrivilege();
+        privilege.setComponent(COMPONENT_TYPE);
+        privilege.setServiceName(sqoopServer.getName());
+        privilege.setAuthorizables(toTSentryAuthorizable(resource));
+        privilege.setAction(SqoopActionConstant.ALL);
+        client.dropPrivilege(subject.getName(), COMPONENT_TYPE, privilege);
+        return null;
+      }
+    });
+  }
+
+  private MPrivilege toSqoopPrivilege(TSentryPrivilege tPrivilege) {
+    //construct a sqoop resource
+    boolean grantOption = false;
+    if (tPrivilege.getGrantOption() == TSentryGrantOption.TRUE) {
+      grantOption = true;
+    }
+    //construct a sqoop privilege
+    return new MPrivilege(
+        toSqoopResource(tPrivilege.getAuthorizables()),
+        tPrivilege.getAction().equalsIgnoreCase(SqoopActionConstant.ALL) ? SqoopActionConstant.ALL_NAME
+            : tPrivilege.getAction(), grantOption);
+  }
+
+  private MResource toSqoopResource(List<TAuthorizable> authorizables) {
+    if ((authorizables == null) || authorizables.isEmpty()) {
+      //server resource
+      return new MResource(sqoopServer.getName(), MResource.TYPE.SERVER);
+    } else {
+      //currently Sqoop only has one-level hierarchy authorizable resource
+      return new MResource(authorizables.get(0).getName(), authorizables.get(0).getType());
+    }
+  }
+
+  /**
+   * construct a Sentry privilege to call by the thrift API
+   * @param privilege
+   * @return {@link TSentryPrivilege}
+   */
+  private TSentryPrivilege toTSentryPrivilege(MPrivilege privilege) {
+    TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
+    tSentryPrivilege.setComponent(COMPONENT_TYPE);
+    tSentryPrivilege.setServiceName(sqoopServer.getName());
+    tSentryPrivilege.setAction(privilege.getAction().equalsIgnoreCase(
+        SqoopActionConstant.ALL_NAME) ? SqoopActionConstant.ALL : privilege
+        .getAction());
+    if (privilege.isWith_grant_option()) {
+      tSentryPrivilege.setGrantOption(TSentryGrantOption.TRUE);
+    } else {
+      tSentryPrivilege.setGrantOption(TSentryGrantOption.FALSE);
+    }
+    tSentryPrivilege.setAuthorizables(toTSentryAuthorizable(privilege.getResource()));
+    return tSentryPrivilege;
+  }
+
+
+  private List<TAuthorizable> toTSentryAuthorizable(MResource resource) {
+    List<TAuthorizable> tAuthorizables = Lists.newArrayList();
+    /**
+     * Currently Sqoop supports grant privileges on server object, but the server name must be equaled the configuration
+     * of org.apache.sqoop.security.authorization.server_name in the Sqoop.properties.
+     */
+    if (resource.getType().equalsIgnoreCase(MResource.TYPE.SERVER.name())) {
+      if (!resource.getName().equalsIgnoreCase(sqoopServer.getName())) {
+        throw new IllegalArgumentException( resource.getName() + " must be equal to " + sqoopServer.getName() + "\n" +
+            " Currently Sqoop supports grant/revoke privileges on server object, but the server name must be equal to the configuration " +
+            "of org.apache.sqoop.security.authorization.server_name in the Sqoop.properties");
+      }
+    } else {
+      tAuthorizables.add(new TAuthorizable(resource.getType(), resource.getName()));
+    }
+    return tAuthorizables;
+  }
+
+  private List<Authorizable> toAuthorizable(final MResource resource) {
+    List<Authorizable> authorizables = Lists.newArrayList();
+    if (resource == null) {
+      return authorizables;
+    }
+    authorizables.add(new Authorizable() {
+      @Override
+      public String getTypeName() {
+        return resource.getType();
+      }
+
+      @Override
+      public String getName() {
+        return resource.getName();
+      }
+    });
+    return authorizables;
+  }
+
+  /**
+   * A Command is a closure used to pass a block of code from individual
+   * functions to execute, which centralizes connection error
+   * handling. Command is parameterized on the return type of the function.
+   */
+  private static interface Command<T> {
+    T run(SentryGenericServiceClient client) throws Exception;
+  }
+
+  private <T> T execute(Command<T> cmd) throws SqoopException {
+    SentryGenericServiceClient client = null;
+    try {
+      client = getClient();
+      return cmd.run(client);
+    } catch (SentryUserException ex) {
+      String msg = "Unable to excute command on sentry server: " + ex.getMessage();
+      LOG.error(msg, ex);
+      throw new SqoopException(SecurityError.AUTH_0014, msg, ex);
+    } catch (Exception ex) {
+      String msg = "Unable to obtain client:" + ex.getMessage();
+      LOG.error(msg, ex);
+      throw new SqoopException(SecurityError.AUTH_0014, msg, ex);
+    } finally {
+      if (client != null) {
+        client.close();
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBindingSingleton.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBindingSingleton.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBindingSingleton.java
new file mode 100644
index 0000000..bdd60a4
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBindingSingleton.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop.binding;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+import org.apache.sqoop.core.SqoopConfiguration;
+import org.apache.sqoop.security.SecurityConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+
+public class SqoopAuthBindingSingleton {
+  private static Logger log = LoggerFactory.getLogger(SqoopAuthBindingSingleton.class);
+  private static SqoopAuthBindingSingleton instance = null;
+
+  private SqoopAuthBinding binding;
+
+  private SqoopAuthBindingSingleton() {
+    SqoopAuthBinding tmpBinding = null;
+    try {
+      String serverName = SqoopConfiguration.getInstance().getContext().getString(SecurityConstants.SERVER_NAME);
+      if (Strings.isNullOrEmpty(serverName)) {
+        throw new IllegalArgumentException(SecurityConstants.SERVER_NAME + " can't be null or empty");
+      }
+      SqoopAuthConf conf = loadAuthzConf();
+      validateSentrySqoopConfig(conf);
+      tmpBinding = new SqoopAuthBinding(conf, serverName.trim());
+      log.info("SqoopAuthBinding created successfully");
+    } catch (Exception ex) {
+      log.error("Unable to create SqoopAuthBinding", ex);
+      throw new RuntimeException("Unable to create SqoopAuthBinding: " + ex.getMessage(), ex);
+    }
+    binding = tmpBinding;
+  }
+
+  private SqoopAuthConf loadAuthzConf() {
+    String sentry_site = SqoopConfiguration.getInstance().getContext()
+        .getString(SqoopAuthConf.SENTRY_SQOOP_SITE_URL);
+    if (Strings.isNullOrEmpty(sentry_site)) {
+      throw new IllegalArgumentException("Configuration key " + SqoopAuthConf.SENTRY_SQOOP_SITE_URL
+          + " value '" + sentry_site + "' is invalid.");
+    }
+
+    SqoopAuthConf sqoopAuthConf = null;
+    try {
+      sqoopAuthConf = new SqoopAuthConf(new URL(sentry_site));
+    } catch (MalformedURLException e) {
+      throw new IllegalArgumentException("Configuration key " + SqoopAuthConf.SENTRY_SQOOP_SITE_URL
+          + " specifies a malformed URL '" + sentry_site + "'", e);
+    }
+    return sqoopAuthConf;
+  }
+
+  private void validateSentrySqoopConfig(SqoopAuthConf conf) {
+    boolean isTestingMode = Boolean.parseBoolean(conf.get(AuthzConfVars.AUTHZ_TESTING_MODE.getVar(),
+                            AuthzConfVars.AUTHZ_TESTING_MODE.getDefault()));
+    String authentication = SqoopConfiguration.getInstance().getContext()
+                            .getString(SecurityConstants.AUTHENTICATION_TYPE, SecurityConstants.TYPE.SIMPLE.name());
+    String kerberos = SecurityConstants.TYPE.KERBEROS.name();
+    if(!isTestingMode && !kerberos.equalsIgnoreCase(authentication)) {
+      throw new IllegalArgumentException(SecurityConstants.AUTHENTICATION_TYPE + "can't be set simple mode in non-testing mode");
+    }
+  }
+
+  public static SqoopAuthBindingSingleton getInstance() {
+    if (instance != null) {
+      return instance;
+    }
+    instance = new SqoopAuthBindingSingleton();
+    return instance;
+  }
+
+  public SqoopAuthBinding getAuthBinding() {
+    return binding;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopProviderBackend.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopProviderBackend.java
new file mode 100644
index 0000000..cadc2f5
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopProviderBackend.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop.binding;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.model.sqoop.Server;
+import org.apache.sentry.provider.common.AuthorizationComponent;
+import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+
+public class SqoopProviderBackend extends SentryGenericProviderBackend {
+  private Server sqoopServer;
+  public SqoopProviderBackend(Configuration conf, String resourcePath) throws Exception {
+    super(conf);
+    sqoopServer = new Server(conf.get(AuthzConfVars.AUTHZ_SERVER_NAME.getVar()));
+  }
+  @Override
+  public String getComponentType() {
+    return AuthorizationComponent.SQOOP;
+  }
+
+  /**
+   * SqoopProviderBackend use the name of Sqoop Server as the identifier to
+   * distinguish itself from multiple Sqoop Servers
+   */
+  @Override
+  public String getComponentIdentifier() {
+    return sqoopServer.getName();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
new file mode 100644
index 0000000..fcf7860
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop.conf;
+
+import java.net.URL;
+import org.apache.hadoop.conf.Configuration;
+
+public class SqoopAuthConf extends Configuration {
+  /**
+   * Configuration key used in sqoop.properties to point at sentry-site.xml
+   */
+  public static final String SENTRY_SQOOP_SITE_URL = "sentry.sqoop.site.url";
+  /**
+   * Config setting definitions
+   */
+  public static enum AuthzConfVars {
+    AUTHZ_PROVIDER("sentry.sqoop.provider","org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider"),
+    AUTHZ_PROVIDER_RESOURCE("sentry.sqoop.provider.resource", ""),
+    AUTHZ_PROVIDER_BACKEND("sentry.sqoop.provider.backend","org.apache.sentry.provider.file.SimpleFileProviderBackend"),
+    AUTHZ_POLICY_ENGINE("sentry.sqoop.policy.engine","org.apache.sentry.policy.sqoop.SimpleSqoopPolicyEngine"),
+    AUTHZ_SERVER_NAME("sentry.sqoop.name", ""),
+    AUTHZ_TESTING_MODE("sentry.sqoop.testing.mode", "false");
+
+    private final String varName;
+    private final String defaultVal;
+
+    AuthzConfVars(String varName, String defaultVal) {
+      this.varName = varName;
+      this.defaultVal = defaultVal;
+    }
+
+    public String getVar() {
+      return varName;
+    }
+
+    public String getDefault() {
+      return defaultVal;
+    }
+
+    public static String getDefault(String varName) {
+      for (AuthzConfVars oneVar : AuthzConfVars.values()) {
+        if (oneVar.getVar().equalsIgnoreCase(varName)) {
+          return oneVar.getDefault();
+        }
+      }
+      return null;
+    }
+  }
+
+  public static final String AUTHZ_SITE_FILE = "sentry-site.xml";
+
+  public SqoopAuthConf(URL sqoopAuthzSiteURL) {
+    super(true);
+    addResource(sqoopAuthzSiteURL);
+  }
+
+  @Override
+  public String get(String varName) {
+    return get(varName, AuthzConfVars.getDefault(varName));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/MockAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/MockAuthenticationProvider.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/MockAuthenticationProvider.java
new file mode 100644
index 0000000..0cd9fc6
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/MockAuthenticationProvider.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop;
+
+import org.apache.sqoop.security.AuthenticationProvider;
+
+public class MockAuthenticationProvider extends AuthenticationProvider {
+
+  @Override
+  public String[] getGroupNames() {
+    return new String[]{""};
+  }
+
+  @Override
+  public String getUserName() {
+    return "";
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSentryAuthorizationHander.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSentryAuthorizationHander.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSentryAuthorizationHander.java
new file mode 100644
index 0000000..7efc0a2
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSentryAuthorizationHander.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop;
+
+import static junit.framework.Assert.fail;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+import org.apache.sqoop.security.SecurityFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.io.Files;
+import com.google.common.io.Resources;
+
+public class TestSentryAuthorizationHander {
+  private static final String RESOURCE_PATH = "test-authz-provider.ini";
+  private SqoopAuthConf authzConf;
+  private File baseDir;
+
+  @Before
+  public void setup() throws Exception {
+    baseDir = Files.createTempDir();
+    PolicyFiles.copyToDir(baseDir, RESOURCE_PATH);
+    authzConf = new SqoopAuthConf(Resources.getResource("sentry-site.xml"));
+    authzConf.set(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(), new File(baseDir, RESOURCE_PATH).getPath());
+  }
+
+  @After
+  public void teardown() {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  /**
+   * Test that incorrect specification of classes for
+   * AUTHZ_ACCESS_CONTROLLER and AUTHZ_ACCESS_VALIDATOR
+   * correctly throw ClassNotFoundExceptions
+   */
+  @Test
+  public void testClassNotFound() throws Exception {
+    try {
+      SecurityFactory.getAuthorizationAccessController("org.apache.sentry.sqoop.authz.BogusSentryAccessController");
+      fail("Exception should have been thrown");
+    } catch (Exception ex) {
+    }
+
+    try {
+      SecurityFactory.getAuthorizationValidator("org.apache.sentry.sqoop.authz.BogusSentryAuthorizationValidator");
+      fail("Exception should have been thrown");
+    } catch (Exception ex) {
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSqoopAuthConf.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSqoopAuthConf.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSqoopAuthConf.java
new file mode 100644
index 0000000..e4991e1
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/sqoop/TestSqoopAuthConf.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.sqoop;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.sentry.sqoop.conf.SqoopAuthConf;
+import org.apache.sentry.sqoop.conf.SqoopAuthConf.AuthzConfVars;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+public class TestSqoopAuthConf {
+  private static SqoopAuthConf authAllConf;
+  private static SqoopAuthConf authNoConf;
+  private static List<AuthzConfVars> currentProps;
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    authAllConf = new SqoopAuthConf(Resources.getResource("sentry-site.xml"));
+    authNoConf = new SqoopAuthConf(Resources.getResource("no-configure-sentry-site.xml"));
+    currentProps = Arrays.asList(new AuthzConfVars[]{
+        AuthzConfVars.AUTHZ_PROVIDER, AuthzConfVars.AUTHZ_PROVIDER_BACKEND,
+        AuthzConfVars.AUTHZ_POLICY_ENGINE, AuthzConfVars.AUTHZ_PROVIDER_RESOURCE
+    });
+  }
+
+  @Test
+  public void testPropertiesHaveConfigured() {
+    Assert.assertEquals("org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider",
+            authAllConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar()));
+    Assert.assertEquals("classpath:test-authz-provider.ini",
+            authAllConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar()));
+    Assert.assertEquals("org.apache.sentry.policy.sqoop.SimpleSqoopPolicyEngine",
+            authAllConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar()));
+    Assert.assertEquals("true", authAllConf.get(AuthzConfVars.AUTHZ_TESTING_MODE.getVar()));
+  }
+
+  @Test
+  public void testPropertiesNoConfigured() {
+    for (AuthzConfVars currentVar : currentProps) {
+      Assert.assertEquals(currentVar.getDefault(), authNoConf.get(currentVar.getVar()));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/resources/no-configure-sentry-site.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/resources/no-configure-sentry-site.xml b/sentry-binding/sentry-binding-sqoop/src/test/resources/no-configure-sentry-site.xml
new file mode 100644
index 0000000..f642712
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/resources/no-configure-sentry-site.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<configuration>
+</configuration>
+

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/resources/sentry-site.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/resources/sentry-site.xml b/sentry-binding/sentry-binding-sqoop/src/test/resources/sentry-site.xml
new file mode 100644
index 0000000..2c98980
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/resources/sentry-site.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<configuration>
+  <property>
+    <name>sentry.sqoop.provider</name>
+    <value>org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider</value>
+  </property>
+  <property>
+    <name>sentry.sqoop.provider.resource</name>
+    <value>classpath:test-authz-provider.ini</value>
+  </property>
+  <property>
+    <name>sentry.sqoop.policy.engine</name>
+    <value>org.apache.sentry.policy.sqoop.SimpleSqoopPolicyEngine</value>
+  </property>
+  <property>
+    <name>sentry.sqoop.testing.mode</name>
+    <value>true</value>
+  </property>
+</configuration>
+

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-binding/sentry-binding-sqoop/src/test/resources/test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/resources/test-authz-provider.ini b/sentry-binding/sentry-binding-sqoop/src/test/resources/test-authz-provider.ini
new file mode 100644
index 0000000..dc11b4b
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/resources/test-authz-provider.ini
@@ -0,0 +1,40 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[groups]
+developer = jdbc_connector_role, hdfs_connector_role,kafka_connector_role,kite_connector_role,\
+    jobs_analyst_role,links_analyst_role
+analyst = jobs_analyst_role,links_analyst_role
+connectors_operator = jdbc_connector_role, hdfs_connector_role,kafka_connector_role,kite_connector_role
+jobs_analyst = jobs_analyst_role
+job1_2_operator = job1_role,job2_role
+links_analyst = links_analyst_role
+link1_2_operator = link1_role,link2_role
+admin = admin_role
+
+[roles]
+admin_role = server=server1->action=*
+jdbc_connector_role = server=server1->connector=generic-jdbc-connector->action=read
+hdfs_connector_role = server=server1->connector=hdfs-connector->action=read
+kafka_connector_role = server=server1->connector=kafka-connector->action=read
+kite_connector_role = server=server1->connector=kite-connector->action=read
+jobs_analyst_role = server=server1->job=*->action=*
+job1_role = server=server1->job=job1->action=read
+job2_role = server=server1->job=job2->action=read
+links_analyst_role = server=server1->link=*->action=*
+link1_role = server=server1->link=link1->action=read
+link2_role = server=server1->link=link2->action=read
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-dist/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-dist/pom.xml b/sentry-dist/pom.xml
index 51e05a5..cde21c0 100644
--- a/sentry-dist/pom.xml
+++ b/sentry-dist/pom.xml
@@ -56,6 +56,10 @@ limitations under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-binding-sqoop</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
       <artifactId>solr-sentry-handlers</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java
index def3486..6409015 100644
--- a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java
+++ b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/AuthorizationComponent.java
@@ -21,4 +21,5 @@ package org.apache.sentry.provider.common;
  */
 public class AuthorizationComponent{
   public static final String Search = "solr";
+  public static final String SQOOP = "sqoop";
 }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-db/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/pom.xml b/sentry-provider/sentry-provider-db/pom.xml
index 7dd40b8..9c4618f 100644
--- a/sentry-provider/sentry-provider-db/pom.xml
+++ b/sentry-provider/sentry-provider-db/pom.xml
@@ -88,6 +88,10 @@ limitations under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-core-model-sqoop</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-provider-common</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
new file mode 100644
index 0000000..11ffde2
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
@@ -0,0 +1,153 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.provider.db.generic;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.sentry.SentryUserException;
+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.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.TSentryRole;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+
+/**
+ * This class used when any component such as Hive, Solr or Sqoop want to integration with the Sentry service
+ */
+public abstract class SentryGenericProviderBackend implements ProviderBackend {
+  private static final Logger LOGGER = LoggerFactory.getLogger(SentryGenericProviderBackend.class);
+  private final Configuration conf;
+  private volatile boolean initialized = false;
+
+  public SentryGenericProviderBackend(Configuration conf) throws Exception {
+    this.conf = conf;
+  }
+
+  @Override
+  public void initialize(ProviderBackendContext context) {
+    if (initialized) {
+      throw new IllegalStateException("SentryGenericProviderBackend has already been initialized, cannot be initialized twice");
+    }
+    this.initialized = true;
+  }
+
+  /**
+   *  The Sentry-296(generate client for connection pooling) has already finished development and reviewed by now. When it
+   *  was committed to master, the getClient method was needed to refactor using the connection pool
+   */
+  private SentryGenericServiceClient getClient() throws Exception {
+    return new SentryGenericServiceClient(conf);
+  }
+
+  @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups,
+      ActiveRoleSet roleSet, Authorizable... authorizableHierarchy) {
+    if (!initialized) {
+      throw new IllegalStateException("SentryGenericProviderBackend has not been properly initialized");
+    }
+    SentryGenericServiceClient client = null;
+    try {
+      client = getClient();
+      return ImmutableSet.copyOf(client.listPrivilegesForProvider(
+          getComponentType(), getComponentIdentifier(), roleSet, groups,
+          Arrays.asList(authorizableHierarchy)));
+    } catch (SentryUserException e) {
+      String msg = "Unable to obtain privileges from server: " + e.getMessage();
+      LOGGER.error(msg, e);
+    } catch (Exception e) {
+      String msg = "Unable to obtain client:" + e.getMessage();
+      LOGGER.error(msg, e);
+    } finally {
+      if (client != null) {
+        client.close();
+      }
+    }
+    return ImmutableSet.of();
+  }
+
+  @Override
+  public ImmutableSet<String> getRoles(Set<String> groups, ActiveRoleSet roleSet) {
+    if (!initialized) {
+      throw new IllegalStateException("SentryGenericProviderBackend has not been properly initialized");
+    }
+    SentryGenericServiceClient client = null;
+    try {
+      Set<TSentryRole> tRoles = Sets.newHashSet();
+      client = getClient();
+      //get the roles according to group
+      String requestor = UserGroupInformation.getCurrentUser().getShortUserName();
+      for (String group : groups) {
+        tRoles.addAll(client.listRolesByGroupName(requestor, group, getComponentType()));
+      }
+      Set<String> roles = Sets.newHashSet();
+      for (TSentryRole tRole : tRoles) {
+        roles.add(tRole.getRoleName());
+      }
+      return ImmutableSet.copyOf(roleSet.isAll() ? roles : Sets.intersection(roles, roleSet.getRoles()));
+    } catch (SentryUserException e) {
+      String msg = "Unable to obtain roles from server: " + e.getMessage();
+      LOGGER.error(msg, e);
+    } catch (Exception e) {
+      String msg = "Unable to obtain client:" + e.getMessage();
+      LOGGER.error(msg, e);
+    } finally {
+      if (client != null) {
+        client.close();
+      }
+    }
+    return ImmutableSet.of();
+  }
+
+  /**
+   * SentryGenericProviderBackend does nothing in the validatePolicy()
+   */
+  @Override
+  public void validatePolicy(boolean strictValidation)
+      throws SentryConfigurationException {
+    if (!initialized) {
+      throw new IllegalStateException("SentryGenericProviderBackend has not been properly initialized");
+    }
+  }
+
+  @Override
+  public void close() {
+  }
+
+  /**
+   * Get the component type for the Generic Provider backend, such as Hive,Solr or Sqoop
+   */
+  public abstract String getComponentType();
+
+  /**
+   * When the providerBackend want to get privileges from the Sentry service.
+   * The component identifier is very important to Sentry service. Take the component type is Hive for example,
+   * when there are multiple HiveServers implemented role-based authorization via Sentry. Each HiveServer must uses a
+   * identifier to distinguish itself from multiple HiveServers.
+   */
+  public abstract String getComponentIdentifier();
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
index daeefdf..98b22b0 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
@@ -32,6 +32,7 @@ import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.BitFieldAction;
 import org.apache.sentry.core.common.BitFieldActionFactory;
 import org.apache.sentry.core.model.search.SearchActionFactory;
+import org.apache.sentry.core.model.sqoop.SqoopActionFactory;
 import org.apache.sentry.provider.db.generic.service.persistent.PrivilegeObject.Builder;
 import org.apache.sentry.provider.db.service.model.MSentryGMPrivilege;
 import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
@@ -50,6 +51,7 @@ public class PrivilegeOperatePersistence {
   private static final Map<String, BitFieldActionFactory> actionFactories = Maps.newHashMap();
   static{
     actionFactories.put("solr", new SearchActionFactory());
+    actionFactories.put("sqoop", new SqoopActionFactory());
   }
 
   public boolean checkPrivilegeOption(Set<MSentryRole> roles, PrivilegeObject privilege, PersistenceManager pm) {

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/357d83fb/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
index d6600a0..62f36b4 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
@@ -29,6 +29,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.SentryUserException;
 import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.provider.common.AuthorizationComponent;
 import org.apache.sentry.provider.db.SentryAccessDeniedException;
 import org.apache.sentry.provider.db.SentryAlreadyExistsException;
 import org.apache.sentry.provider.db.SentryInvalidInputException;
@@ -255,6 +256,9 @@ public class SentryGenericPolicyProcessor implements SentryGenericPolicyService.
     Set<String> permissions = Sets.newHashSet();
     for (PrivilegeObject privilege : privileges) {
       List<String> hierarchy = Lists.newArrayList();
+      if (hasComponentServerPrivilege(privilege.getComponent())) {
+        hierarchy.add(KV_JOINER.join("server", privilege.getService()));
+      }
       for (Authorizable authorizable : privilege.getAuthorizables()) {
         hierarchy.add(KV_JOINER.join(authorizable.getTypeName(),authorizable.getName()));
       }
@@ -264,6 +268,11 @@ public class SentryGenericPolicyProcessor implements SentryGenericPolicyService.
     return permissions;
   }
 
+  private boolean hasComponentServerPrivilege(String component) {
+    //judge the component whether has the server privilege, for example: sqoop has the privilege on the server
+    return AuthorizationComponent.SQOOP.equalsIgnoreCase(component);
+  }
+
   @Override
   public TCreateSentryRoleResponse create_sentry_role(
       final TCreateSentryRoleRequest request) throws TException {