Skip to content

Commit d157733

Browse files
committed
HADOOP-13558. UserGroupInformation created from a Subject incorrectly tries to renew the Kerberos ticket. Contributed by Xiao Chen.
(cherry picked from commit 680be58)
1 parent f9415b7 commit d157733

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -620,9 +620,24 @@ private void setLogin(LoginContext login) {
620620
* @param subject the user's subject
621621
*/
622622
UserGroupInformation(Subject subject) {
623+
this(subject, false);
624+
}
625+
626+
/**
627+
* Create a UGI from the given subject.
628+
* @param subject the subject
629+
* @param externalKeyTab if the subject's keytab is managed by the user.
630+
* Setting this to true will prevent UGI from attempting
631+
* to login the keytab, or to renew it.
632+
*/
633+
private UserGroupInformation(Subject subject, final boolean externalKeyTab) {
623634
this.subject = subject;
624635
this.user = subject.getPrincipals(User.class).iterator().next();
625-
this.isKeytab = KerberosUtil.hasKerberosKeyTab(subject);
636+
if (externalKeyTab) {
637+
this.isKeytab = false;
638+
} else {
639+
this.isKeytab = KerberosUtil.hasKerberosKeyTab(subject);
640+
}
626641
this.isKrbTkt = KerberosUtil.hasKerberosTicket(subject);
627642
}
628643

@@ -838,10 +853,11 @@ static void loginUserFromSubject(Subject subject) throws IOException {
838853
newLoginContext(authenticationMethod.getLoginAppName(),
839854
subject, new HadoopConfiguration());
840855
login.login();
841-
UserGroupInformation realUser = new UserGroupInformation(subject);
856+
LOG.debug("Assuming keytab is managed externally since logged in from"
857+
+ " subject.");
858+
UserGroupInformation realUser = new UserGroupInformation(subject, true);
842859
realUser.setLogin(login);
843860
realUser.setAuthenticationMethod(authenticationMethod);
844-
realUser = new UserGroupInformation(login.getSubject());
845861
// If the HADOOP_PROXY_USER environment variable or property
846862
// is specified, create a proxy user as the logged in user.
847863
String proxyUser = System.getenv(HADOOP_PROXY_USER);

hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import javax.security.auth.Subject;
3434
import javax.security.auth.kerberos.KerberosPrincipal;
35+
import javax.security.auth.kerberos.KeyTab;
3536
import javax.security.auth.login.AppConfigurationEntry;
3637
import javax.security.auth.login.LoginContext;
3738

@@ -976,4 +977,27 @@ public void testExternalTokenFiles() throws Exception {
976977
assertTrue(credsugiTokens.contains(token1));
977978
assertTrue(credsugiTokens.contains(token2));
978979
}
980+
981+
@Test
982+
public void testCheckTGTAfterLoginFromSubject() throws Exception {
983+
// security on, default is remove default realm
984+
SecurityUtil.setAuthenticationMethod(AuthenticationMethod.KERBEROS, conf);
985+
UserGroupInformation.setConfiguration(conf);
986+
987+
// Login from a pre-set subject with a keytab
988+
final Subject subject = new Subject();
989+
KeyTab keytab = KeyTab.getInstance();
990+
subject.getPrivateCredentials().add(keytab);
991+
UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
992+
ugi.doAs(new PrivilegedExceptionAction<Void>() {
993+
@Override
994+
public Void run() throws IOException {
995+
UserGroupInformation.loginUserFromSubject(subject);
996+
// this should not throw.
997+
UserGroupInformation.getLoginUser().checkTGTAndReloginFromKeytab();
998+
return null;
999+
}
1000+
});
1001+
1002+
}
9791003
}

0 commit comments

Comments
 (0)