gss_acquire_cred_ext.c revision 1.1
1/* $NetBSD: gss_acquire_cred_ext.c,v 1.1 2014/04/24 12:45:29 pettai Exp $ */ 2 3/*- 4 * Copyright (c) 2005 Doug Rabson 5 * All rights reserved. 6 * 7 * Portions Copyright (c) 2011 PADL Software Pty Ltd. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * $FreeBSD: src/lib/libgssapi/gss_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ 31 */ 32 33#include "mech_locl.h" 34 35OM_uint32 36_gss_acquire_mech_cred(OM_uint32 *minor_status, 37 gssapi_mech_interface m, 38 const struct _gss_mechanism_name *mn, 39 gss_const_OID credential_type, 40 const void *credential_data, 41 OM_uint32 time_req, 42 gss_const_OID desired_mech, 43 gss_cred_usage_t cred_usage, 44 struct _gss_mechanism_cred **output_cred_handle) 45{ 46 OM_uint32 major_status; 47 struct _gss_mechanism_cred *mc; 48 gss_OID_set_desc set2; 49 50 *output_cred_handle = NULL; 51 52 mc = calloc(1, sizeof(struct _gss_mechanism_cred)); 53 if (mc == NULL) { 54 *minor_status = ENOMEM; 55 return GSS_S_FAILURE; 56 } 57 58 mc->gmc_mech = m; 59 mc->gmc_mech_oid = &m->gm_mech_oid; 60 61 set2.count = 1; 62 set2.elements = mc->gmc_mech_oid; 63 64 if (m->gm_acquire_cred_ext) { 65 major_status = m->gm_acquire_cred_ext(minor_status, 66 mn->gmn_name, 67 credential_type, 68 credential_data, 69 time_req, 70 mc->gmc_mech_oid, 71 cred_usage, 72 &mc->gmc_cred); 73 } else if (gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD) && 74 m->gm_compat && 75 m->gm_compat->gmc_acquire_cred_with_password) { 76 /* 77 * Shim for mechanisms that adhere to API-as-SPI and do not 78 * implement gss_acquire_cred_ext(). 79 */ 80 81 major_status = m->gm_compat->gmc_acquire_cred_with_password(minor_status, 82 mn->gmn_name, 83 (const gss_buffer_t)credential_data, 84 time_req, 85 &set2, 86 cred_usage, 87 &mc->gmc_cred, 88 NULL, 89 NULL); 90 } else if (credential_type == GSS_C_NO_OID) { 91 major_status = m->gm_acquire_cred(minor_status, 92 mn->gmn_name, 93 time_req, 94 &set2, 95 cred_usage, 96 &mc->gmc_cred, 97 NULL, 98 NULL); 99 } else { 100 major_status = GSS_S_UNAVAILABLE; 101 free(mc); 102 mc= NULL; 103 } 104 105 *output_cred_handle = mc; 106 return major_status; 107} 108 109OM_uint32 110_gss_acquire_cred_ext(OM_uint32 *minor_status, 111 const gss_name_t desired_name, 112 gss_const_OID credential_type, 113 const void *credential_data, 114 OM_uint32 time_req, 115 gss_const_OID desired_mech, 116 gss_cred_usage_t cred_usage, 117 gss_cred_id_t *output_cred_handle) 118{ 119 OM_uint32 major_status; 120 struct _gss_name *name = (struct _gss_name *) desired_name; 121 gssapi_mech_interface m; 122 struct _gss_cred *cred; 123 gss_OID_set_desc set, *mechs; 124 size_t i; 125 126 *minor_status = 0; 127 if (output_cred_handle == NULL) 128 return GSS_S_CALL_INACCESSIBLE_READ; 129 130 _gss_load_mech(); 131 132 if (desired_mech != GSS_C_NO_OID) { 133 int match = 0; 134 135 gss_test_oid_set_member(minor_status, (gss_OID)desired_mech, 136 _gss_mech_oids, &match); 137 if (!match) 138 return GSS_S_BAD_MECH; 139 140 set.count = 1; 141 set.elements = (gss_OID)desired_mech; 142 mechs = &set; 143 } else 144 mechs = _gss_mech_oids; 145 146 cred = calloc(1, sizeof(*cred)); 147 if (cred == NULL) { 148 *minor_status = ENOMEM; 149 return GSS_S_FAILURE; 150 } 151 152 HEIM_SLIST_INIT(&cred->gc_mc); 153 154 for (i = 0; i < mechs->count; i++) { 155 struct _gss_mechanism_name *mn = NULL; 156 struct _gss_mechanism_cred *mc = NULL; 157 gss_name_t desired_mech_name = GSS_C_NO_NAME; 158 159 m = __gss_get_mechanism(&mechs->elements[i]); 160 if (!m) 161 continue; 162 163 if (desired_name != GSS_C_NO_NAME) { 164 major_status = _gss_find_mn(minor_status, name, 165 &mechs->elements[i], &mn); 166 if (major_status != GSS_S_COMPLETE) 167 continue; 168 169 desired_mech_name = mn->gmn_name; 170 } 171 172 major_status = _gss_acquire_mech_cred(minor_status, m, mn, 173 credential_type, credential_data, 174 time_req, desired_mech, cred_usage, 175 &mc); 176 if (GSS_ERROR(major_status)) 177 continue; 178 179 HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link); 180 } 181 182 /* 183 * If we didn't manage to create a single credential, return 184 * an error. 185 */ 186 if (!HEIM_SLIST_FIRST(&cred->gc_mc)) { 187 free(cred); 188 *minor_status = 0; 189 return GSS_S_NO_CRED; 190 } 191 192 *output_cred_handle = (gss_cred_id_t) cred; 193 *minor_status = 0; 194 return GSS_S_COMPLETE; 195} 196