HADOOP-15143. NPE due to Invalid KerberosTicket in UGI. Contributed by Mukul Kumar Singh.
(cherry picked from commit d31c9d8c49
)
This commit is contained in:
parent
e575406715
commit
169dacf1ee
|
@ -1253,7 +1253,10 @@ public class UserGroupInformation {
|
||||||
Object cred = iter.next();
|
Object cred = iter.next();
|
||||||
if (cred instanceof KerberosTicket) {
|
if (cred instanceof KerberosTicket) {
|
||||||
KerberosTicket ticket = (KerberosTicket) cred;
|
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(
|
LOG.warn(
|
||||||
"The first kerberos ticket is not TGT"
|
"The first kerberos ticket is not TGT"
|
||||||
+ "(the server principal is {}), remove and destroy it.",
|
+ "(the server principal is {}), remove and destroy it.",
|
||||||
|
|
|
@ -155,4 +155,81 @@ public class TestFixKerberosTicketOrder extends KerberosSecurityTestcase {
|
||||||
.filter(t -> t.getServer().getName().startsWith(server2Protocol))
|
.filter(t -> t.getServer().getName().startsWith(server2Protocol))
|
||||||
.findAny().isPresent());
|
.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