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)
