From: Greg Hudson Date: Mon, 2 Jul 2012 04:57:34 +0000 (-0400) Subject: Get default cred only once in gss-krb5 initiator X-Git-Tag: krb5-1.11-alpha1~476 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=49ba7c90fce86581ff6faaa9ee48c80b0be9491e;p=thirdparty%2Fkrb5.git Get default cred only once in gss-krb5 initiator In the regular krb5 code path, only get a default krb5 cred for the initial token, since we don't need the cred for mutual_auth anyway. In the IAKERB mechanism, cache the default cred in iakerb_ctx_id_rec so we don't have to construct it again for each token. Also, get an IAKERB default cred, not a regular krb5 cred (a bug which is harmless now, but becomes more of a problem with keytab initiation changes). --- diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c index 31fd190a5f..1b3236e664 100644 --- a/src/lib/gssapi/krb5/iakerb.c +++ b/src/lib/gssapi/krb5/iakerb.c @@ -40,6 +40,7 @@ enum iakerb_state { struct _iakerb_ctx_id_rec { krb5_magic magic; /* KG_IAKERB_CONTEXT */ krb5_context k5c; + gss_cred_id_t defcred; /* Initiator only */ enum iakerb_state state; /* Initiator only */ krb5_init_creds_context icc; /* Initiator only */ krb5_tkt_creds_context tcc; /* Initiator only */ @@ -65,6 +66,7 @@ iakerb_release_context(iakerb_ctx_id_t ctx) if (ctx == NULL) return; + krb5_gss_release_cred(&tmp, &ctx->defcred); krb5_init_creds_free(ctx->k5c, ctx->icc); krb5_tkt_creds_free(ctx->k5c, ctx->tcc); krb5_gss_delete_sec_context(&tmp, &ctx->gssc, NULL); @@ -710,6 +712,7 @@ iakerb_alloc_context(iakerb_ctx_id_t *pctx) ctx = k5alloc(sizeof(*ctx), &code); if (ctx == NULL) goto cleanup; + ctx->defcred = GSS_C_NO_CREDENTIAL; ctx->magic = KG_IAKERB_CONTEXT; ctx->state = IAKERB_AS_REQ; ctx->count = 0; @@ -893,10 +896,8 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status, OM_uint32 *time_rec) { OM_uint32 major_status = GSS_S_FAILURE; - OM_uint32 tmpmin; krb5_error_code code; iakerb_ctx_id_t ctx; - gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL; krb5_gss_cred_id_t kcred; krb5_gss_name_t kname; krb5_boolean cred_locked = FALSE; @@ -908,22 +909,24 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status, *minor_status = code; goto cleanup; } - } else + if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { + major_status = iakerb_gss_acquire_cred(minor_status, NULL, + GSS_C_INDEFINITE, + GSS_C_NULL_OID_SET, + GSS_C_INITIATE, + &ctx->defcred, NULL, NULL); + if (GSS_ERROR(major_status)) + goto cleanup; + claimant_cred_handle = ctx->defcred; + } + } else { ctx = (iakerb_ctx_id_t)*context_handle; + if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) + claimant_cred_handle = ctx->defcred; + } kname = (krb5_gss_name_t)target_name; - if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { - major_status = krb5_gss_acquire_cred(minor_status, NULL, - GSS_C_INDEFINITE, - GSS_C_NULL_OID_SET, - GSS_C_INITIATE, - &defcred, NULL, NULL); - if (GSS_ERROR(major_status)) - goto cleanup; - claimant_cred_handle = defcred; - } - major_status = kg_cred_resolve(minor_status, ctx->k5c, claimant_cred_handle, target_name); if (GSS_ERROR(major_status)) @@ -1011,7 +1014,6 @@ cleanup: iakerb_release_context(ctx); *context_handle = GSS_C_NO_CONTEXT; } - krb5_gss_release_cred(&tmpmin, &defcred); return major_status; } diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index 6451a6dde5..d0eda5f3d3 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -948,29 +948,6 @@ krb5_gss_init_sec_context_ext( if (actual_mech_type) *actual_mech_type = NULL; - /* verify the credential, or use the default */ - /*SUPPRESS 29*/ - if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { - major_status = kg_get_defcred(minor_status, &defcred); - if (major_status && GSS_ERROR(major_status)) { - if (*context_handle == GSS_C_NO_CONTEXT) - krb5_free_context(context); - return(major_status); - } - claimant_cred_handle = defcred; - } - - major_status = kg_cred_resolve(minor_status, context, claimant_cred_handle, - target_name); - if (GSS_ERROR(major_status)) { - save_error_info(*minor_status, context); - krb5_gss_release_cred(&tmp_min_stat, &defcred); - if (*context_handle == GSS_C_NO_CONTEXT) - krb5_free_context(context); - return(major_status); - } - cred = (krb5_gss_cred_id_t)claimant_cred_handle; - /* verify the mech_type */ if (mech_type == GSS_C_NULL_OID || g_OID_equal(mech_type, gss_mech_krb5)) { @@ -982,8 +959,6 @@ krb5_gss_init_sec_context_ext( } else if (g_OID_equal(mech_type, gss_mech_iakerb)) { mech_type = (gss_OID) gss_mech_iakerb; } else { - k5_mutex_unlock(&cred->lock); - krb5_gss_release_cred(minor_status, &defcred); *minor_status = 0; if (*context_handle == GSS_C_NO_CONTEXT) krb5_free_context(context); @@ -994,6 +969,29 @@ krb5_gss_init_sec_context_ext( /*SUPPRESS 29*/ if (*context_handle == GSS_C_NO_CONTEXT) { + /* verify the credential, or use the default */ + /*SUPPRESS 29*/ + if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) { + major_status = kg_get_defcred(minor_status, &defcred); + if (major_status && GSS_ERROR(major_status)) { + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); + return(major_status); + } + claimant_cred_handle = defcred; + } + + major_status = kg_cred_resolve(minor_status, context, + claimant_cred_handle, target_name); + if (GSS_ERROR(major_status)) { + save_error_info(*minor_status, context); + krb5_gss_release_cred(&tmp_min_stat, &defcred); + if (*context_handle == GSS_C_NO_CONTEXT) + krb5_free_context(context); + return(major_status); + } + cred = (krb5_gss_cred_id_t)claimant_cred_handle; + major_status = kg_new_connection(minor_status, cred, context_handle, target_name, mech_type, req_flags, time_req, input_chan_bindings, @@ -1001,6 +999,7 @@ krb5_gss_init_sec_context_ext( output_token, ret_flags, time_rec, context, exts); k5_mutex_unlock(&cred->lock); + krb5_gss_release_cred(&tmp_min_stat, &defcred); if (*context_handle == GSS_C_NO_CONTEXT) { save_error_info (*minor_status, context); krb5_free_context(context); @@ -1008,7 +1007,6 @@ krb5_gss_init_sec_context_ext( ((krb5_gss_ctx_id_rec *) *context_handle)->k5_context = context; } else { /* mutual_auth doesn't care about the credentials */ - k5_mutex_unlock(&cred->lock); major_status = mutual_auth(minor_status, context_handle, target_name, mech_type, req_flags, time_req, input_chan_bindings, @@ -1020,7 +1018,6 @@ krb5_gss_init_sec_context_ext( too. */ } - krb5_gss_release_cred(&tmp_min_stat, &defcred); return(major_status); }