Hi,

I am trying to obtain a service ticket for a cross-realm service within one 
hierarchy (forest).

The root realm is COMPANY.NET, my realm is R004.COMPANY.NET, target realm is 
R002.COMPANY.NET and
SPN ldap/server.r002.company.net.

Host to realm mapping in my krb5.conf:
[domain_realm]
    .r004.company.net = R004.COMPANY.NET
    r004.company.net = R004.COMPANY.NET
    .company.net = COMPANY.NET
    company.net = COMPANY.NET

I have tested the same case with MIT Kerberos and SSPI and both have a 
completely different approach
of requesting service tickets. They do:

TGS-REQ for ldap/server.r002.company.net to a KDC in my home realm
TGS-REP is krbtgt/[email protected]
TGS-REQ for ldap/server.r002.company.net to a KDC in R002.COMPANY.NET with
          krbtgt/[email protected]
TGS-REP is ldap/[email protected]

This works as desired.

JGSS in turn does this:
Match hostname to domain realm => COMPANY.NET
TGS-REQ for krbtgt/COMPANY.NET
TGS-REP is krbtgt/[email protected]
TGS-REQ for ldap/server.r002.company.net to a KDC in COMPANY.NET with
          krbtgt/[email protected]
TGS-REP is krbtgt/[email protected]
and here happens the crash
KrbException: Message stream modified (41)
KrbException: Fail to create credential. (63) - No service creds
        at 
sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(CredentialsUtil.java:299)
        at 
sun.security.krb5.Credentials.acquireServiceCreds(Credentials.java:454)
        at 
sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:641)
        at 
sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:248)
        at 
sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
in KrbKdcRep.java#check(), lines 54 to 56:
        if (!req.reqBody.sname.equalsWithoutRealm(rep.encKDCRepPart.sname)) {
                rep.encKDCRepPart.key.destroy();
                throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
        }

This code assumes that the ticket is already the final service ticket but it is 
an intermediate TGT
for the target realm. I would expect another TGS-REQ/TGS-REP from JGSS. Due to 
the logic implemented,
the only known workaround is to add another [domain_realm] mapping but this is 
daunting because we have
tens of those and I do not know all realms/hostnames upfront due to dynamic TGT 
referrals.

Another case is HTTP proxy (HTTP/proxyfarm.company.net). JGSS requests at 
COMPANY.NET but
receives a TGT for R002.COMPANY.NET. Especially in this case, I am not able to 
know the realm upfront.
Adding the domain realm mapping does not help because this file is used 
initially only or even worse,
direct hostname to realm mapping is hell. Removing [domain_realm] makes it 
immediately fail due to
the TGT referral. MIT Kerberos follows all TGT referrals as necessary.

The manpage for krb5.conf for [domain_realm] says:
"If no translation entry applies to a hostname used for a service principal for 
a service ticket request,
the library will try to get a referral to the appropriate realm from the client 
realm's KDC..."

I would expect that the TGS logic would resemble the one described above, 
follow all referrals until
it gets the desired service ticket. Ultimately, not [domain_realm] is 
necessary, at least with MIT Kerberos
and Active Directory.

Setup:
* KDCs are Windows Server 2008/2012
* Clients are Windows 7 Enterprise
* MIT Kerberos 1.14.1 on FreeBSD
* Oracle JDKs 1.7.0_72 and 1.80_72

All tests happen on Windows, deployment happens on HP-UX with HP JVM which is 
merely a repackaged Oracle
JVM with native patches for that OS.

I have already created a bundle with log files, krb5.conf and Wireshark pcap 
files, debug screenshots for
JGSS, MIT Kerberos and SSPI and will happily share in private. Also willing to 
assist as necessary.

This is actually an annoying blocker disabling us to use cross-domain and 
cross-forest services. I would
prefer a solution for Java 7 because we haven't migrated to Java 8 yet but 
willing to do so.

How can we resolve this issue?

Thanks and regards,

Michael Osipov

Reply via email to