diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/KDiag.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/KDiag.java index 6cef9627482..2567a9042c1 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/KDiag.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/KDiag.java @@ -37,6 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.crypto.Cipher; + import java.io.Closeable; import java.io.File; import java.io.FileInputStream; @@ -60,6 +61,7 @@ import static org.apache.hadoop.security.UserGroupInformation.*; import static org.apache.hadoop.security.authentication.util.KerberosUtil.*; import static org.apache.hadoop.util.StringUtils.popOption; import static org.apache.hadoop.util.StringUtils.popOptionWithArgument; +import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_TOKEN_FILES; /** * Kerberos diagnostics @@ -144,6 +146,7 @@ public class KDiag extends Configured implements Tool, Closeable { public static final String CAT_OS = "JAAS"; public static final String CAT_SASL = "SASL"; public static final String CAT_UGI = "UGI"; + public static final String CAT_TOKEN = "TOKEN"; public static final String ARG_KEYLEN = "--keylen"; public static final String ARG_KEYTAB = "--keytab"; @@ -370,6 +373,7 @@ public class KDiag extends Configured implements Tool, Closeable { try { UserGroupInformation.setConfiguration(conf); + validateHadoopTokenFiles(conf); validateKrb5File(); printDefaultRealm(); validateSasl(HADOOP_SECURITY_SASL_PROPS_RESOLVER_CLASS); @@ -499,6 +503,47 @@ public class KDiag extends Configured implements Tool, Closeable { } } + /** + * Validate that hadoop.token.files (if specified) exist and are valid. + * @throws ClassNotFoundException + * @throws SecurityException + * @throws NoSuchMethodException + * @throws KerberosDiagsFailure + */ + private void validateHadoopTokenFiles(Configuration conf) + throws ClassNotFoundException, KerberosDiagsFailure, NoSuchMethodException, + SecurityException { + title("Locating Hadoop token files"); + + String tokenFileLocation = System.getProperty(HADOOP_TOKEN_FILES); + if(tokenFileLocation != null) { + println("Found " + HADOOP_TOKEN_FILES + " in system properties : " + + tokenFileLocation); + } + + if(conf.get(HADOOP_TOKEN_FILES) != null) { + println("Found " + HADOOP_TOKEN_FILES + " in hadoop configuration : " + + conf.get(HADOOP_TOKEN_FILES)); + if(System.getProperty(HADOOP_TOKEN_FILES) != null) { + println(HADOOP_TOKEN_FILES + " in the system properties overrides the" + + " one specified in hadoop configuration"); + } else { + tokenFileLocation = conf.get(HADOOP_TOKEN_FILES); + } + } + + if (tokenFileLocation != null) { + for (String tokenFileName: + StringUtils.getTrimmedStrings(tokenFileLocation)) { + if (tokenFileName.length() > 0) { + File tokenFile = new File(tokenFileName); + verifyFileIsValid(tokenFile, CAT_TOKEN, "token"); + verify(tokenFile, conf, CAT_TOKEN, "token"); + } + } + } + } + /** * Locate the {@code krb5.conf} file and dump it. * @@ -918,6 +963,28 @@ public class KDiag extends Configured implements Tool, Closeable { } } + /** + * Verify that tokenFile contains valid Credentials. + * + * If not, an exception is raised, or, if {@link #nofail} is set, + * an error will be logged and the method return false. + * + */ + private boolean verify(File tokenFile, Configuration conf, String category, + String message) throws KerberosDiagsFailure { + try { + Credentials.readTokenStorageFile(tokenFile, conf); + } catch(Exception e) { + if (!nofail) { + fail(category, message); + } else { + error(category, message); + } + return false; + } + return true; + } + /** * Print a message as an error * @param category error category diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestKDiagNoKDC.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestKDiagNoKDC.java index 9d4b87feb36..dbc40c52e51 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestKDiagNoKDC.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestKDiagNoKDC.java @@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.util.Properties; +import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_TOKEN_FILES; import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION; import static org.apache.hadoop.security.KDiag.ARG_KEYLEN; import static org.apache.hadoop.security.KDiag.ARG_KEYTAB; @@ -44,6 +45,7 @@ import static org.apache.hadoop.security.KDiag.ARG_SECURE; import static org.apache.hadoop.security.KDiag.CAT_CONFIG; import static org.apache.hadoop.security.KDiag.CAT_KERBEROS; import static org.apache.hadoop.security.KDiag.CAT_LOGIN; +import static org.apache.hadoop.security.KDiag.CAT_TOKEN; import static org.apache.hadoop.security.KDiag.KerberosDiagsFailure; import static org.apache.hadoop.security.KDiag.exec; @@ -120,4 +122,10 @@ public class TestKDiagNoKDC extends Assert { assertEquals(-1, kdiag("usage")); } + @Test + public void testTokenFile() throws Throwable { + conf.set(HADOOP_TOKEN_FILES, "SomeNonExistentFile"); + kdiagFailure(CAT_TOKEN, ARG_KEYLEN, KEYLEN); + conf.unset(HADOOP_TOKEN_FILES); + } }