diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 6a3e71130df..367c1274f93 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -908,6 +908,9 @@ Release 2.8.0 - UNRELEASED HADOOP-12559. KMS connection failures should trigger TGT renewal. (Zhe Zhang via xyao) + HADOOP-12682. Fix TestKMS#testKMSRestart* failure. + (Wei-Chiu Chuang via xyao) + Release 2.7.3 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java index 0c82173a5be..7d8a88e9c18 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java @@ -963,6 +963,42 @@ public class UserGroupInformation { LOG.info("Login successful for user " + keytabPrincipal + " using keytab file " + keytabFile); } + + /** + * Log the current user out who previously logged in using keytab. + * This method assumes that the user logged in by calling + * {@link #loginUserFromKeytab(String, String)}. + * + * @throws IOException if a failure occurred in logout, or if the user did + * not log in by invoking loginUserFromKeyTab() before. + */ + @InterfaceAudience.Public + @InterfaceStability.Evolving + public void logoutUserFromKeytab() throws IOException { + if (!isSecurityEnabled() || + user.getAuthenticationMethod() != AuthenticationMethod.KERBEROS) { + return; + } + LoginContext login = getLogin(); + if (login == null || keytabFile == null) { + throw new IOException("loginUserFromKeytab must be done first"); + } + + try { + if (LOG.isDebugEnabled()) { + LOG.debug("Initiating logout for " + getUserName()); + } + synchronized (UserGroupInformation.class) { + login.logout(); + } + } catch (LoginException le) { + throw new IOException("Logout failure for " + user + " from keytab " + + keytabFile, le); + } + + LOG.info("Logout successful for user " + keytabPrincipal + + " using keytab file " + keytabFile); + } /** * Re-login a user from keytab if TGT is expired or is close to expiry. diff --git a/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java b/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java index c5a990b58b7..7131b7c9a41 100644 --- a/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java +++ b/hadoop-common-project/hadoop-kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMS.java @@ -44,10 +44,8 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import javax.security.auth.Subject; import javax.security.auth.kerberos.KerberosPrincipal; import javax.security.auth.login.AppConfigurationEntry; -import javax.security.auth.login.LoginContext; import java.io.File; import java.io.FileWriter; @@ -59,16 +57,13 @@ import java.net.ServerSocket; import java.net.SocketTimeoutException; import java.net.URI; import java.net.URL; -import java.security.Principal; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.Set; import java.util.UUID; import java.util.concurrent.Callable; @@ -250,22 +245,12 @@ public class TestKMS { private T doAs(String user, final PrivilegedExceptionAction action) throws Exception { - Set principals = new HashSet(); - principals.add(new KerberosPrincipal(user)); - - //client login - Subject subject = new Subject(false, principals, - new HashSet(), new HashSet()); - LoginContext loginContext = new LoginContext("", subject, null, - KerberosConfiguration.createClientConfig(user, keytab)); + UserGroupInformation.loginUserFromKeytab(user, keytab.getAbsolutePath()); + UserGroupInformation ugi = UserGroupInformation.getLoginUser(); try { - loginContext.login(); - subject = loginContext.getSubject(); - UserGroupInformation ugi = - UserGroupInformation.getUGIFromSubject(subject); return ugi.doAs(action); } finally { - loginContext.logout(); + ugi.logoutUserFromKeytab(); } }