HADOOP-15143. NPE due to Invalid KerberosTicket in UGI. Contributed by Mukul Kumar Singh.
This commit is contained in:
parent
52babbb4a0
commit
d31c9d8c49
@ -1253,7 +1253,10 @@ void fixKerberosTicketOrder() {
|
||||
Object cred = iter.next();
|
||||
if (cred instanceof KerberosTicket) {
|
||||
KerberosTicket ticket = (KerberosTicket) cred;
|
||||
if (!ticket.getServer().getName().startsWith("krbtgt")) {
|
||||
if (ticket.isDestroyed() || ticket.getServer() == null) {
|
||||
LOG.warn("Ticket is already destroyed, remove it.");
|
||||
iter.remove();
|
||||
} else if (!ticket.getServer().getName().startsWith("krbtgt")) {
|
||||
LOG.warn(
|
||||
"The first kerberos ticket is not TGT"
|
||||
+ "(the server principal is {}), remove and destroy it.",
|
||||
|
@ -155,4 +155,81 @@ public Void run() throws Exception {
|
||||
.filter(t -> t.getServer().getName().startsWith(server2Protocol))
|
||||
.findAny().isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithDestroyedTGT() throws Exception {
|
||||
UserGroupInformation ugi =
|
||||
UserGroupInformation.loginUserFromKeytabAndReturnUGI(clientPrincipal,
|
||||
keytabFile.getCanonicalPath());
|
||||
ugi.doAs(new PrivilegedExceptionAction<Void>() {
|
||||
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
SaslClient client = Sasl.createSaslClient(
|
||||
new String[] {AuthMethod.KERBEROS.getMechanismName()},
|
||||
clientPrincipal, server1Protocol, host, props, null);
|
||||
client.evaluateChallenge(new byte[0]);
|
||||
client.dispose();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
Subject subject = ugi.getSubject();
|
||||
|
||||
// mark the ticket as destroyed
|
||||
for (KerberosTicket ticket : subject
|
||||
.getPrivateCredentials(KerberosTicket.class)) {
|
||||
if (ticket.getServer().getName().startsWith("krbtgt")) {
|
||||
ticket.destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ugi.fixKerberosTicketOrder();
|
||||
|
||||
// verify that after fixing, the tgt ticket should be removed
|
||||
assertFalse("The first ticket is not tgt",
|
||||
subject.getPrivateCredentials().stream()
|
||||
.filter(c -> c instanceof KerberosTicket)
|
||||
.map(c -> ((KerberosTicket) c).getServer().getName()).findFirst()
|
||||
.isPresent());
|
||||
|
||||
|
||||
// should fail as we send a service ticket instead of tgt to KDC.
|
||||
intercept(SaslException.class,
|
||||
() -> ugi.doAs(new PrivilegedExceptionAction<Void>() {
|
||||
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
SaslClient client = Sasl.createSaslClient(
|
||||
new String[] {AuthMethod.KERBEROS.getMechanismName()},
|
||||
clientPrincipal, server2Protocol, host, props, null);
|
||||
client.evaluateChallenge(new byte[0]);
|
||||
client.dispose();
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
|
||||
// relogin to get a new ticket
|
||||
ugi.reloginFromKeytab();
|
||||
|
||||
// make sure we can get new service ticket after the relogin.
|
||||
ugi.doAs(new PrivilegedExceptionAction<Void>() {
|
||||
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
SaslClient client = Sasl.createSaslClient(
|
||||
new String[] {AuthMethod.KERBEROS.getMechanismName()},
|
||||
clientPrincipal, server2Protocol, host, props, null);
|
||||
client.evaluateChallenge(new byte[0]);
|
||||
client.dispose();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
assertTrue("No service ticket for " + server2Protocol + " found",
|
||||
subject.getPrivateCredentials(KerberosTicket.class).stream()
|
||||
.filter(t -> t.getServer().getName().startsWith(server2Protocol))
|
||||
.findAny().isPresent());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user