[31591] in CVS-changelog-for-Kerberos-V5

home help back first fref pref prev next nref lref last post

krb5 commit: Pass through null deleg_cred from SPNEGO to mech

daemon@ATHENA.MIT.EDU (ghudson@mit.edu)
Fri Oct 30 13:10:32 2026

From: ghudson@mit.edu
To: cvs-krb5@mit.edu
Message-Id: <20261030004351.BD7EC105814@krbdev.mit.edu>
Date: Thu, 29 Oct 2026 20:43:51 -0400 (EDT)
MIME-Version: 1.0
Reply-To: krbdev@mit.edu
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: cvs-krb5-bounces@mit.edu

https://github.com/krb5/krb5/commit/3a2e9b5b7dbb1692751f64e54ea73146f4825f4d
commit 3a2e9b5b7dbb1692751f64e54ea73146f4825f4d
Author: Greg Hudson <ghudson@mit.edu>
Date:   Fri Oct 23 19:00:17 2026 -0400

    Pass through null deleg_cred from SPNEGO to mech
    
    In the SPNEGO and NegoEx implementations, if the caller of
    gss_accept_sec_context() passes a null delegated_cred_handle argument,
    pass it through to the mech instead of requesting and discarding a
    delegated credential.
    
    ticket: 9270 (new)
    tags: pullup
    target_version: 1.22-next

 src/lib/gssapi/spnego/gssapiP_negoex.h |  3 ++-
 src/lib/gssapi/spnego/negoex_ctx.c     | 15 ++++++++-------
 src/lib/gssapi/spnego/spnego_mech.c    | 19 ++++++++++++-------
 3 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/src/lib/gssapi/spnego/gssapiP_negoex.h b/src/lib/gssapi/spnego/gssapiP_negoex.h
index 489ab7c42..3c514b235 100644
--- a/src/lib/gssapi/spnego/gssapiP_negoex.h
+++ b/src/lib/gssapi/spnego/gssapiP_negoex.h
@@ -207,4 +207,5 @@ negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
 OM_uint32
 negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
               gss_buffer_t input_token, gss_channel_bindings_t bindings,
-              gss_buffer_t output_token, OM_uint32 *time_rec);
+              gss_buffer_t output_token, OM_uint32 *time_rec,
+              gss_cred_id_t *deleg_cred);
diff --git a/src/lib/gssapi/spnego/negoex_ctx.c b/src/lib/gssapi/spnego/negoex_ctx.c
index 8848ee4db..2e9668c47 100644
--- a/src/lib/gssapi/spnego/negoex_ctx.c
+++ b/src/lib/gssapi/spnego/negoex_ctx.c
@@ -352,7 +352,8 @@ static OM_uint32
 mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
             gss_cred_id_t cred, struct negoex_message *messages,
             size_t nmessages, gss_channel_bindings_t bindings,
-            gss_buffer_t output_token, OM_uint32 *time_rec)
+            gss_buffer_t output_token, OM_uint32 *time_rec,
+            gss_cred_id_t *deleg_cred)
 {
     OM_uint32 major, tmpmin;
     struct negoex_auth_mech *mech;
@@ -392,14 +393,13 @@ mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
 
     if (ctx->internal_name != GSS_C_NO_NAME)
         gss_release_name(&tmpmin, &ctx->internal_name);
-    if (ctx->deleg_cred != GSS_C_NO_CREDENTIAL)
-        gss_release_cred(&tmpmin, &ctx->deleg_cred);
+    if (deleg_cred != NULL && *deleg_cred != GSS_C_NO_CREDENTIAL)
+        gss_release_cred(&tmpmin, deleg_cred);
 
     major = gss_accept_sec_context(minor, &mech->mech_context, cred,
                                    &msg->token, bindings, &ctx->internal_name,
                                    &ctx->actual_mech, output_token,
-                                   &ctx->ctx_flags, time_rec,
-                                   &ctx->deleg_cred);
+                                   &ctx->ctx_flags, time_rec, deleg_cred);
 
     if (major == GSS_S_COMPLETE)
         mech->complete = 1;
@@ -704,7 +704,8 @@ cleanup:
 OM_uint32
 negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
               gss_buffer_t input_token, gss_channel_bindings_t bindings,
