Path: blob/main/crypto/heimdal/lib/gssapi/mech/gss_acquire_cred_ext.c
34907 views
/*-1* Copyright (c) 2005 Doug Rabson2* All rights reserved.3*4* Portions Copyright (c) 2011 PADL Software Pty Ltd.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*27* $FreeBSD: src/lib/libgssapi/gss_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $28*/2930#include "mech_locl.h"3132OM_uint3233_gss_acquire_mech_cred(OM_uint32 *minor_status,34gssapi_mech_interface m,35const struct _gss_mechanism_name *mn,36gss_const_OID credential_type,37const void *credential_data,38OM_uint32 time_req,39gss_const_OID desired_mech,40gss_cred_usage_t cred_usage,41struct _gss_mechanism_cred **output_cred_handle)42{43OM_uint32 major_status;44struct _gss_mechanism_cred *mc;45gss_OID_set_desc set2;4647*output_cred_handle = NULL;4849mc = calloc(1, sizeof(struct _gss_mechanism_cred));50if (mc == NULL) {51*minor_status = ENOMEM;52return GSS_S_FAILURE;53}5455mc->gmc_mech = m;56mc->gmc_mech_oid = &m->gm_mech_oid;5758set2.count = 1;59set2.elements = mc->gmc_mech_oid;6061if (m->gm_acquire_cred_ext) {62major_status = m->gm_acquire_cred_ext(minor_status,63mn->gmn_name,64credential_type,65credential_data,66time_req,67mc->gmc_mech_oid,68cred_usage,69&mc->gmc_cred);70} else if (gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD) &&71m->gm_compat &&72m->gm_compat->gmc_acquire_cred_with_password) {73/*74* Shim for mechanisms that adhere to API-as-SPI and do not75* implement gss_acquire_cred_ext().76*/7778major_status = m->gm_compat->gmc_acquire_cred_with_password(minor_status,79mn->gmn_name,80(const gss_buffer_t)credential_data,81time_req,82&set2,83cred_usage,84&mc->gmc_cred,85NULL,86NULL);87} else if (credential_type == GSS_C_NO_OID) {88major_status = m->gm_acquire_cred(minor_status,89mn->gmn_name,90time_req,91&set2,92cred_usage,93&mc->gmc_cred,94NULL,95NULL);96} else {97major_status = GSS_S_UNAVAILABLE;98free(mc);99mc= NULL;100}101102*output_cred_handle = mc;103return major_status;104}105106OM_uint32107_gss_acquire_cred_ext(OM_uint32 *minor_status,108const gss_name_t desired_name,109gss_const_OID credential_type,110const void *credential_data,111OM_uint32 time_req,112gss_const_OID desired_mech,113gss_cred_usage_t cred_usage,114gss_cred_id_t *output_cred_handle)115{116OM_uint32 major_status;117struct _gss_name *name = (struct _gss_name *) desired_name;118gssapi_mech_interface m;119struct _gss_cred *cred;120gss_OID_set_desc set, *mechs;121size_t i;122123*minor_status = 0;124if (output_cred_handle == NULL)125return GSS_S_CALL_INACCESSIBLE_READ;126127_gss_load_mech();128129if (desired_mech != GSS_C_NO_OID) {130int match = 0;131132gss_test_oid_set_member(minor_status, (gss_OID)desired_mech,133_gss_mech_oids, &match);134if (!match)135return GSS_S_BAD_MECH;136137set.count = 1;138set.elements = (gss_OID)desired_mech;139mechs = &set;140} else141mechs = _gss_mech_oids;142143cred = calloc(1, sizeof(*cred));144if (cred == NULL) {145*minor_status = ENOMEM;146return GSS_S_FAILURE;147}148149HEIM_SLIST_INIT(&cred->gc_mc);150151for (i = 0; i < mechs->count; i++) {152struct _gss_mechanism_name *mn = NULL;153struct _gss_mechanism_cred *mc = NULL;154gss_name_t desired_mech_name = GSS_C_NO_NAME;155156m = __gss_get_mechanism(&mechs->elements[i]);157if (!m)158continue;159160if (desired_name != GSS_C_NO_NAME) {161major_status = _gss_find_mn(minor_status, name,162&mechs->elements[i], &mn);163if (major_status != GSS_S_COMPLETE)164continue;165166desired_mech_name = mn->gmn_name;167}168169major_status = _gss_acquire_mech_cred(minor_status, m, mn,170credential_type, credential_data,171time_req, desired_mech, cred_usage,172&mc);173if (GSS_ERROR(major_status))174continue;175176HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);177}178179/*180* If we didn't manage to create a single credential, return181* an error.182*/183if (!HEIM_SLIST_FIRST(&cred->gc_mc)) {184free(cred);185*minor_status = 0;186return GSS_S_NO_CRED;187}188189*output_cred_handle = (gss_cred_id_t) cred;190*minor_status = 0;191return GSS_S_COMPLETE;192}193194195