[BUG] JGSS is querying wrong realm for service ticket and fails ultimately

Osipov, Michael (IN IT IN) michael.osipov at innomotics.com
Fri Aug 30 15:06:22 UTC 2024


On 2024-08-30 14:44, Wei-Jun Wang wrote:
> Hi Michael,
> 
> Java starts from the default KDC and it expects a referral could happen. 

I guess you mean default realm's KDC, not default KDC? If so, it fails 
because the KDC is not entitled to send referrals.

> Does MIT krb5 always start from the client’s own KDC?

As far as I can see: yes. What I can say that MIT Kerberos has a domain 
plugin [1], [2] which extracts the domain from a hostname and assumes it 
to be the realm, if the hostname is unqualified the default realm is 
appended. This service name will then be sent to the client's default 
realm, if all match a service ticket or a referral is returned. If 
neither works, the fallback (default realm) is queried and the a service 
ticket or a referral is returned.

I did some extensive testing. Files will we sent privately.
My sample application:
> $ cat test.py
> import gssapi
> import gssapi.raw
> import base64
> import sys
> 
> cred = gssapi.Credentials(usage='initiate')
> print("Principal: " + str(cred.name))
> for arg in sys.argv[1:]:
>     target = gssapi.Name(arg, name_type=gssapi.NameType.hostbased_service)
>     client_ctx = gssapi.SecurityContext(name=target, usage='initiate')
>     print(str(target) + ": ", end="")
>     try:
>         token = client_ctx.step()
>         print("PASS")
>     except:
>         print("FAIL")

Obviously, if my client's realm does not trust the target what is the 
point in contacting the target right away? You'll see that in the files, 
one principal from AD001.SIEMENS.NET and INNOMOTICS.NET. The trust works 
exactly as expected. If you want to me reproduce the above with Java, 
just let me know.

> If you change the default realm to AD001.SIEMENS.NET <http:// 
> AD001.SIEMENS.NET>, does it work? Does it work with your other scenarios?

Yes, that is the previous behavior which will work, but since I need to 
leave the realm AD001.SIEMENS.NET for all non-user account I must set 
INNOMOTICS.NET as my default realm.

FWIW, I have reverted the default realm and tried with a principal from 
INNOMOTICS.NET and MIT Kerberos still does the right thing.

Michael

[1] 
https://github.com/krb5/krb5/blob/b9b654e5b469140d5603f27af5bf83ee9a826349/src/lib/krb5/os/hostrealm.c#L89
[2] 
https://github.com/krb5/krb5/blob/master/src/lib/krb5/os/hostrealm_domain.c#L96-L102


