IMPALA-4000: Restricted Sentry authorization for Kudu Tables

At this time, there is no comprehensive way of enforcing a Sentry
authorization policy against tables stored in Kudu. The following
behavior was implemented in this patch:
- Only the ALL privilege level can be granted to Kudu tables.
  Finer-grained levels such as only SELECT or only INSERT are not
  supported.
- Column level permissions on Kudu tables are not supported.
- Only users with ALL privileges on SERVER may create external Kudu
  tables.

Change-Id: I183f08ad8ce80deee011a6b90ad67b9cefc0452c
Reviewed-on: http://gerrit.cloudera.org:8080/5047
Reviewed-by: Taras Bobrovytsky <[email protected]>
Tested-by: Internal Jenkins


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

Branch: refs/heads/master
Commit: 9032952758b00c172a63fb83f6eb1c638f20de5f
Parents: 8adc49e
Author: Taras Bobrovytsky <[email protected]>
Authored: Thu Nov 10 19:05:02 2016 -0800
Committer: Internal Jenkins <[email protected]>
Committed: Tue Nov 29 17:06:16 2016 +0000

----------------------------------------------------------------------
 .../java/org/apache/impala/analysis/Analyzer.java    |  1 +
 .../org/apache/impala/analysis/CreateTableStmt.java  | 15 +++++++++++++--
 .../org/apache/impala/analysis/PrivilegeSpec.java    | 12 ++++++++++++
 .../authorization/PrivilegeRequestBuilder.java       |  8 ++++++++
 .../apache/impala/analysis/AnalyzeAuthStmtsTest.java | 11 +++++++++++
 .../apache/impala/analysis/AuthorizationTest.java    | 13 +++++++++++++
 6 files changed, 58 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/90329527/fe/src/main/java/org/apache/impala/analysis/Analyzer.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/analysis/Analyzer.java 
