Date: | Fri, 08 May 2020 17:15:44 -0400 |
Subject: | GSS_KRB5_NT_PRINCIPAL_NAME server name import uses default realm instead of referral realm |
From: | ghudson@mit.edu |
To: | rt@krbdev.mit.edu |
Applications that interact with Microsoft SQL Server often use GSS_KRB5_NT_PRINCIPAL_NAME instead of GSS_C_NT_HOSTBASED_SERVICE, because there may be a port number in the host part, and prior to ticket 7795, that didn't work with host-based names. Importing a principal name circumvents the [domain_realms] lookup and the preference for using referrals if there is no [domain_realm].
The application may import (1) MSSQLSvc/hostpart@, (2) MSSQLSvc/hostpart, or (3) MSSQLSvc/hostpart@realm, where realm is probably the configured default realm. Case 1 should work currently. Case 3 may not work if realm is a bad starting point for the TGS query; for example, if the client principal and actual service location are in REALM1, but the default realm is REALM2, the client will fetch a cross TGT for REALM2, get referred back to REALM1, and fail to get a ticket due to the lineage check in REALM1's KDC. We can't necessarily do anything about case 3 without violating the principle of least surprise.
Case 2 is currently treated the same as case 3, because importing a principal or user name passes the string through krb5_parse_name(), adding in the default realm. It would be better to instead use referrals.
My first inclination here is to implement Heimdal's KRB5_PRINCIPAL_PARSE_NO_DEF_REALM and use it when importing string representations, so that we don't lose track of whether a realm was specified and use referrals in case 3. This may have undesirable side-effects, because not all names are target names. If the name is instead used with gss_acquire_cred() or gss_acquire_name_with_password(), the lack of realm may be an issue. The change does mostly pass the test suite; the most damning failure happens when t_inq_ctx.c imports a GSS_C_NT_USER_NAME name of "user" and passes it to IAKERB's gss_acquire_cred_with_password(). No realm is supplied in the IAKERB message and the acceptor rejects it.
The application may import (1) MSSQLSvc/hostpart@, (2) MSSQLSvc/hostpart, or (3) MSSQLSvc/hostpart@realm, where realm is probably the configured default realm. Case 1 should work currently. Case 3 may not work if realm is a bad starting point for the TGS query; for example, if the client principal and actual service location are in REALM1, but the default realm is REALM2, the client will fetch a cross TGT for REALM2, get referred back to REALM1, and fail to get a ticket due to the lineage check in REALM1's KDC. We can't necessarily do anything about case 3 without violating the principle of least surprise.
Case 2 is currently treated the same as case 3, because importing a principal or user name passes the string through krb5_parse_name(), adding in the default realm. It would be better to instead use referrals.
My first inclination here is to implement Heimdal's KRB5_PRINCIPAL_PARSE_NO_DEF_REALM and use it when importing string representations, so that we don't lose track of whether a realm was specified and use referrals in case 3. This may have undesirable side-effects, because not all names are target names. If the name is instead used with gss_acquire_cred() or gss_acquire_name_with_password(), the lack of realm may be an issue. The change does mostly pass the test suite; the most damning failure happens when t_inq_ctx.c imports a GSS_C_NT_USER_NAME name of "user" and passes it to IAKERB's gss_acquire_cred_with_password(). No realm is supplied in the IAKERB message and the acceptor rejects it.