static OM_uint32 alloc_union_cred(OM_uint32 *minor_status, gss_mechanism mech, gss_cred_id_t mech_cred, gss_union_cred_t *pcred) { OM_uint32 status; OM_uint32 temp_minor_status; gss_union_cred_t cred = NULL; *pcred = NULL; status = GSS_S_FAILURE; cred = calloc(1, sizeof(*cred)); if (cred == NULL) { *minor_status = ENOMEM; goto cleanup; } cred->loopback = cred; cred->count = 1; cred->cred_array = calloc(cred->count, sizeof(gss_cred_id_t)); if (cred->cred_array == NULL) { *minor_status = ENOMEM; goto cleanup; } cred->cred_array[0] = mech_cred; status = generic_gss_copy_oid(minor_status, &mech->mech_type, &cred->mechs_array); if (status != GSS_S_COMPLETE) goto cleanup; status = GSS_S_COMPLETE; *pcred = cred; cleanup: if (status != GSS_S_COMPLETE) gss_release_cred(&temp_minor_status, (gss_cred_id_t *)&cred); return status; }
OM_uint32 KRB5_CALLCONV gss_inquire_name(OM_uint32 *minor_status, gss_name_t name, int *name_is_MN, gss_OID *MN_mech, gss_buffer_set_t *attrs) { OM_uint32 status, tmp; gss_union_name_t union_name; gss_mechanism mech; if (minor_status == NULL) return GSS_S_CALL_INACCESSIBLE_WRITE; if (name == GSS_C_NO_NAME) return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME; if (MN_mech != NULL) *MN_mech = GSS_C_NO_OID; if (attrs != NULL) *attrs = GSS_C_NO_BUFFER_SET; *minor_status = 0; union_name = (gss_union_name_t)name; if (union_name->mech_type == GSS_C_NO_OID) { /* We don't yet support non-mechanism attributes */ if (name_is_MN != NULL) name_is_MN = 0; *minor_status = 0; return GSS_S_COMPLETE; } if (name_is_MN != NULL) *name_is_MN = 1; if (MN_mech != NULL) { status = generic_gss_copy_oid(minor_status, union_name->mech_type, MN_mech); if (GSS_ERROR(status)) return status; } mech = gssint_get_mechanism(name->mech_type); if (mech == NULL) { gss_release_oid(&tmp, MN_mech); return GSS_S_BAD_NAME; } if (mech->gss_inquire_name == NULL) { gss_release_oid(&tmp, MN_mech); return GSS_S_UNAVAILABLE; } status = (*mech->gss_inquire_name)(minor_status, union_name->mech_name, NULL, NULL, attrs); if (status != GSS_S_COMPLETE) { generic_gss_release_oid(&tmp, MN_mech); map_error(minor_status, mech); } return status; }
OM_uint32 KRB5_CALLCONV gss_set_sec_context_option (OM_uint32 *minor_status, gss_ctx_id_t *context_handle, const gss_OID desired_object, const gss_buffer_t value) { OM_uint32 status, minor; gss_union_ctx_id_t ctx; gss_mechanism mech; gss_ctx_id_t internal_ctx = GSS_C_NO_CONTEXT; if (minor_status == NULL) return GSS_S_CALL_INACCESSIBLE_WRITE; if (context_handle == NULL) return GSS_S_CALL_INACCESSIBLE_WRITE; *minor_status = 0; /* * select the approprate underlying mechanism routine and * call it. */ ctx = (gss_union_ctx_id_t) *context_handle; if (ctx == NULL) { mech = gssint_get_mechanism (GSS_C_NO_OID); } else { mech = gssint_get_mechanism (ctx->mech_type); } if (mech == NULL) return GSS_S_BAD_MECH; if (mech->gss_set_sec_context_option == NULL) return GSS_S_UNAVAILABLE; status = mech->gss_set_sec_context_option(minor_status, ctx ? &ctx->internal_ctx_id : &internal_ctx, desired_object, value); if (status == GSS_S_COMPLETE) { if (ctx == NULL && internal_ctx != GSS_C_NO_CONTEXT) { /* Allocate a union context handle to wrap new context */ ctx = (gss_union_ctx_id_t)malloc(sizeof(*ctx)); if (ctx == NULL) { *minor_status = ENOMEM; gssint_delete_internal_sec_context(&minor, &mech->mech_type, &internal_ctx, GSS_C_NO_BUFFER); return GSS_S_FAILURE; } status = generic_gss_copy_oid(minor_status, &mech->mech_type, &ctx->mech_type); if (status != GSS_S_COMPLETE) { gssint_delete_internal_sec_context(&minor, ctx->mech_type, &internal_ctx, GSS_C_NO_BUFFER); free(ctx); return status; } ctx->internal_ctx_id = internal_ctx; *context_handle = (gss_ctx_id_t)ctx; } } else map_error(minor_status, mech); return status; }