In the specific way you show in your example? No, because neither tickets nor keytabs contain this sort of "user X allowed for service Y" information at all.
A ticket may carry raw facts such as the username or group memberships (the PAC), but they're not verified against a keytab; they're merely decrypted using the keytab (it is literally an "encryption key table") but any actual authorization checks would be done by the service's own code/logic. So the only use of a keytab would be to see the raw contents of the PAC from within a ticket, but not to get a pass/fail.
(I don't know any generic tools for decrypting a PAC – there are probably some among the "Active Directory red team" tools.)
In rare cases where authorization checks are done by the KDC before issuing a ticket, the keytab is again useless because the KDC just wouldn't issue the ticket at all if authorization checks had failed – it would not issue a deliberately invalid ticket. So if this were the situation, it would be enough to just request the ticket and see if you get one at all. (I doubt this is the situation, however.)
(MIT Krb5 has the kvno
command to request a ticket, but there are other ways.)
So as far as "validity" goes, the only check you can do is whether the keytab is able to decrypt the ticket at all (i.e. whether the key in the keytab is in sync with the key at the KDC). For this you don't need the specific service, but the easiest way is actually to have the Kerberos library perform the whole authentication procedure as if you were the service. In other words, write a minimal Kerberos service that just talks GSSAPI authentication to itself (as both client and server). This is fortunately just a few lines in python-gssapi
:
keytab = "foo.keytab"
spn = gssapi.Name("[email protected]", gssapi.NameType.hostbased_service)
server_creds = gssapi.Credentials(usage="accept", name=spn,
store={"keytab": keytab})
server_ctx = gssapi.SecurityContext(usage="accept", creds=server_creds)
client_ctx = gssapi.SecurityContext(usage="initiate", name=spn)
# Client: Get the token that would be sent in "Authorization: Negotiate"
c2s_token = client_ctx.step(None)
# Server: Consume the token (verify it against the keytab)
# Throws an exception if the keytab is out of sync with the KDC
s2c_token = server_ctx.step(c2s_token)
# Server: Read out the client principal name from the ticket
if server_ctx.complete:
print("Authenticated as", server_ctx.initiator_name)
This is basically what mod_auth_gssapi (or the legacy mod_auth_kerb) will do to verify a ticket. Again, note that it does not perform any authorization checks – all that Kerberos does is say "ticket belongs to user X", while the actual access checks must be done by the program itself.