Path: blob/main/crypto/heimdal/lib/gssapi/mech/gss_add_cred.c
34907 views
/*-1* Copyright (c) 2005 Doug Rabson2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*25* $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $26*/2728#include "mech_locl.h"2930struct _gss_mechanism_cred *31_gss_copy_cred(struct _gss_mechanism_cred *mc)32{33struct _gss_mechanism_cred *new_mc;34gssapi_mech_interface m = mc->gmc_mech;35OM_uint32 major_status, minor_status;36gss_name_t name;37gss_cred_id_t cred;38OM_uint32 initiator_lifetime, acceptor_lifetime;39gss_cred_usage_t cred_usage;4041major_status = m->gm_inquire_cred_by_mech(&minor_status,42mc->gmc_cred, mc->gmc_mech_oid,43&name, &initiator_lifetime, &acceptor_lifetime, &cred_usage);44if (major_status) {45_gss_mg_error(m, major_status, minor_status);46return (0);47}4849major_status = m->gm_add_cred(&minor_status,50GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid,51cred_usage, initiator_lifetime, acceptor_lifetime,52&cred, 0, 0, 0);53m->gm_release_name(&minor_status, &name);5455if (major_status) {56_gss_mg_error(m, major_status, minor_status);57return (0);58}5960new_mc = malloc(sizeof(struct _gss_mechanism_cred));61if (!new_mc) {62m->gm_release_cred(&minor_status, &cred);63return (0);64}65new_mc->gmc_mech = m;66new_mc->gmc_mech_oid = &m->gm_mech_oid;67new_mc->gmc_cred = cred;6869return (new_mc);70}7172GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL73gss_add_cred(OM_uint32 *minor_status,74const gss_cred_id_t input_cred_handle,75const gss_name_t desired_name,76const gss_OID desired_mech,77gss_cred_usage_t cred_usage,78OM_uint32 initiator_time_req,79OM_uint32 acceptor_time_req,80gss_cred_id_t *output_cred_handle,81gss_OID_set *actual_mechs,82OM_uint32 *initiator_time_rec,83OM_uint32 *acceptor_time_rec)84{85OM_uint32 major_status;86gssapi_mech_interface m;87struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle;88struct _gss_cred *new_cred;89gss_cred_id_t release_cred;90struct _gss_mechanism_cred *mc, *target_mc, *copy_mc;91struct _gss_mechanism_name *mn;92OM_uint32 junk;9394*minor_status = 0;95*output_cred_handle = GSS_C_NO_CREDENTIAL;96if (initiator_time_rec)97*initiator_time_rec = 0;98if (acceptor_time_rec)99*acceptor_time_rec = 0;100if (actual_mechs)101*actual_mechs = GSS_C_NO_OID_SET;102103new_cred = malloc(sizeof(struct _gss_cred));104if (!new_cred) {105*minor_status = ENOMEM;106return (GSS_S_FAILURE);107}108HEIM_SLIST_INIT(&new_cred->gc_mc);109110/*111* We go through all the mc attached to the input_cred_handle112* and check the mechanism. If it matches, we call113* gss_add_cred for that mechanism, otherwise we copy the mc114* to new_cred.115*/116target_mc = 0;117if (cred) {118HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {119if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {120target_mc = mc;121}122copy_mc = _gss_copy_cred(mc);123if (!copy_mc) {124release_cred = (gss_cred_id_t)new_cred;125gss_release_cred(&junk, &release_cred);126*minor_status = ENOMEM;127return (GSS_S_FAILURE);128}129HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link);130}131}132133/*134* Figure out a suitable mn, if any.135*/136if (desired_name) {137major_status = _gss_find_mn(minor_status,138(struct _gss_name *) desired_name,139desired_mech,140&mn);141if (major_status != GSS_S_COMPLETE) {142free(new_cred);143return major_status;144}145} else {146mn = 0;147}148149m = __gss_get_mechanism(desired_mech);150151mc = malloc(sizeof(struct _gss_mechanism_cred));152if (!mc) {153release_cred = (gss_cred_id_t)new_cred;154gss_release_cred(&junk, &release_cred);155*minor_status = ENOMEM;156return (GSS_S_FAILURE);157}158mc->gmc_mech = m;159mc->gmc_mech_oid = &m->gm_mech_oid;160161major_status = m->gm_add_cred(minor_status,162target_mc ? target_mc->gmc_cred : GSS_C_NO_CREDENTIAL,163desired_name ? mn->gmn_name : GSS_C_NO_NAME,164desired_mech,165cred_usage,166initiator_time_req,167acceptor_time_req,168&mc->gmc_cred,169actual_mechs,170initiator_time_rec,171acceptor_time_rec);172173if (major_status) {174_gss_mg_error(m, major_status, *minor_status);175release_cred = (gss_cred_id_t)new_cred;176gss_release_cred(&junk, &release_cred);177free(mc);178return (major_status);179}180HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link);181*output_cred_handle = (gss_cred_id_t) new_cred;182183return (GSS_S_COMPLETE);184}185186187188