Path: blob/main/crypto/heimdal/lib/gssapi/mech/gss_acquire_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_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $26*/2728#include "mech_locl.h"2930GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL31gss_acquire_cred(OM_uint32 *minor_status,32const gss_name_t desired_name,33OM_uint32 time_req,34const gss_OID_set desired_mechs,35gss_cred_usage_t cred_usage,36gss_cred_id_t *output_cred_handle,37gss_OID_set *actual_mechs,38OM_uint32 *time_rec)39{40OM_uint32 major_status;41gss_OID_set mechs = desired_mechs;42gss_OID_set_desc set;43struct _gss_name *name = (struct _gss_name *) desired_name;44gssapi_mech_interface m;45struct _gss_cred *cred;46struct _gss_mechanism_cred *mc;47OM_uint32 min_time, cred_time;48size_t i;4950*minor_status = 0;51if (output_cred_handle == NULL)52return GSS_S_CALL_INACCESSIBLE_READ;53if (actual_mechs)54*actual_mechs = GSS_C_NO_OID_SET;55if (time_rec)56*time_rec = 0;5758_gss_load_mech();5960/*61* First make sure that at least one of the requested62* mechanisms is one that we support.63*/64if (mechs) {65for (i = 0; i < mechs->count; i++) {66int t;67gss_test_oid_set_member(minor_status,68&mechs->elements[i], _gss_mech_oids, &t);69if (t)70break;71}72if (i == mechs->count) {73*minor_status = 0;74return (GSS_S_BAD_MECH);75}76}7778if (actual_mechs) {79major_status = gss_create_empty_oid_set(minor_status,80actual_mechs);81if (major_status)82return (major_status);83}8485cred = malloc(sizeof(struct _gss_cred));86if (!cred) {87if (actual_mechs)88gss_release_oid_set(minor_status, actual_mechs);89*minor_status = ENOMEM;90return (GSS_S_FAILURE);91}92HEIM_SLIST_INIT(&cred->gc_mc);9394if (mechs == GSS_C_NO_OID_SET)95mechs = _gss_mech_oids;9697set.count = 1;98min_time = GSS_C_INDEFINITE;99for (i = 0; i < mechs->count; i++) {100struct _gss_mechanism_name *mn = NULL;101102m = __gss_get_mechanism(&mechs->elements[i]);103if (!m)104continue;105106if (desired_name != GSS_C_NO_NAME) {107major_status = _gss_find_mn(minor_status, name,108&mechs->elements[i], &mn);109if (major_status != GSS_S_COMPLETE)110continue;111}112113mc = malloc(sizeof(struct _gss_mechanism_cred));114if (!mc) {115continue;116}117mc->gmc_mech = m;118mc->gmc_mech_oid = &m->gm_mech_oid;119120/*121* XXX Probably need to do something with actual_mechs.122*/123set.elements = &mechs->elements[i];124major_status = m->gm_acquire_cred(minor_status,125(desired_name != GSS_C_NO_NAME126? mn->gmn_name : GSS_C_NO_NAME),127time_req, &set, cred_usage,128&mc->gmc_cred, NULL, &cred_time);129if (major_status) {130free(mc);131continue;132}133if (cred_time < min_time)134min_time = cred_time;135136if (actual_mechs) {137major_status = gss_add_oid_set_member(minor_status,138mc->gmc_mech_oid, actual_mechs);139if (major_status) {140m->gm_release_cred(minor_status,141&mc->gmc_cred);142free(mc);143continue;144}145}146147HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);148}149150/*151* If we didn't manage to create a single credential, return152* an error.153*/154if (!HEIM_SLIST_FIRST(&cred->gc_mc)) {155free(cred);156if (actual_mechs)157gss_release_oid_set(minor_status, actual_mechs);158*minor_status = 0;159return (GSS_S_NO_CRED);160}161162if (time_rec)163*time_rec = min_time;164*output_cred_handle = (gss_cred_id_t) cred;165*minor_status = 0;166return (GSS_S_COMPLETE);167}168169170