From 5d3c7091d401b0a562131dee8fa210d416b441df Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 26 Dec 2013 19:05:34 -0500 Subject: Add way to specify rcache when acquiring creds The "rcache" URN can specify a cache type and name to be used with the credentials being acquired. Signed-off-by: Simo Sorce --- src/lib/gssapi/krb5/acquire_cred.c | 60 +++++++++++++++++++++++++++++++------- src/lib/gssapi/krb5/gssapiP_krb5.h | 1 + 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 9547207b1..92beb4317 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -182,6 +182,7 @@ static OM_uint32 acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, krb5_keytab req_keytab, + char *rcache_name, krb5_gss_cred_id_rec *cred) { krb5_error_code code; @@ -206,6 +207,24 @@ acquire_accept_cred(krb5_context context, return GSS_S_CRED_UNAVAIL; } + /* Open an explicitly requested rcache. */ + if (rcache_name != NULL) { + code = krb5_rc_resolve_full(context, &cred->rcache, rcache_name); + if (code) { + krb5_kt_close(context, kt); + *minor_status = code; + return GSS_S_FAILURE; + } + code = krb5_rc_recover_or_initialize(context, cred->rcache, + context->clockskew); + if (code) { + krb5_rc_close(context, cred->rcache); + krb5_kt_close(context, kt); + *minor_status = code; + return GSS_S_FAILURE; + } + } + if (cred->name != NULL) { /* Make sure we keys matching the desired name in the keytab. */ code = check_keytab(context, kt, cred->name); @@ -222,12 +241,14 @@ acquire_accept_cred(krb5_context context, } /* Open the replay cache for this principal. */ - code = krb5_get_server_rcache(context, &cred->name->princ->data[0], - &cred->rcache); - if (code) { - krb5_kt_close(context, kt); - *minor_status = code; - return GSS_S_FAILURE; + if (rcache_name == NULL) { + code = krb5_get_server_rcache(context, &cred->name->princ->data[0], + &cred->rcache); + if (code) { + krb5_kt_close(context, kt); + *minor_status = code; + return GSS_S_FAILURE; + } } } else { /* Make sure we have a keytab with keys in it. */ @@ -711,7 +732,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, OM_uint32 time_req, gss_cred_usage_t cred_usage, krb5_ccache ccache, krb5_keytab client_keytab, krb5_keytab keytab, krb5_boolean iakerb, - gss_cred_id_t *output_cred_handle, + char *rcache, gss_cred_id_t *output_cred_handle, OM_uint32 *time_rec) { krb5_gss_cred_id_t cred = NULL; @@ -739,6 +760,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, #endif /* LEAN_CLIENT */ cred->destroy_ccache = 0; cred->ccache = NULL; + cred->rcache = NULL; code = k5_mutex_init(&cred->lock); if (code) @@ -767,7 +789,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, * in cred->name if desired_princ is specified. */ if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) { - ret = acquire_accept_cred(context, minor_status, keytab, cred); + ret = acquire_accept_cred(context, minor_status, keytab, rcache, cred); if (ret != GSS_S_COMPLETE) goto error_out; } @@ -815,6 +837,8 @@ error_out: if (cred != NULL) { if (cred->ccache) krb5_cc_close(context, cred->ccache); + if (cred->rcache) + krb5_rc_close(context, cred->rcache); if (cred->client_keytab) krb5_kt_close(context, cred->client_keytab); #ifndef LEAN_CLIENT @@ -857,7 +881,7 @@ acquire_cred(OM_uint32 *minor_status, gss_name_t desired_name, ret = acquire_cred_context(context, minor_status, desired_name, password, time_req, cred_usage, ccache, NULL, keytab, - iakerb, output_cred_handle, time_rec); + iakerb, NULL, output_cred_handle, time_rec); out: krb5_free_context(context); @@ -1125,6 +1149,7 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status, krb5_keytab client_keytab = NULL; krb5_keytab keytab = NULL; krb5_ccache ccache = NULL; + char *rcache = NULL; const char *value; OM_uint32 ret; @@ -1181,9 +1206,23 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status, } } + ret = kg_value_from_cred_store(cred_store, KRB5_CS_RCACHE_URN, &value); + if (GSS_ERROR(ret)) + goto out; + + if (value) { + rcache = strdup(value); + if (rcache == NULL) { + *minor_status = ENOMEM; + ret = GSS_S_CRED_UNAVAIL; + goto out; + } + } + ret = acquire_cred_context(context, minor_status, desired_name, NULL, time_req, cred_usage, ccache, client_keytab, - keytab, 0, output_cred_handle, time_rec); + keytab, 0, rcache, output_cred_handle, + time_rec); out: if (ccache != NULL) @@ -1192,6 +1231,7 @@ out: krb5_kt_close(context, client_keytab); if (keytab != NULL) krb5_kt_close(context, keytab); + free(rcache); krb5_free_context(context); return ret; } diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index 01678168f..8e4f6d947 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -1260,6 +1260,7 @@ data_to_gss(krb5_data *input_k5data, gss_buffer_t output_buffer) #define KRB5_CS_CLI_KEYTAB_URN "client_keytab" #define KRB5_CS_KEYTAB_URN "keytab" #define KRB5_CS_CCACHE_URN "ccache" +#define KRB5_CS_RCACHE_URN "rcache" OM_uint32 kg_value_from_cred_store(gss_const_key_value_set_t cred_store, -- cgit