From: Greg Hudson Date: Mon, 29 Feb 2016 21:51:22 +0000 (-0500) Subject: Skip unnecessary mech calls in gss_inquire_cred() X-Git-Tag: krb5-1.13.5-final~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dd51cee8414b37e7ff4ffb8b2d1b0659b106f87c;p=thirdparty%2Fkrb5.git Skip unnecessary mech calls in gss_inquire_cred() If the caller does not request a name, lifetime, or cred_usage when calling gss_inquire_cred(), service the call by copying the mechanism list (if requested) but do not call into the mech. This change alleviates an issue (reported by Adam Bernstein) where SPNEGO can fail in the presence of expired krb5 credentials rather than proceeding with a different mechanism, or can resolve a krb5 credential without the benefit of the target name. (cherry picked from commit ff5eb892910eeac335d989ae14020da4ffbcc8ec) ticket: 8373 version_fixed: 1.13.5 status: resolved tags: -pullup --- diff --git a/src/lib/gssapi/mechglue/g_inq_cred.c b/src/lib/gssapi/mechglue/g_inq_cred.c index c8e45fe0bb..b70131af48 100644 --- a/src/lib/gssapi/mechglue/g_inq_cred.c +++ b/src/lib/gssapi/mechglue/g_inq_cred.c @@ -92,27 +92,32 @@ gss_OID_set * mechanisms; mech_cred = GSS_C_NO_CREDENTIAL; mech = gssint_get_mechanism(GSS_C_NULL_OID); } - if (mech == NULL) - return (GSS_S_DEFECTIVE_CREDENTIAL); - if (!mech->gss_inquire_cred) - return (GSS_S_UNAVAILABLE); - status = mech->gss_inquire_cred(minor_status, mech_cred, - name ? &mech_name : NULL, - lifetime, cred_usage, NULL); - if (status != GSS_S_COMPLETE) { - map_error(minor_status, mech); - return(status); - } + /* Skip the call into the mech if the caller doesn't care about any of the + * values we would ask for. */ + if (name != NULL || lifetime != NULL || cred_usage != NULL) { + if (mech == NULL) + return (GSS_S_DEFECTIVE_CREDENTIAL); + if (!mech->gss_inquire_cred) + return (GSS_S_UNAVAILABLE); - if (name) { - /* Convert mech_name into a union_name equivalent. */ - status = gssint_convert_name_to_union_name(&temp_minor_status, - mech, mech_name, name); + status = mech->gss_inquire_cred(minor_status, mech_cred, + name ? &mech_name : NULL, + lifetime, cred_usage, NULL); if (status != GSS_S_COMPLETE) { - *minor_status = temp_minor_status; map_error(minor_status, mech); - return (status); + return(status); + } + + if (name) { + /* Convert mech_name into a union_name equivalent. */ + status = gssint_convert_name_to_union_name(&temp_minor_status, + mech, mech_name, name); + if (status != GSS_S_COMPLETE) { + *minor_status = temp_minor_status; + map_error(minor_status, mech); + return (status); + } } }