1226031Sstas/*- 2226031Sstas * Copyright (c) 2005 Doug Rabson 3226031Sstas * All rights reserved. 4226031Sstas * 5226031Sstas * Redistribution and use in source and binary forms, with or without 6226031Sstas * modification, are permitted provided that the following conditions 7226031Sstas * are met: 8226031Sstas * 1. Redistributions of source code must retain the above copyright 9226031Sstas * notice, this list of conditions and the following disclaimer. 10226031Sstas * 2. Redistributions in binary form must reproduce the above copyright 11226031Sstas * notice, this list of conditions and the following disclaimer in the 12226031Sstas * documentation and/or other materials provided with the distribution. 13226031Sstas * 14226031Sstas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17226031Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24226031Sstas * SUCH DAMAGE. 25226031Sstas * 26226031Sstas * $FreeBSD: src/lib/libgssapi/gss_inquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ 27226031Sstas */ 28226031Sstas 29226031Sstas#include "mech_locl.h" 30226031Sstas 31226031Sstas#define AUSAGE 1 32226031Sstas#define IUSAGE 2 33226031Sstas 34226031Sstasstatic void 35226031Sstasupdateusage(gss_cred_usage_t usage, int *usagemask) 36226031Sstas{ 37226031Sstas if (usage == GSS_C_BOTH) 38226031Sstas *usagemask |= AUSAGE | IUSAGE; 39226031Sstas else if (usage == GSS_C_ACCEPT) 40226031Sstas *usagemask |= AUSAGE; 41226031Sstas else if (usage == GSS_C_INITIATE) 42226031Sstas *usagemask |= IUSAGE; 43226031Sstas} 44226031Sstas 45226031SstasGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 46226031Sstasgss_inquire_cred(OM_uint32 *minor_status, 47226031Sstas const gss_cred_id_t cred_handle, 48226031Sstas gss_name_t *name_ret, 49226031Sstas OM_uint32 *lifetime, 50226031Sstas gss_cred_usage_t *cred_usage, 51226031Sstas gss_OID_set *mechanisms) 52226031Sstas{ 53226031Sstas OM_uint32 major_status; 54226031Sstas struct _gss_mech_switch *m; 55226031Sstas struct _gss_cred *cred = (struct _gss_cred *) cred_handle; 56226031Sstas struct _gss_name *name; 57226031Sstas struct _gss_mechanism_name *mn; 58226031Sstas OM_uint32 min_lifetime; 59226031Sstas int found = 0; 60226031Sstas int usagemask = 0; 61226031Sstas gss_cred_usage_t usage; 62226031Sstas 63226031Sstas _gss_load_mech(); 64226031Sstas 65226031Sstas *minor_status = 0; 66226031Sstas if (name_ret) 67226031Sstas *name_ret = GSS_C_NO_NAME; 68226031Sstas if (lifetime) 69226031Sstas *lifetime = 0; 70226031Sstas if (cred_usage) 71226031Sstas *cred_usage = 0; 72226031Sstas if (mechanisms) 73226031Sstas *mechanisms = GSS_C_NO_OID_SET; 74226031Sstas 75226031Sstas if (name_ret) { 76226031Sstas name = calloc(1, sizeof(*name)); 77226031Sstas if (name == NULL) { 78226031Sstas *minor_status = ENOMEM; 79226031Sstas return (GSS_S_FAILURE); 80226031Sstas } 81226031Sstas HEIM_SLIST_INIT(&name->gn_mn); 82226031Sstas } else { 83226031Sstas name = NULL; 84226031Sstas } 85226031Sstas 86226031Sstas if (mechanisms) { 87226031Sstas major_status = gss_create_empty_oid_set(minor_status, 88226031Sstas mechanisms); 89226031Sstas if (major_status) { 90226031Sstas if (name) free(name); 91226031Sstas return (major_status); 92226031Sstas } 93226031Sstas } 94226031Sstas 95226031Sstas min_lifetime = GSS_C_INDEFINITE; 96226031Sstas if (cred) { 97226031Sstas struct _gss_mechanism_cred *mc; 98226031Sstas 99226031Sstas HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { 100226031Sstas gss_name_t mc_name; 101226031Sstas OM_uint32 mc_lifetime; 102226031Sstas 103226031Sstas major_status = mc->gmc_mech->gm_inquire_cred(minor_status, 104226031Sstas mc->gmc_cred, &mc_name, &mc_lifetime, &usage, NULL); 105226031Sstas if (major_status) 106226031Sstas continue; 107226031Sstas 108226031Sstas updateusage(usage, &usagemask); 109226031Sstas if (name) { 110226031Sstas mn = malloc(sizeof(struct _gss_mechanism_name)); 111226031Sstas if (!mn) { 112226031Sstas mc->gmc_mech->gm_release_name(minor_status, 113226031Sstas &mc_name); 114226031Sstas continue; 115226031Sstas } 116226031Sstas mn->gmn_mech = mc->gmc_mech; 117226031Sstas mn->gmn_mech_oid = mc->gmc_mech_oid; 118226031Sstas mn->gmn_name = mc_name; 119226031Sstas HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); 120226031Sstas } else { 121226031Sstas mc->gmc_mech->gm_release_name(minor_status, 122226031Sstas &mc_name); 123226031Sstas } 124226031Sstas 125226031Sstas if (mc_lifetime < min_lifetime) 126226031Sstas min_lifetime = mc_lifetime; 127226031Sstas 128226031Sstas if (mechanisms) 129226031Sstas gss_add_oid_set_member(minor_status, 130226031Sstas mc->gmc_mech_oid, mechanisms); 131226031Sstas found++; 132226031Sstas } 133226031Sstas } else { 134226031Sstas HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) { 135226031Sstas gss_name_t mc_name; 136226031Sstas OM_uint32 mc_lifetime; 137226031Sstas 138226031Sstas major_status = m->gm_mech.gm_inquire_cred(minor_status, 139226031Sstas GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime, 140226031Sstas &usage, NULL); 141226031Sstas if (major_status) 142226031Sstas continue; 143226031Sstas 144226031Sstas updateusage(usage, &usagemask); 145226031Sstas if (name && mc_name) { 146226031Sstas mn = malloc( 147226031Sstas sizeof(struct _gss_mechanism_name)); 148226031Sstas if (!mn) { 149226031Sstas m->gm_mech.gm_release_name( 150226031Sstas minor_status, &mc_name); 151226031Sstas continue; 152226031Sstas } 153226031Sstas mn->gmn_mech = &m->gm_mech; 154226031Sstas mn->gmn_mech_oid = &m->gm_mech_oid; 155226031Sstas mn->gmn_name = mc_name; 156226031Sstas HEIM_SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link); 157226031Sstas } else if (mc_name) { 158226031Sstas m->gm_mech.gm_release_name(minor_status, 159226031Sstas &mc_name); 160226031Sstas } 161226031Sstas 162226031Sstas if (mc_lifetime < min_lifetime) 163226031Sstas min_lifetime = mc_lifetime; 164226031Sstas 165226031Sstas if (mechanisms) 166226031Sstas gss_add_oid_set_member(minor_status, 167226031Sstas &m->gm_mech_oid, mechanisms); 168226031Sstas found++; 169226031Sstas } 170226031Sstas } 171226031Sstas 172226031Sstas if (found == 0) { 173226031Sstas gss_name_t n = (gss_name_t)name; 174226031Sstas if (n) 175226031Sstas gss_release_name(minor_status, &n); 176226031Sstas gss_release_oid_set(minor_status, mechanisms); 177226031Sstas *minor_status = 0; 178226031Sstas return (GSS_S_NO_CRED); 179226031Sstas } 180226031Sstas 181226031Sstas *minor_status = 0; 182226031Sstas if (name_ret) 183226031Sstas *name_ret = (gss_name_t) name; 184226031Sstas if (lifetime) 185226031Sstas *lifetime = min_lifetime; 186226031Sstas if (cred_usage) { 187226031Sstas if ((usagemask & (AUSAGE|IUSAGE)) == (AUSAGE|IUSAGE)) 188226031Sstas *cred_usage = GSS_C_BOTH; 189226031Sstas else if (usagemask & IUSAGE) 190226031Sstas *cred_usage = GSS_C_INITIATE; 191226031Sstas else if (usagemask & AUSAGE) 192226031Sstas *cred_usage = GSS_C_ACCEPT; 193226031Sstas } 194226031Sstas return (GSS_S_COMPLETE); 195226031Sstas} 196