>> On Aug 30, 2024, at 05:09, Osipov, Michael (IN IT IN) 
>> <michael.osipov at innomotics.com> wrote:
>>
>> Folks,
>>
>> please consider the following case/bug with JGSS:
>> Tried with OpenJDK 8u4xx, can try newer, but doubt that it will be any 
>> different.
>>
>> * KDCs are Active Directory
>> * Machine: member of INNOMOTICS.NET
>> * krb5.conf: Default realm is INNOMOTICS.NET
>> * Client: Logged in from a different realm in this machine: 
>> foo at AD001.SIEMENS.NET
>> * One-way trust from AD001.SIEMENS.NET, means with an account from 
>> AD001.SIEMENS.NET you can access resources from both realms, but you 
>> cannot access resources from AD001.SIEMENS.NET with your 
>> INNOMOTICS.NET account. That is on purpose.
>>
>> Use case:
>> Client wants to access AD DS via LDAP and authenticate with an SASL 
>> GSSAPI bind: ldap at dc1.ad001.siemens.net. Client and target realm are 
>> identical. AS-REQ, AS-REP from AD001.SIEMENS.NET are fine, now here is 
>> the problem: To form the TGS-REQ it requests a cross-realm TGT for 
>> INNOMOTICS.NET and then asks a KDC in INNOMOTICS.NET for a service 
>> ticket for ldap at dc1.ad001.siemens.net. This KDC of course says:
>>> 16174 >>>KRBError:
>>> 16175      sTime is Thu Aug 29 20:19:07 CEST 2024 1724955547000
>>> 16176      suSec is 106542
>>> 16177      error code is 7
>>> 16178      error Message is Server not found in Kerberos database
>>> 16179      sname is ldap/dc1.ad001.siemens.net at INNOMOTICS.NET
>>> 16180      msgType is 30
>>
>> End of story. The bug for me is that, for some reason, JGSS assumes 
>> that the target is in the default realm of the machine instead of 
>> asking its own realm which should give it all necessary cross-realm 
>> referrals.
>>
>> Here is what MIT Kerberos does:
>>> $ cat /etc/krb5.conf
>>> # Kerberos configuration
>>> [libdefaults]
>>>    default_realm = INNOMOTICS.NET
>>>    forwardable = true
>>>    canonicalize = true
>>>    dns_lookup_kdc = true
>>>    dns_canonicalize_hostname = false
>>>    qualify_shortname = ""
>>>    rdns = false
>>>    udp_preference_limit = 1
>>>    kdc_timeout = 1000
>>>    max_retries = 1
>>> $ klist
>>> Ticketzwischenspeicher: FILE:/tmp/krb5cc_2011
>>> Standard-Principal: foo at AD001.SIEMENS.NET
>>> Valid starting       Expires              Service principal
>>> 2024-08-30T10:13:05  2024-08-30T20:13:05  krbtgt/ 
>>> AD001.SIEMENS.NET at AD001.SIEMENS.NET
>>>        erneuern bis 2024-08-31T10:10:22
>>> $ ldapwhoami -H ldap://ad001.siemens.net
>>> SASL/GSSAPI authentication started
>>> SASL username: foo at AD001.SIEMENS.NET
>>> SASL SSF: 256
>>> SASL data security layer installed.
>>> u:AD001\foo
>>> $ klist
>>> Ticketzwischenspeicher: FILE:/tmp/krb5cc_2011
>>> Standard-Principal: foo at AD001.SIEMENS.NET
>>> Valid starting       Expires              Service principal
>>> 2024-08-30T10:13:05  2024-08-30T20:13:05  krbtgt/ 
>>> AD001.SIEMENS.NET at AD001.SIEMENS.NET
>>>        erneuern bis 2024-08-31T10:10:22
>>> 2024-08-30T10:13:19  2024-08-30T20:13:05  ldap/dc1.ad001.siemens.net@
>>>        erneuern bis 2024-08-31T10:10:22
>>>        Ticket server: ldap/dc1.ad001.siemens.net at AD001.SIEMENS.NET
>>
>> Also looking at the output of KRB5_TRACE and pcaps MIT Kerberos never 
>> contacts any KDC in INNOMOTICS.NET.
>>
>> The workaround is the following in krb5.conf:
>>> # JGSS does not use the client's realm to obtain a ticket and needs 
>>> this hinT
>>> [domain_realm]
>>>    .ad001.siemens.net = AD001.SIEMENS.NET
>>>    ad001.siemens.net = AD001.SIEMENS.NET
>>
>> This is ugly because:
>> * I have to do this on all affected machines and cannot rely on AD to 
>> give me the right referral
>> * if I have an SPN, e.g. HTTP/svc.ad001.siemens.net in INNOMOTICS.NET, 
>> a migrated machine from AD001.SIEMENS.NET to INNOMOTICS.NET available 
>> under multiple virtual hostnames the init_sec_context will likely fail 
>> because that SPN is not known AD001.SIEMENS.NET, I can hope that AD 
>> will send me a referral. But in any case it will incur unnecessary 
>> round trips. I need to explicitly exempt those hosts here throughout 
>> my setup.
>>
>> Max, can you have a look at this? I can provide all the necessary 
>> debug/trace/pcap files to you. Just let me know what you would like to 
>> see.
>>
>> Michael
> 



More information about the security-dev mailing list