If you are sure the exception is thrown from the code snippet you quoted, that is because Java's Kerberos 5 implementation requires that the service name in TGS_REP must match the one in the TGS_REQ. Otherwise it fails.
MIT and SSPI support referral so the names can be different. The workaround you described is the only solution by now. --Max > On Apr 19, 2016, at 5:05 PM, Osipov, Michael <[email protected]> > wrote: > > 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 >
