diff options
author | Luke Howard <lukeh@padl.com> | 2009-08-21 22:52:37 +0000 |
---|---|---|
committer | Luke Howard <lukeh@padl.com> | 2009-08-21 22:52:37 +0000 |
commit | a849e618bf2d69a8dc5a4477d2d682bc3dca3b53 (patch) | |
tree | c597f9dbba2b9231d1e52f254b96498a5493eb9a | |
parent | 18959aecd70831a84263953b9f86df158bb11187 (diff) | |
download | krb5-a849e618bf2d69a8dc5a4477d2d682bc3dca3b53.zip krb5-a849e618bf2d69a8dc5a4477d2d682bc3dca3b53.tar.gz krb5-a849e618bf2d69a8dc5a4477d2d682bc3dca3b53.tar.bz2 |
Refactor to reduce duplicate code
krb5_gss_acquire_cred_impersonate_name() now returns proxy credentials,
so it is not necessary to call gss_acquire_cred_impersonate_cred()
before using them with gss_init_sec_context().
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/s4u@22573 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r-- | src/lib/gssapi/krb5/init_sec_context.c | 8 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/s4u_gss_glue.c | 275 |
2 files changed, 123 insertions, 160 deletions
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index b58d287..afaae1d 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -140,7 +140,13 @@ static krb5_error_code get_credentials(context, cred, server, now, if ((code = krb5_cc_get_principal(context, cred->ccache, &cc_princ))) goto cleanup; - if (cred->proxy_cred) { + /* + * Do constrained delegation if we have proxy credentials and + * we're not trying to get a ticket to ourselves (in which case + * we can just use the S4U2Self or evidence ticket directly). + */ + if (cred->proxy_cred && + !krb5_principal_compare(context, cc_princ, server)) { krb5_creds mcreds; flags |= KRB5_GC_CANONICALIZE | diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c index af66421..d177e9b 100644 --- a/src/lib/gssapi/krb5/s4u_gss_glue.c +++ b/src/lib/gssapi/krb5/s4u_gss_glue.c @@ -30,6 +30,21 @@ #endif #include <assert.h> +/* + * Create a GSS credential that can be used for S4U2Proxy. + */ +static OM_uint32 +kg_compose_proxy_cred(OM_uint32 *minor_status, + krb5_gss_cred_id_t impersonator_cred, + krb5_const_principal subject_name, + krb5_creds *subject_creds, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + krb5_gss_cred_id_t *output_cred, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec, + krb5_context context); + static OM_uint32 kg_set_desired_mechs(OM_uint32 *minor_status, const gss_OID_set desired_mechs, @@ -107,63 +122,24 @@ kg_is_initiator_cred(krb5_gss_cred_id_t cred) } static OM_uint32 -kg_impersonate(OM_uint32 *minor_status, - const krb5_gss_cred_id_t impersonator_cred, - const krb5_principal user, - OM_uint32 time_req, - const gss_OID_set desired_mechs, - krb5_gss_cred_id_t *output_cred, - gss_OID_set *actual_mechs, - OM_uint32 *time_rec, - krb5_context context) +kg_impersonate_name(OM_uint32 *minor_status, + const krb5_gss_cred_id_t impersonator_cred, + const krb5_principal user, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + krb5_gss_cred_id_t *output_cred, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec, + krb5_context context) { OM_uint32 major_status; krb5_error_code code; - krb5_gss_cred_id_t cred = NULL; krb5_creds in_creds, *out_creds = NULL; memset(&in_creds, 0, sizeof(in_creds)); memset(&out_creds, 0, sizeof(out_creds)); - k5_mutex_assert_locked(&impersonator_cred->lock); - - if (!kg_is_initiator_cred(impersonator_cred) || - impersonator_cred->ccache == NULL || - impersonator_cred->princ == NULL) { - *minor_status = (OM_uint32)G_BAD_USAGE; - major_status = GSS_S_FAILURE; - goto cleanup; - } - - cred = (krb5_gss_cred_id_t)xmalloc(sizeof(*cred)); - if (cred == NULL) { - *minor_status = ENOMEM; - major_status = GSS_S_FAILURE; - goto cleanup; - } - memset(cred, 0, sizeof(*cred)); - - code = k5_mutex_init(&cred->lock); - if (code != 0) { - *minor_status = code; - major_status = GSS_S_FAILURE; - goto cleanup; - } - - cred->usage = GSS_C_INITIATE; - - major_status = kg_set_desired_mechs(minor_status, desired_mechs, cred); - if (GSS_ERROR(major_status)) - goto cleanup; - - code = krb5_copy_principal(context, user, &cred->princ); - if (code != 0) { - *minor_status = code; - major_status = GSS_S_FAILURE; - goto cleanup; - } - - in_creds.client = cred->princ; + in_creds.client = user; in_creds.server = impersonator_cred->princ; if (impersonator_cred->req_enctypes != NULL) @@ -176,71 +152,21 @@ kg_impersonate(OM_uint32 *minor_status, NULL, &out_creds); if (code != 0) { *minor_status = code; - major_status = GSS_S_FAILURE; - goto cleanup; - } - - code = krb5_cc_new_unique(context, "MEMORY", NULL, &cred->ccache); - if (code != 0) { - *minor_status = code; - major_status = GSS_S_FAILURE; - goto cleanup; - } - - code = krb5_cc_initialize(context, cred->ccache, cred->princ); - if (code != 0) { - *minor_status = code; - major_status = GSS_S_FAILURE; - goto cleanup; - } - - code = krb5_cc_store_cred(context, cred->ccache, out_creds); - if (code != 0) { - *minor_status = code; - major_status = GSS_S_FAILURE; - goto cleanup; - } - - cred->tgt_expire = out_creds->times.endtime; - - if (time_rec != NULL) { - krb5_timestamp now; - - code = krb5_timeofday(context, &now); - if (code != 0) { - *minor_status = code; - major_status = GSS_S_FAILURE; - goto cleanup; - } - - *time_rec = cred->tgt_expire - now; - } - - major_status = kg_return_mechs(minor_status, cred, actual_mechs); - if (GSS_ERROR(major_status)) - goto cleanup; - - if (!kg_save_cred_id((gss_cred_id_t)cred)) { - *minor_status = (OM_uint32)G_VALIDATE_FAILED; - major_status = GSS_S_FAILURE; - goto cleanup; + return GSS_S_FAILURE; } - major_status = GSS_S_COMPLETE; - *output_cred = cred; - -cleanup: - if (GSS_ERROR(major_status) && cred != NULL) { - k5_mutex_destroy(&cred->lock); - if (cred->ccache != NULL) - krb5_cc_destroy(context, cred->ccache); - if (cred->princ != NULL) - krb5_free_principal(context, cred->princ); - xfree(cred); - } + major_status = kg_compose_proxy_cred(minor_status, + impersonator_cred, + user, + out_creds, + time_req, + desired_mechs, + output_cred, + actual_mechs, + time_rec, + context); - if (out_creds != NULL) - krb5_free_creds(context, out_creds); + krb5_free_creds(context, out_creds); return major_status; } @@ -295,15 +221,15 @@ krb5_gss_acquire_cred_impersonate_name(OM_uint32 *minor_status, return major_status; } - major_status = kg_impersonate(minor_status, - (krb5_gss_cred_id_t)impersonator_cred_handle, - (krb5_principal)desired_name, - time_req, - desired_mechs, - &cred, - actual_mechs, - time_rec, - context); + major_status = kg_impersonate_name(minor_status, + (krb5_gss_cred_id_t)impersonator_cred_handle, + (krb5_principal)desired_name, + time_req, + desired_mechs, + &cred, + actual_mechs, + time_rec, + context); *output_cred_handle = (gss_cred_id_t)cred; @@ -366,25 +292,22 @@ kg_duplicate_ccache(krb5_context context, } static OM_uint32 -kg_compose_cred(OM_uint32 *minor_status, - krb5_gss_cred_id_t impersonator_cred, - krb5_gss_cred_id_t subject_cred, - OM_uint32 time_req, - const gss_OID_set desired_mechs, - krb5_gss_cred_id_t *output_cred, - gss_OID_set *actual_mechs, - OM_uint32 *time_rec, - krb5_context context) +kg_compose_proxy_cred(OM_uint32 *minor_status, + krb5_gss_cred_id_t impersonator_cred, + krb5_const_principal subject_name, + krb5_creds *subject_creds, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + krb5_gss_cred_id_t *output_cred, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec, + krb5_context context) { OM_uint32 major_status; krb5_error_code code; krb5_gss_cred_id_t cred = NULL; - krb5_creds evidence_creds; - - memset(&evidence_creds, 0, sizeof(evidence_creds)); k5_mutex_assert_locked(&impersonator_cred->lock); - k5_mutex_assert_locked(&subject_cred->lock); if (!kg_is_initiator_cred(impersonator_cred) || impersonator_cred->princ == NULL) { @@ -393,12 +316,8 @@ kg_compose_cred(OM_uint32 *minor_status, goto cleanup; } - if (!kg_is_initiator_cred(subject_cred) || - subject_cred->princ == NULL) { - *minor_status = (OM_uint32)G_BAD_USAGE; - major_status = GSS_S_FAILURE; - goto cleanup; - } + assert(subject_name != NULL); + assert(subject_creds != NULL); cred = (krb5_gss_cred_id_t)xmalloc(sizeof(*cred)); if (cred == NULL) { @@ -424,8 +343,7 @@ kg_compose_cred(OM_uint32 *minor_status, cred->tgt_expire = impersonator_cred->tgt_expire; - /* The returned credential's subject matches subject_cred */ - code = krb5_copy_principal(context, subject_cred->princ, &cred->princ); + code = krb5_copy_principal(context, subject_name, &cred->princ); if (code != 0) { *minor_status = code; major_status = GSS_S_FAILURE; @@ -439,15 +357,7 @@ kg_compose_cred(OM_uint32 *minor_status, goto cleanup; } - code = kg_get_evidence_ticket(context, impersonator_cred, - subject_cred, &evidence_creds); - if (code != 0) { - *minor_status = code; - major_status = GSS_S_FAILURE; - goto cleanup; - } - - code = krb5_cc_store_cred(context, cred->ccache, &evidence_creds); + code = krb5_cc_store_cred(context, cred->ccache, subject_creds); if (code != 0) { *minor_status = code; major_status = GSS_S_FAILURE; @@ -490,6 +400,53 @@ cleanup: xfree(cred); } + return major_status; +} + +static OM_uint32 +kg_impersonate_cred(OM_uint32 *minor_status, + krb5_gss_cred_id_t impersonator_cred, + krb5_gss_cred_id_t subject_cred, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + krb5_gss_cred_id_t *output_cred, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec, + krb5_context context) +{ + OM_uint32 major_status; + krb5_error_code code; + krb5_creds evidence_creds; + + k5_mutex_assert_locked(&impersonator_cred->lock); + k5_mutex_assert_locked(&subject_cred->lock); + + if (!kg_is_initiator_cred(subject_cred) || + subject_cred->princ == NULL) { + *minor_status = (OM_uint32)G_BAD_USAGE; + return GSS_S_FAILURE; + } + + memset(&evidence_creds, 0, sizeof(evidence_creds)); + + code = kg_get_evidence_ticket(context, impersonator_cred, + subject_cred, &evidence_creds); + if (code != 0) { + *minor_status = code; + return GSS_S_FAILURE; + } + + major_status = kg_compose_proxy_cred(minor_status, + impersonator_cred, + subject_cred->princ, + &evidence_creds, + time_req, + desired_mechs, + output_cred, + actual_mechs, + time_rec, + context); + krb5_free_cred_contents(context, &evidence_creds); return major_status; @@ -560,15 +517,15 @@ krb5_gss_acquire_cred_impersonate_cred(OM_uint32 *minor_status, return major_status; } - major_status = kg_compose_cred(minor_status, - (krb5_gss_cred_id_t)impersonator_cred_handle, - (krb5_gss_cred_id_t)subject_cred_handle, - time_req, - desired_mechs, - &cred, - actual_mechs, - time_rec, - context); + major_status = kg_impersonate_cred(minor_status, + (krb5_gss_cred_id_t)impersonator_cred_handle, + (krb5_gss_cred_id_t)subject_cred_handle, + time_req, + desired_mechs, + &cred, + actual_mechs, + time_rec, + context); *output_cred_handle = (gss_cred_id_t)cred; |