-              gss_buffer_t output_token, OM_uint32 *time_rec)
+              gss_buffer_t output_token, OM_uint32 *time_rec,
+              gss_cred_id_t *deleg_cred)
 {
     OM_uint32 major, tmpmin;
     gss_buffer_desc mech_output_token = GSS_C_EMPTY_BUFFER;
@@ -757,7 +758,7 @@ negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
      * is generated, so that we send the token to the initiator.
      */
     major = mech_accept(minor, ctx, cred, messages, nmessages, bindings,
-                        &mech_output_token, time_rec);
+                        &mech_output_token, time_rec, deleg_cred);
     if (major != GSS_S_COMPLETE && mech_output_token.length == 0)
         goto cleanup;
 
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 23f93c240..5c597d6be 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -127,7 +127,7 @@ acc_ctx_vfy_oid(OM_uint32 *, spnego_gss_ctx_id_t, gss_OID,
 static OM_uint32
 acc_ctx_call_acc(OM_uint32 *, spnego_gss_ctx_id_t, spnego_gss_cred_id_t,
 		 gss_buffer_t, gss_channel_bindings_t, gss_buffer_t,
-		 OM_uint32 *, OM_uint32 *, send_token_flag *);
+		 OM_uint32 *, gss_cred_id_t *, OM_uint32 *, send_token_flag *);
 
 static gss_OID
 negotiate_mech(spnego_gss_ctx_id_t, gss_OID_set, OM_uint32 *);
@@ -1471,8 +1471,8 @@ static OM_uint32
 acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
 		 spnego_gss_cred_id_t spcred, gss_buffer_t mechtok_in,
 		 gss_channel_bindings_t bindings, gss_buffer_t mechtok_out,
-		 OM_uint32 *time_rec, OM_uint32 *negState,
-		 send_token_flag *tokflag)
+		 OM_uint32 *time_rec, gss_cred_id_t *deleg_cred,
+		 OM_uint32 *negState, send_token_flag *tokflag)
 {
 	OM_uint32 ret, tmpmin;
 	gss_OID_desc mechoid;
@@ -1497,16 +1497,18 @@ acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
 	mcred = (spcred == NULL) ? GSS_C_NO_CREDENTIAL : spcred->mcred;
 	if (negoex) {
 		ret = negoex_accept(minor_status, sc, mcred, mechtok_in,
-				    bindings, mechtok_out, time_rec);
+				    bindings, mechtok_out, time_rec,
+				    deleg_cred);
 	} else {
 		(void) gss_release_name(&tmpmin, &sc->internal_name);
-		(void) gss_release_cred(&tmpmin, &sc->deleg_cred);
+		if (deleg_cred != NULL && *deleg_cred != GSS_C_NO_CREDENTIAL)
+		    (void) gss_release_cred(&tmpmin, deleg_cred);
 		ret = gss_accept_sec_context(minor_status, &sc->ctx_handle,
 					     mcred, mechtok_in, bindings,
 					     &sc->internal_name,
 					     &sc->actual_mech, mechtok_out,
 					     &sc->ctx_flags, time_rec,
-					     &sc->deleg_cred);
+					     deleg_cred);
 	}
 	if (ret == GSS_S_COMPLETE) {
 #ifdef MS_BUG_TEST
@@ -1560,6 +1562,7 @@ spnego_gss_accept_sec_context(
 	send_token_flag return_token;
 	gss_buffer_t mechtok_in, mic_in, mic_out;
 	gss_buffer_desc mechtok_out = GSS_C_EMPTY_BUFFER;
+	gss_cred_id_t *deleg_cred;
 	spnego_gss_ctx_id_t sc = NULL;
 	spnego_gss_cred_id_t spcred = NULL;
 	int sendTokenInit = 0, tmpret;
@@ -1661,9 +1664,11 @@ spnego_gss_accept_sec_context(
 	 * whether it is the first round-trip.
 	 */
 	if (negState != REQUEST_MIC && mechtok_in != GSS_C_NO_BUFFER) {
+		deleg_cred = (delegated_cred_handle != NULL) ?
+			&sc->deleg_cred : NULL;
 		ret = acc_ctx_call_acc(minor_status, sc, spcred, mechtok_in,
 				       bindings, &mechtok_out, time_rec,
-				       &negState, &return_token);
+				       deleg_cred, &negState, &return_token);
 	}
 
 	/* Step 3: process or generate the MIC, if the negotiated mech is
_______________________________________________
cvs-krb5 mailing list
cvs-krb5@mit.edu
https://mailman.mit.edu/mailman/listinfo/cvs-krb5

home help back first fref pref prev next nref lref last post