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 be7b96decdd..07ab77ee683 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 @@ -254,7 +254,7 @@ public boolean removePrincipal(String principal, boolean service) throws Kerbero } @Override - protected String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache) { + protected String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache, Map kerberosConfiguration) { return new String[]{ executableKinit, "-c", 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 9936f434129..a708d7156e2 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 @@ -111,7 +111,7 @@ public void open(PrincipalKeyCredential administratorCredentials, String realm, // Pre-determine the paths to relevant Kerberos executables executableKinit = getExecutable("kinit"); - setOpen(init()); + setOpen(init(kerberosConfiguration)); } @Override @@ -269,9 +269,11 @@ String getCredentialCacheFilePath() { * @param executableKinit the absolute path to the kinit executable * @param credentials the KDC adminisrator's credentials * @param credentialsCache the absolute path to the expected location of the Kerberos ticket/credential cache file + * @param kerberosConfigurations a Map of key/value pairs containing data from the kerberos-env configuration set + * @throws KerberosOperationException in case there was any error during kinit command creation * @return an array of Strings containing the command to execute */ - protected abstract String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache); + protected abstract String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache, Map kerberosConfigurations) throws KerberosOperationException; /** * Export the requested keytab entries for a given principal into the specified file. @@ -294,7 +296,7 @@ String getCredentialCacheFilePath() { * @return * @throws KerberosOperationException */ - protected boolean init() throws KerberosOperationException { + protected boolean init(Map kerberosConfiguration) throws KerberosOperationException { if (credentialsCacheFile != null) { if (!credentialsCacheFile.delete()) { LOG.debug("Failed to remove the orphaned cache file, {}", credentialsCacheFile.getAbsolutePath()); @@ -317,7 +319,7 @@ protected boolean init() throws KerberosOperationException { PrincipalKeyCredential credentials = getAdministratorCredential(); - ShellCommandUtil.Result result = executeCommand(getKinitCommand(executableKinit, credentials, credentialsCache), + ShellCommandUtil.Result result = executeCommand(getKinitCommand(executableKinit, credentials, credentialsCache, kerberosConfiguration), environmentMap, new InteractivePasswordHandler(String.valueOf(credentials.getKey()), null)); diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java index a159880cd9e..2646d2cd332 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java @@ -94,6 +94,11 @@ public abstract class KerberosOperationHandler { */ public final static String KERBEROS_ENV_ADMIN_SERVER_HOST = "admin_server_host"; + /** + * Kerberos-env configuration property name: kadmin_principal_name + */ + public final static String KERBEROS_ENV_KADMIN_PRINCIPAL_NAME = "kadmin_principal_name"; + /** * Kerberos-env configuration property name: executable_search_paths */ 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 254f7052e3d..e2467569ebc 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 @@ -19,12 +19,15 @@ package org.apache.ambari.server.serveraction.kerberos; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.security.credential.PrincipalKeyCredential; +import org.apache.ambari.server.state.kerberos.VariableReplacementHelper; import org.apache.ambari.server.utils.ShellCommandUtil; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; @@ -47,6 +50,9 @@ public class MITKerberosOperationHandler extends KDCKerberosOperationHandler { @Inject private Configuration configuration; + + @Inject + private VariableReplacementHelper variableReplacementHelper; /** * A String containing user-specified attributes used when creating principals @@ -333,16 +339,27 @@ else if (stdErr.contains("Missing parameters in krb5.conf required for kadmin cl } @Override - protected String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache) { + protected String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache, Map kerberosConfiguration) throws KerberosOperationException { // kinit -c -S kadmin/`hostname -f` - return new String[]{ - executableKinit, - "-c", - credentialsCache, - "-S", - String.format("kadmin/%s", getAdminServerHost(false)), - credentials.getPrincipal() - }; + try { + final String kadminPrincipalName = variableReplacementHelper.replaceVariables(kerberosConfiguration.get(KERBEROS_ENV_KADMIN_PRINCIPAL_NAME), buildReplacementsMap(kerberosConfiguration)); + return new String[]{ + executableKinit, + "-c", + credentialsCache, + "-S", + kadminPrincipalName, + credentials.getPrincipal() + }; + } catch (AmbariException e) { + throw new KerberosOperationException("Error while getting 'kinit' command", e); + } + } + + private Map> buildReplacementsMap(Map kerberosConfiguration) { + final Map> replacementsMap = new HashMap<>(); + replacementsMap.put("", kerberosConfiguration); + return replacementsMap; } @Override diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelper.java index a83f080cd4e..bf2539ea19d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelper.java @@ -60,6 +60,7 @@ public class VariableReplacementHelper { put("replace", new ReplaceValue()); put("append", new AppendFunction()); put("principalPrimary", new PrincipalPrimary()); + put("stripPort", new StripPort()); } }; @@ -432,4 +433,19 @@ public String perform(String[] args, String data, Maphost[:port] + */ + private static class StripPort implements Function { + @Override + public String perform(String[] args, String data, Map> replacementsMap) { + if (data == null) { + return null; + } + final int semicolonIndex = data.indexOf(":"); + return semicolonIndex == -1 ? data : data.substring(0, semicolonIndex); + } + } } 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 dd3a3c389d3..0071c5b77e9 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 @@ -265,6 +265,7 @@ public void testGetAdminServerHost() throws KerberosOperationException { Map config = new HashMap<>(); config.put("encryption_types", "aes des3-cbc-sha1 rc4 des-cbc-md5"); + config.put(MITKerberosOperationHandler.KERBEROS_ENV_KADMIN_PRINCIPAL_NAME, "kadmin/kdc.example.com"); replayAll(); diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelperTest.java index 839af39da48..5152bee8c78 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/VariableReplacementHelperTest.java @@ -196,6 +196,8 @@ public void testReplaceVariablesWithFunctions() throws AmbariException { put("", new HashMap() {{ put("delimited.data", "one,two,three,four"); put("realm", "UNIT.TEST"); + put("admin_server_host", "c7401.ambari.apache.org"); + put("admin_server_host_port", "c7401.ambari.apache.org:8080"); }}); put("kafka-broker", new HashMap() {{ @@ -259,6 +261,9 @@ public void testReplaceVariablesWithFunctions() throws AmbariException { assertEquals("test=unit.test", helper.replaceVariables("test=${realm|toLower()}", configurations)); assertEquals("PLAINTEXTSASL://localhost:6667", helper.replaceVariables("${kafka-broker/listeners|replace(\\bPLAINTEXT\\b,PLAINTEXTSASL)}", configurations)); + + assertEquals("kadmin/c7401.ambari.apache.org", helper.replaceVariables("kadmin/${admin_server_host|stripPort()}", configurations)); + assertEquals("kadmin/c7401.ambari.apache.org", helper.replaceVariables("kadmin/${admin_server_host_port|stripPort()}", configurations)); } @Test