Path: blob/main/crypto/heimdal/lib/gssapi/krb5/add_cred.c
34923 views
/*1* Copyright (c) 2003 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "gsskrb5_locl.h"3435OM_uint32 GSSAPI_CALLCONV _gsskrb5_add_cred (36OM_uint32 *minor_status,37const gss_cred_id_t input_cred_handle,38const gss_name_t desired_name,39const gss_OID desired_mech,40gss_cred_usage_t cred_usage,41OM_uint32 initiator_time_req,42OM_uint32 acceptor_time_req,43gss_cred_id_t *output_cred_handle,44gss_OID_set *actual_mechs,45OM_uint32 *initiator_time_rec,46OM_uint32 *acceptor_time_rec)47{48krb5_context context;49OM_uint32 ret, lifetime;50gsskrb5_cred cred, handle;51krb5_const_principal dname;5253handle = NULL;54cred = (gsskrb5_cred)input_cred_handle;55dname = (krb5_const_principal)desired_name;5657GSSAPI_KRB5_INIT (&context);5859if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0) {60*minor_status = 0;61return GSS_S_BAD_MECH;62}6364if (cred == NULL && output_cred_handle == NULL) {65*minor_status = 0;66return GSS_S_NO_CRED;67}6869if (cred == NULL) { /* XXX standard conformance failure */70*minor_status = 0;71return GSS_S_NO_CRED;72}7374/* check if requested output usage is compatible with output usage */75if (output_cred_handle != NULL) {76HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);77if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) {78HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);79*minor_status = GSS_KRB5_S_G_BAD_USAGE;80return(GSS_S_FAILURE);81}82}8384/* check that we have the same name */85if (dname != NULL &&86krb5_principal_compare(context, dname,87cred->principal) != FALSE) {88if (output_cred_handle)89HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);90*minor_status = 0;91return GSS_S_BAD_NAME;92}9394/* make a copy */95if (output_cred_handle) {96krb5_error_code kret;9798handle = calloc(1, sizeof(*handle));99if (handle == NULL) {100HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);101*minor_status = ENOMEM;102return (GSS_S_FAILURE);103}104105handle->usage = cred_usage;106handle->lifetime = cred->lifetime;107handle->principal = NULL;108handle->keytab = NULL;109handle->ccache = NULL;110handle->mechanisms = NULL;111HEIMDAL_MUTEX_init(&handle->cred_id_mutex);112113ret = GSS_S_FAILURE;114115kret = krb5_copy_principal(context, cred->principal,116&handle->principal);117if (kret) {118HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);119free(handle);120*minor_status = kret;121return GSS_S_FAILURE;122}123124if (cred->keytab) {125char *name = NULL;126127ret = GSS_S_FAILURE;128129kret = krb5_kt_get_full_name(context, cred->keytab, &name);130if (kret) {131*minor_status = kret;132goto failure;133}134135kret = krb5_kt_resolve(context, name,136&handle->keytab);137krb5_xfree(name);138if (kret){139*minor_status = kret;140goto failure;141}142}143144if (cred->ccache) {145const char *type, *name;146char *type_name = NULL;147148ret = GSS_S_FAILURE;149150type = krb5_cc_get_type(context, cred->ccache);151if (type == NULL){152*minor_status = ENOMEM;153goto failure;154}155156if (strcmp(type, "MEMORY") == 0) {157ret = krb5_cc_new_unique(context, type,158NULL, &handle->ccache);159if (ret) {160*minor_status = ret;161goto failure;162}163164ret = krb5_cc_copy_cache(context, cred->ccache,165handle->ccache);166if (ret) {167*minor_status = ret;168goto failure;169}170171} else {172name = krb5_cc_get_name(context, cred->ccache);173if (name == NULL) {174*minor_status = ENOMEM;175goto failure;176}177178kret = asprintf(&type_name, "%s:%s", type, name);179if (kret < 0 || type_name == NULL) {180*minor_status = ENOMEM;181goto failure;182}183184kret = krb5_cc_resolve(context, type_name,185&handle->ccache);186free(type_name);187if (kret) {188*minor_status = kret;189goto failure;190}191}192}193ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);194if (ret)195goto failure;196197ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,198&handle->mechanisms);199if (ret)200goto failure;201}202203HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);204205ret = _gsskrb5_inquire_cred(minor_status, (gss_cred_id_t)cred,206NULL, &lifetime, NULL, actual_mechs);207if (ret)208goto failure;209210if (initiator_time_rec)211*initiator_time_rec = lifetime;212if (acceptor_time_rec)213*acceptor_time_rec = lifetime;214215if (output_cred_handle) {216*output_cred_handle = (gss_cred_id_t)handle;217}218219*minor_status = 0;220return ret;221222failure:223224if (handle) {225if (handle->principal)226krb5_free_principal(context, handle->principal);227if (handle->keytab)228krb5_kt_close(context, handle->keytab);229if (handle->ccache)230krb5_cc_destroy(context, handle->ccache);231if (handle->mechanisms)232gss_release_oid_set(NULL, &handle->mechanisms);233free(handle);234}235if (output_cred_handle)236HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);237return ret;238}239240241