Repository: incubator-sentry Updated Branches: refs/heads/master 4c2ce7938 -> 282b79dd7
SENTRY-300: HiveAuthzBinding checks for Hive server2 config which is not available when using Sentry with Hive meta store server (Sravya Tirukkovalur via 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/282b79dd Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/282b79dd Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/282b79dd Branch: refs/heads/master Commit: 282b79dd71c924f3b573f40f5c84e9fffdad0032 Parents: 4c2ce79 Author: Prasad Mujumdar <[email protected]> Authored: Mon Jun 16 13:52:58 2014 -0700 Committer: Prasad Mujumdar <[email protected]> Committed: Mon Jun 16 13:52:58 2014 -0700 ---------------------------------------------------------------------- .../binding/hive/authz/HiveAuthzBinding.java | 60 ++++++++++++++++++-- .../metastore/MetastoreAuthzBinding.java | 2 +- .../binding/hive/TestHiveAuthzBindings.java | 45 +++++++++++++-- .../apache/sentry/tests/e2e/hive/Context.java | 21 +++++-- .../tests/e2e/hive/TestServerConfiguration.java | 20 ++----- 5 files changed, 116 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/282b79dd/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java index 39f5384..b478ec2 100644 --- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java +++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java @@ -69,13 +69,25 @@ public class HiveAuthzBinding { private volatile boolean open; private ActiveRoleSet activeRoleSet; + public static enum HiveHook { + HiveServer2, + HiveMetaStore + ; + } + public HiveAuthzBinding (HiveConf hiveConf, HiveAuthzConf authzConf) throws Exception { + this(HiveHook.HiveServer2, hiveConf, authzConf); + } + + public HiveAuthzBinding (HiveHook hiveHook, HiveConf hiveConf, HiveAuthzConf authzConf) throws Exception { + validateHiveConfig(hiveHook, hiveConf, authzConf); this.hiveConf = hiveConf; this.authServer = new Server(authzConf.get(AuthzConfVars.AUTHZ_SERVER_NAME.getVar())); this.authProvider = getAuthProvider(hiveConf, authzConf, authServer.getName()); this.open = true; this.activeRoleSet = parseActiveRoleSet(hiveConf.get(HiveAuthzConf.SENTRY_ACTIVE_ROLE_SET, authzConf.get(HiveAuthzConf.SENTRY_ACTIVE_ROLE_SET, "")).trim()); + } private static ActiveRoleSet parseActiveRoleSet(String name) { @@ -137,16 +149,45 @@ public class HiveAuthzBinding { authProvider.close(); } - // Instantiate the configured authz provider - public static AuthorizationProvider getAuthProvider(HiveConf hiveConf, HiveAuthzConf authzConf, - String serverName) throws Exception { + private void validateHiveConfig(HiveHook hiveHook, HiveConf hiveConf, HiveAuthzConf authzConf) + throws InvalidConfigurationException{ + if(hiveHook.equals(HiveHook.HiveMetaStore)) { + validateHiveMetaStoreConfig(hiveConf, authzConf); + }else if(hiveHook.equals(HiveHook.HiveServer2)) { + validateHiveServer2Config(hiveConf, authzConf); + } + } + + private void validateHiveMetaStoreConfig(HiveConf hiveConf, HiveAuthzConf authzConf) + throws InvalidConfigurationException{ + boolean isTestingMode = Boolean.parseBoolean(Strings.nullToEmpty( + authzConf.get(AuthzConfVars.SENTRY_TESTING_MODE.getVar())).trim()); + LOG.debug("Testing mode is " + isTestingMode); + if(!isTestingMode) { + boolean sasl = hiveConf.getBoolVar(ConfVars.METASTORE_USE_THRIFT_SASL); + if(!sasl) { + throw new InvalidConfigurationException( + ConfVars.METASTORE_USE_THRIFT_SASL + " can't be false in non-testing mode"); + } + } else { + boolean setUgi = hiveConf.getBoolVar(ConfVars.METASTORE_EXECUTE_SET_UGI); + if(!setUgi) { + throw new InvalidConfigurationException( + ConfVars.METASTORE_EXECUTE_SET_UGI.toString() + " can't be false in non secure mode"); + } + } + } + + private void validateHiveServer2Config(HiveConf hiveConf, HiveAuthzConf authzConf) + throws InvalidConfigurationException{ boolean isTestingMode = Boolean.parseBoolean(Strings.nullToEmpty( authzConf.get(AuthzConfVars.SENTRY_TESTING_MODE.getVar())).trim()); LOG.debug("Testing mode is " + isTestingMode); if(!isTestingMode) { String authMethod = Strings.nullToEmpty(hiveConf.getVar(ConfVars.HIVE_SERVER2_AUTHENTICATION)).trim(); if("none".equalsIgnoreCase(authMethod)) { - throw new InvalidConfigurationException("Authentication can't be NONE in non-testing mode"); + throw new InvalidConfigurationException(ConfVars.HIVE_SERVER2_AUTHENTICATION + + " can't be none in non-testing mode"); } boolean impersonation = hiveConf.getBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS); boolean allowImpersonation = Boolean.parseBoolean(Strings.nullToEmpty( @@ -154,14 +195,21 @@ public class HiveAuthzBinding { if(impersonation && !allowImpersonation) { LOG.error("Role based authorization does not work with HiveServer2 impersonation"); - return new NoAuthorizationProvider(); + throw new InvalidConfigurationException(ConfVars.HIVE_SERVER2_ENABLE_DOAS + + " can't be set to true in non-testing mode"); } } String defaultUmask = hiveConf.get(CommonConfigurationKeys.FS_PERMISSIONS_UMASK_KEY); if("077".equalsIgnoreCase(defaultUmask)) { LOG.error("HiveServer2 required a default umask of 077"); - return new NoAuthorizationProvider(); + throw new InvalidConfigurationException(CommonConfigurationKeys.FS_PERMISSIONS_UMASK_KEY + + " should be 077 in non-testing mode"); } + } + + // Instantiate the configured authz provider + public static AuthorizationProvider getAuthProvider(HiveConf hiveConf, HiveAuthzConf authzConf, + String serverName) throws Exception { // get the provider class and resources from the authz config String authProviderName = authzConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar()); String resourceName = http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/282b79dd/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java index 30c3488..057f704 100644 --- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java +++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/MetastoreAuthzBinding.java @@ -339,7 +339,7 @@ public class MetastoreAuthzBinding extends MetaStorePreEventListener { private HiveAuthzBinding getHiveAuthzBinding() throws Exception { if (hiveAuthzBinding == null) { - hiveAuthzBinding = new HiveAuthzBinding(hiveConf, authzConf); + hiveAuthzBinding = new HiveAuthzBinding(HiveAuthzBinding.HiveHook.HiveMetaStore, hiveConf, authzConf); } return hiveAuthzBinding; } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/282b79dd/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestHiveAuthzBindings.java ---------------------------------------------------------------------- diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestHiveAuthzBindings.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestHiveAuthzBindings.java index e6d790a..1f9d1ec 100644 --- a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestHiveAuthzBindings.java +++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestHiveAuthzBindings.java @@ -283,21 +283,54 @@ public class TestHiveAuthzBindings { } /** - * Turn on impersonation and make sure that the authorization fails. + * Turn on impersonation and make sure InvalidConfigurationException is thrown. * @throws Exception */ - @Test(expected=AuthorizationException.class) + @Test(expected=InvalidConfigurationException.class) public void testImpersonationRestriction() throws Exception { // perpare the hive and auth configs hiveConf.setBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS, true); hiveConf.setVar(ConfVars.HIVE_SERVER2_AUTHENTICATION, "Kerberos"); authzConf.set(AuthzConfVars.SENTRY_TESTING_MODE.getVar(), "false"); testAuth = new HiveAuthzBinding(hiveConf, authzConf); + } - // following check should pass, but with impersonation it will fail with due to NoAuthorizationProvider - inputTabHierarcyList.add(buildObjectHierarchy(SERVER1, CUSTOMER_DB, PURCHASES_TAB)); - testAuth.authorize(HiveOperation.QUERY, queryPrivileges, ADMIN_SUBJECT, - inputTabHierarcyList, outputTabHierarcyList); + /** + * HiveServer2 not using string authentication, make sure InvalidConfigurationException is thrown. + * @throws Exception + */ + @Test(expected=InvalidConfigurationException.class) + public void testHiveServer2AuthRestriction() throws Exception { + // prepare the hive and auth configs + hiveConf.setBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS, false); + hiveConf.setVar(ConfVars.HIVE_SERVER2_AUTHENTICATION, "none"); + authzConf.set(AuthzConfVars.SENTRY_TESTING_MODE.getVar(), "false"); + testAuth = new HiveAuthzBinding(hiveConf, authzConf); + } + + /** + * hive.metastore.sasl.enabled != true, make sure InvalidConfigurationException is thrown. + * @throws Exception + */ + @Test(expected=InvalidConfigurationException.class) + public void testHiveMetaStoreSSLConfig() throws Exception { + // prepare the hive and auth configs + hiveConf.setBoolVar(ConfVars.METASTORE_USE_THRIFT_SASL, false); + hiveConf.setBoolVar(ConfVars.METASTORE_EXECUTE_SET_UGI, true); + authzConf.set(AuthzConfVars.SENTRY_TESTING_MODE.getVar(), "false"); + testAuth = new HiveAuthzBinding(HiveAuthzBinding.HiveHook.HiveMetaStore, hiveConf, authzConf); + } + /** + * hive.metastore.execute.setugi != true, make sure InvalidConfigurationException is thrown. + * @throws Exception + */ + @Test(expected=InvalidConfigurationException.class) + public void testHiveMetaStoreUGIConfig() throws Exception { + // prepare the hive and auth configs + hiveConf.setBoolVar(ConfVars.METASTORE_USE_THRIFT_SASL, true); + hiveConf.setBoolVar(ConfVars.METASTORE_EXECUTE_SET_UGI, false); + authzConf.set(AuthzConfVars.SENTRY_TESTING_MODE.getVar(), "true"); + testAuth = new HiveAuthzBinding(HiveAuthzBinding.HiveHook.HiveMetaStore, hiveConf, authzConf); } /** http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/282b79dd/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/Context.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/Context.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/Context.java index 4985912..e725eb0 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/Context.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/Context.java @@ -17,6 +17,7 @@ package org.apache.sentry.tests.e2e.hive; +import org.apache.sentry.binding.hive.conf.InvalidConfigurationException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -63,6 +64,7 @@ public class Context { public static final String AUTHZ_LINK_FAILURE_SQL_STATE = "08S01"; public static final String AUTHZ_EXCEPTION_ERROR_MSG = "No valid privileges"; private static final String METASTORE_AUTH_ERROR_MSG = "does not have privileges"; + private static final String INVALID_CONFIG_ERROR_MSG = InvalidConfigurationException.class.getSimpleName(); private final HiveServer hiveServer; private final FileSystem fileSystem; @@ -259,11 +261,11 @@ public class Context { .createRemoteUser(userName); PigServer pigServer = (PigServer) ShimLoader.getHadoopShims().doAs( clientUgi, new PrivilegedExceptionAction<Object>() { - @Override - public PigServer run() throws Exception { - return new PigServer(exType, new HiveConf()); - } - }); + @Override + public PigServer run() throws Exception { + return new PigServer(exType, new HiveConf()); + } + }); return pigServer; } @@ -295,4 +297,13 @@ public class Context { + e.getClass().getName(), e); } } + public void verifyInvalidConfigurationException(Throwable e) + throws Exception { + if (e instanceof SQLException) { + assertTrue(e.getMessage().contains(INVALID_CONFIG_ERROR_MSG)); + } else { + throw new Exception("Excepted " + INVALID_CONFIG_ERROR_MSG + " but got: " + + e.getClass().getName(), e); + } + } } http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/282b79dd/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestServerConfiguration.java ---------------------------------------------------------------------- diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestServerConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestServerConfiguration.java index c05bb4f..436e842 100644 --- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestServerConfiguration.java +++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestServerConfiguration.java @@ -70,18 +70,7 @@ public class TestServerConfiguration extends AbstractTestWithHiveServer { public void testImpersonationIsDisabled() throws Exception { properties.put(HiveServerFactory.ACCESS_TESTING_MODE, "false"); properties.put("hive.server2.enable.impersonation", "true"); - context = createContext(properties); - policyFile - .setUserGroupMapping(StaticUserGroup.getStaticMapping()) - .write(context.getPolicyFile()); - Connection connection = context.createConnection(ADMIN1); - Statement statement = context.createStatement(connection); - try { - statement.execute("create table test (a string)"); - Assert.fail("Expected SQLException"); - } catch (SQLException e) { - context.verifyAuthzException(e); - } + verifyInvalidConfigurationException(); } /** @@ -91,18 +80,21 @@ public class TestServerConfiguration extends AbstractTestWithHiveServer { public void testAuthenticationIsStrong() throws Exception { properties.put(HiveServerFactory.ACCESS_TESTING_MODE, "false"); properties.put("hive.server2.authentication", "NONE"); + verifyInvalidConfigurationException(); + } + + private void verifyInvalidConfigurationException() throws Exception{ context = createContext(properties); policyFile .setUserGroupMapping(StaticUserGroup.getStaticMapping()) .write(context.getPolicyFile()); - System.out.println(Files.toString(context.getPolicyFile(), Charsets.UTF_8)); Connection connection = context.createConnection(ADMIN1); Statement statement = context.createStatement(connection); try { statement.execute("create table test (a string)"); Assert.fail("Expected SQLException"); } catch (SQLException e) { - context.verifyAuthzException(e); + context.verifyInvalidConfigurationException(e); } }
