diff options
author | wyllys <none@none> | 2005-07-13 10:02:39 -0700 |
---|---|---|
committer | wyllys <none@none> | 2005-07-13 10:02:39 -0700 |
commit | 354d1447ce995f3923a8f53d41c49fd3e6543282 (patch) | |
tree | b3380cb1588026a43df9055acffff2ed4428a11a /usr/src/lib | |
parent | f3f5a4dd0d8a3e3659add4eeca8b25772c3b35a2 (diff) | |
download | illumos-gate-354d1447ce995f3923a8f53d41c49fd3e6543282.tar.gz |
6259944 call gss_acquire_cred() with SPNEGO OID, it returns GSS_S_COMPLETE but did not return any credential
6260520 Call gss_context_time() with a handle of an un-established SPNEGO context, it will core dump.
6285582 gss_add_cred() is broken when input_cred_handle == GSS_C_NO_CREDENTIAL, assumes GSS_C_NO_NAME
6287358 SPNEGO init_sec_context fails when given 'actual_mechs' parameter
6290437 gss_accept_sec_context needs better handling of delegated credentials
6293338 call gss_create_empty_oid_set() with oid_set=NULL, it will seg fault.
Diffstat (limited to 'usr/src/lib')
-rw-r--r-- | usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h | 27 | ||||
-rw-r--r-- | usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c | 157 | ||||
-rw-r--r-- | usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec | 6 | ||||
-rw-r--r-- | usr/src/lib/libgss/g_accept_sec_context.c | 180 | ||||
-rw-r--r-- | usr/src/lib/libgss/g_acquire_cred.c | 62 | ||||
-rw-r--r-- | usr/src/lib/libgss/g_inquire_cred.c | 41 | ||||
-rw-r--r-- | usr/src/lib/libgss/oid_ops.c | 33 |
7 files changed, 316 insertions, 190 deletions
diff --git a/usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h b/usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h index 7954eca49f..df3d980c3d 100644 --- a/usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h +++ b/usr/src/lib/gss_mechs/mech_spnego/mech/gssapiP_spnego.h @@ -91,17 +91,8 @@ typedef enum {NO_TOKEN_SEND, INIT_TOKEN_SEND, CONT_TOKEN_SEND, typedef void *spnego_token_t; -/* spnego name structure for internal representation. */ -typedef struct { - gss_OID type; - gss_buffer_t buffer; - gss_OID mech_type; - gss_name_t mech_name; -} spnego_name_desc, *spnego_name_t; - /* Structure for context handle */ typedef struct { - OM_uint32 magic_num; gss_buffer_desc DER_mechTypes; gss_OID internal_mech; gss_ctx_id_t ctx_handle; @@ -111,12 +102,6 @@ typedef struct { OM_uint32 last_status; } spnego_gss_ctx_id_rec, *spnego_gss_ctx_id_t; -/* - * The magic number must be less than a standard pagesize - * to avoid a possible collision with a real address. - */ -#define SPNEGO_MAGIC_ID 0x00000fed - /* SPNEGO oid structure */ static const gss_OID_desc spnego_oids[] = { {SPNEGO_OID_LENGTH, SPNEGO_OID}, @@ -353,6 +338,18 @@ OM_uint32 spnego_gss_verify int *qop_state ); +OM_uint32 spnego_gss_inquire_cred +( + void *context, + OM_uint32 *minor_status, + const gss_cred_id_t cred_handle, + gss_name_t *name, + OM_uint32 *lifetime, + gss_cred_usage_t *cred_usage, + gss_OID_set *mechanisms +); + + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c b/usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c index 2fc3c3141a..dc8619c3b3 100644 --- a/usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c +++ b/usr/src/lib/gss_mechs/mech_spnego/mech/spnego_mech.c @@ -106,7 +106,7 @@ static struct gss_config spnego_mechanism = spnego_gss_display_name, spnego_gss_import_name, spnego_gss_release_name, - NULL, /* gss_inquire_cred */ + spnego_gss_inquire_cred, /* gss_inquire_cred */ NULL, /* gss_add_cred */ /* EXPORT DELETE START */ /* CRYPT DELETE START */ spnego_gss_seal, /* gss_seal */ @@ -253,7 +253,6 @@ create_spnego_ctx(void) return (NULL); } - spnego_ctx->magic_num = SPNEGO_MAGIC_ID; spnego_ctx->ctx_handle = GSS_C_NO_CONTEXT; spnego_ctx->internal_mech = NULL; spnego_ctx->optionStr = NULL; @@ -312,7 +311,7 @@ spnego_gss_init_sec_context(void *ct, dsyslog("Entering init_sec_context\n"); if (context_handle == NULL) - return (GSS_S_FAILURE); + return (GSS_S_NO_CONTEXT); *minor_status = 0; output_token->length = 0; @@ -362,7 +361,7 @@ spnego_gss_init_sec_context(void *ct, } if (input_token != NULL && input_token->value != NULL) { - ret = GSS_S_FAILURE; + ret = GSS_S_DEFECTIVE_TOKEN; goto cleanup; } @@ -380,7 +379,7 @@ spnego_gss_init_sec_context(void *ct, spnego_ctx = (spnego_gss_ctx_id_t)(*context_handle); if (input_token == NULL || input_token->value == NULL) { - ret = GSS_S_FAILURE; + ret = GSS_S_DEFECTIVE_TOKEN; goto cleanup; } ptr = (unsigned char *) input_token->value; @@ -536,13 +535,6 @@ spnego_gss_init_sec_context(void *ct, } } - if (actual_mech) { - (void) generic_gss_release_oid(&mstat, actual_mech); - ret = generic_gss_copy_oid(&mstat, - (gss_OID) gss_mech_spnego, actual_mech); - if (ret != GSS_S_COMPLETE) - goto cleanup; - } if (send_token == NO_TOKEN_SEND) { output_token->length = 0; @@ -633,12 +625,6 @@ spnego_gss_init_sec_context(void *ct, if ((status == GSS_S_COMPLETE) && (ret == GSS_S_COMPLETE)) { - /* - * Now, switch the output context to refer to the - * negotiated mechanism's context. - */ - *context_handle = (gss_ctx_id_t)spnego_ctx->ctx_handle; - if (actual_mech) { (void) generic_gss_release_oid(&mstat, actual_mech); ret = generic_gss_copy_oid(&mstat, @@ -647,7 +633,6 @@ spnego_gss_init_sec_context(void *ct, goto cleanup; } - release_spnego_ctx(&spnego_ctx); } else if (ret == GSS_S_CONTINUE_NEEDED) { if (make_spnego_tokenInit_msg(spnego_ctx, mechSet, @@ -664,7 +649,8 @@ cleanup: ret != GSS_S_CONTINUE_NEEDED) { if (spnego_ctx != NULL && spnego_ctx->ctx_handle != NULL) - free(spnego_ctx->ctx_handle); + gss_delete_sec_context(&mstat, &spnego_ctx->ctx_handle, + GSS_C_NO_BUFFER); if (spnego_ctx != NULL) release_spnego_ctx(&spnego_ctx); @@ -739,7 +725,7 @@ spnego_gss_accept_sec_context(void *ct, dsyslog("Entering accept_sec_context\n"); if (context_handle == NULL) - return (GSS_S_FAILURE); + return (GSS_S_NO_CONTEXT); if (src_name) *src_name = (gss_name_t)NULL; @@ -1047,14 +1033,7 @@ spnego_gss_accept_sec_context(void *ct, } ret = status; - /* - * If we got this far OK, then switch the - * returned context handle to reference the - * "real" context handle for the mech. - */ if (status == GSS_S_COMPLETE) { - *context_handle = - (gss_ctx_id_t)spnego_ctx->ctx_handle; if (internal_name != NULL && src_name != NULL) *src_name = internal_name; } @@ -1099,7 +1078,6 @@ senderror: } else { (void) gss_release_buffer(&mstat, output_token); } - release_spnego_ctx(&spnego_ctx); cleanup: if (ret != GSS_S_COMPLETE && @@ -1226,6 +1204,23 @@ spnego_gss_display_name(void *ctx, /*ARGSUSED*/ OM_uint32 +spnego_gss_inquire_cred(void *ctx, + OM_uint32 *minor_status, + const gss_cred_id_t cred_handle, + gss_name_t *name, + OM_uint32 *lifetime, + gss_cred_usage_t *cred_usage, + gss_OID_set *mechanisms) +{ + /* A SPNEGO cred is just a standard libgss cred record */ + return (gss_inquire_cred(minor_status, + cred_handle, name, + lifetime, cred_usage, + mechanisms)); +} + +/*ARGSUSED*/ +OM_uint32 spnego_gss_inquire_names_for_mech(void *ctx, OM_uint32 *minor_status, gss_OID mechanism, @@ -1278,8 +1273,14 @@ spnego_gss_unseal(void *context, int *qop_state) { OM_uint32 ret; + spnego_gss_ctx_id_t ctx = + (spnego_gss_ctx_id_t)context_handle; + + if (context_handle == NULL) + return (GSS_S_NO_CONTEXT); + ret = gss_unseal(minor_status, - context_handle, + ctx->ctx_handle, input_message_buffer, output_message_buffer, conf_state, @@ -1299,8 +1300,14 @@ spnego_gss_seal(void *context, gss_buffer_t output_message_buffer) { OM_uint32 ret; + spnego_gss_ctx_id_t ctx = + (spnego_gss_ctx_id_t)context_handle; + + if (context_handle == NULL) + return (GSS_S_NO_CONTEXT); + ret = gss_seal(minor_status, - context_handle, + ctx->ctx_handle, conf_req_flag, qop_req, input_message_buffer, @@ -1317,8 +1324,14 @@ spnego_gss_process_context_token(void *context, const gss_buffer_t token_buffer) { OM_uint32 ret; + spnego_gss_ctx_id_t ctx = + (spnego_gss_ctx_id_t)context_handle; + + if (context_handle == NULL) + return (GSS_S_NO_CONTEXT); + ret = gss_process_context_token(minor_status, - context_handle, + ctx->ctx_handle, token_buffer); return (ret); @@ -1334,18 +1347,17 @@ spnego_gss_delete_sec_context(void *context, spnego_gss_ctx_id_t *ctx = (spnego_gss_ctx_id_t *)context_handle; - if (context_handle == NULL) - return (GSS_S_FAILURE); + if (context_handle == NULL || *ctx == NULL) + return (GSS_S_NO_CONTEXT); /* - * If this is still an SPNEGO mech, release it locally. + * If this is still a SPNEGO mech, release it locally. */ - if (*ctx != NULL && - (*ctx)->magic_num == SPNEGO_MAGIC_ID) { + if ((*ctx)->ctx_handle == GSS_C_NO_CONTEXT) { (void) release_spnego_ctx(ctx); } else { ret = gss_delete_sec_context(minor_status, - context_handle, + &(*ctx)->ctx_handle, output_token); } @@ -1359,9 +1371,16 @@ spnego_gss_context_time(void *context, OM_uint32 *time_rec) { OM_uint32 ret; + spnego_gss_ctx_id_t ctx = + (spnego_gss_ctx_id_t)context_handle; + + if (context_handle == NULL) + return (GSS_S_NO_CONTEXT); + ret = gss_context_time(minor_status, - context_handle, + ctx->ctx_handle, time_rec); + return (ret); } @@ -1372,8 +1391,14 @@ spnego_gss_export_sec_context(void *context, gss_buffer_t interprocess_token) { OM_uint32 ret; + spnego_gss_ctx_id_t *ctx = + (spnego_gss_ctx_id_t *)context_handle; + + if (context_handle == NULL || *ctx == NULL) + return (GSS_S_NO_CONTEXT); + ret = gss_export_sec_context(minor_status, - context_handle, + &(*ctx)->ctx_handle, interprocess_token); return (ret); } @@ -1385,9 +1410,16 @@ spnego_gss_import_sec_context(void *context, gss_ctx_id_t *context_handle) { OM_uint32 ret; + spnego_gss_ctx_id_t *ctx = + (spnego_gss_ctx_id_t *)context_handle; + + if (context_handle == NULL || *ctx == NULL) + return (GSS_S_NO_CONTEXT); + ret = gss_import_sec_context(minor_status, interprocess_token, - context_handle); + &(*ctx)->ctx_handle); + return (ret); } @@ -1404,9 +1436,14 @@ spnego_gss_inquire_context(void *context, int *open) { OM_uint32 ret = GSS_S_COMPLETE; + spnego_gss_ctx_id_t ctx = + (spnego_gss_ctx_id_t)context_handle; + + if (context_handle == NULL) + return (GSS_S_NO_CONTEXT); ret = gss_inquire_context(minor_status, - context_handle, + ctx->ctx_handle, src_name, targ_name, lifetime_rec, @@ -1428,8 +1465,14 @@ spnego_gss_wrap_size_limit(void *context, OM_uint32 *max_input_size) { OM_uint32 ret; + spnego_gss_ctx_id_t ctx = + (spnego_gss_ctx_id_t)context_handle; + + if (context_handle == NULL) + return (GSS_S_NO_CONTEXT); + ret = gss_wrap_size_limit(minor_status, - context_handle, + ctx->ctx_handle, conf_req_flag, qop_req, req_output_size, @@ -1446,11 +1489,18 @@ spnego_gss_sign(void *context, gss_buffer_t message_token) { OM_uint32 ret; + spnego_gss_ctx_id_t ctx = + (spnego_gss_ctx_id_t)context_handle; + + if (context_handle == NULL) + return (GSS_S_NO_CONTEXT); + ret = gss_sign(minor_status, - context_handle, + ctx->ctx_handle, qop_req, message_buffer, message_token); + return (ret); } @@ -1463,8 +1513,14 @@ spnego_gss_verify(void *context, int *qop_state) { OM_uint32 ret; + spnego_gss_ctx_id_t ctx = + (spnego_gss_ctx_id_t)context_handle; + + if (context_handle == NULL) + return (GSS_S_NO_CONTEXT); + ret = gss_verify_mic(minor_status, - context_handle, + ctx->ctx_handle, msg_buffer, token_buffer, (uint32_t *)qop_state); @@ -1482,7 +1538,11 @@ release_spnego_ctx(spnego_gss_ctx_id_t *ctx) { spnego_gss_ctx_id_t context; OM_uint32 minor_stat; - context = *ctx; + + if (ctx != NULL) + context = *ctx; + else + return; if (context != NULL) { (void) gss_release_buffer(&minor_stat, @@ -1495,6 +1555,11 @@ release_spnego_ctx(spnego_gss_ctx_id_t *ctx) free(context->optionStr); context->optionStr = NULL; } + if (context->ctx_handle != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&minor_stat, + &context->ctx_handle, + GSS_C_NO_BUFFER); + free(context); *ctx = NULL; } diff --git a/usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec b/usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec index 3eeab98af1..acd14eb89a 100644 --- a/usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec +++ b/usr/src/lib/gss_mechs/mech_spnego/spec/spnego.spec @@ -105,3 +105,9 @@ end function spnego_gss_verify version SUNWprivate end + +function spnego_gss_inquire_cred +version SUNWprivate +end + + diff --git a/usr/src/lib/libgss/g_accept_sec_context.c b/usr/src/lib/libgss/g_accept_sec_context.c index 442d472f47..cf2ed8696b 100644 --- a/usr/src/lib/libgss/g_accept_sec_context.c +++ b/usr/src/lib/libgss/g_accept_sec_context.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -63,7 +63,7 @@ OM_uint32 *time_rec; gss_cred_id_t *d_cred; /* delegated cred handle */ { - OM_uint32 status, temp_status, temp_minor_status; + OM_uint32 status, temp_status, t_minstat; gss_union_ctx_id_t union_ctx_id; gss_union_cred_t union_cred; gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL; @@ -72,6 +72,8 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ gss_name_t tmp_src_name = GSS_C_NO_NAME; gss_OID_desc token_mech_type_desc; gss_OID token_mech_type = &token_mech_type_desc; + gss_OID actual_mech = GSS_C_NO_OID; + OM_uint32 flags; gss_mechanism mech; /* check parameters first */ @@ -119,7 +121,7 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ return (GSS_S_FAILURE); union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT; - status = generic_gss_copy_oid(&temp_minor_status, + status = generic_gss_copy_oid(&t_minstat, token_mech_type, &union_ctx_id->mech_type); if (status != GSS_S_COMPLETE) { @@ -158,9 +160,9 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ input_token_buffer, input_chan_bindings, &internal_name, - mech_type, + &actual_mech, output_token, - ret_flags, + &flags, time_rec, d_cred ? &tmp_d_cred : NULL); @@ -172,6 +174,9 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ if (status != GSS_S_COMPLETE) goto error_out; + if (mech_type != NULL) + *mech_type = actual_mech; + /* * if src_name is non-NULL, * convert internal_name into a union name equivalent @@ -181,18 +186,18 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ */ if (internal_name != NULL) { temp_status = __gss_convert_name_to_union_name( - &temp_minor_status, mech, + &t_minstat, mech, internal_name, &tmp_src_name); if (temp_status != GSS_S_COMPLETE) { - *minor_status = temp_minor_status; + *minor_status = t_minstat; if (output_token->length) (void) gss_release_buffer( - &temp_minor_status, + &t_minstat, output_token); if (internal_name != GSS_C_NO_NAME) mech->gss_release_name( mech->context, - &temp_minor_status, + &t_minstat, &internal_name); return (temp_status); } @@ -204,88 +209,107 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ } /* Ensure we're returning correct creds format */ - if ((ret_flags && GSS_C_DELEG_FLAG) && - tmp_d_cred != GSS_C_NO_CREDENTIAL) { - gss_union_cred_t d_u_cred = NULL; - - d_u_cred = malloc(sizeof (gss_union_cred_desc)); - if (d_u_cred == NULL) { - status = GSS_S_FAILURE; - goto error_out; - } - (void) memset(d_u_cred, 0, - sizeof (gss_union_cred_desc)); + if ((flags & GSS_C_DELEG_FLAG) && + tmp_d_cred != GSS_C_NO_CREDENTIAL) { + /* + * If we got back an OID different from the original + * token OID, assume the delegated_cred is already + * a proper union_cred and just return it. Don't + * try to re-wrap it. This is for SPNEGO or other + * pseudo-mechanisms. + */ + if (actual_mech != GSS_C_NO_OID && + token_mech_type != GSS_C_NO_OID && + !g_OID_equal(actual_mech, token_mech_type)) { + *d_cred = tmp_d_cred; + } else { + gss_union_cred_t d_u_cred = NULL; - d_u_cred->count = 1; + d_u_cred = malloc(sizeof (gss_union_cred_desc)); + if (d_u_cred == NULL) { + status = GSS_S_FAILURE; + goto error_out; + } + (void) memset(d_u_cred, 0, + sizeof (gss_union_cred_desc)); - status = generic_gss_copy_oid(&temp_minor_status, - token_mech_type, - &d_u_cred->mechs_array); + d_u_cred->count = 1; - if (status != GSS_S_COMPLETE) { - free(d_u_cred); - goto error_out; - } + status = generic_gss_copy_oid( + &t_minstat, + actual_mech, + &d_u_cred->mechs_array); - d_u_cred->cred_array = malloc(sizeof (gss_cred_id_t)); - if (d_u_cred->cred_array != NULL) { - d_u_cred->cred_array[0] = tmp_d_cred; - } else { - free(d_u_cred); - status = GSS_S_FAILURE; - goto error_out; - } + if (status != GSS_S_COMPLETE) { + free(d_u_cred); + goto error_out; + } - if (status != GSS_S_COMPLETE) { - free(d_u_cred->cred_array); - free(d_u_cred); - goto error_out; - } + d_u_cred->cred_array = malloc( + sizeof (gss_cred_id_t)); + if (d_u_cred->cred_array != NULL) { + d_u_cred->cred_array[0] = tmp_d_cred; + } else { + free(d_u_cred); + status = GSS_S_FAILURE; + goto error_out; + } - internal_name = GSS_C_NO_NAME; + if (status != GSS_S_COMPLETE) { + free(d_u_cred->cred_array); + free(d_u_cred); + goto error_out; + } - d_u_cred->auxinfo.creation_time = time(0); - d_u_cred->auxinfo.time_rec = 0; + internal_name = GSS_C_NO_NAME; - if (mech->gss_inquire_cred) { - status = mech->gss_inquire_cred(mech->context, - minor_status, - tmp_d_cred, - &internal_name, - &d_u_cred->auxinfo.time_rec, - &d_u_cred->auxinfo.cred_usage, - NULL); - } + d_u_cred->auxinfo.creation_time = time(0); + d_u_cred->auxinfo.time_rec = 0; - if (internal_name != NULL) { - temp_status = __gss_convert_name_to_union_name( - &temp_minor_status, mech, - internal_name, &tmp_src_name); - if (temp_status != GSS_S_COMPLETE) { - *minor_status = temp_minor_status; - if (output_token->length) - (void) gss_release_buffer( - &temp_minor_status, - output_token); - free(d_u_cred->cred_array); - free(d_u_cred); - return (temp_status); + if (mech->gss_inquire_cred) { + status = mech->gss_inquire_cred( + mech->context, + minor_status, + tmp_d_cred, + &internal_name, + &d_u_cred->auxinfo.time_rec, + &d_u_cred->auxinfo.cred_usage, + NULL); } - } - if (tmp_src_name != NULL) { - status = gss_display_name( - &temp_minor_status, - tmp_src_name, - &d_u_cred->auxinfo.name, - &d_u_cred->auxinfo.name_type); - } + if (internal_name != NULL) { + temp_status = + __gss_convert_name_to_union_name( + &t_minstat, mech, + internal_name, &tmp_src_name); + if (temp_status != GSS_S_COMPLETE) { + *minor_status = t_minstat; + if (output_token->length) + (void) gss_release_buffer( + &t_minstat, + output_token); + free(d_u_cred->cred_array); + free(d_u_cred); + return (temp_status); + } + } - *d_cred = (gss_cred_id_t)d_u_cred; + if (tmp_src_name != NULL) { + status = gss_display_name( + &t_minstat, + tmp_src_name, + &d_u_cred->auxinfo.name, + &d_u_cred->auxinfo.name_type); + } + + *d_cred = (gss_cred_id_t)d_u_cred; + } + if (ret_flags != NULL) + *ret_flags = flags; } if (src_name == NULL && tmp_src_name != NULL) - (void) gss_release_name(&temp_minor_status, + (void) gss_release_name(&t_minstat, &tmp_src_name); return (status); } else { @@ -305,13 +329,13 @@ error_out: } if (output_token->length) - (void) gss_release_buffer(&temp_minor_status, output_token); + (void) gss_release_buffer(&t_minstat, output_token); if (src_name) *src_name = GSS_C_NO_NAME; if (tmp_src_name != GSS_C_NO_NAME) - (void) gss_release_buffer(&temp_minor_status, + (void) gss_release_buffer(&t_minstat, (gss_buffer_t)tmp_src_name); return (status); diff --git a/usr/src/lib/libgss/g_acquire_cred.c b/usr/src/lib/libgss/g_acquire_cred.c index a6ecd5a533..9fffa3c63d 100644 --- a/usr/src/lib/libgss/g_acquire_cred.c +++ b/usr/src/lib/libgss/g_acquire_cred.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,6 @@ /* * glue routine for gss_acquire_cred */ - #include <mechglueP.h> #include <stdio.h> #ifdef HAVE_STDLIB_H @@ -274,33 +273,52 @@ gss_add_cred(minor_status, input_cred_handle, return (GSS_S_FAILURE); (void) memset(union_cred, 0, sizeof (gss_union_cred_desc)); - - /* for default credentials we will use GSS_C_NO_NAME */ - internal_name = GSS_C_NO_NAME; } else { + /* Input Cred is non-NULL */ union_cred = (gss_union_cred_t)input_cred_handle; + if (__gss_get_mechanism_cred(union_cred, desired_mech) != - GSS_C_NO_CREDENTIAL) - return (GSS_S_DUPLICATE_ELEMENT); + GSS_C_NO_CREDENTIAL) { + status = GSS_S_DUPLICATE_ELEMENT; + goto errout; + } - /* may need to create a mechanism specific name */ - if (desired_name) { - union_name = (gss_union_name_t)desired_name; - if (union_name->mech_type && - g_OID_equal(union_name->mech_type, - &mech->mech_type)) - internal_name = union_name->mech_name; - else { - if (__gss_import_internal_name(minor_status, - &mech->mech_type, union_name, - &allocated_name) != GSS_S_COMPLETE) - return (GSS_S_BAD_NAME); + /* + * If no name was given, determine the name from the + * existing credential. + */ + if (desired_name == GSS_C_NO_NAME) { + if (gss_import_name(minor_status, + &union_cred->auxinfo.name, + union_cred->auxinfo.name_type, + &allocated_name) == GSS_S_COMPLETE && + (gss_canonicalize_name(minor_status, + allocated_name, + &mech->mech_type, + NULL) == GSS_S_COMPLETE)) { internal_name = allocated_name; } + } /* else, get the name from the desired_name below */ + } + if (desired_name != GSS_C_NO_NAME) { + /* may need to create a mechanism specific name */ + union_name = (gss_union_name_t)desired_name; + + if (union_name->mech_type && + g_OID_equal(union_name->mech_type, + &mech->mech_type)) + internal_name = union_name->mech_name; + else { + if (__gss_import_internal_name(minor_status, + &mech->mech_type, union_name, + &allocated_name) != GSS_S_COMPLETE) { + status = GSS_S_BAD_NAME; + goto errout; + } + internal_name = allocated_name; } } - if (cred_usage == GSS_C_ACCEPT) time_req = acceptor_time_req; else if (cred_usage == GSS_C_INITIATE) @@ -317,7 +335,7 @@ gss_add_cred(minor_status, input_cred_handle, if (status != GSS_S_COMPLETE) goto errout; - /* may need to set credential auxinfo strucutre */ + /* may need to set credential auxinfo structure */ if (union_cred->auxinfo.creation_time == 0) { union_cred->auxinfo.creation_time = time(NULL); union_cred->auxinfo.time_rec = time_rec; @@ -327,7 +345,7 @@ gss_add_cred(minor_status, input_cred_handle, * we must set the name; if name is not supplied * we must do inquire cred to get it */ - if (internal_name == NULL) { + if (internal_name == GSS_C_NO_NAME) { if (mech->gss_inquire_cred == NULL || ((status = mech->gss_inquire_cred( mech->context, diff --git a/usr/src/lib/libgss/g_inquire_cred.c b/usr/src/lib/libgss/g_inquire_cred.c index 78fc641b74..f7b4d025c4 100644 --- a/usr/src/lib/libgss/g_inquire_cred.c +++ b/usr/src/lib/libgss/g_inquire_cred.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -234,26 +234,31 @@ gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name, if (mech_cred == NULL) return (GSS_S_DEFECTIVE_CREDENTIAL); - status = mech->gss_inquire_cred_by_mech(mech->context, minor_status, - mech_cred, mech_type, - name ? &internal_name : NULL, - initiator_lifetime, - acceptor_lifetime, cred_usage); - - if (status != GSS_S_COMPLETE) - return (status); + if (mech->gss_inquire_cred_by_mech != NULL) { + status = mech->gss_inquire_cred_by_mech(mech->context, + minor_status, + mech_cred, mech_type, + name ? &internal_name : NULL, + initiator_lifetime, + acceptor_lifetime, cred_usage); - if (name) { - /* - * Convert internal_name into a union_name equivalent. - */ - status = __gss_convert_name_to_union_name( - &temp_minor_status, mech, - internal_name, name); - if (status != GSS_S_COMPLETE) { - *minor_status = temp_minor_status; + if (status != GSS_S_COMPLETE) return (status); + + if (name) { + /* + * Convert internal_name into a union_name equivalent. + */ + status = __gss_convert_name_to_union_name( + &temp_minor_status, mech, + internal_name, name); + if (status != GSS_S_COMPLETE) { + *minor_status = temp_minor_status; + return (status); + } } + } else { + return (GSS_S_UNAVAILABLE); } return (GSS_S_COMPLETE); diff --git a/usr/src/lib/libgss/oid_ops.c b/usr/src/lib/libgss/oid_ops.c index 135b45deea..3e806b510b 100644 --- a/usr/src/lib/libgss/oid_ops.c +++ b/usr/src/lib/libgss/oid_ops.c @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -103,6 +103,12 @@ generic_gss_copy_oid(minor_status, oid, new_oid) if (minor_status) *minor_status = 0; + if (new_oid == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + if (oid == GSS_C_NO_OID) + return (GSS_S_CALL_INACCESSIBLE_READ); + p = (gss_OID) malloc(sizeof (gss_OID_desc)); if (!p) { return (GSS_S_FAILURE); @@ -127,6 +133,9 @@ gss_OID_set *oid_set; if (minor_status) *minor_status = 0; + if (oid_set == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + if ((*oid_set = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)))) { (void) memset(*oid_set, 0, sizeof (gss_OID_set_desc)); return (GSS_S_COMPLETE); @@ -147,30 +156,34 @@ gss_OID_set *oid_set; if (minor_status) *minor_status = 0; - if (member_oid == NULL || member_oid->length == 0 || + if (member_oid == GSS_C_NO_OID || member_oid->length == 0 || member_oid->elements == NULL) return (GSS_S_CALL_INACCESSIBLE_READ); + if (oid_set == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + elist = (*oid_set)->elements; /* Get an enlarged copy of the array */ if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) * sizeof (gss_OID_desc)))) { - /* Copy in the old junk */ + /* Copy in the old junk */ if (elist) (void) memcpy((*oid_set)->elements, elist, ((*oid_set)->count * sizeof (gss_OID_desc))); - /* Duplicate the input element */ + /* Duplicate the input element */ lastel = &(*oid_set)->elements[(*oid_set)->count]; if ((lastel->elements = (void *) malloc(member_oid->length))) { - /* Success - copy elements */ + + /* Success - copy elements */ (void) memcpy(lastel->elements, member_oid->elements, member_oid->length); - /* Set length */ + /* Set length */ lastel->length = member_oid->length; - /* Update count */ + /* Update count */ (*oid_set)->count++; if (elist) free(elist); @@ -196,7 +209,7 @@ generic_gss_test_oid_set_member(minor_status, member, set, present) if (minor_status) *minor_status = 0; - if (member == NULL || set == NULL) + if (member == GSS_C_NO_OID || set == NULL) return (GSS_S_CALL_INACCESSIBLE_READ); if (present == NULL) @@ -235,14 +248,12 @@ gss_buffer_t oid_str; if (minor_status) *minor_status = 0; - if (oid == NULL || oid->length == 0 || oid->elements == NULL) + if (oid == GSS_C_NO_OID || oid->length == 0 || oid->elements == NULL) return (GSS_S_CALL_INACCESSIBLE_READ); if (oid_str == NULL) return (GSS_S_CALL_INACCESSIBLE_WRITE); - /* Decoded according to krb5/gssapi_krb5.c */ - /* First determine the size of the string */ string_length = 0; number = 0; |