b/fe/src/main/java/org/apache/impala/analysis/Analyzer.java
index fa03434..3ab367c 100644
--- a/fe/src/main/java/org/apache/impala/analysis/Analyzer.java
+++ b/fe/src/main/java/org/apache/impala/analysis/Analyzer.java
@@ -151,6 +151,7 @@ public class Analyzer {
   private String authErrorMsg_;
 
   // If false, privilege requests will not be registered in the analyzer.
+  // Note: it's not the purpose of this flag to control if security is enabled 
in general.
   private boolean enablePrivChecks_ = true;
 
   // By default, all registered semi-joined tuples are invisible, i.e., their 
slots

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/90329527/fe/src/main/java/org/apache/impala/analysis/CreateTableStmt.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/analysis/CreateTableStmt.java 
b/fe/src/main/java/org/apache/impala/analysis/CreateTableStmt.java
index b896acc..f2db81b 100644
--- a/fe/src/main/java/org/apache/impala/analysis/CreateTableStmt.java
+++ b/fe/src/main/java/org/apache/impala/analysis/CreateTableStmt.java
@@ -22,6 +22,7 @@ import java.util.Map;
 
 import org.apache.avro.Schema;
 import org.apache.avro.SchemaParseException;
+import org.apache.impala.authorization.PrivilegeRequestBuilder;
 import org.apache.impala.catalog.KuduTable;
 import org.apache.impala.catalog.RowFormat;
 import org.apache.impala.common.AnalysisException;
@@ -197,7 +198,7 @@ public class CreateTableStmt extends StatementBase {
 
     analyzeKuduTableProperties(analyzer);
     if (isExternal()) {
-      analyzeExternalKuduTableParams();
+      analyzeExternalKuduTableParams(analyzer);
     } else {
       analyzeManagedKuduTableParams(analyzer);
     }
@@ -238,7 +239,17 @@ public class CreateTableStmt extends StatementBase {
   /**
    * Analyzes and checks parameters specified for external Kudu tables.
    */
-  private void analyzeExternalKuduTableParams() throws AnalysisException {
+  private void analyzeExternalKuduTableParams(Analyzer analyzer)
+      throws AnalysisException {
+    if (analyzer.getAuthzConfig().isEnabled()) {
+      // Today there is no comprehensive way of enforcing a Sentry 
authorization policy
+      // against tables stored in Kudu. This is why only users with ALL 
privileges on
+      // SERVER may create external Kudu tables. See IMPALA-4000 for details.
+      String authzServer = analyzer.getAuthzConfig().getServerName();
+      Preconditions.checkNotNull(authzServer);
+      analyzer.registerPrivReq(new PrivilegeRequestBuilder().onServer(
+          authzServer).all().toRequest());
+    }
     AnalysisUtils.throwIfNull(getTblProperties().get(KuduTable.KEY_TABLE_NAME),
         String.format("Table property %s must be specified when creating " +
             "an external Kudu table.", KuduTable.KEY_TABLE_NAME));

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/90329527/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java 
b/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
index f064604..b999cda 100644
--- a/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
+++ b/fe/src/main/java/org/apache/impala/analysis/PrivilegeSpec.java
@@ -21,6 +21,7 @@ import java.util.List;
 
 import org.apache.impala.authorization.Privilege;
 import org.apache.impala.catalog.DataSourceTable;
+import org.apache.impala.catalog.KuduTable;
 import org.apache.impala.catalog.RolePrivilege;
 import org.apache.impala.catalog.Table;
 import org.apache.impala.catalog.TableLoadingException;
@@ -282,6 +283,17 @@ public class PrivilegeSpec implements ParseNode {
           "to issue a GRANT/REVOKE statement.", tableName_.toString()));
     }
     Preconditions.checkNotNull(table);
+    if (table instanceof KuduTable) {
+      // We only support the ALL privilege on Kudu tables since many of the 
finer-grained
+      // levels (DELETE/UPDATE) are not available. See IMPALA-4000 for details.
+      if (privilegeLevel_ != TPrivilegeLevel.ALL) {
+        throw new AnalysisException("Kudu tables only support the ALL 
privilege level.");
+      }
+      if (scope_ == TPrivilegeScope.COLUMN) {
+        throw new AnalysisException("Column-level privileges on Kudu " +
+            "tables are not supported.");
+      }
+    }
     return table;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/90329527/fe/src/main/java/org/apache/impala/authorization/PrivilegeRequestBuilder.java
----------------------------------------------------------------------
diff --git 
a/fe/src/main/java/org/apache/impala/authorization/PrivilegeRequestBuilder.java 
b/fe/src/main/java/org/apache/impala/authorization/PrivilegeRequestBuilder.java
index 8cf146c..f47c52f 100644
--- 
a/fe/src/main/java/org/apache/impala/authorization/PrivilegeRequestBuilder.java
+++ 
b/fe/src/main/java/org/apache/impala/authorization/PrivilegeRequestBuilder.java
@@ -54,6 +54,14 @@ public class PrivilegeRequestBuilder {
   }
 
   /**
+   * Sets the authorizeable object to be a server.
+   */
+  public PrivilegeRequestBuilder onServer(String serverName) {
+    authorizeable_ = new AuthorizeableServer(serverName);
+    return this;
+  }
+
+  /**
    * Sets the authorizeable object to be a database.
    */
   public PrivilegeRequestBuilder onDb(String dbName) {

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/90329527/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
----------------------------------------------------------------------
diff --git 
a/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java 
b/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
index c37047f..07a1c0a 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeAuthStmtsTest.java
@@ -160,6 +160,13 @@ public class AnalyzeAuthStmtsTest extends AnalyzerTest {
       AnalysisError(String.format("%s INSERT ON URI 'hdfs:////abc//123' %s 
myrole",
           formatArgs), "Only 'ALL' privilege may be applied at URI scope in 
privilege " +
           "spec.");
+      // IMPALA-4000: Insert privilege on a Kudu table
+      AnalysisError(String.format(
+          "%s SELECT ON TABLE functional_kudu.alltypessmall %s myrole", 
formatArgs),
+          "Kudu tables only support the ALL privilege level.");
+      AnalysisError(String.format(
+          "%s INSERT ON TABLE functional_kudu.alltypessmall %s myrole", 
formatArgs),
+          "Kudu tables only support the ALL privilege level.");
 
       // SELECT privilege
       AnalyzesOk(String.format("%s SELECT ON TABLE alltypessmall %s myrole", 
formatArgs),
@@ -196,6 +203,10 @@ public class AnalyzeAuthStmtsTest extends AnalyzerTest {
       AnalysisError(String.format("%s SELECT (id, bool_col) ON TABLE " +
           "functional.alltypes_hive_view %s myrole", formatArgs), 
"Column-level " +
           "privileges on views are not supported.");
+      // IMPALA-4000: Column-level privileges on a KUDU table
+      AnalysisError(String.format("%s SELECT (id, bool_col) ON TABLE " +
+          "functional_kudu.alltypessmall %s myrole", formatArgs),
+          "Kudu tables only support the ALL privilege level.");
       // Columns/table that don't exist
       AnalysisError(String.format("%s SELECT (invalid_col) ON TABLE " +
           "functional.alltypes %s myrole", formatArgs), "Error setting 
column-level " +

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/90329527/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java 
b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
index 38aff7d..431ac01 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AuthorizationTest.java
@@ -903,6 +903,17 @@ public class AuthorizationTest {
         "User '%s' does not have privileges to execute 'CREATE' on: " +
         "nodb.alltypes");
 
+    // IMPALA-4000: Only users with ALL privileges on SERVER may create 
external Kudu
+    // tables.
+    AuthzError("create external table tpch.kudu_tbl stored as kudu " +
+        "TBLPROPERTIES ('kudu.master_addresses'='127.0.0.1', 
'kudu.table_name'='tbl')",
+        "User '%s' does not have privileges to access: server1");
+
+    // IMPALA-4000: ALL privileges on SERVER are not required to create 
managed tables.
+    AuthzOk("create table tpch.kudu_tbl (i int, j int, primary key (i))" +
+        " DISTRIBUTE BY HASH (i) INTO 9 BUCKETS stored as kudu TBLPROPERTIES " 
+
+        "('kudu.master_addresses'='127.0.0.1')");
+
     // User does not have permission to create table at the specified 
location..
     AuthzError("create table tpch.new_table (i int) location " +
         "'hdfs://localhost:20500/test-warehouse/alltypes'",
@@ -2154,6 +2165,8 @@ public class AuthorizationTest {
     AuthzOk(fe, context, "select * from functional.alltypesagg");
     AuthzOk(fe, context, "select * from functional.alltypes");
     AuthzOk(fe, context, "invalidate metadata");
+    AuthzOk(fe, context, "create external table tpch.kudu_tbl stored as kudu " 
+
+        "TBLPROPERTIES ('kudu.master_addresses'='127.0.0.1', 
'kudu.table_name'='tbl')");
   }
 
   private void TestWithIncorrectConfig(AuthorizationConfig authzConfig, User 
user)

Reply via email to