You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2018/08/30 20:19:44 UTC
[ambari] branch branch-2.7 updated: [AMBARI-24522] Cannot connect
to MIT KDC admin server when port is specified in
kerberos-env/admin_server_host
This is an automated email from the ASF dual-hosted git repository.
rlevas pushed a commit to branch branch-2.7
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/branch-2.7 by this push:
new 50d771e [AMBARI-24522] Cannot connect to MIT KDC admin server when port is specified in kerberos-env/admin_server_host
50d771e is described below
commit 50d771e30216e3a4b48cf9081bc79c8c86de7e69
Author: Robert Levas <rl...@hortonworks.com>
AuthorDate: Tue Aug 21 17:29:41 2018 -0400
[AMBARI-24522] Cannot connect to MIT KDC admin server when port is specified in kerberos-env/admin_server_host
---
.../kerberos/IPAKerberosOperationHandler.java | 4 +-
.../kerberos/KDCKerberosOperationHandler.java | 35 ++++++++++++++--
.../kerberos/MITKerberosOperationHandler.java | 4 +-
.../kerberos/IPAKerberosOperationHandlerTest.java | 45 +++++++++++++++++++++
.../kerberos/MITKerberosOperationHandlerTest.java | 46 ++++++++++++++++++++++
5 files changed, 127 insertions(+), 7 deletions(-)
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
index 64a1bb8..be7b96d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandler.java
@@ -279,8 +279,8 @@ public class IPAKerberosOperationHandler extends KDCKerberosOperationHandler {
}
String[] createKeytabFileCommand = (StringUtils.isEmpty(encryptionTypeSpec))
- ? new String[]{executableIpaGetKeytab, "-s", getAdminServerHost(), "-p", principal, "-k", keytabFileDestinationPath}
- : new String[]{executableIpaGetKeytab, "-s", getAdminServerHost(), "-e", encryptionTypeSpec, "-p", principal, "-k", keytabFileDestinationPath};
+ ? new String[]{executableIpaGetKeytab, "-s", getAdminServerHost(true), "-p", principal, "-k", keytabFileDestinationPath}
+ : new String[]{executableIpaGetKeytab, "-s", getAdminServerHost(true), "-e", encryptionTypeSpec, "-p", principal, "-k", keytabFileDestinationPath};
ShellCommandUtil.Result result = executeCommand(createKeytabFileCommand);
if (!result.isSuccessful()) {
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java
index bf3ac22..9936f43 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandler.java
@@ -28,6 +28,8 @@ import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
+import org.apache.ambari.server.utils.HTTPUtils;
+import org.apache.ambari.server.utils.HostAndPort;
import org.apache.ambari.server.utils.ShellCommandUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.directory.server.kerberos.shared.keytab.Keytab;
@@ -50,6 +52,11 @@ abstract class KDCKerberosOperationHandler extends KerberosOperationHandler {
private String adminServerHost = null;
/**
+ * The FQDN and port where KDC administration server is
+ */
+ private String adminServerHostAndPort = null;
+
+ /**
* A map of principal names to {@link Keytab} entries to ensure a Keyab file is not created/exported
* for the same principal more than once.
*/
@@ -83,7 +90,22 @@ abstract class KDCKerberosOperationHandler extends KerberosOperationHandler {
super.open(administratorCredentials, realm, kerberosConfiguration);
if (kerberosConfiguration != null) {
- adminServerHost = kerberosConfiguration.get(KERBEROS_ENV_ADMIN_SERVER_HOST);
+ // Spit the host and port from the the admin_server_host value
+ String value = kerberosConfiguration.get(KERBEROS_ENV_ADMIN_SERVER_HOST);
+ HostAndPort hostAndPort = HTTPUtils.getHostAndPortFromProperty(value);
+
+ // hostAndPort will be null if the value is not in the form of host:port
+ if (hostAndPort == null) {
+ // host-only and host and port values are the same since there is no port
+ // both are equal to the value from the property
+ adminServerHost = value;
+ adminServerHostAndPort = value;
+ } else {
+ // host-only is the split value;
+ // host and port value is the value from the property
+ adminServerHost = hostAndPort.host;
+ adminServerHostAndPort = value;
+ }
}
// Pre-determine the paths to relevant Kerberos executables
@@ -106,6 +128,7 @@ abstract class KDCKerberosOperationHandler extends KerberosOperationHandler {
executableKinit = null;
cachedKeytabs = null;
adminServerHost = null;
+ adminServerHostAndPort = null;
super.close();
}
@@ -225,8 +248,14 @@ abstract class KDCKerberosOperationHandler extends KerberosOperationHandler {
return super.executeCommand(command, _envp, interactiveHandler);
}
- String getAdminServerHost() {
- return adminServerHost;
+ /**
+ * Returns the KDC administration server host value (with or without the port)
+ *
+ * @param includePort <code>true</code> to include the port (if available); <code>false</code> to exclude the port
+ * @return the KDC administration server host value (with or without the port)
+ */
+ String getAdminServerHost(boolean includePort) {
+ return (includePort) ? adminServerHostAndPort : adminServerHost;
}
String getCredentialCacheFilePath() {
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
index bbcd6e8..254f705 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
@@ -241,7 +241,7 @@ public class MITKerberosOperationHandler extends KDCKerberosOperationHandler {
}
// Add explicit KDC admin host, if available
- String adminSeverHost = getAdminServerHost();
+ String adminSeverHost = getAdminServerHost(true);
if (!StringUtils.isEmpty(adminSeverHost)) {
command.add("-s");
command.add(adminSeverHost);
@@ -340,7 +340,7 @@ public class MITKerberosOperationHandler extends KDCKerberosOperationHandler {
"-c",
credentialsCache,
"-S",
- String.format("kadmin/%s", getAdminServerHost()),
+ String.format("kadmin/%s", getAdminServerHost(false)),
credentials.getPrincipal()
};
}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
index f9ee5b7..44c7a36 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
@@ -19,25 +19,33 @@
package org.apache.ambari.server.serveraction.kerberos;
import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.newCapture;
import static org.easymock.EasyMock.replay;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.stack.OsFamily;
import org.apache.ambari.server.utils.ShellCommandUtil;
+import org.easymock.Capture;
+import org.easymock.CaptureType;
import org.easymock.EasyMock;
import org.junit.BeforeClass;
+import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
+import junit.framework.Assert;
+
public class IPAKerberosOperationHandlerTest extends KDCKerberosOperationHandlerTest {
private static Injector injector;
@@ -67,6 +75,43 @@ public class IPAKerberosOperationHandlerTest extends KDCKerberosOperationHandler
});
}
+ @Test
+ public void testGetAdminServerHost() throws KerberosOperationException {
+ ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+ expect(kinitResult.isSuccessful()).andReturn(true).anyTimes();
+
+ Capture<String[]> capturedKinitCommand = newCapture(CaptureType.ALL);
+
+ IPAKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand);
+ expect(handler.executeCommand(capture(capturedKinitCommand), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(kinitResult)
+ .anyTimes();
+
+
+ Map<String,String> config = new HashMap<>();
+ config.put("encryption_types", "aes des3-cbc-sha1 rc4 des-cbc-md5");
+
+ replayAll();
+
+ config.put("admin_server_host", "kdc.example.com");
+ handler.open(getAdminCredentials(), DEFAULT_REALM, config);
+ Assert.assertEquals("kdc.example.com", handler.getAdminServerHost(false));
+ Assert.assertEquals("kdc.example.com", handler.getAdminServerHost(true));
+ handler.close();
+
+ config.put("admin_server_host", "kdc.example.com:749");
+ handler.open(getAdminCredentials(), DEFAULT_REALM, config);
+ Assert.assertEquals("kdc.example.com", handler.getAdminServerHost(false));
+ Assert.assertEquals("kdc.example.com:749", handler.getAdminServerHost(true));
+ handler.close();
+
+ verifyAll();
+
+ Assert.assertTrue(capturedKinitCommand.hasCaptured());
+ List<String[]> capturedValues = capturedKinitCommand.getValues();
+ Assert.assertEquals(2, capturedValues.size());
+ }
+
@Override
protected IPAKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
IPAKerberosOperationHandler handler = createMockBuilder(IPAKerberosOperationHandler.class)
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
index c7c26c3..dd3a3c3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
@@ -26,6 +26,7 @@ import static org.easymock.EasyMock.newCapture;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.ambari.server.configuration.Configuration;
@@ -34,6 +35,7 @@ import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.stack.OsFamily;
import org.apache.ambari.server.utils.ShellCommandUtil;
import org.easymock.Capture;
+import org.easymock.CaptureType;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -248,6 +250,50 @@ public class MITKerberosOperationHandlerTest extends KDCKerberosOperationHandler
verifyAll();
}
+ @Test
+ public void testGetAdminServerHost() throws KerberosOperationException {
+ ShellCommandUtil.Result kinitResult = createMock(ShellCommandUtil.Result.class);
+ expect(kinitResult.isSuccessful()).andReturn(true).anyTimes();
+
+ Capture<String[]> capturedKinitCommand = newCapture(CaptureType.ALL);
+
+ MITKerberosOperationHandler handler = createMockedHandler(methodExecuteCommand);
+ expect(handler.executeCommand(capture(capturedKinitCommand), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(kinitResult)
+ .anyTimes();
+
+
+ Map<String,String> config = new HashMap<>();
+ config.put("encryption_types", "aes des3-cbc-sha1 rc4 des-cbc-md5");
+
+ replayAll();
+
+ config.put("admin_server_host", "kdc.example.com");
+ handler.open(getAdminCredentials(), DEFAULT_REALM, config);
+ Assert.assertEquals("kdc.example.com", handler.getAdminServerHost(false));
+ Assert.assertEquals("kdc.example.com", handler.getAdminServerHost(true));
+ handler.close();
+
+ config.put("admin_server_host", "kdc.example.com:749");
+ handler.open(getAdminCredentials(), DEFAULT_REALM, config);
+ Assert.assertEquals("kdc.example.com", handler.getAdminServerHost(false));
+ Assert.assertEquals("kdc.example.com:749", handler.getAdminServerHost(true));
+ handler.close();
+
+ verifyAll();
+
+ Assert.assertTrue(capturedKinitCommand.hasCaptured());
+ List<String[]> capturedValues = capturedKinitCommand.getValues();
+ Assert.assertEquals(2, capturedValues.size());
+
+ // The capture values will be an array of strings used to build the command:
+ // ["/usr/bin/kinit", "-c", "SOME_FILE_PATH", "-S", "SERVER_PRINCIPAL", "CLIENT_PRINCIPAL"]
+ // We are interested in the 4th item in the array - the service's principal.
+ // It must not contain the port else authentication will fail
+ Assert.assertEquals("kadmin/kdc.example.com", capturedValues.get(0)[4]);
+ Assert.assertEquals("kadmin/kdc.example.com", capturedValues.get(1)[4]);
+ }
+
@Override
protected MITKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
MITKerberosOperationHandler handler = createMockBuilder(MITKerberosOperationHandler.class)