diff options
Diffstat (limited to 'src/lib/gssapi/krb5/acquire_cred.c')
-rw-r--r-- | src/lib/gssapi/krb5/acquire_cred.c | 84 |
1 files changed, 62 insertions, 22 deletions
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 526e6dddb7..b2d6ce1116 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -27,6 +27,10 @@ #include <strings.h> #endif +/* + * $Id$ + */ + /* get credentials corresponding to a key in the krb5 keytab. If the default name is requested, return the name in output_princ. If output_princ is non-NULL, the caller will use or free it, regardless @@ -35,14 +39,13 @@ */ static OM_uint32 -acquire_accept_cred(ctx, minor_status, desired_name, output_princ, cred) - void *ctx; +acquire_accept_cred(context, minor_status, desired_name, output_princ, cred) + krb5_context context; OM_uint32 *minor_status; gss_name_t desired_name; krb5_principal *output_princ; krb5_gss_cred_id_rec *cred; { - krb5_context context = ctx; krb5_error_code code; krb5_principal princ; krb5_keytab kt; @@ -65,6 +68,7 @@ acquire_accept_cred(ctx, minor_status, desired_name, output_princ, cred) if (desired_name == (gss_name_t) NULL) { if (code = krb5_sname_to_principal(context, NULL, NULL, KRB5_NT_SRV_HST, &princ)) { + (void) krb5_kt_close(context, kt); *minor_status = code; return(GSS_S_FAILURE); } @@ -76,6 +80,7 @@ acquire_accept_cred(ctx, minor_status, desired_name, output_princ, cred) /* iterate over the keytab searching for the principal */ if (code = krb5_kt_start_seq_get(context, kt, &cur)) { + (void) krb5_kt_close(context, kt); *minor_status = code; return(GSS_S_FAILURE); } @@ -92,16 +97,19 @@ acquire_accept_cred(ctx, minor_status, desired_name, output_princ, cred) if (code == KRB5_KT_END) { /* this means that the principal wasn't in the keytab */ (void)krb5_kt_end_seq_get(context, kt, &cur); + (void) krb5_kt_close(context, kt); *minor_status = KG_KEYTAB_NOMATCH; return(GSS_S_CRED_UNAVAIL); } else if (code) { /* this means some error occurred reading the keytab */ (void)krb5_kt_end_seq_get(context, kt, &cur); + (void) krb5_kt_close(context, kt); *minor_status = code; return(GSS_S_FAILURE); } else { /* this means that we found a matching entry */ if (code = krb5_kt_end_seq_get(context, kt, &cur)) { + (void) krb5_kt_close(context, kt); *minor_status = code; return(GSS_S_FAILURE); } @@ -204,7 +212,6 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred) if (got_endtime == 0) { cred->tgt_expire = creds.times.endtime; got_endtime = 1; - *minor_status = KG_TGT_MISSING; } krb5_free_cred_contents(context, &creds); } @@ -215,6 +222,12 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred) (void)krb5_cc_close(context, ccache); *minor_status = code; return(GSS_S_FAILURE); + } else if (! got_endtime) { + /* this means the ccache was entirely empty */ + (void)krb5_cc_end_seq_get(context, ccache, &cur); + (void)krb5_cc_close(context, ccache); + *minor_status = KG_EMPTY_CCACHE; + return(GSS_S_FAILURE); } else { /* this means that we found an endtime to use. */ if (code = krb5_cc_end_seq_get(context, ccache, &cur)) { @@ -239,10 +252,9 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred) /*ARGSUSED*/ OM_uint32 -krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, +krb5_gss_acquire_cred(minor_status, desired_name, time_req, desired_mechs, cred_usage, output_cred_handle, actual_mechs, time_rec) - void *ctx; OM_uint32 *minor_status; gss_name_t desired_name; OM_uint32 time_req; @@ -252,13 +264,17 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, gss_OID_set *actual_mechs; OM_uint32 *time_rec; { - krb5_context context = ctx; + krb5_context context; size_t i; krb5_gss_cred_id_t cred; - gss_OID_set mechs; + gss_OID_set valid_mechs, ret_mechs; + int req_old, req_new; OM_uint32 ret; krb5_error_code code; + if (GSS_ERROR(kg_get_context(minor_status, &context))) + return(GSS_S_FAILURE); + /* make sure all outputs are valid */ *output_cred_handle = NULL; @@ -279,11 +295,26 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, /* verify that the requested mechanism set is the default, or contains krb5 */ - if (desired_mechs != GSS_C_NULL_OID_SET) { - for (i=0; i<desired_mechs->count; i++) + if (desired_mechs == GSS_C_NULL_OID_SET) { + valid_mechs = gss_mech_set_krb5_both; + } else { + req_old = 0; + req_new = 0; + + for (i=0; i<desired_mechs->count; i++) { + if (g_OID_equal(gss_mech_krb5_old, &(desired_mechs->elements[i]))) + req_old++; if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i]))) - break; - if (i == desired_mechs->count) { + req_new++; + } + + if (req_old && req_new) { + valid_mechs = gss_mech_set_krb5_both; + } else if (req_old) { + valid_mechs = gss_mech_set_krb5_old; + } else if (req_new) { + valid_mechs = gss_mech_set_krb5; + } else { *minor_status = 0; return(GSS_S_BAD_MECH); } @@ -300,6 +331,9 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, cred->usage = cred_usage; cred->princ = NULL; + cred->actual_mechs = valid_mechs; + cred->prerfc_mech = req_old; + cred->rfc_mech = req_new; cred->keytab = NULL; cred->ccache = NULL; @@ -390,7 +424,7 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, /* create mechs */ if (actual_mechs) { - if (! g_copy_OID_set(gss_mech_set_krb5, &mechs)) { + if (! g_copy_OID_set(cred->actual_mechs, &ret_mechs)) { if (cred->ccache) (void)krb5_cc_close(context, cred->ccache); if (cred->keytab) @@ -406,8 +440,8 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, /* intern the credential handle */ if (! kg_save_cred_id((gss_cred_id_t) cred)) { - free(mechs->elements); - free(mechs); + free(ret_mechs->elements); + free(ret_mechs); if (cred->ccache) (void)krb5_cc_close(context, cred->ccache); if (cred->keytab) @@ -424,19 +458,18 @@ krb5_gss_acquire_cred(ctx, minor_status, desired_name, time_req, *minor_status = 0; *output_cred_handle = (gss_cred_id_t) cred; if (actual_mechs) - *actual_mechs = mechs; + *actual_mechs = ret_mechs; return(GSS_S_COMPLETE); } /* V2 interface */ OM_uint32 -krb5_gss_add_cred(ctx, minor_status, input_cred_handle, +krb5_gss_add_cred(minor_status, input_cred_handle, desired_name, desired_mech, cred_usage, initiator_time_req, acceptor_time_req, output_cred_handle, actual_mechs, initiator_time_rec, acceptor_time_rec) - void *ctx; OM_uint32 *minor_status; gss_cred_id_t input_cred_handle; gss_name_t desired_name; @@ -449,12 +482,19 @@ krb5_gss_add_cred(ctx, minor_status, input_cred_handle, OM_uint32 *initiator_time_rec; OM_uint32 *acceptor_time_rec; { - krb5_context context = ctx; /* - * This does not apply to our single-mechanism implementation. Until we - * come up with a better error code, return failure. + * This does not apply to our single-mechanism implementation. Decide + * if the correct error is BAD_MECH or DUPLICATE_ELEMENT. */ + + /* verify that the requested mechanism is the default, or + is krb5 */ + + if ((desired_mech != GSS_C_NULL_OID) && + (g_OID_equal(desired_mech, gss_mech_krb5))) + return(GSS_S_BAD_MECH); + *minor_status = 0; - return(GSS_S_FAILURE); + return(GSS_S_DUPLICATE_ELEMENT); } |