You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2016/05/12 22:10:15 UTC
[40/50] [abbrv] incubator-impala git commit: IMPALA-2660: Respect
auth_to_local configs from hdfs configs
IMPALA-2660: Respect auth_to_local configs from hdfs configs
This patch implements a new feature to read the auth_to_local
configs from hdfs configuration files, using the parameter
hadoop.security.auth_to_local. This is done by modifying the
User#getShortName() method to use its hdfs equivalent.
This patch includes an end to end authorization test using
sentry where we add specific auth_to_local setting for a certain
user and test if the sentry authorization passes for this user
after applying these rules. Given we don't have tests that run
on a kerberized min-cluster, this patch adds a hack to load this
configuration during even on non-kerberized 'test runs'.
However this feature is disabled by default to preserve the
existing behavior. To enable it,
1. Use kerberos as authentication mechanism (by setting --principal) and
2. Add "--load_auth_to_local_rules=true" to the cluster startup args
Change-Id: I76485b83c14ba26f6fce66e5f83e8014667829e0
Reviewed-on: http://gerrit.cloudera.org:8080/2800
Reviewed-by: Bharath Vissapragada <bh...@cloudera.com>
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/3092c966
Tree: http://git-wip-us.apache.org/repos/asf/incubator-impala/tree/3092c966
Diff: http://git-wip-us.apache.org/repos/asf/incubator-impala/diff/3092c966
Branch: refs/heads/master
Commit: 3092c96619f54bd47d71c2bc19c99bb03807ec1a
Parents: c0ee93b
Author: Bharath Vissapragada <bh...@cloudera.com>
Authored: Fri Mar 4 09:46:16 2016 -0800
Committer: Tim Armstrong <ta...@cloudera.com>
Committed: Thu May 12 14:18:01 2016 -0700
----------------------------------------------------------------------
be/src/catalog/catalog.cc | 11 +-
be/src/common/global-flags.cc | 5 +
be/src/service/frontend.cc | 9 +-
.../impala/analysis/AnalysisContext.java | 9 +-
.../impala/analysis/ShowGrantRoleStmt.java | 3 +-
.../cloudera/impala/analysis/ShowRolesStmt.java | 5 +-
.../authorization/AuthorizationChecker.java | 8 +-
.../com/cloudera/impala/authorization/User.java | 81 +++++++--
.../cloudera/impala/service/BackendConfig.java | 11 +-
.../com/cloudera/impala/service/Frontend.java | 9 +-
.../com/cloudera/impala/service/JniCatalog.java | 6 +-
.../cloudera/impala/service/JniFrontend.java | 4 +-
.../impala/util/RequestPoolService.java | 10 +-
.../cloudera/impala/analysis/AuditingTest.java | 3 +-
.../impala/analysis/AuthorizationTest.java | 165 ++++++++++++++-----
.../impala/util/TestRequestPoolService.java | 4 +-
fe/src/test/resources/authz-policy.ini.template | 3 +
.../common/etc/hadoop/conf/core-site.xml.tmpl | 11 ++
18 files changed, 277 insertions(+), 80 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/be/src/catalog/catalog.cc
----------------------------------------------------------------------
diff --git a/be/src/catalog/catalog.cc b/be/src/catalog/catalog.cc
index 606aa8f..26810f1 100644
--- a/be/src/catalog/catalog.cc
+++ b/be/src/catalog/catalog.cc
@@ -25,6 +25,9 @@
using namespace impala;
+DECLARE_bool(load_auth_to_local_rules);
+DECLARE_string(principal);
+
DEFINE_bool(load_catalog_in_background, false,
"If true, loads catalog metadata in the background. If false, metadata is loaded "
"lazily (on access).");
@@ -38,7 +41,7 @@ DECLARE_int32(non_impala_java_vlog);
Catalog::Catalog() {
JniMethodDescriptor methods[] = {
- {"<init>", "(ZILjava/lang/String;II)V", &catalog_ctor_},
+ {"<init>", "(ZILjava/lang/String;IIZ)V", &catalog_ctor_},
{"updateCatalog", "([B)[B", &update_metastore_id_},
{"execDdl", "([B)[B", &exec_ddl_id_},
{"resetMetadata", "([B)[B", &reset_metadata_id_},
@@ -64,9 +67,13 @@ Catalog::Catalog() {
jboolean load_in_background = FLAGS_load_catalog_in_background;
jint num_metadata_loading_threads = FLAGS_num_metadata_loading_threads;
jstring sentry_config = jni_env->NewStringUTF(FLAGS_sentry_config.c_str());
+ // auth_to_local rules are read if --load_auth_to_local_rules is set to true
+ // and impala is kerberized.
+ jboolean auth_to_local = FLAGS_load_auth_to_local_rules && !FLAGS_principal.empty();
jobject catalog = jni_env->NewObject(catalog_class_, catalog_ctor_,
load_in_background, num_metadata_loading_threads, sentry_config,
- FlagToTLogLevel(FLAGS_v), FlagToTLogLevel(FLAGS_non_impala_java_vlog));
+ FlagToTLogLevel(FLAGS_v), FlagToTLogLevel(FLAGS_non_impala_java_vlog),
+ auth_to_local);
EXIT_IF_EXC(jni_env);
ABORT_IF_ERROR(JniUtil::LocalToGlobalRef(jni_env, catalog, &catalog_));
}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/be/src/common/global-flags.cc
----------------------------------------------------------------------
diff --git a/be/src/common/global-flags.cc b/be/src/common/global-flags.cc
index f0315ca..b3f83d9 100644
--- a/be/src/common/global-flags.cc
+++ b/be/src/common/global-flags.cc
@@ -76,6 +76,11 @@ DEFINE_string(minidump_path, "/tmp/impala-minidumps", "Directory to write minidu
DEFINE_int32(max_minidumps, 9, "Maximum number of minidump files to keep per daemon. "
"Older files are removed first. Set to 0 to keep all minidump files.");
+DEFINE_bool(load_auth_to_local_rules, false, "If true, load auth_to_local configuration "
+ "from hdfs' core-site.xml. When enabled, impalad reads the rules from the property "
+ "hadoop.security.auth_to_local and applies them to translate the Kerberos principal "
+ "to its corresponding local user name for authorization.");
+
// Stress option for testing failed memory allocation. Debug builds only.
#ifndef NDEBUG
DEFINE_int32(stress_free_pool_alloc, 0, "A stress option which causes memory allocations "
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/be/src/service/frontend.cc
----------------------------------------------------------------------
diff --git a/be/src/service/frontend.cc b/be/src/service/frontend.cc
index a0b76c3..2b7c5b0 100644
--- a/be/src/service/frontend.cc
+++ b/be/src/service/frontend.cc
@@ -28,6 +28,8 @@ using namespace impala;
DECLARE_string(sentry_config);
DECLARE_int32(non_impala_java_vlog);
+DECLARE_bool(load_auth_to_local_rules);
+DECLARE_string(principal);
DEFINE_bool(load_catalog_at_startup, false, "if true, load all catalog data at startup");
@@ -56,7 +58,7 @@ DEFINE_string(authorized_proxy_user_config_delimiter, ",",
Frontend::Frontend() {
JniMethodDescriptor methods[] = {
{"<init>", "(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;"
- "Ljava/lang/String;II)V", &fe_ctor_},
+ "Ljava/lang/String;IIZ)V", &fe_ctor_},
{"createExecRequest", "([B)[B", &create_exec_request_id_},
{"getExplainPlan", "([B)Ljava/lang/String;", &get_explain_plan_id_},
{"getHadoopConfig", "([B)[B", &get_hadoop_config_id_},
@@ -101,9 +103,12 @@ Frontend::Frontend() {
jni_env->NewStringUTF(FLAGS_sentry_config.c_str());
jstring auth_provider_class =
jni_env->NewStringUTF(FLAGS_authorization_policy_provider_class.c_str());
+ // auth_to_local rules are read if --load_auth_to_local_rules is set to true
+ // and impala is kerberized.
+ jboolean auth_to_local = FLAGS_load_auth_to_local_rules && !FLAGS_principal.empty();
jobject fe = jni_env->NewObject(fe_class_, fe_ctor_, lazy, server_name,
policy_file_path, sentry_config, auth_provider_class, FlagToTLogLevel(FLAGS_v),
- FlagToTLogLevel(FLAGS_non_impala_java_vlog));
+ FlagToTLogLevel(FLAGS_non_impala_java_vlog), auth_to_local);
EXIT_IF_EXC(jni_env);
ABORT_IF_ERROR(JniUtil::LocalToGlobalRef(jni_env, fe, &fe_));
}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/analysis/AnalysisContext.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/analysis/AnalysisContext.java b/fe/src/main/java/com/cloudera/impala/analysis/AnalysisContext.java
index 31c156c..098501c 100644
--- a/fe/src/main/java/com/cloudera/impala/analysis/AnalysisContext.java
+++ b/fe/src/main/java/com/cloudera/impala/analysis/AnalysisContext.java
@@ -32,6 +32,7 @@ import com.cloudera.impala.catalog.AuthorizationException;
import com.cloudera.impala.catalog.Db;
import com.cloudera.impala.catalog.ImpaladCatalog;
import com.cloudera.impala.common.AnalysisException;
+import com.cloudera.impala.common.InternalException;
import com.cloudera.impala.common.Pair;
import com.cloudera.impala.thrift.TAccessEvent;
import com.cloudera.impala.thrift.TLineageGraph;
@@ -384,7 +385,8 @@ public class AnalysisContext {
* analyze() must have already been called. Throws an AuthorizationException if the
* user doesn't have sufficient privileges to run this statement.
*/
- public void authorize(AuthorizationChecker authzChecker) throws AuthorizationException {
+ public void authorize(AuthorizationChecker authzChecker)
+ throws AuthorizationException, InternalException {
Preconditions.checkNotNull(analysisResult_);
Analyzer analyzer = getAnalyzer();
// Process statements for which column-level privilege requests may be registered.
@@ -451,7 +453,7 @@ public class AnalysisContext {
* this request. Also, checks if the request references a system database.
*/
private void authorizePrivilegeRequest(AuthorizationChecker authzChecker,
- PrivilegeRequest request) throws AuthorizationException {
+ PrivilegeRequest request) throws AuthorizationException, InternalException {
Preconditions.checkNotNull(request);
String dbName = null;
if (request.getAuthorizeable() != null) {
@@ -474,7 +476,8 @@ public class AnalysisContext {
* sufficient privileges.
*/
private void authorizeTableAccess(AuthorizationChecker authzChecker,
- List<PrivilegeRequest> requests) throws AuthorizationException {
+ List<PrivilegeRequest> requests)
+ throws AuthorizationException, InternalException {
Preconditions.checkState(!requests.isEmpty());
Analyzer analyzer = getAnalyzer();
boolean hasTableSelectPriv = true;
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/analysis/ShowGrantRoleStmt.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/analysis/ShowGrantRoleStmt.java b/fe/src/main/java/com/cloudera/impala/analysis/ShowGrantRoleStmt.java
index b543a57..1d921c8 100644
--- a/fe/src/main/java/com/cloudera/impala/analysis/ShowGrantRoleStmt.java
+++ b/fe/src/main/java/com/cloudera/impala/analysis/ShowGrantRoleStmt.java
@@ -16,6 +16,7 @@ package com.cloudera.impala.analysis;
import com.cloudera.impala.catalog.Role;
import com.cloudera.impala.common.AnalysisException;
+import com.cloudera.impala.common.InternalException;
import com.cloudera.impala.thrift.TShowGrantRoleParams;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
@@ -36,7 +37,7 @@ public class ShowGrantRoleStmt extends AuthorizationStmt {
privilegeSpec_ = privilegeSpec;
}
- public TShowGrantRoleParams toThrift() {
+ public TShowGrantRoleParams toThrift() throws InternalException {
TShowGrantRoleParams params = new TShowGrantRoleParams();
params.setRole_name(roleName_);
params.setRequesting_user(requestingUser_.getShortName());
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/analysis/ShowRolesStmt.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/analysis/ShowRolesStmt.java b/fe/src/main/java/com/cloudera/impala/analysis/ShowRolesStmt.java
index 54ad698..1e1b59e 100644
--- a/fe/src/main/java/com/cloudera/impala/analysis/ShowRolesStmt.java
+++ b/fe/src/main/java/com/cloudera/impala/analysis/ShowRolesStmt.java
@@ -16,6 +16,7 @@ package com.cloudera.impala.analysis;
import com.cloudera.impala.authorization.User;
import com.cloudera.impala.common.AnalysisException;
+import com.cloudera.impala.common.InternalException;
import com.cloudera.impala.thrift.TShowRolesParams;
import com.google.common.base.Preconditions;
@@ -50,7 +51,7 @@ public class ShowRolesStmt extends AuthorizationStmt {
}
}
- public TShowRolesParams toThrift() {
+ public TShowRolesParams toThrift() throws InternalException {
TShowRolesParams params = new TShowRolesParams();
params.setRequesting_user(requestingUser_.getShortName());
params.setIs_show_current_roles(isShowCurrentRoles_);
@@ -65,4 +66,4 @@ public class ShowRolesStmt extends AuthorizationStmt {
super.analyze(analyzer);
requestingUser_ = analyzer.getUser();
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/authorization/AuthorizationChecker.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/authorization/AuthorizationChecker.java b/fe/src/main/java/com/cloudera/impala/authorization/AuthorizationChecker.java
index 6d978ab..a4a45ed 100644
--- a/fe/src/main/java/com/cloudera/impala/authorization/AuthorizationChecker.java
+++ b/fe/src/main/java/com/cloudera/impala/authorization/AuthorizationChecker.java
@@ -32,6 +32,7 @@ import org.apache.sentry.provider.file.SimpleFileProviderBackend;
import com.cloudera.impala.catalog.AuthorizationException;
import com.cloudera.impala.catalog.AuthorizationPolicy;
+import com.cloudera.impala.common.InternalException;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
@@ -108,7 +109,7 @@ public class AuthorizationChecker {
* that is in the AuthorizationProvider to properly resolve Hadoop groups or
* local group mappings.
*/
- public Set<String> getUserGroups(User user) {
+ public Set<String> getUserGroups(User user) throws InternalException {
return provider_.getGroupMapping().getGroups(user.getShortName());
}
@@ -117,7 +118,7 @@ public class AuthorizationChecker {
* the user does not have sufficient privileges.
*/
public void checkAccess(User user, PrivilegeRequest privilegeRequest)
- throws AuthorizationException {
+ throws AuthorizationException, InternalException {
Preconditions.checkNotNull(privilegeRequest);
if (!hasAccess(user, privilegeRequest)) {
@@ -145,7 +146,8 @@ public class AuthorizationChecker {
* Returns true if the given user has permission to execute the given
* request, false otherwise. Always returns true if authorization is disabled.
*/
- public boolean hasAccess(User user, PrivilegeRequest request) {
+ public boolean hasAccess(User user, PrivilegeRequest request)
+ throws InternalException {
Preconditions.checkNotNull(user);
Preconditions.checkNotNull(request);
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/authorization/User.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/authorization/User.java b/fe/src/main/java/com/cloudera/impala/authorization/User.java
index 4f19813..d87944c 100644
--- a/fe/src/main/java/com/cloudera/impala/authorization/User.java
+++ b/fe/src/main/java/com/cloudera/impala/authorization/User.java
@@ -15,34 +15,87 @@
package com.cloudera.impala.authorization;
import com.google.common.base.Preconditions;
+import com.google.common.annotations.VisibleForTesting;
+import com.cloudera.impala.common.InternalException;
+import com.cloudera.impala.common.RuntimeEnv;
+import com.cloudera.impala.service.BackendConfig;
+
+import java.io.IOException;
+
+import org.apache.hadoop.conf.Configuration;
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTH_TO_LOCAL;
+import org.apache.hadoop.security.authentication.util.KerberosName;
/*
* Class that represents a User of an Impala session.
*/
public class User {
+
+ static {
+ // If auth_to_local is enabled, we read the configuration hadoop.security.auth_to_local
+ // from core-site.xml and use it for principal to short name conversion. If it is not,
+ // we use the defaultRule ("RULE:[1:$1] RULE:[2:$1]"), which just extracts the user
+ // name from any principal of form a@REALM or a/b@REALM. If auth_to_local is enabled
+ // and hadoop.security.auth_to_local is not specified in the hadoop configs, we use
+ // the "DEFAULT" rule that just extracts the username from any principal in the
+ // cluster's local realm. For more details on principal to short name translation,
+ // refer to org.apache.hadoop.security.KerberosName.
+ final String defaultRule = "RULE:[1:$1] RULE:[2:$1]";
+ final Configuration conf = new Configuration();
+ if (BackendConfig.isAuthToLocalEnabled()) {
+ KerberosName.setRules(conf.get(HADOOP_SECURITY_AUTH_TO_LOCAL, "DEFAULT"));
+ } else {
+ // just extract the simple user name
+ KerberosName.setRules(defaultRule);
+ }
+ }
+
private final String name_;
+ private KerberosName kerberosName_;
+
public User(String name) {
Preconditions.checkNotNull(name);
- this.name_ = name;
+ name_ = name;
+ this.kerberosName_ = new KerberosName(name);
}
public String getName() { return name_; }
+ public String getShortName() throws InternalException {
+ try {
+ return kerberosName_.getShortName();
+ } catch (IOException e) {
+ throw new InternalException(
+ "Error calling getShortName() for user: " + getName(), e);
+ }
+ }
+
/*
- * Get the short version of the user name (the user's name up to the first '/' or '@')
- * from the full principal name.
- * Similar to: org.apache.hadoop.security.UserGroupInformation.getShortName()
+ * Returns the shortname for the user after applying auth_to_local
+ * rules from string 'rules'. This is exposed for testing purposes only.
+ * Ideally these rules are populated from hdfs configuration files.
*/
- public String getShortName() {
- int idx = name_.indexOf('/');
- int idx2 = name_.indexOf('@');
- int endIdx = Math.min(idx, idx2);
- // At least one of them was not found.
- if (endIdx == -1) endIdx = Math.max(idx, idx2);
-
- // If neither are found (or are found at the beginning of the user name),
- // return the username.
- return (endIdx <= 0) ? name_ : name_.substring(0, endIdx);
+ @VisibleForTesting
+ public String getShortNameForTesting(String rules) {
+ Preconditions.checkNotNull(rules);
+ Preconditions.checkState(RuntimeEnv.INSTANCE.isTestEnv());
+ String currentRules = KerberosName.getRules();
+ KerberosName.setRules(rules);
+ String shortName = null;
+ try {
+ shortName = getShortName();
+ } catch (InternalException e) {
+ e.printStackTrace();
+ }
+ // reset the rules
+ KerberosName.setRules(currentRules);
+ return shortName;
+ }
+
+ @VisibleForTesting
+ public static void setRulesForTesting(String rules) {
+ Preconditions.checkState(RuntimeEnv.INSTANCE.isTestEnv());
+ KerberosName.setRules(rules);
}
}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/service/BackendConfig.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/service/BackendConfig.java b/fe/src/main/java/com/cloudera/impala/service/BackendConfig.java
index 9d743c1..5dd6216 100644
--- a/fe/src/main/java/com/cloudera/impala/service/BackendConfig.java
+++ b/fe/src/main/java/com/cloudera/impala/service/BackendConfig.java
@@ -28,10 +28,19 @@ public class BackendConfig {
// the default FLAGS_read_size used by the IO manager in the backend.
private final long READ_SIZE;
+ // This is overriden by JniFrontend/JniCatalog classes with user set configuration.
+ // TODO: Read this from backend instead of using static variables.
+ private static boolean allowAuthToLocalRules_ = false;
+
private BackendConfig() {
// TODO: Populate these by making calls to the backend instead of default constants.
READ_SIZE = 8 * 1024 * 1024L;
}
public long getReadSize() { return READ_SIZE; }
-}
\ No newline at end of file
+
+ public static boolean isAuthToLocalEnabled() { return allowAuthToLocalRules_; }
+ public static void setAuthToLocal(boolean authToLocal) {
+ allowAuthToLocalRules_ = authToLocal;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/service/Frontend.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/service/Frontend.java b/fe/src/main/java/com/cloudera/impala/service/Frontend.java
index fc1f2fc..9288c05 100644
--- a/fe/src/main/java/com/cloudera/impala/service/Frontend.java
+++ b/fe/src/main/java/com/cloudera/impala/service/Frontend.java
@@ -249,7 +249,7 @@ public class Frontend {
* result argument.
*/
private void createCatalogOpRequest(AnalysisContext.AnalysisResult analysis,
- TExecRequest result) {
+ TExecRequest result) throws InternalException {
TCatalogOpRequest ddl = new TCatalogOpRequest();
TResultSetMetadata metadata = new TResultSetMetadata();
if (analysis.isUseStmt()) {
@@ -614,7 +614,7 @@ public class Frontend {
* the given user. If pattern is null, it matches all columns.
*/
public List<Column> getColumns(Table table, PatternMatcher columnPattern,
- User user) {
+ User user) throws InternalException {
Preconditions.checkNotNull(table);
List<Column> columns = Lists.newArrayList();
for (Column column: table.getColumnsInHiveOrder()) {
@@ -635,7 +635,7 @@ public class Frontend {
* Returns all databases that match the pattern and
* are accessible to the given user. If pattern is null, matches all dbs.
*/
- public List<Db> getDbs(String dbPattern, User user) {
+ public List<Db> getDbs(String dbPattern, User user) throws InternalException {
List<Db> dbs = impaladCatalog_.getDbs(dbPattern);
// If authorization is enabled, filter out the databases the user does not
// have permissions on.
@@ -652,7 +652,8 @@ public class Frontend {
/**
* Check whether database is accessible to given user.
*/
- private boolean isAccessibleToUser(Db db, User user) {
+ private boolean isAccessibleToUser(Db db, User user)
+ throws InternalException {
if (db.getName().toLowerCase().equals(Catalog.DEFAULT_DB.toLowerCase())) {
// Default DB should always be shown.
return true;
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/service/JniCatalog.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/service/JniCatalog.java b/fe/src/main/java/com/cloudera/impala/service/JniCatalog.java
index 64efd58..eb3ac92 100644
--- a/fe/src/main/java/com/cloudera/impala/service/JniCatalog.java
+++ b/fe/src/main/java/com/cloudera/impala/service/JniCatalog.java
@@ -33,6 +33,7 @@ import com.cloudera.impala.catalog.Function;
import com.cloudera.impala.common.ImpalaException;
import com.cloudera.impala.common.InternalException;
import com.cloudera.impala.common.JniUtil;
+import com.cloudera.impala.service.BackendConfig;
import com.cloudera.impala.thrift.TCatalogObject;
import com.cloudera.impala.thrift.TDatabase;
import com.cloudera.impala.thrift.TDdlExecRequest;
@@ -75,8 +76,9 @@ public class JniCatalog {
}
public JniCatalog(boolean loadInBackground, int numMetadataLoadingThreads,
- String sentryServiceConfig, int impalaLogLevel, int otherLogLevel)
- throws InternalException {
+ String sentryServiceConfig, int impalaLogLevel, int otherLogLevel,
+ boolean allowAuthToLocal) throws InternalException {
+ BackendConfig.setAuthToLocal(allowAuthToLocal);
Preconditions.checkArgument(numMetadataLoadingThreads > 0);
// This trick saves having to pass a TLogLevel enum, which is an object and more
// complex to pass through JNI.
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/service/JniFrontend.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/service/JniFrontend.java b/fe/src/main/java/com/cloudera/impala/service/JniFrontend.java
index cacefc0..b5fcbf3 100644
--- a/fe/src/main/java/com/cloudera/impala/service/JniFrontend.java
+++ b/fe/src/main/java/com/cloudera/impala/service/JniFrontend.java
@@ -49,6 +49,7 @@ import com.cloudera.impala.common.FileSystemUtil;
import com.cloudera.impala.common.ImpalaException;
import com.cloudera.impala.common.InternalException;
import com.cloudera.impala.common.JniUtil;
+import com.cloudera.impala.service.BackendConfig;
import com.cloudera.impala.thrift.TCatalogObject;
import com.cloudera.impala.thrift.TDatabase;
import com.cloudera.impala.thrift.TDescribeDbParams;
@@ -108,7 +109,8 @@ public class JniFrontend {
*/
public JniFrontend(boolean lazy, String serverName, String authorizationPolicyFile,
String sentryConfigFile, String authPolicyProviderClass, int impalaLogLevel,
- int otherLogLevel) throws InternalException {
+ int otherLogLevel, boolean allowAuthToLocal) throws InternalException {
+ BackendConfig.setAuthToLocal(allowAuthToLocal);
GlogAppender.Install(TLogLevel.values()[impalaLogLevel],
TLogLevel.values()[otherLogLevel]);
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/main/java/com/cloudera/impala/util/RequestPoolService.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/com/cloudera/impala/util/RequestPoolService.java b/fe/src/main/java/com/cloudera/impala/util/RequestPoolService.java
index e41db76..5e5e0c2 100644
--- a/fe/src/main/java/com/cloudera/impala/util/RequestPoolService.java
+++ b/fe/src/main/java/com/cloudera/impala/util/RequestPoolService.java
@@ -283,7 +283,7 @@ public class RequestPoolService {
@VisibleForTesting
TResolveRequestPoolResult resolveRequestPool(
- TResolveRequestPoolParams resolvePoolParams) {
+ TResolveRequestPoolParams resolvePoolParams) throws InternalException {
String requestedPool = resolvePoolParams.getRequested_pool();
String user = resolvePoolParams.getUser();
TResolveRequestPoolResult result = new TResolveRequestPoolResult();
@@ -410,7 +410,7 @@ public class RequestPoolService {
*/
@VisibleForTesting
String assignToPool(String requestedPool, String user)
- throws IOException {
+ throws InternalException, IOException {
Preconditions.checkState(running_.get());
Preconditions.checkNotNull(requestedPool);
Preconditions.checkArgument(!Strings.isNullOrEmpty(user));
@@ -432,14 +432,16 @@ public class RequestPoolService {
* @return True if the user has access to the pool.
*/
@VisibleForTesting
- boolean hasAccess(String pool, String user) {
+ boolean hasAccess(String pool, String user) throws InternalException {
Preconditions.checkState(running_.get());
Preconditions.checkArgument(!Strings.isNullOrEmpty(pool));
Preconditions.checkArgument(!Strings.isNullOrEmpty(user));
// Convert the user name to a short name (e.g. 'user1@domain' to 'user1') because
// the UserGroupInformation will check group membership which should always be done
// on the short name of the principal.
- String shortName = new User(user).getShortName();
+ String shortName;
+ User requestingUser = new User(user);
+ shortName = requestingUser.getShortName();
UserGroupInformation ugi = UserGroupInformation.createRemoteUser(shortName);
return allocationConf_.get().hasAccess(pool, QueueACL.SUBMIT_APPLICATIONS, ugi);
}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/test/java/com/cloudera/impala/analysis/AuditingTest.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/com/cloudera/impala/analysis/AuditingTest.java b/fe/src/test/java/com/cloudera/impala/analysis/AuditingTest.java
index 4258994..6b3c426 100644
--- a/fe/src/test/java/com/cloudera/impala/analysis/AuditingTest.java
+++ b/fe/src/test/java/com/cloudera/impala/analysis/AuditingTest.java
@@ -24,6 +24,7 @@ import com.cloudera.impala.catalog.AuthorizationException;
import com.cloudera.impala.catalog.Catalog;
import com.cloudera.impala.catalog.ImpaladCatalog;
import com.cloudera.impala.common.AnalysisException;
+import com.cloudera.impala.common.InternalException;
import com.cloudera.impala.service.Frontend;
import com.cloudera.impala.testutil.ImpaladTestCatalog;
import com.cloudera.impala.testutil.TestUtils;
@@ -327,7 +328,7 @@ public class AuditingTest extends AnalyzerTest {
@Test
public void TestAccessEventsOnAuthFailure() throws AuthorizationException,
- AnalysisException {
+ AnalysisException, InternalException {
// The policy file doesn't exist so all operations will result in
// an AuthorizationError
AuthorizationConfig config = AuthorizationConfig.createHadoopGroupAuthConfig(
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/test/java/com/cloudera/impala/analysis/AuthorizationTest.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/com/cloudera/impala/analysis/AuthorizationTest.java b/fe/src/test/java/com/cloudera/impala/analysis/AuthorizationTest.java
index 499fdf7..b82d5d4 100644
--- a/fe/src/test/java/com/cloudera/impala/analysis/AuthorizationTest.java
+++ b/fe/src/test/java/com/cloudera/impala/analysis/AuthorizationTest.java
@@ -21,15 +21,20 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
+import org.apache.hadoop.conf.Configuration;
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTH_TO_LOCAL;
import org.apache.hive.service.cli.thrift.TGetColumnsReq;
import org.apache.hive.service.cli.thrift.TGetSchemasReq;
import org.apache.hive.service.cli.thrift.TGetTablesReq;
import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -49,6 +54,7 @@ import com.cloudera.impala.catalog.Type;
import com.cloudera.impala.common.AnalysisException;
import com.cloudera.impala.common.ImpalaException;
import com.cloudera.impala.common.InternalException;
+import com.cloudera.impala.common.RuntimeEnv;
import com.cloudera.impala.service.Frontend;
import com.cloudera.impala.testutil.ImpaladTestCatalog;
import com.cloudera.impala.testutil.TestUtils;
@@ -65,6 +71,7 @@ import com.cloudera.impala.thrift.TSessionState;
import com.cloudera.impala.util.SentryPolicyService;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
@RunWith(Parameterized.class)
public class AuthorizationTest {
@@ -155,6 +162,16 @@ public class AuthorizationTest {
testCtxs_.add(new TestContext(sentryServiceAuthzConfig, sentryServiceCatalog));
}
+ @BeforeClass
+ public static void setUp() throws Exception {
+ RuntimeEnv.INSTANCE.setTestEnv(true);
+ }
+
+ @AfterClass
+ public static void cleanUp() {
+ RuntimeEnv.INSTANCE.reset();
+ }
+
public AuthorizationTest(TestContext ctx) throws Exception {
ctx_ = ctx;
queryCtx_ = TestUtils.createQueryContext(Catalog.DEFAULT_DB, USER.getName());
@@ -421,7 +438,7 @@ public class AuthorizationTest {
}
@Test
- public void TestSelect() throws AuthorizationException, AnalysisException {
+ public void TestSelect() throws ImpalaException {
// Can select from table that user has privileges on.
AuthzOk("select * from functional.alltypesagg");
@@ -535,7 +552,7 @@ public class AuthorizationTest {
}
@Test
- public void TestUnion() throws AuthorizationException, AnalysisException {
+ public void TestUnion() throws ImpalaException {
AuthzOk("select * from functional.alltypesagg union all " +
"select * from functional.alltypesagg");
@@ -553,7 +570,7 @@ public class AuthorizationTest {
}
@Test
- public void TestInsert() throws AuthorizationException, AnalysisException {
+ public void TestInsert() throws ImpalaException {
AuthzOk("insert into functional_parquet.alltypes " +
"partition(month,year) select * from functional_seq_snap.alltypes");
@@ -613,7 +630,7 @@ public class AuthorizationTest {
}
@Test
- public void TestWithClause() throws AuthorizationException, AnalysisException {
+ public void TestWithClause() throws ImpalaException {
// User has SELECT privileges on table in WITH-clause view.
AuthzOk("with t as (select * from functional.alltypesagg) select * from t");
// User doesn't have SELECT privileges on table in WITH-clause view.
@@ -648,7 +665,7 @@ public class AuthorizationTest {
}
@Test
- public void TestExplain() throws AuthorizationException, AnalysisException {
+ public void TestExplain() throws ImpalaException {
AuthzOk("explain select * from functional.alltypesagg");
AuthzOk("explain insert into functional_parquet.alltypes " +
"partition(month,year) select * from functional_seq_snap.alltypes");
@@ -727,7 +744,7 @@ public class AuthorizationTest {
}
@Test
- public void TestUseDb() throws AnalysisException, AuthorizationException {
+ public void TestUseDb() throws ImpalaException {
// Positive cases (user has privileges on these tables).
AuthzOk("use functional");
AuthzOk("use tpcds");
@@ -804,7 +821,7 @@ public class AuthorizationTest {
}
@Test
- public void TestCreateTable() throws AnalysisException, AuthorizationException {
+ public void TestCreateTable() throws ImpalaException {
AuthzOk("create table tpch.new_table (i int)");
AuthzOk("create table tpch.new_lineitem like tpch.lineitem");
// Create table IF NOT EXISTS, user has permission and table exists.
@@ -903,7 +920,7 @@ public class AuthorizationTest {
}
@Test
- public void TestCreateView() throws AuthorizationException, AnalysisException {
+ public void TestCreateView() throws ImpalaException {
AuthzOk("create view tpch.new_view as select * from functional.alltypesagg");
AuthzOk("create view tpch.new_view (a, b, c) as " +
"select int_col, string_col, timestamp_col from functional.alltypesagg");
@@ -1003,7 +1020,7 @@ public class AuthorizationTest {
}
@Test
- public void TestDropDatabase() throws AnalysisException, AuthorizationException {
+ public void TestDropDatabase() throws ImpalaException {
// User has permissions.
AuthzOk("drop database tpch");
AuthzOk("drop database tpch cascade");
@@ -1057,7 +1074,7 @@ public class AuthorizationTest {
}
@Test
- public void TestDropTable() throws AnalysisException, AuthorizationException {
+ public void TestDropTable() throws ImpalaException {
// Drop table (user has permission).
AuthzOk("drop table tpch.lineitem");
AuthzOk("drop table if exists tpch.lineitem");
@@ -1093,7 +1110,7 @@ public class AuthorizationTest {
}
@Test
- public void TestDropView() throws AnalysisException, AuthorizationException {
+ public void TestDropView() throws ImpalaException {
// Drop view (user has permission).
AuthzOk("drop view functional_seq_snap.alltypes_view");
AuthzOk("drop view if exists functional_seq_snap.alltypes_view");
@@ -1126,7 +1143,7 @@ public class AuthorizationTest {
}
@Test
- public void TestTruncate() throws AuthorizationException, AnalysisException {
+ public void TestTruncate() throws ImpalaException {
AuthzOk("truncate table functional_parquet.alltypes");
// User doesn't have INSERT permissions in the target table.
@@ -1147,7 +1164,7 @@ public class AuthorizationTest {
}
@Test
- public void TestAlterTable() throws AnalysisException, AuthorizationException {
+ public void TestAlterTable() throws ImpalaException {
// User has permissions to modify tables.
AuthzOk("ALTER TABLE functional_seq_snap.alltypes ADD COLUMNS (c1 int)");
AuthzOk("ALTER TABLE functional_seq_snap.alltypes REPLACE COLUMNS (c1 int)");
@@ -1274,7 +1291,7 @@ public class AuthorizationTest {
}
@Test
- public void TestAlterView() throws AnalysisException, AuthorizationException {
+ public void TestAlterView() throws ImpalaException {
AuthzOk("ALTER VIEW functional_seq_snap.alltypes_view rename to " +
"functional_seq_snap.v1");
@@ -1330,7 +1347,7 @@ public class AuthorizationTest {
}
@Test
- public void TestComputeStatsTable() throws AnalysisException, AuthorizationException {
+ public void TestComputeStatsTable() throws ImpalaException {
AuthzOk("compute stats functional_seq_snap.alltypes");
AuthzError("compute stats functional.alltypes",
@@ -1344,7 +1361,7 @@ public class AuthorizationTest {
}
@Test
- public void TestDropStats() throws AnalysisException, AuthorizationException {
+ public void TestDropStats() throws ImpalaException {
AuthzOk("drop stats functional_seq_snap.alltypes");
AuthzError("drop stats functional.alltypes",
@@ -1358,7 +1375,7 @@ public class AuthorizationTest {
}
@Test
- public void TestDescribeDb() throws AuthorizationException, AnalysisException {
+ public void TestDescribeDb() throws ImpalaException {
AuthzOk("describe database functional_seq_snap");
// Database doesn't exist.
@@ -1370,7 +1387,7 @@ public class AuthorizationTest {
}
@Test
- public void TestDescribe() throws AuthorizationException, AnalysisException {
+ public void TestDescribe() throws ImpalaException {
AuthzOk("describe functional.alltypesagg");
AuthzOk("describe functional.alltypes");
AuthzOk("describe functional.complex_view");
@@ -1406,7 +1423,7 @@ public class AuthorizationTest {
}
@Test
- public void TestLoad() throws AuthorizationException, AnalysisException {
+ public void TestLoad() throws ImpalaException {
// User has permission on table and URI.
AuthzOk("load data inpath 'hdfs://localhost:20500/test-warehouse/tpch.lineitem'" +
" into table functional.alltypes partition(month=10, year=2009)");
@@ -1453,7 +1470,7 @@ public class AuthorizationTest {
}
@Test
- public void TestShowPermissions() throws AuthorizationException, AnalysisException {
+ public void TestShowPermissions() throws ImpalaException {
AuthzOk("show tables in functional");
AuthzOk("show databases");
AuthzOk("show tables in _impala_builtins");
@@ -1657,11 +1674,10 @@ public class AuthorizationTest {
}
@Test
- public void TestShortUsernameUsed() throws AnalysisException,
- AuthorizationException {
+ public void TestShortUsernameUsed() throws Exception {
// Different long variations of the same username.
List<User> users = Lists.newArrayList(
- new User(USER.getName() + "/abc.host.com"),
+ new User(USER.getName() + "/abc.host.com@"),
new User(USER.getName() + "/abc.host.com@REAL.COM"),
new User(USER.getName() + "@REAL.COM"));
for (User user: users) {
@@ -1677,14 +1693,84 @@ public class AuthorizationTest {
"User '%s' does not have privileges to execute 'SELECT' on: default.alltypes",
user);
}
- // If the first character is '/' or '@', the short username should be the same as
+ // If the first character is '/', the short username should be the same as
// the full username.
assertEquals("/" + USER.getName(), new User("/" + USER.getName()).getShortName());
- assertEquals("@" + USER.getName(), new User("@" + USER.getName()).getShortName());
}
@Test
- public void TestFunction() throws ImpalaException {
+ public void TestShortUsernameWithAuthToLocal() throws ImpalaException {
+ // We load the auth_to_local configs from core-site.xml in the test mode even if
+ // kerberos is disabled. We use the following configuration for tests
+ // <property>
+ // <name>hadoop.security.auth_to_local</name>
+ // <value>RULE:[2:$1@$0](authtest@REALM.COM)s/(.*)@REALM.COM/auth_to_local_user/
+ // RULE:[1:$1]
+ // RULE:[2:$1]
+ // DEFAULT
+ // </value>
+ // </property>
+ AuthorizationConfig authzConfig = new AuthorizationConfig("server1",
+ AUTHZ_POLICY_FILE, "",
+ LocalGroupResourceAuthorizationProvider.class.getName());
+ ImpaladCatalog catalog = new ImpaladTestCatalog(authzConfig);
+
+ // This test relies on the auth_to_local rule -
+ // "RULE:[2:$1@$0](authtest@REALM.COM)s/(.*)@REALM.COM/auth_to_local_user/"
+ // which converts any principal of type authtest/<hostname>@REALM.COM to user
+ // auth_to_local_user. We have a sentry privilege in place that grants 'SELECT'
+ // privilege on tpcds.* to user auth_to_local_user. To test the integration, we try
+ // running the query with authtest/hostname@REALM.COM user which is converted to user
+ // 'auth_to_local_user' and the authz should pass.
+ User.setRulesForTesting(
+ new Configuration().get(HADOOP_SECURITY_AUTH_TO_LOCAL, "DEFAULT"));
+ User user = new User("authtest/hostname@REALM.COM");
+ AnalysisContext context = new AnalysisContext(catalog,
+ TestUtils.createQueryContext(Catalog.DEFAULT_DB, user.getName()), authzConfig);
+ Frontend fe = new Frontend(authzConfig, catalog);
+
+ // Can select from table that user has privileges on.
+ AuthzOk(fe, context, "select * from tpcds.customer");
+ // Does not have privileges to execute a query
+ AuthzError(fe, context, "select * from functional.alltypes",
+ "User '%s' does not have privileges to execute 'SELECT' on: functional.alltypes",
+ user);
+
+ // Unit tests for User#getShortName()
+ // Different auth_to_local rules to apply on the username.
+ List<String> rules = Lists.newArrayList(
+ // Expects user@REALM and returns 'usera' (appends a in the end)
+ "RULE:[1:$1@$0](.*@REALM.COM)s/(.*)@REALM.COM/$1a/g",
+ // Same as above but expects user/host@REALM
+ "RULE:[2:$1@$0](.*@REALM.COM)s/(.*)@REALM.COM/$1a/g");
+
+ // Map from the user to the expected getShortName() output after applying
+ // the corresponding rule from 'rules' list.
+ List<Map.Entry<User, String>> users = Lists.newArrayList(
+ Maps.immutableEntry(new User(USER.getName() + "@REALM.COM"), USER.getName()
+ + "a"),
+ Maps.immutableEntry(new User(USER.getName() + "/abc.host.com@REALM.COM"),
+ USER.getName() + "a"));
+
+ for (int idx = 0; idx < users.size(); ++idx) {
+ Map.Entry<User, String> userObj = users.get(idx);
+ assertEquals(userObj.getKey().getShortNameForTesting(rules.get(idx)),
+ userObj.getValue());
+ }
+
+ // Test malformed rules. RuleParser throws an IllegalArgumentException.
+ String malformedRule = "{((()";
+ try {
+ user.getShortNameForTesting(malformedRule);
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue(e.getMessage().contains("Invalid rule"));
+ return;
+ }
+ Assert.fail("No exception caught while using getShortName() on a malformed rule");
+ }
+
+ @Test
+ public void TestFunction() throws Exception {
// First try with the less privileged user.
User currentUser = USER;
AnalysisContext context = new AnalysisContext(ctx_.catalog,
@@ -1771,7 +1857,8 @@ public class AuthorizationTest {
}
@Test
- public void TestServerNameAuthorized() throws AnalysisException {
+ public void TestServerNameAuthorized()
+ throws AnalysisException, InternalException {
if (ctx_.authzConfig.isFileBasedPolicy()) {
// Authorization config that has a different server name from policy file.
TestWithIncorrectConfig(AuthorizationConfig.createHadoopGroupAuthConfig(
@@ -1781,7 +1868,8 @@ public class AuthorizationTest {
}
@Test
- public void TestNoPermissionsWhenPolicyFileDoesNotExist() throws AnalysisException {
+ public void TestNoPermissionsWhenPolicyFileDoesNotExist()
+ throws AnalysisException, InternalException {
// Test doesn't make sense except for file based policies.
if (!ctx_.authzConfig.isFileBasedPolicy()) return;
@@ -1894,8 +1982,7 @@ public class AuthorizationTest {
}
@Test
- public void TestLocalGroupPolicyProvider() throws AnalysisException,
- AuthorizationException {
+ public void TestLocalGroupPolicyProvider() throws ImpalaException {
if (!ctx_.authzConfig.isFileBasedPolicy()) return;
// Use an authorization configuration that uses the
// LocalGroupResourceAuthorizationProvider.
@@ -1930,7 +2017,7 @@ public class AuthorizationTest {
}
private void TestWithIncorrectConfig(AuthorizationConfig authzConfig, User user)
- throws AnalysisException {
+ throws AnalysisException, InternalException {
Frontend fe = new Frontend(authzConfig, ctx_.catalog);
AnalysisContext ac = new AnalysisContext(new ImpaladTestCatalog(),
TestUtils.createQueryContext(Catalog.DEFAULT_DB, user.getName()), authzConfig);
@@ -1947,18 +2034,16 @@ public class AuthorizationTest {
"User '%s' does not have privileges to access: functional.*", user);
}
- private void AuthzOk(String stmt) throws AuthorizationException,
- AnalysisException {
+ private void AuthzOk(String stmt) throws ImpalaException {
AuthzOk(analysisContext_, stmt);
}
- private void AuthzOk(AnalysisContext context, String stmt)
- throws AuthorizationException, AnalysisException {
+ private void AuthzOk(AnalysisContext context, String stmt) throws ImpalaException {
AuthzOk(fe_, context, stmt);
}
private static void AuthzOk(Frontend fe, AnalysisContext context, String stmt)
- throws AuthorizationException, AnalysisException {
+ throws ImpalaException {
context.analyze(stmt);
context.authorize(fe.getAuthzChecker());
}
@@ -1968,17 +2053,19 @@ public class AuthorizationTest {
* string matches.
*/
private void AuthzError(String stmt, String expectedErrorString)
- throws AnalysisException {
+ throws AnalysisException, InternalException {
AuthzError(analysisContext_, stmt, expectedErrorString, USER);
}
private void AuthzError(AnalysisContext analysisContext,
- String stmt, String expectedErrorString, User user) throws AnalysisException {
+ String stmt, String expectedErrorString, User user)
+ throws AnalysisException, InternalException {
AuthzError(fe_, analysisContext, stmt, expectedErrorString, user);
}
private static void AuthzError(Frontend fe, AnalysisContext analysisContext,
- String stmt, String expectedErrorString, User user) throws AnalysisException {
+ String stmt, String expectedErrorString, User user)
+ throws AnalysisException, InternalException {
Preconditions.checkNotNull(expectedErrorString);
try {
try {
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/test/java/com/cloudera/impala/util/TestRequestPoolService.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/com/cloudera/impala/util/TestRequestPoolService.java b/fe/src/test/java/com/cloudera/impala/util/TestRequestPoolService.java
index 34255bd..c40ca0f 100644
--- a/fe/src/test/java/com/cloudera/impala/util/TestRequestPoolService.java
+++ b/fe/src/test/java/com/cloudera/impala/util/TestRequestPoolService.java
@@ -27,6 +27,7 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import com.cloudera.impala.common.ByteUnits;
+import com.cloudera.impala.common.InternalException;
import com.cloudera.impala.thrift.TErrorCode;
import com.cloudera.impala.thrift.TPoolConfig;
import com.cloudera.impala.thrift.TResolveRequestPoolParams;
@@ -233,7 +234,8 @@ public class TestRequestPoolService {
checkPoolConfigResult("root.queueC", -1, 200, 128 * ByteUnits.MEGABYTE);
}
- private void checkModifiedConfigResults() throws IOException {
+ private void checkModifiedConfigResults()
+ throws InternalException, IOException {
// Test pool resolution: now there's a queueC
Assert.assertEquals("root.queueA", poolService_.assignToPool("queueA", "userA"));
Assert.assertNull(poolService_.assignToPool("queueX", "userA"));
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/fe/src/test/resources/authz-policy.ini.template
----------------------------------------------------------------------
diff --git a/fe/src/test/resources/authz-policy.ini.template b/fe/src/test/resources/authz-policy.ini.template
index e07cad5..4c11bc4 100644
--- a/fe/src/test/resources/authz-policy.ini.template
+++ b/fe/src/test/resources/authz-policy.ini.template
@@ -8,6 +8,7 @@ ${USER} = all_tpch, all_newdb, all_functional_seq_snap, select_tpcds,\
select_functional_complex_view, select_functional_view_view,\
insert_parquet, new_table_uri, tpch_data_uri, select_column_level_functional,\
upper_case_uri
+auth_to_local_group = test_role
server_admin = all_server
# The [roles] section defines privileges for objects in the authorizeable hierarchy.
@@ -20,6 +21,7 @@ all_tpch = server=server1->db=tpch
all_newdb = server=server1->db=newdb
all_functional_seq_snap = server=server1->db=functional_seq_snap
select_tpcds = server=server1->db=tpcds->table=*->action=select
+test_role = server=server1->db=tpcds->table=*->action=select
select_functional_alltypesagg =\
server=server1->db=functional->table=alltypesagg->action=select
insert_functional_alltypes = server=server1->db=functional->table=alltypes->action=insert
@@ -59,4 +61,5 @@ upper_case_uri = server=server1->uri=hdfs://localhost:20500/test-warehouse/UPPER
# HadoopGroupResourcePolicyProvider.
[users]
test_user = ${USER}
+auth_to_local_user = auth_to_local_group
admin_user = server_admin
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/3092c966/testdata/cluster/node_templates/common/etc/hadoop/conf/core-site.xml.tmpl
----------------------------------------------------------------------
diff --git a/testdata/cluster/node_templates/common/etc/hadoop/conf/core-site.xml.tmpl b/testdata/cluster/node_templates/common/etc/hadoop/conf/core-site.xml.tmpl
index 4f858f1..ab86878 100644
--- a/testdata/cluster/node_templates/common/etc/hadoop/conf/core-site.xml.tmpl
+++ b/testdata/cluster/node_templates/common/etc/hadoop/conf/core-site.xml.tmpl
@@ -35,6 +35,16 @@
</property>
<property>
+ <!-- AuthorizationTest depends on auth_to_local configs. These tests are run
+ irrespective of whether kerberos is enabled. -->
+ <name>hadoop.security.auth_to_local</name>
+ <value>RULE:[2:$1@$0](authtest@REALM.COM)s/(.*)@REALM.COM/auth_to_local_user/
+RULE:[1:$1]
+RULE:[2:$1]
+DEFAULT</value>
+ </property>
+
+ <property>
<name>hadoop.proxyuser.${USER}.groups</name>
<value>*</value>
</property>
@@ -104,6 +114,7 @@
<name>hadoop.proxyuser.llama.groups</name>
<value>*</value>
</property>
+
<!-- END Kerberos settings -->
</configuration>