diff --git a/llap-client/pom.xml b/llap-client/pom.xml
index 6923c3505b2635b4ee95697b47487d97f3f1484d..84e87ec36d368d80305e0ac1a97d25d2fb9e0322 100644
--- a/llap-client/pom.xml
+++ b/llap-client/pom.xml
@@ -156,6 +156,18 @@
+
+ org.powermock
+ powermock-module-junit4
+ ${powermock.version}
+ test
+
+
+ org.powermock
+ powermock-api-mockito
+ ${powermock.version}
+ test
+
${basedir}/src/java
diff --git a/llap-client/src/java/org/apache/hadoop/hive/registry/impl/ZookeeperUtils.java b/llap-client/src/java/org/apache/hadoop/hive/registry/impl/ZookeeperUtils.java
index be7657a5080b78df806994af8c492140384c3926..c3d34c486dc072689510873a413ea19195dc3de8 100644
--- a/llap-client/src/java/org/apache/hadoop/hive/registry/impl/ZookeeperUtils.java
+++ b/llap-client/src/java/org/apache/hadoop/hive/registry/impl/ZookeeperUtils.java
@@ -55,14 +55,19 @@ public static String setupZookeeperAuth(Configuration conf, String saslLoginCont
/**
* Check if Kerberos authentication is enabled.
+ * This is used by:
+ * - LLAP daemons
+ * - Tez AM
+ * - HS2
+ * - LLAP status service
+ * Among the these Tez AM process has the lowest security setting wrt Kerberos in UGI.
+ * Even in secure scenarios Tez AM will return false for
+ * UGI.getLoginUser().hasKerberosCredentials() as it does not log in using Kerberos.
+ * Hence UGI.isSecurityEnabled() is the tightest setting we can check against.
*/
public static boolean isKerberosEnabled(Configuration conf) {
- try {
- return UserGroupInformation.getLoginUser().hasKerberosCredentials() &&
+ return UserGroupInformation.isSecurityEnabled() &&
HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_ZOOKEEPER_USE_KERBEROS);
- } catch (IOException e) {
- return false;
- }
}
/**
diff --git a/llap-client/src/test/org/apache/hadoop/hive/registry/impl/TestZookeeperUtils.java b/llap-client/src/test/org/apache/hadoop/hive/registry/impl/TestZookeeperUtils.java
index 46e74380c2409783ece8cbbcc010f0112c98d3b9..0f2cae6d76ceb6e71fa9e3ebd8f86efc85fa668a 100644
--- a/llap-client/src/test/org/apache/hadoop/hive/registry/impl/TestZookeeperUtils.java
+++ b/llap-client/src/test/org/apache/hadoop/hive/registry/impl/TestZookeeperUtils.java
@@ -24,11 +24,18 @@
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.BDDMockito;
import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
/**
* ZookeeperUtils test suite.
*/
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(UserGroupInformation.class)
public class TestZookeeperUtils {
private Configuration conf;
@@ -37,18 +44,26 @@
@Before
public void setup() {
conf = new Configuration();
+ PowerMockito.mockStatic(UserGroupInformation.class);
+ BDDMockito.given(UserGroupInformation.isSecurityEnabled()).willReturn(true);
ugi = Mockito.mock(UserGroupInformation.class);
UserGroupInformation.setLoginUser(ugi);
}
+ /**
+ * Secure scenario, invoked e.g. from within HS2 or LLAP daemon process, kinit'ed inside proc.
+ */
@Test
- public void testHadoopAuthKerberosAndZookeeperUseKerberos() {
+ public void testHadoopAuthKerberosFromKeytabAndZookeeperUseKerberos() {
Mockito.when(ugi.hasKerberosCredentials()).thenReturn(true);
Mockito.when(ugi.isFromKeytab()).thenReturn(true);
Assert.assertTrue(HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_ZOOKEEPER_USE_KERBEROS));
Assert.assertTrue(ZookeeperUtils.isKerberosEnabled(conf));
}
+ /**
+ * Secure scenario, invoked e.g. from within HS2 or LLAP status process, kinit'ed in parent proc.
+ */
@Test
public void testHadoopAuthKerberosFromTicketAndZookeeperUseKerberos() {
Mockito.when(ugi.hasKerberosCredentials()).thenReturn(true);
@@ -57,17 +72,36 @@ public void testHadoopAuthKerberosFromTicketAndZookeeperUseKerberos() {
Assert.assertTrue(ZookeeperUtils.isKerberosEnabled(conf));
}
+ /**
+ * Secure scenario, invoked e.g. from within Tez AM process.
+ */
@Test
- public void testHadoopAuthKerberosAndZookeeperNoKerberos(){
- Mockito.when(ugi.hasKerberosCredentials()).thenReturn(true);
- conf.setBoolean(HiveConf.ConfVars.HIVE_ZOOKEEPER_USE_KERBEROS.varname, false);
- Assert.assertFalse(ZookeeperUtils.isKerberosEnabled(conf));
+ public void testHadoopAuthKerberosNoLoginAndZookeeperUseKerberos() {
+ Mockito.when(ugi.hasKerberosCredentials()).thenReturn(false);
+ Mockito.when(ugi.isFromKeytab()).thenReturn(false);
+ Assert.assertTrue(HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_ZOOKEEPER_USE_KERBEROS));
+ Assert.assertTrue(ZookeeperUtils.isKerberosEnabled(conf));
}
+ /**
+ * Unsecure scenario.
+ */
@Test
- public void testHadoopAuthSimpleAndZookeeperKerberos(){
+ public void testHadoopAuthSimpleAndZookeeperUseKerberos() {
+ BDDMockito.given(UserGroupInformation.isSecurityEnabled()).willReturn(false);
Mockito.when(ugi.hasKerberosCredentials()).thenReturn(false);
+ Mockito.when(ugi.isFromKeytab()).thenReturn(false);
+ Assert.assertTrue(HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_ZOOKEEPER_USE_KERBEROS));
+ Assert.assertFalse(ZookeeperUtils.isKerberosEnabled(conf));
+ }
+
+ /**
+ * Secure scenario with hive.zookeeper.kerberos.enabled=false.
+ */
+ @Test
+ public void testHadoopAuthKerberosAndZookeeperNoKerberos(){
conf.setBoolean(HiveConf.ConfVars.HIVE_ZOOKEEPER_USE_KERBEROS.varname, false);
Assert.assertFalse(ZookeeperUtils.isKerberosEnabled(conf));
}
+
}
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/tez/TezSessionState.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/tez/TezSessionState.java
index b4cdcb538deef9f2ff58c889b2a7b3d952e52344..8becef1cd3a7534813e5479d7a59b5f8b49bf465 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/tez/TezSessionState.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/tez/TezSessionState.java
@@ -392,6 +392,14 @@ public TezClient call() throws Exception {
}
}
+ /**
+ * Check if Kerberos authentication is enabled.
+ * This is used by:
+ * - HS2 (upon Tez session creation)
+ * In secure scenarios HS2 might either be logged on (by Kerberos) by itself or by a launcher
+ * script it was forked from. In the latter case UGI.getLoginUser().isFromKeytab() returns false,
+ * hence UGI.getLoginUser().hasKerberosCredentials() is a tightest setting we can check against.
+ */
private boolean isKerberosEnabled(Configuration conf) {
try {
return UserGroupInformation.getLoginUser().hasKerberosCredentials() &&
diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/security/ZooKeeperTokenStore.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/security/ZooKeeperTokenStore.java
index 785fa02854099f959171dc6438775787ca36132b..da28fed825d7bbb131bf9cf86afdec3b4a3977f3 100644
--- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/security/ZooKeeperTokenStore.java
+++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/security/ZooKeeperTokenStore.java
@@ -93,9 +93,17 @@
return nodeAcls;
}
+ /**
+ * Check if Kerberos authentication is enabled.
+ * This is used by:
+ * - HMS
+ * In secure scenarios the HMS is logged in (by itself) using Kerberos keytab, hence
+ * UGI.getLoginUser().isFromKeytab() returns true.
+ * This makes checking against this method the tightest setting we can check against.
+ */
private boolean isKerberosEnabled(Configuration conf) {
try {
- return UserGroupInformation.getLoginUser().hasKerberosCredentials() &&
+ return UserGroupInformation.getLoginUser().isFromKeytab() &&
MetastoreConf.getBoolVar(conf, MetastoreConf.ConfVars.THRIFT_ZOOKEEPER_USE_KERBEROS);
} catch (IOException e) {
return false;