From a7f1dc8aa8c602faf9745588cba1e337f0e59afd Mon Sep 17 00:00:00 2001 From: Xiao Chen Date: Tue, 6 Sep 2016 20:25:26 -0700 Subject: [PATCH] HADOOP-13558. UserGroupInformation created from a Subject incorrectly tries to renew the Kerberos ticket. Contributed by Xiao Chen. (cherry picked from commit 680be58aac03a9ffab6b07c8fde9602ddb9dc858) (cherry picked from commit d157733082697e67be56f516606a0127f5830c58) Conflicts: hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java --- .../hadoop/security/UserGroupInformation.java | 22 ++++++++++++++--- .../security/TestUserGroupInformation.java | 24 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) 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 df1035d0094..2f08e7f8fda 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 @@ -608,9 +608,24 @@ public class UserGroupInformation { * @param subject the user's subject */ UserGroupInformation(Subject subject) { + this(subject, false); + } + + /** + * Create a UGI from the given subject. + * @param subject the subject + * @param externalKeyTab if the subject's keytab is managed by the user. + * Setting this to true will prevent UGI from attempting + * to login the keytab, or to renew it. + */ + private UserGroupInformation(Subject subject, final boolean externalKeyTab) { this.subject = subject; this.user = subject.getPrincipals(User.class).iterator().next(); - this.isKeytab = KerberosUtil.hasKerberosKeyTab(subject); + if (externalKeyTab) { + this.isKeytab = false; + } else { + this.isKeytab = KerberosUtil.hasKerberosKeyTab(subject); + } this.isKrbTkt = KerberosUtil.hasKerberosTicket(subject); } @@ -826,10 +841,11 @@ public class UserGroupInformation { newLoginContext(authenticationMethod.getLoginAppName(), subject, new HadoopConfiguration()); login.login(); - UserGroupInformation realUser = new UserGroupInformation(subject); + LOG.debug("Assuming keytab is managed externally since logged in from" + + " subject."); + UserGroupInformation realUser = new UserGroupInformation(subject, true); realUser.setLogin(login); realUser.setAuthenticationMethod(authenticationMethod); - realUser = new UserGroupInformation(login.getSubject()); // If the HADOOP_PROXY_USER environment variable or property // is specified, create a proxy user as the logged in user. String proxyUser = System.getenv(HADOOP_PROXY_USER); diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java index 5b05df0ff63..ff1c3ef406e 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java @@ -31,6 +31,7 @@ import org.junit.*; import javax.security.auth.Subject; import javax.security.auth.kerberos.KerberosPrincipal; +import javax.security.auth.kerberos.KeyTab; import javax.security.auth.login.AppConfigurationEntry; import javax.security.auth.login.LoginContext; @@ -930,4 +931,27 @@ public class TestUserGroupInformation { } } } + + @Test + public void testCheckTGTAfterLoginFromSubject() throws Exception { + // security on, default is remove default realm + SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, conf); + UserGroupInformation.setConfiguration(conf); + + // Login from a pre-set subject with a keytab + final Subject subject = new Subject(); + KeyTab keytab = KeyTab.getInstance(); + subject.getPrivateCredentials().add(keytab); + UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); + ugi.doAs(new PrivilegedExceptionAction() { + @Override + public Void run() throws IOException { + UserGroupInformation.loginUserFromSubject(subject); + // this should not throw. + UserGroupInformation.getLoginUser().checkTGTAndReloginFromKeytab(); + return null; + } + }); + + } }