diff --git a/lib/gssapi/ChangeLog b/lib/gssapi/ChangeLog index b5679ceef..31c303581 100644 --- a/lib/gssapi/ChangeLog +++ b/lib/gssapi/ChangeLog @@ -1,3 +1,8 @@ +2003-05-21 Love Hörnquist Åstrand + + * gss_acquire_cred.3: document argument lifetime_rec to function + gss_inquire_context + 2003-05-17 Love Hörnquist Åstrand * test_acquire_cred.c: test gss_add_cred more then once diff --git a/lib/gssapi/accept_sec_context.c b/lib/gssapi/accept_sec_context.c index 4b55acb21..0a35c4af8 100644 --- a/lib/gssapi/accept_sec_context.c +++ b/lib/gssapi/accept_sec_context.c @@ -35,6 +35,7 @@ RCSID("$Id$"); +HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER; krb5_keytab gssapi_krb5_keytab; OM_uint32 @@ -47,15 +48,20 @@ gsskrb5_register_acceptor_identity (const char *identity) if(ret) return GSS_S_FAILURE; + HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); + if(gssapi_krb5_keytab != NULL) { krb5_kt_close(gssapi_krb5_context, gssapi_krb5_keytab); gssapi_krb5_keytab = NULL; } asprintf(&p, "FILE:%s", identity); - if(p == NULL) + if(p == NULL) { + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); return GSS_S_FAILURE; + } ret = krb5_kt_resolve(gssapi_krb5_context, p, &gssapi_krb5_keytab); free(p); + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); if(ret) return GSS_S_FAILURE; return GSS_S_COMPLETE; @@ -105,6 +111,7 @@ gss_accept_sec_context } } + HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex); (*context_handle)->auth_context = NULL; (*context_handle)->source = NULL; (*context_handle)->target = NULL; @@ -208,6 +215,8 @@ gss_accept_sec_context if (ret) goto failure; + HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); + if (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) { if (gssapi_krb5_keytab != NULL) { keytab = gssapi_krb5_keytab; @@ -224,6 +233,9 @@ gss_accept_sec_context keytab, &ap_options, &ticket); + + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); + if (kret) { ret = GSS_S_FAILURE; *minor_status = kret; @@ -421,6 +433,7 @@ gss_accept_sec_context if((*context_handle)->target) krb5_free_principal (gssapi_krb5_context, (*context_handle)->target); + HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); free (*context_handle); if (src_name != NULL) { gss_release_name (&minor, src_name); diff --git a/lib/gssapi/acquire_cred.c b/lib/gssapi/acquire_cred.c index e8c28f6d3..06fdc4b7d 100644 --- a/lib/gssapi/acquire_cred.c +++ b/lib/gssapi/acquire_cred.c @@ -41,6 +41,8 @@ get_keytab(krb5_keytab *keytab) char kt_name[256]; krb5_error_code kret; + HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); + if (gssapi_krb5_keytab != NULL) { kret = krb5_kt_get_name(gssapi_krb5_context, gssapi_krb5_keytab, @@ -49,6 +51,9 @@ get_keytab(krb5_keytab *keytab) kret = krb5_kt_resolve(gssapi_krb5_context, kt_name, keytab); } else kret = krb5_kt_default(gssapi_krb5_context, keytab); + + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); + return (kret); } @@ -253,11 +258,13 @@ OM_uint32 gss_acquire_cred } memset(handle, 0, sizeof (*handle)); + HEIMDAL_MUTEX_init(&handle->cred_id_mutex); if (desired_name != GSS_C_NO_NAME) { ret = gss_duplicate_name(minor_status, desired_name, &handle->principal); if (ret != GSS_S_COMPLETE) { + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); return (ret); } @@ -266,6 +273,7 @@ OM_uint32 gss_acquire_cred ret = acquire_initiator_cred(minor_status, desired_name, time_req, desired_mechs, cred_usage, handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); return (ret); } @@ -273,10 +281,12 @@ OM_uint32 gss_acquire_cred ret = acquire_acceptor_cred(minor_status, desired_name, time_req, desired_mechs, cred_usage, handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); return (ret); } } else { + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); *minor_status = GSS_KRB5_S_G_BAD_USAGE; return GSS_S_FAILURE; @@ -291,6 +301,7 @@ OM_uint32 gss_acquire_cred if (ret != GSS_S_COMPLETE) { if (handle->mechanisms != NULL) gss_release_oid_set(NULL, &handle->mechanisms); + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); return (ret); } diff --git a/lib/gssapi/add_cred.c b/lib/gssapi/add_cred.c index b207415c2..b7dcb4dfa 100644 --- a/lib/gssapi/add_cred.c +++ b/lib/gssapi/add_cred.c @@ -65,16 +65,21 @@ OM_uint32 gss_add_cred ( } /* check if requested output usage is compatible with output usage */ - if (output_cred_handle != NULL && - (cred->usage != cred_usage && cred->usage != GSS_C_BOTH)) { - *minor_status = GSS_KRB5_S_G_BAD_USAGE; - return(GSS_S_FAILURE); + if (output_cred_handle != NULL) { + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); + if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = GSS_KRB5_S_G_BAD_USAGE; + return(GSS_S_FAILURE); + } } /* check that we have the same name */ if (desired_name != GSS_C_NO_NAME && krb5_principal_compare(gssapi_krb5_context, desired_name, cred->principal) != FALSE) { + if (output_cred_handle) + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); *minor_status = 0; return GSS_S_BAD_NAME; } @@ -84,6 +89,7 @@ OM_uint32 gss_add_cred ( handle = (gss_cred_id_t)malloc(sizeof(*handle)); if (handle == GSS_C_NO_CREDENTIAL) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); *minor_status = ENOMEM; return (GSS_S_FAILURE); } @@ -96,12 +102,14 @@ OM_uint32 gss_add_cred ( handle->keytab = NULL; handle->ccache = NULL; handle->mechanisms = NULL; + HEIMDAL_MUTEX_init(&handle->cred_id_mutex); ret = GSS_S_FAILURE; ret = gss_duplicate_name(minor_status, cred->principal, &handle->principal); if (ret) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); free(handle); *minor_status = ENOMEM; return GSS_S_FAILURE; @@ -193,8 +201,10 @@ OM_uint32 gss_add_cred ( if (acceptor_time_rec) *acceptor_time_rec = lifetime; - if (output_cred_handle) + if (output_cred_handle) { *output_cred_handle = handle; + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + } *minor_status = 0; return ret; @@ -212,5 +222,7 @@ OM_uint32 gss_add_cred ( gss_release_oid_set(NULL, &handle->mechanisms); free(handle); } + if (output_cred_handle) + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); return ret; } diff --git a/lib/gssapi/compat.c b/lib/gssapi/compat.c index 49d926f9d..f9de5f4ef 100644 --- a/lib/gssapi/compat.c +++ b/lib/gssapi/compat.c @@ -83,12 +83,16 @@ _gss_DES3_get_mic_compat(OM_uint32 *minor_status, gss_ctx_id_t ctx) if ((ctx->more_flags & COMPAT_OLD_DES3_SELECTED) == 0) { ret = check_compat(minor_status, ctx->target, "broken_des3_mic", &use_compat, TRUE); - if (ret) + if (ret) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return ret; + } ret = check_compat(minor_status, ctx->target, "correct_des3_mic", &use_compat, FALSE); - if (ret) + if (ret) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return ret; + } if (use_compat) ctx->more_flags |= COMPAT_OLD_DES3; @@ -102,12 +106,14 @@ gss_krb5_compat_des3_mic(OM_uint32 *minor_status, gss_ctx_id_t ctx, int on) { *minor_status = 0; + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); if (on) { ctx->more_flags |= COMPAT_OLD_DES3; } else { ctx->more_flags &= ~COMPAT_OLD_DES3; } ctx->more_flags |= COMPAT_OLD_DES3_SELECTED; + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return 0; } diff --git a/lib/gssapi/context_time.c b/lib/gssapi/context_time.c index 36c6e8ff3..2d196f2b3 100644 --- a/lib/gssapi/context_time.c +++ b/lib/gssapi/context_time.c @@ -35,31 +35,54 @@ RCSID("$Id$"); +OM_uint32 +gssapi_lifetime_left(OM_uint32 *minor_status, + OM_uint32 lifetime, + OM_uint32 *lifetime_rec) +{ + krb5_timestamp timeret; + krb5_error_code kret; + + kret = krb5_timeofday(gssapi_krb5_context, &timeret); + if (kret) { + *minor_status = kret; + gssapi_krb5_set_error_string (); + return GSS_S_FAILURE; + } + + if (lifetime < timeret) + *lifetime_rec = 0; + else + *lifetime_rec = lifetime - timeret; + + return GSS_S_COMPLETE; +} + + OM_uint32 gss_context_time (OM_uint32 * minor_status, const gss_ctx_id_t context_handle, OM_uint32 * time_rec ) { - krb5_error_code kret; krb5_timestamp timeret; + OM_uint32 lifetime; + OM_uint32 major_status; GSSAPI_KRB5_INIT (); - kret = krb5_timeofday(gssapi_krb5_context, &timeret); - if (kret) { - *minor_status = kret; - gssapi_krb5_set_error_string (); - return GSS_S_FAILURE; - } + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + lifetime = context_handle->lifetime; + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + + major_status = gssapi_lifetime_left(minor_status, lifetime, time_rec); + if (major_status != GSS_S_COMPLETE) + return major_status; *minor_status = 0; - if (context_handle->lifetime < timeret) { - *time_rec = 0; + if (*time_rec == 0) return GSS_S_CONTEXT_EXPIRED; - } - - *time_rec = context_handle->lifetime - timeret; + return GSS_S_COMPLETE; } diff --git a/lib/gssapi/copy_ccache.c b/lib/gssapi/copy_ccache.c index 15d2e1c54..b8938acb3 100644 --- a/lib/gssapi/copy_ccache.c +++ b/lib/gssapi/copy_ccache.c @@ -42,12 +42,16 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status, { krb5_error_code kret; + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); + if (cred->ccache == NULL) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); *minor_status = EINVAL; return GSS_S_FAILURE; } kret = krb5_cc_copy_cache(gssapi_krb5_context, cred->ccache, out); + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); if (kret) { *minor_status = kret; gssapi_krb5_set_error_string (); diff --git a/lib/gssapi/delete_sec_context.c b/lib/gssapi/delete_sec_context.c index 4c609b3fc..0d2143955 100644 --- a/lib/gssapi/delete_sec_context.c +++ b/lib/gssapi/delete_sec_context.c @@ -48,6 +48,8 @@ OM_uint32 gss_delete_sec_context output_token->value = NULL; } + HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex); + krb5_auth_con_free (gssapi_krb5_context, (*context_handle)->auth_context); if((*context_handle)->source) @@ -62,6 +64,9 @@ OM_uint32 gss_delete_sec_context free((*context_handle)->ticket); } + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); + HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); + memset(*context_handle, 0, sizeof(**context_handle)); free (*context_handle); *context_handle = GSS_C_NO_CONTEXT; *minor_status = 0; diff --git a/lib/gssapi/export_sec_context.c b/lib/gssapi/export_sec_context.c index 8ec622377..f90b75cd9 100644 --- a/lib/gssapi/export_sec_context.c +++ b/lib/gssapi/export_sec_context.c @@ -52,13 +52,18 @@ gss_export_sec_context ( krb5_error_code kret; GSSAPI_KRB5_INIT (); + + HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex); + if (!((*context_handle)->flags & GSS_C_TRANS_FLAG)) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); *minor_status = 0; return GSS_S_UNAVAILABLE; } sp = krb5_storage_emem (); if (sp == NULL) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); *minor_status = ENOMEM; return GSS_S_FAILURE; } @@ -206,11 +211,13 @@ gss_export_sec_context ( kret = krb5_storage_to_data (sp, &data); krb5_storage_free (sp); if (kret) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); *minor_status = kret; return GSS_S_FAILURE; } interprocess_token->length = data.length; interprocess_token->value = data.data; + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); ret = gss_delete_sec_context (minor_status, context_handle, GSS_C_NO_BUFFER); if (ret != GSS_S_COMPLETE) @@ -218,6 +225,7 @@ gss_export_sec_context ( *minor_status = 0; return ret; failure: + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); krb5_storage_free (sp); return ret; } diff --git a/lib/gssapi/get_mic.c b/lib/gssapi/get_mic.c index bdf935e65..43ccd06ac 100644 --- a/lib/gssapi/get_mic.c +++ b/lib/gssapi/get_mic.c @@ -90,6 +90,7 @@ mic_des schedule, &zero); memcpy (p - 8, hash, 8); /* SGN_CKSUM */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); /* sequence number */ krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, @@ -111,6 +112,7 @@ mic_des krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); memset (deskey, 0, sizeof(deskey)); memset (schedule, 0, sizeof(schedule)); @@ -199,6 +201,7 @@ mic_des3 memcpy (p + 8, cksum.checksum.data, cksum.checksum.length); + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); /* sequence number */ krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, @@ -246,6 +249,7 @@ mic_des3 krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); free_Checksum (&cksum); *minor_status = 0; diff --git a/lib/gssapi/gssapi.h b/lib/gssapi/gssapi.h index 493565163..60f36121a 100644 --- a/lib/gssapi/gssapi.h +++ b/lib/gssapi/gssapi.h @@ -63,17 +63,8 @@ struct Principal; typedef struct Principal *gss_name_t; -typedef struct gss_ctx_id_t_desc_struct { - struct krb5_auth_context_data *auth_context; - gss_name_t source, target; - OM_uint32 flags; - enum { LOCAL = 1, OPEN = 2, - COMPAT_OLD_DES3 = 4, COMPAT_OLD_DES3_SELECTED = 8 } more_flags; - struct krb5_ticket *ticket; - time_t lifetime; -} gss_ctx_id_t_desc; - -typedef gss_ctx_id_t_desc *gss_ctx_id_t; +struct gss_ctx_id_t_desc_struct; +typedef struct gss_ctx_id_t_desc_struct *gss_ctx_id_t; typedef struct gss_OID_desc_struct { OM_uint32 length; @@ -91,16 +82,8 @@ struct krb5_ccache_data; typedef int gss_cred_usage_t; -typedef struct gss_cred_id_t_desc_struct { - gss_name_t principal; - struct krb5_keytab_data *keytab; - OM_uint32 lifetime; - gss_cred_usage_t usage; - gss_OID_set mechanisms; - struct krb5_ccache_data *ccache; -} gss_cred_id_t_desc; - -typedef gss_cred_id_t_desc *gss_cred_id_t; +struct gss_cred_id_t_desc_struct; +typedef struct gss_cred_id_t_desc_struct *gss_cred_id_t; typedef struct gss_buffer_desc_struct { size_t length; diff --git a/lib/gssapi/gssapi_locl.h b/lib/gssapi/gssapi_locl.h index 3cf709618..4a7056302 100644 --- a/lib/gssapi/gssapi_locl.h +++ b/lib/gssapi/gssapi_locl.h @@ -44,9 +44,43 @@ #include #include +/* + * + */ + +typedef struct gss_ctx_id_t_desc_struct { + struct krb5_auth_context_data *auth_context; + gss_name_t source, target; + OM_uint32 flags; + enum { LOCAL = 1, OPEN = 2, + COMPAT_OLD_DES3 = 4, COMPAT_OLD_DES3_SELECTED = 8 } more_flags; + struct krb5_ticket *ticket; + time_t lifetime; + HEIMDAL_MUTEX ctx_id_mutex; +} gss_ctx_id_t_desc; + +typedef struct gss_cred_id_t_desc_struct { + gss_name_t principal; + struct krb5_keytab_data *keytab; + OM_uint32 lifetime; + gss_cred_usage_t usage; + gss_OID_set mechanisms; + struct krb5_ccache_data *ccache; + HEIMDAL_MUTEX cred_id_mutex; +} gss_cred_id_t_desc; + +/* + * + */ + extern krb5_context gssapi_krb5_context; extern krb5_keytab gssapi_krb5_keytab; +extern HEIMDAL_MUTEX gssapi_keytab_mutex; + +/* + * Prototypes + */ krb5_error_code gssapi_krb5_init (void); @@ -145,4 +179,7 @@ gssapi_krb5_get_error_string (void); OM_uint32 _gss_DES3_get_mic_compat(OM_uint32 *minor_status, gss_ctx_id_t ctx); +OM_uint32 +gssapi_lifetime_left(OM_uint32 *, OM_uint32, OM_uint32 *); + #endif diff --git a/lib/gssapi/import_sec_context.c b/lib/gssapi/import_sec_context.c index f309b4b06..f2a0e8ce8 100644 --- a/lib/gssapi/import_sec_context.c +++ b/lib/gssapi/import_sec_context.c @@ -73,6 +73,7 @@ gss_import_sec_context ( return GSS_S_FAILURE; } memset (*context_handle, 0, sizeof(**context_handle)); + HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex); kret = krb5_auth_con_init (gssapi_krb5_context, &(*context_handle)->auth_context); @@ -206,6 +207,7 @@ failure: krb5_free_address (gssapi_krb5_context, localp); if (remotep) krb5_free_address (gssapi_krb5_context, remotep); + HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); free (*context_handle); *context_handle = GSS_C_NO_CONTEXT; return ret; diff --git a/lib/gssapi/init_sec_context.c b/lib/gssapi/init_sec_context.c index efd5ae9c4..b4300757f 100644 --- a/lib/gssapi/init_sec_context.c +++ b/lib/gssapi/init_sec_context.c @@ -212,6 +212,7 @@ init_auth (*context_handle)->more_flags = 0; (*context_handle)->ticket = NULL; (*context_handle)->lifetime = GSS_C_INDEFINITE; + HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex); kret = krb5_auth_con_init (gssapi_krb5_context, &(*context_handle)->auth_context); @@ -428,6 +429,7 @@ init_auth if((*context_handle)->target) krb5_free_principal (gssapi_krb5_context, (*context_handle)->target); + HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); free (*context_handle); krb5_data_free (&outbuf); *context_handle = GSS_C_NO_CONTEXT; @@ -459,20 +461,25 @@ repl_mutual output_token->length = 0; output_token->value = NULL; + HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex); + if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM; ret = gssapi_krb5_decapsulate (minor_status, input_token, &indata, "\x02\x00"); - if (ret) - /* XXX - Handle AP_ERROR */ + if (ret) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); + /* XXX - Handle AP_ERROR */ return ret; + } kret = krb5_rd_rep (gssapi_krb5_context, (*context_handle)->auth_context, &indata, &repl); if (kret) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); gssapi_krb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; diff --git a/lib/gssapi/inquire_context.c b/lib/gssapi/inquire_context.c index fbab36920..4fddfd379 100644 --- a/lib/gssapi/inquire_context.c +++ b/lib/gssapi/inquire_context.c @@ -49,12 +49,14 @@ OM_uint32 gss_inquire_context ( { OM_uint32 ret; + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + if (src_name) { ret = gss_duplicate_name (minor_status, context_handle->source, src_name); if (ret) - return ret; + goto failed; } if (targ_name) { @@ -62,11 +64,16 @@ OM_uint32 gss_inquire_context ( context_handle->target, targ_name); if (ret) - return ret; + goto failed; } - if (lifetime_rec) - *lifetime_rec = context_handle->lifetime; + if (lifetime_rec) { + ret = gssapi_lifetime_left(minor_status, + context_handle->lifetime, + lifetime_rec); + if (ret) + goto failed; + } if (mech_type) *mech_type = GSS_KRB5_MECHANISM; @@ -81,5 +88,10 @@ OM_uint32 gss_inquire_context ( *open_context = context_handle->more_flags & OPEN; *minor_status = 0; - return GSS_S_COMPLETE; + ret = GSS_S_COMPLETE; + + failed: + + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + return ret; } diff --git a/lib/gssapi/inquire_cred.c b/lib/gssapi/inquire_cred.c index 2e873f275..a098755d6 100644 --- a/lib/gssapi/inquire_cred.c +++ b/lib/gssapi/inquire_cred.c @@ -57,26 +57,40 @@ OM_uint32 gss_inquire_cred return GSS_S_FAILURE; } + HEIMDAL_MUTEX_lock(&cred_handle->cred_id_mutex); + if (name != NULL) { if (cred_handle->principal != NULL) { ret = gss_duplicate_name(minor_status, cred_handle->principal, name); - if (ret) + if (ret) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return ret; + } } else if (cred_handle->usage == GSS_C_ACCEPT) { *minor_status = krb5_sname_to_principal(gssapi_krb5_context, NULL, NULL, KRB5_NT_SRV_HST, name); - if (*minor_status) + if (*minor_status) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return GSS_S_FAILURE; + } } else { *minor_status = krb5_get_default_principal(gssapi_krb5_context, name); - if (*minor_status) + if (*minor_status) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return GSS_S_FAILURE; + } } } if (lifetime != NULL) { - *lifetime = cred_handle->lifetime; + ret = gssapi_lifetime_left(minor_status, + cred_handle->lifetime, + lifetime); + if (ret) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); + return ret; + } } if (cred_usage != NULL) { *cred_usage = cred_handle->usage; @@ -84,14 +98,17 @@ OM_uint32 gss_inquire_cred if (mechanisms != NULL) { ret = gss_create_empty_oid_set(minor_status, mechanisms); if (ret) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return ret; } ret = gss_add_oid_set_member(minor_status, &cred_handle->mechanisms->elements[0], mechanisms); if (ret) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return ret; } } + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return GSS_S_COMPLETE; } diff --git a/lib/gssapi/inquire_cred_by_mech.c b/lib/gssapi/inquire_cred_by_mech.c index e09a54e87..9d0dfae61 100644 --- a/lib/gssapi/inquire_cred_by_mech.c +++ b/lib/gssapi/inquire_cred_by_mech.c @@ -64,7 +64,9 @@ OM_uint32 gss_inquire_cred_by_mech ( if (ret == 0 && cred_handle != GSS_C_NO_CREDENTIAL) { gss_cred_usage_t usage; + HEIMDAL_MUTEX_lock(&cred_handle->cred_id_mutex); usage = cred_handle->usage; + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); if (initiator_lifetime) { if (usage == GSS_C_INITIATE || usage == GSS_C_BOTH) diff --git a/lib/gssapi/krb5/ChangeLog b/lib/gssapi/krb5/ChangeLog index b5679ceef..31c303581 100644 --- a/lib/gssapi/krb5/ChangeLog +++ b/lib/gssapi/krb5/ChangeLog @@ -1,3 +1,8 @@ +2003-05-21 Love Hörnquist Åstrand + + * gss_acquire_cred.3: document argument lifetime_rec to function + gss_inquire_context + 2003-05-17 Love Hörnquist Åstrand * test_acquire_cred.c: test gss_add_cred more then once diff --git a/lib/gssapi/krb5/accept_sec_context.c b/lib/gssapi/krb5/accept_sec_context.c index 4b55acb21..0a35c4af8 100644 --- a/lib/gssapi/krb5/accept_sec_context.c +++ b/lib/gssapi/krb5/accept_sec_context.c @@ -35,6 +35,7 @@ RCSID("$Id$"); +HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER; krb5_keytab gssapi_krb5_keytab; OM_uint32 @@ -47,15 +48,20 @@ gsskrb5_register_acceptor_identity (const char *identity) if(ret) return GSS_S_FAILURE; + HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); + if(gssapi_krb5_keytab != NULL) { krb5_kt_close(gssapi_krb5_context, gssapi_krb5_keytab); gssapi_krb5_keytab = NULL; } asprintf(&p, "FILE:%s", identity); - if(p == NULL) + if(p == NULL) { + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); return GSS_S_FAILURE; + } ret = krb5_kt_resolve(gssapi_krb5_context, p, &gssapi_krb5_keytab); free(p); + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); if(ret) return GSS_S_FAILURE; return GSS_S_COMPLETE; @@ -105,6 +111,7 @@ gss_accept_sec_context } } + HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex); (*context_handle)->auth_context = NULL; (*context_handle)->source = NULL; (*context_handle)->target = NULL; @@ -208,6 +215,8 @@ gss_accept_sec_context if (ret) goto failure; + HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); + if (acceptor_cred_handle == GSS_C_NO_CREDENTIAL) { if (gssapi_krb5_keytab != NULL) { keytab = gssapi_krb5_keytab; @@ -224,6 +233,9 @@ gss_accept_sec_context keytab, &ap_options, &ticket); + + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); + if (kret) { ret = GSS_S_FAILURE; *minor_status = kret; @@ -421,6 +433,7 @@ gss_accept_sec_context if((*context_handle)->target) krb5_free_principal (gssapi_krb5_context, (*context_handle)->target); + HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); free (*context_handle); if (src_name != NULL) { gss_release_name (&minor, src_name); diff --git a/lib/gssapi/krb5/acquire_cred.c b/lib/gssapi/krb5/acquire_cred.c index e8c28f6d3..06fdc4b7d 100644 --- a/lib/gssapi/krb5/acquire_cred.c +++ b/lib/gssapi/krb5/acquire_cred.c @@ -41,6 +41,8 @@ get_keytab(krb5_keytab *keytab) char kt_name[256]; krb5_error_code kret; + HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex); + if (gssapi_krb5_keytab != NULL) { kret = krb5_kt_get_name(gssapi_krb5_context, gssapi_krb5_keytab, @@ -49,6 +51,9 @@ get_keytab(krb5_keytab *keytab) kret = krb5_kt_resolve(gssapi_krb5_context, kt_name, keytab); } else kret = krb5_kt_default(gssapi_krb5_context, keytab); + + HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex); + return (kret); } @@ -253,11 +258,13 @@ OM_uint32 gss_acquire_cred } memset(handle, 0, sizeof (*handle)); + HEIMDAL_MUTEX_init(&handle->cred_id_mutex); if (desired_name != GSS_C_NO_NAME) { ret = gss_duplicate_name(minor_status, desired_name, &handle->principal); if (ret != GSS_S_COMPLETE) { + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); return (ret); } @@ -266,6 +273,7 @@ OM_uint32 gss_acquire_cred ret = acquire_initiator_cred(minor_status, desired_name, time_req, desired_mechs, cred_usage, handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); return (ret); } @@ -273,10 +281,12 @@ OM_uint32 gss_acquire_cred ret = acquire_acceptor_cred(minor_status, desired_name, time_req, desired_mechs, cred_usage, handle, actual_mechs, time_rec); if (ret != GSS_S_COMPLETE) { + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); return (ret); } } else { + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); *minor_status = GSS_KRB5_S_G_BAD_USAGE; return GSS_S_FAILURE; @@ -291,6 +301,7 @@ OM_uint32 gss_acquire_cred if (ret != GSS_S_COMPLETE) { if (handle->mechanisms != NULL) gss_release_oid_set(NULL, &handle->mechanisms); + HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); return (ret); } diff --git a/lib/gssapi/krb5/add_cred.c b/lib/gssapi/krb5/add_cred.c index b207415c2..b7dcb4dfa 100644 --- a/lib/gssapi/krb5/add_cred.c +++ b/lib/gssapi/krb5/add_cred.c @@ -65,16 +65,21 @@ OM_uint32 gss_add_cred ( } /* check if requested output usage is compatible with output usage */ - if (output_cred_handle != NULL && - (cred->usage != cred_usage && cred->usage != GSS_C_BOTH)) { - *minor_status = GSS_KRB5_S_G_BAD_USAGE; - return(GSS_S_FAILURE); + if (output_cred_handle != NULL) { + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); + if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = GSS_KRB5_S_G_BAD_USAGE; + return(GSS_S_FAILURE); + } } /* check that we have the same name */ if (desired_name != GSS_C_NO_NAME && krb5_principal_compare(gssapi_krb5_context, desired_name, cred->principal) != FALSE) { + if (output_cred_handle) + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); *minor_status = 0; return GSS_S_BAD_NAME; } @@ -84,6 +89,7 @@ OM_uint32 gss_add_cred ( handle = (gss_cred_id_t)malloc(sizeof(*handle)); if (handle == GSS_C_NO_CREDENTIAL) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); *minor_status = ENOMEM; return (GSS_S_FAILURE); } @@ -96,12 +102,14 @@ OM_uint32 gss_add_cred ( handle->keytab = NULL; handle->ccache = NULL; handle->mechanisms = NULL; + HEIMDAL_MUTEX_init(&handle->cred_id_mutex); ret = GSS_S_FAILURE; ret = gss_duplicate_name(minor_status, cred->principal, &handle->principal); if (ret) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); free(handle); *minor_status = ENOMEM; return GSS_S_FAILURE; @@ -193,8 +201,10 @@ OM_uint32 gss_add_cred ( if (acceptor_time_rec) *acceptor_time_rec = lifetime; - if (output_cred_handle) + if (output_cred_handle) { *output_cred_handle = handle; + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + } *minor_status = 0; return ret; @@ -212,5 +222,7 @@ OM_uint32 gss_add_cred ( gss_release_oid_set(NULL, &handle->mechanisms); free(handle); } + if (output_cred_handle) + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); return ret; } diff --git a/lib/gssapi/krb5/compat.c b/lib/gssapi/krb5/compat.c index 49d926f9d..f9de5f4ef 100644 --- a/lib/gssapi/krb5/compat.c +++ b/lib/gssapi/krb5/compat.c @@ -83,12 +83,16 @@ _gss_DES3_get_mic_compat(OM_uint32 *minor_status, gss_ctx_id_t ctx) if ((ctx->more_flags & COMPAT_OLD_DES3_SELECTED) == 0) { ret = check_compat(minor_status, ctx->target, "broken_des3_mic", &use_compat, TRUE); - if (ret) + if (ret) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return ret; + } ret = check_compat(minor_status, ctx->target, "correct_des3_mic", &use_compat, FALSE); - if (ret) + if (ret) { + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return ret; + } if (use_compat) ctx->more_flags |= COMPAT_OLD_DES3; @@ -102,12 +106,14 @@ gss_krb5_compat_des3_mic(OM_uint32 *minor_status, gss_ctx_id_t ctx, int on) { *minor_status = 0; + HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); if (on) { ctx->more_flags |= COMPAT_OLD_DES3; } else { ctx->more_flags &= ~COMPAT_OLD_DES3; } ctx->more_flags |= COMPAT_OLD_DES3_SELECTED; + HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); return 0; } diff --git a/lib/gssapi/krb5/context_time.c b/lib/gssapi/krb5/context_time.c index 36c6e8ff3..2d196f2b3 100644 --- a/lib/gssapi/krb5/context_time.c +++ b/lib/gssapi/krb5/context_time.c @@ -35,31 +35,54 @@ RCSID("$Id$"); +OM_uint32 +gssapi_lifetime_left(OM_uint32 *minor_status, + OM_uint32 lifetime, + OM_uint32 *lifetime_rec) +{ + krb5_timestamp timeret; + krb5_error_code kret; + + kret = krb5_timeofday(gssapi_krb5_context, &timeret); + if (kret) { + *minor_status = kret; + gssapi_krb5_set_error_string (); + return GSS_S_FAILURE; + } + + if (lifetime < timeret) + *lifetime_rec = 0; + else + *lifetime_rec = lifetime - timeret; + + return GSS_S_COMPLETE; +} + + OM_uint32 gss_context_time (OM_uint32 * minor_status, const gss_ctx_id_t context_handle, OM_uint32 * time_rec ) { - krb5_error_code kret; krb5_timestamp timeret; + OM_uint32 lifetime; + OM_uint32 major_status; GSSAPI_KRB5_INIT (); - kret = krb5_timeofday(gssapi_krb5_context, &timeret); - if (kret) { - *minor_status = kret; - gssapi_krb5_set_error_string (); - return GSS_S_FAILURE; - } + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + lifetime = context_handle->lifetime; + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + + major_status = gssapi_lifetime_left(minor_status, lifetime, time_rec); + if (major_status != GSS_S_COMPLETE) + return major_status; *minor_status = 0; - if (context_handle->lifetime < timeret) { - *time_rec = 0; + if (*time_rec == 0) return GSS_S_CONTEXT_EXPIRED; - } - - *time_rec = context_handle->lifetime - timeret; + return GSS_S_COMPLETE; } diff --git a/lib/gssapi/krb5/copy_ccache.c b/lib/gssapi/krb5/copy_ccache.c index 15d2e1c54..b8938acb3 100644 --- a/lib/gssapi/krb5/copy_ccache.c +++ b/lib/gssapi/krb5/copy_ccache.c @@ -42,12 +42,16 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status, { krb5_error_code kret; + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); + if (cred->ccache == NULL) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); *minor_status = EINVAL; return GSS_S_FAILURE; } kret = krb5_cc_copy_cache(gssapi_krb5_context, cred->ccache, out); + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); if (kret) { *minor_status = kret; gssapi_krb5_set_error_string (); diff --git a/lib/gssapi/krb5/delete_sec_context.c b/lib/gssapi/krb5/delete_sec_context.c index 4c609b3fc..0d2143955 100644 --- a/lib/gssapi/krb5/delete_sec_context.c +++ b/lib/gssapi/krb5/delete_sec_context.c @@ -48,6 +48,8 @@ OM_uint32 gss_delete_sec_context output_token->value = NULL; } + HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex); + krb5_auth_con_free (gssapi_krb5_context, (*context_handle)->auth_context); if((*context_handle)->source) @@ -62,6 +64,9 @@ OM_uint32 gss_delete_sec_context free((*context_handle)->ticket); } + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); + HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); + memset(*context_handle, 0, sizeof(**context_handle)); free (*context_handle); *context_handle = GSS_C_NO_CONTEXT; *minor_status = 0; diff --git a/lib/gssapi/krb5/export_sec_context.c b/lib/gssapi/krb5/export_sec_context.c index 8ec622377..f90b75cd9 100644 --- a/lib/gssapi/krb5/export_sec_context.c +++ b/lib/gssapi/krb5/export_sec_context.c @@ -52,13 +52,18 @@ gss_export_sec_context ( krb5_error_code kret; GSSAPI_KRB5_INIT (); + + HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex); + if (!((*context_handle)->flags & GSS_C_TRANS_FLAG)) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); *minor_status = 0; return GSS_S_UNAVAILABLE; } sp = krb5_storage_emem (); if (sp == NULL) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); *minor_status = ENOMEM; return GSS_S_FAILURE; } @@ -206,11 +211,13 @@ gss_export_sec_context ( kret = krb5_storage_to_data (sp, &data); krb5_storage_free (sp); if (kret) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); *minor_status = kret; return GSS_S_FAILURE; } interprocess_token->length = data.length; interprocess_token->value = data.data; + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); ret = gss_delete_sec_context (minor_status, context_handle, GSS_C_NO_BUFFER); if (ret != GSS_S_COMPLETE) @@ -218,6 +225,7 @@ gss_export_sec_context ( *minor_status = 0; return ret; failure: + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); krb5_storage_free (sp); return ret; } diff --git a/lib/gssapi/krb5/get_mic.c b/lib/gssapi/krb5/get_mic.c index bdf935e65..43ccd06ac 100644 --- a/lib/gssapi/krb5/get_mic.c +++ b/lib/gssapi/krb5/get_mic.c @@ -90,6 +90,7 @@ mic_des schedule, &zero); memcpy (p - 8, hash, 8); /* SGN_CKSUM */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); /* sequence number */ krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, @@ -111,6 +112,7 @@ mic_des krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); memset (deskey, 0, sizeof(deskey)); memset (schedule, 0, sizeof(schedule)); @@ -199,6 +201,7 @@ mic_des3 memcpy (p + 8, cksum.checksum.data, cksum.checksum.length); + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); /* sequence number */ krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, @@ -246,6 +249,7 @@ mic_des3 krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); free_Checksum (&cksum); *minor_status = 0; diff --git a/lib/gssapi/krb5/gssapi.h b/lib/gssapi/krb5/gssapi.h index 493565163..60f36121a 100644 --- a/lib/gssapi/krb5/gssapi.h +++ b/lib/gssapi/krb5/gssapi.h @@ -63,17 +63,8 @@ struct Principal; typedef struct Principal *gss_name_t; -typedef struct gss_ctx_id_t_desc_struct { - struct krb5_auth_context_data *auth_context; - gss_name_t source, target; - OM_uint32 flags; - enum { LOCAL = 1, OPEN = 2, - COMPAT_OLD_DES3 = 4, COMPAT_OLD_DES3_SELECTED = 8 } more_flags; - struct krb5_ticket *ticket; - time_t lifetime; -} gss_ctx_id_t_desc; - -typedef gss_ctx_id_t_desc *gss_ctx_id_t; +struct gss_ctx_id_t_desc_struct; +typedef struct gss_ctx_id_t_desc_struct *gss_ctx_id_t; typedef struct gss_OID_desc_struct { OM_uint32 length; @@ -91,16 +82,8 @@ struct krb5_ccache_data; typedef int gss_cred_usage_t; -typedef struct gss_cred_id_t_desc_struct { - gss_name_t principal; - struct krb5_keytab_data *keytab; - OM_uint32 lifetime; - gss_cred_usage_t usage; - gss_OID_set mechanisms; - struct krb5_ccache_data *ccache; -} gss_cred_id_t_desc; - -typedef gss_cred_id_t_desc *gss_cred_id_t; +struct gss_cred_id_t_desc_struct; +typedef struct gss_cred_id_t_desc_struct *gss_cred_id_t; typedef struct gss_buffer_desc_struct { size_t length; diff --git a/lib/gssapi/krb5/gssapi_locl.h b/lib/gssapi/krb5/gssapi_locl.h index 3cf709618..4a7056302 100644 --- a/lib/gssapi/krb5/gssapi_locl.h +++ b/lib/gssapi/krb5/gssapi_locl.h @@ -44,9 +44,43 @@ #include #include +/* + * + */ + +typedef struct gss_ctx_id_t_desc_struct { + struct krb5_auth_context_data *auth_context; + gss_name_t source, target; + OM_uint32 flags; + enum { LOCAL = 1, OPEN = 2, + COMPAT_OLD_DES3 = 4, COMPAT_OLD_DES3_SELECTED = 8 } more_flags; + struct krb5_ticket *ticket; + time_t lifetime; + HEIMDAL_MUTEX ctx_id_mutex; +} gss_ctx_id_t_desc; + +typedef struct gss_cred_id_t_desc_struct { + gss_name_t principal; + struct krb5_keytab_data *keytab; + OM_uint32 lifetime; + gss_cred_usage_t usage; + gss_OID_set mechanisms; + struct krb5_ccache_data *ccache; + HEIMDAL_MUTEX cred_id_mutex; +} gss_cred_id_t_desc; + +/* + * + */ + extern krb5_context gssapi_krb5_context; extern krb5_keytab gssapi_krb5_keytab; +extern HEIMDAL_MUTEX gssapi_keytab_mutex; + +/* + * Prototypes + */ krb5_error_code gssapi_krb5_init (void); @@ -145,4 +179,7 @@ gssapi_krb5_get_error_string (void); OM_uint32 _gss_DES3_get_mic_compat(OM_uint32 *minor_status, gss_ctx_id_t ctx); +OM_uint32 +gssapi_lifetime_left(OM_uint32 *, OM_uint32, OM_uint32 *); + #endif diff --git a/lib/gssapi/krb5/import_sec_context.c b/lib/gssapi/krb5/import_sec_context.c index f309b4b06..f2a0e8ce8 100644 --- a/lib/gssapi/krb5/import_sec_context.c +++ b/lib/gssapi/krb5/import_sec_context.c @@ -73,6 +73,7 @@ gss_import_sec_context ( return GSS_S_FAILURE; } memset (*context_handle, 0, sizeof(**context_handle)); + HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex); kret = krb5_auth_con_init (gssapi_krb5_context, &(*context_handle)->auth_context); @@ -206,6 +207,7 @@ failure: krb5_free_address (gssapi_krb5_context, localp); if (remotep) krb5_free_address (gssapi_krb5_context, remotep); + HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); free (*context_handle); *context_handle = GSS_C_NO_CONTEXT; return ret; diff --git a/lib/gssapi/krb5/init_sec_context.c b/lib/gssapi/krb5/init_sec_context.c index efd5ae9c4..b4300757f 100644 --- a/lib/gssapi/krb5/init_sec_context.c +++ b/lib/gssapi/krb5/init_sec_context.c @@ -212,6 +212,7 @@ init_auth (*context_handle)->more_flags = 0; (*context_handle)->ticket = NULL; (*context_handle)->lifetime = GSS_C_INDEFINITE; + HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex); kret = krb5_auth_con_init (gssapi_krb5_context, &(*context_handle)->auth_context); @@ -428,6 +429,7 @@ init_auth if((*context_handle)->target) krb5_free_principal (gssapi_krb5_context, (*context_handle)->target); + HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex); free (*context_handle); krb5_data_free (&outbuf); *context_handle = GSS_C_NO_CONTEXT; @@ -459,20 +461,25 @@ repl_mutual output_token->length = 0; output_token->value = NULL; + HEIMDAL_MUTEX_lock(&(*context_handle)->ctx_id_mutex); + if (actual_mech_type) *actual_mech_type = GSS_KRB5_MECHANISM; ret = gssapi_krb5_decapsulate (minor_status, input_token, &indata, "\x02\x00"); - if (ret) - /* XXX - Handle AP_ERROR */ + if (ret) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); + /* XXX - Handle AP_ERROR */ return ret; + } kret = krb5_rd_rep (gssapi_krb5_context, (*context_handle)->auth_context, &indata, &repl); if (kret) { + HEIMDAL_MUTEX_unlock(&(*context_handle)->ctx_id_mutex); gssapi_krb5_set_error_string (); *minor_status = kret; return GSS_S_FAILURE; diff --git a/lib/gssapi/krb5/inquire_context.c b/lib/gssapi/krb5/inquire_context.c index fbab36920..4fddfd379 100644 --- a/lib/gssapi/krb5/inquire_context.c +++ b/lib/gssapi/krb5/inquire_context.c @@ -49,12 +49,14 @@ OM_uint32 gss_inquire_context ( { OM_uint32 ret; + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); + if (src_name) { ret = gss_duplicate_name (minor_status, context_handle->source, src_name); if (ret) - return ret; + goto failed; } if (targ_name) { @@ -62,11 +64,16 @@ OM_uint32 gss_inquire_context ( context_handle->target, targ_name); if (ret) - return ret; + goto failed; } - if (lifetime_rec) - *lifetime_rec = context_handle->lifetime; + if (lifetime_rec) { + ret = gssapi_lifetime_left(minor_status, + context_handle->lifetime, + lifetime_rec); + if (ret) + goto failed; + } if (mech_type) *mech_type = GSS_KRB5_MECHANISM; @@ -81,5 +88,10 @@ OM_uint32 gss_inquire_context ( *open_context = context_handle->more_flags & OPEN; *minor_status = 0; - return GSS_S_COMPLETE; + ret = GSS_S_COMPLETE; + + failed: + + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); + return ret; } diff --git a/lib/gssapi/krb5/inquire_cred.c b/lib/gssapi/krb5/inquire_cred.c index 2e873f275..a098755d6 100644 --- a/lib/gssapi/krb5/inquire_cred.c +++ b/lib/gssapi/krb5/inquire_cred.c @@ -57,26 +57,40 @@ OM_uint32 gss_inquire_cred return GSS_S_FAILURE; } + HEIMDAL_MUTEX_lock(&cred_handle->cred_id_mutex); + if (name != NULL) { if (cred_handle->principal != NULL) { ret = gss_duplicate_name(minor_status, cred_handle->principal, name); - if (ret) + if (ret) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return ret; + } } else if (cred_handle->usage == GSS_C_ACCEPT) { *minor_status = krb5_sname_to_principal(gssapi_krb5_context, NULL, NULL, KRB5_NT_SRV_HST, name); - if (*minor_status) + if (*minor_status) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return GSS_S_FAILURE; + } } else { *minor_status = krb5_get_default_principal(gssapi_krb5_context, name); - if (*minor_status) + if (*minor_status) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return GSS_S_FAILURE; + } } } if (lifetime != NULL) { - *lifetime = cred_handle->lifetime; + ret = gssapi_lifetime_left(minor_status, + cred_handle->lifetime, + lifetime); + if (ret) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); + return ret; + } } if (cred_usage != NULL) { *cred_usage = cred_handle->usage; @@ -84,14 +98,17 @@ OM_uint32 gss_inquire_cred if (mechanisms != NULL) { ret = gss_create_empty_oid_set(minor_status, mechanisms); if (ret) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return ret; } ret = gss_add_oid_set_member(minor_status, &cred_handle->mechanisms->elements[0], mechanisms); if (ret) { + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return ret; } } + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); return GSS_S_COMPLETE; } diff --git a/lib/gssapi/krb5/inquire_cred_by_mech.c b/lib/gssapi/krb5/inquire_cred_by_mech.c index e09a54e87..9d0dfae61 100644 --- a/lib/gssapi/krb5/inquire_cred_by_mech.c +++ b/lib/gssapi/krb5/inquire_cred_by_mech.c @@ -64,7 +64,9 @@ OM_uint32 gss_inquire_cred_by_mech ( if (ret == 0 && cred_handle != GSS_C_NO_CREDENTIAL) { gss_cred_usage_t usage; + HEIMDAL_MUTEX_lock(&cred_handle->cred_id_mutex); usage = cred_handle->usage; + HEIMDAL_MUTEX_unlock(&cred_handle->cred_id_mutex); if (initiator_lifetime) { if (usage == GSS_C_INITIATE || usage == GSS_C_BOTH) diff --git a/lib/gssapi/krb5/release_cred.c b/lib/gssapi/krb5/release_cred.c index 00be94ae0..f5b3a7f64 100644 --- a/lib/gssapi/krb5/release_cred.c +++ b/lib/gssapi/krb5/release_cred.c @@ -48,6 +48,8 @@ OM_uint32 gss_release_cred GSSAPI_KRB5_INIT (); + HEIMDAL_MUTEX_lock(&(*cred_handle)->cred_id_mutex); + if ((*cred_handle)->principal != NULL) krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal); if ((*cred_handle)->keytab != NULL) @@ -55,6 +57,9 @@ OM_uint32 gss_release_cred if ((*cred_handle)->ccache != NULL) krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache); gss_release_oid_set(NULL, &(*cred_handle)->mechanisms); + HEIMDAL_MUTEX_unlock(&(*cred_handle)->cred_id_mutex); + HEIMDAL_MUTEX_destroy(&(*cred_handle)->cred_id_mutex); + memset(*cred_handle, 0, sizeof(**cred_handle)); free(*cred_handle); *cred_handle = GSS_C_NO_CREDENTIAL; return GSS_S_COMPLETE; diff --git a/lib/gssapi/krb5/unwrap.c b/lib/gssapi/krb5/unwrap.c index 2e66f30eb..daccaefc6 100644 --- a/lib/gssapi/krb5/unwrap.c +++ b/lib/gssapi/krb5/unwrap.c @@ -41,6 +41,7 @@ gss_krb5_get_remotekey(const gss_ctx_id_t context_handle, { krb5_keyblock *skey; + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getremotesubkey(gssapi_krb5_context, context_handle->auth_context, &skey); @@ -52,6 +53,7 @@ gss_krb5_get_remotekey(const gss_ctx_id_t context_handle, krb5_auth_con_getkey(gssapi_krb5_context, context_handle->auth_context, &skey); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if(skey == NULL) return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */ *key = skey; @@ -151,6 +153,7 @@ unwrap_des /* verify sequence number */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_getremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -177,6 +180,7 @@ unwrap_des krb5_auth_con_setremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); /* copy out data */ @@ -278,6 +282,7 @@ unwrap_des3 /* verify sequence number */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_getremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -328,6 +333,7 @@ unwrap_des3 krb5_auth_con_setremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); /* verify checksum */ diff --git a/lib/gssapi/krb5/verify_mic.c b/lib/gssapi/krb5/verify_mic.c index 6e001de71..929462a49 100644 --- a/lib/gssapi/krb5/verify_mic.c +++ b/lib/gssapi/krb5/verify_mic.c @@ -94,6 +94,7 @@ verify_mic_des /* verify sequence number */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_getremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -121,6 +122,7 @@ verify_mic_des krb5_auth_con_setremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); *minor_status = 0; return GSS_S_COMPLETE; @@ -203,6 +205,7 @@ retry: goto retry; } + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_getremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -254,6 +257,7 @@ retry: krb5_auth_con_setremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); krb5_crypto_destroy (gssapi_krb5_context, crypto); *minor_status = 0; diff --git a/lib/gssapi/krb5/wrap.c b/lib/gssapi/krb5/wrap.c index 033a6d8bf..8c4087b18 100644 --- a/lib/gssapi/krb5/wrap.c +++ b/lib/gssapi/krb5/wrap.c @@ -41,6 +41,7 @@ gss_krb5_get_localkey(const gss_ctx_id_t context_handle, { krb5_keyblock *skey; + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getlocalsubkey(gssapi_krb5_context, context_handle->auth_context, &skey); @@ -52,6 +53,7 @@ gss_krb5_get_localkey(const gss_ctx_id_t context_handle, krb5_auth_con_getkey(gssapi_krb5_context, context_handle->auth_context, &skey); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if(skey == NULL) return GSS_S_FAILURE; *key = skey; @@ -188,6 +190,7 @@ wrap_des memcpy (p - 8, hash, 8); /* sequence number */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -208,6 +211,7 @@ wrap_des krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); /* encrypt the data */ p += 16; @@ -322,6 +326,7 @@ wrap_des3 memcpy (p + 8, cksum.checksum.data, cksum.checksum.length); free_Checksum (&cksum); + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); /* sequence number */ krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, @@ -370,6 +375,7 @@ wrap_des3 krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); /* encrypt the data */ p += 28; diff --git a/lib/gssapi/release_cred.c b/lib/gssapi/release_cred.c index 00be94ae0..f5b3a7f64 100644 --- a/lib/gssapi/release_cred.c +++ b/lib/gssapi/release_cred.c @@ -48,6 +48,8 @@ OM_uint32 gss_release_cred GSSAPI_KRB5_INIT (); + HEIMDAL_MUTEX_lock(&(*cred_handle)->cred_id_mutex); + if ((*cred_handle)->principal != NULL) krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal); if ((*cred_handle)->keytab != NULL) @@ -55,6 +57,9 @@ OM_uint32 gss_release_cred if ((*cred_handle)->ccache != NULL) krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache); gss_release_oid_set(NULL, &(*cred_handle)->mechanisms); + HEIMDAL_MUTEX_unlock(&(*cred_handle)->cred_id_mutex); + HEIMDAL_MUTEX_destroy(&(*cred_handle)->cred_id_mutex); + memset(*cred_handle, 0, sizeof(**cred_handle)); free(*cred_handle); *cred_handle = GSS_C_NO_CREDENTIAL; return GSS_S_COMPLETE; diff --git a/lib/gssapi/unwrap.c b/lib/gssapi/unwrap.c index 2e66f30eb..daccaefc6 100644 --- a/lib/gssapi/unwrap.c +++ b/lib/gssapi/unwrap.c @@ -41,6 +41,7 @@ gss_krb5_get_remotekey(const gss_ctx_id_t context_handle, { krb5_keyblock *skey; + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getremotesubkey(gssapi_krb5_context, context_handle->auth_context, &skey); @@ -52,6 +53,7 @@ gss_krb5_get_remotekey(const gss_ctx_id_t context_handle, krb5_auth_con_getkey(gssapi_krb5_context, context_handle->auth_context, &skey); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if(skey == NULL) return GSS_KRB5_S_KG_NO_SUBKEY; /* XXX */ *key = skey; @@ -151,6 +153,7 @@ unwrap_des /* verify sequence number */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_getremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -177,6 +180,7 @@ unwrap_des krb5_auth_con_setremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); /* copy out data */ @@ -278,6 +282,7 @@ unwrap_des3 /* verify sequence number */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_getremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -328,6 +333,7 @@ unwrap_des3 krb5_auth_con_setremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); /* verify checksum */ diff --git a/lib/gssapi/verify_mic.c b/lib/gssapi/verify_mic.c index 6e001de71..929462a49 100644 --- a/lib/gssapi/verify_mic.c +++ b/lib/gssapi/verify_mic.c @@ -94,6 +94,7 @@ verify_mic_des /* verify sequence number */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_getremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -121,6 +122,7 @@ verify_mic_des krb5_auth_con_setremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); *minor_status = 0; return GSS_S_COMPLETE; @@ -203,6 +205,7 @@ retry: goto retry; } + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_getremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -254,6 +257,7 @@ retry: krb5_auth_con_setremoteseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); krb5_crypto_destroy (gssapi_krb5_context, crypto); *minor_status = 0; diff --git a/lib/gssapi/wrap.c b/lib/gssapi/wrap.c index 033a6d8bf..8c4087b18 100644 --- a/lib/gssapi/wrap.c +++ b/lib/gssapi/wrap.c @@ -41,6 +41,7 @@ gss_krb5_get_localkey(const gss_ctx_id_t context_handle, { krb5_keyblock *skey; + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getlocalsubkey(gssapi_krb5_context, context_handle->auth_context, &skey); @@ -52,6 +53,7 @@ gss_krb5_get_localkey(const gss_ctx_id_t context_handle, krb5_auth_con_getkey(gssapi_krb5_context, context_handle->auth_context, &skey); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); if(skey == NULL) return GSS_S_FAILURE; *key = skey; @@ -188,6 +190,7 @@ wrap_des memcpy (p - 8, hash, 8); /* sequence number */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, &seq_number); @@ -208,6 +211,7 @@ wrap_des krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); /* encrypt the data */ p += 16; @@ -322,6 +326,7 @@ wrap_des3 memcpy (p + 8, cksum.checksum.data, cksum.checksum.length); free_Checksum (&cksum); + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); /* sequence number */ krb5_auth_con_getlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, @@ -370,6 +375,7 @@ wrap_des3 krb5_auth_con_setlocalseqnumber (gssapi_krb5_context, context_handle->auth_context, ++seq_number); + HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); /* encrypt the data */ p += 28;