gss_add_cred_with_password.c revision 303975
1238104Sdes/*- 2238104Sdes * Copyright (c) 2005 Doug Rabson 3238104Sdes * All rights reserved. 4238104Sdes * 5238104Sdes * Redistribution and use in source and binary forms, with or without 6238104Sdes * modification, are permitted provided that the following conditions 7238104Sdes * are met: 8238104Sdes * 1. Redistributions of source code must retain the above copyright 9238104Sdes * notice, this list of conditions and the following disclaimer. 10238104Sdes * 2. Redistributions in binary form must reproduce the above copyright 11238104Sdes * notice, this list of conditions and the following disclaimer in the 12238104Sdes * documentation and/or other materials provided with the distribution. 13238104Sdes * 14238104Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15238104Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16238104Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17238104Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18238104Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19238104Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20238104Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21238104Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22238104Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23238104Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24238104Sdes * SUCH DAMAGE. 25238104Sdes * 26238104Sdes * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ 27238104Sdes */ 28238104Sdes 29238104Sdes#include "mech_locl.h" 30238104Sdes 31238104SdesGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 32238104Sdesgss_add_cred_with_password(OM_uint32 *minor_status, 33238104Sdes const gss_cred_id_t input_cred_handle, 34238104Sdes const gss_name_t desired_name, 35238104Sdes const gss_OID desired_mech, 36238104Sdes const gss_buffer_t password, 37238104Sdes gss_cred_usage_t cred_usage, 38238104Sdes OM_uint32 initiator_time_req, 39238104Sdes OM_uint32 acceptor_time_req, 40238104Sdes gss_cred_id_t *output_cred_handle, 41238104Sdes gss_OID_set *actual_mechs, 42238104Sdes OM_uint32 *initiator_time_rec, 43238104Sdes OM_uint32 *acceptor_time_rec) 44238104Sdes{ 45238104Sdes OM_uint32 major_status; 46238104Sdes gssapi_mech_interface m; 47238104Sdes struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle; 48238104Sdes struct _gss_cred *new_cred; 49238104Sdes struct _gss_mechanism_cred *mc; 50238104Sdes struct _gss_mechanism_name *mn = NULL; 51238104Sdes OM_uint32 junk, time_req; 52238104Sdes 53238104Sdes *minor_status = 0; 54238104Sdes *output_cred_handle = GSS_C_NO_CREDENTIAL; 55238104Sdes if (initiator_time_rec) 56238104Sdes *initiator_time_rec = 0; 57238104Sdes if (acceptor_time_rec) 58238104Sdes *acceptor_time_rec = 0; 59238104Sdes if (actual_mechs) 60238104Sdes *actual_mechs = GSS_C_NO_OID_SET; 61238104Sdes 62238104Sdes m = __gss_get_mechanism(desired_mech); 63238104Sdes if (m == NULL) { 64238104Sdes *minor_status = 0; 65238104Sdes return (GSS_S_BAD_MECH); 66238104Sdes } 67238104Sdes 68238104Sdes new_cred = calloc(1, sizeof(struct _gss_cred)); 69238104Sdes if (new_cred == NULL) { 70238104Sdes *minor_status = ENOMEM; 71238104Sdes return (GSS_S_FAILURE); 72238104Sdes } 73238104Sdes HEIM_SLIST_INIT(&new_cred->gc_mc); 74238104Sdes 75238104Sdes /* 76238104Sdes * Copy credentials from un-desired mechanisms to the new credential. 77238104Sdes */ 78238104Sdes if (cred) { 79238104Sdes HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { 80238104Sdes struct _gss_mechanism_cred *copy_mc; 81238104Sdes 82238104Sdes if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) { 83238104Sdes continue; 84238104Sdes } 85238104Sdes copy_mc = _gss_copy_cred(mc); 86238104Sdes if (copy_mc == NULL) { 87238104Sdes gss_release_cred(&junk, (gss_cred_id_t *)&new_cred); 88238104Sdes *minor_status = ENOMEM; 89238104Sdes return (GSS_S_FAILURE); 90238104Sdes } 91238104Sdes HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link); 92238104Sdes } 93238104Sdes } 94238104Sdes 95238104Sdes /* 96269257Sdes * Figure out a suitable mn, if any. 97269257Sdes */ 98269257Sdes if (desired_name != GSS_C_NO_NAME) { 99269257Sdes major_status = _gss_find_mn(minor_status, 100269257Sdes (struct _gss_name *) desired_name, 101269257Sdes desired_mech, 102269257Sdes &mn); 103238104Sdes if (major_status != GSS_S_COMPLETE) { 104238104Sdes gss_release_cred(&junk, (gss_cred_id_t *)&new_cred); 105238104Sdes return (major_status); 106238104Sdes } 107238104Sdes } 108238104Sdes 109238104Sdes if (cred_usage == GSS_C_BOTH) 110246827Sdes time_req = initiator_time_req > acceptor_time_req ? acceptor_time_req : initiator_time_req; 111238104Sdes else if (cred_usage == GSS_C_INITIATE) 112238104Sdes time_req = initiator_time_req; 113238104Sdes else 114238104Sdes time_req = acceptor_time_req; 115238104Sdes 116238104Sdes major_status = _gss_acquire_mech_cred(minor_status, m, mn, 117238104Sdes GSS_C_CRED_PASSWORD, password, 118238104Sdes time_req, desired_mech, 119238104Sdes cred_usage, &mc); 120238104Sdes if (major_status != GSS_S_COMPLETE) { 121238104Sdes gss_release_cred(&junk, (gss_cred_id_t *)&new_cred); 122238104Sdes return (major_status); 123238104Sdes } 124238104Sdes 125238104Sdes HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link); 126238104Sdes 127238104Sdes if (actual_mechs || initiator_time_rec || acceptor_time_rec) { 128238104Sdes OM_uint32 time_rec; 129269257Sdes 130269257Sdes major_status = gss_inquire_cred(minor_status, 131238104Sdes (gss_cred_id_t)new_cred, 132238104Sdes NULL, 133238104Sdes &time_rec, 134238104Sdes NULL, 135238104Sdes actual_mechs); 136238104Sdes if (GSS_ERROR(major_status)) { 137238104Sdes gss_release_cred(&junk, (gss_cred_id_t *)&new_cred); 138238104Sdes return (major_status); 139238104Sdes } 140238104Sdes if (initiator_time_rec && 141238104Sdes (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH)) 142238104Sdes *initiator_time_rec = time_rec; 143238104Sdes if (acceptor_time_rec && 144238104Sdes (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH)) 145238104Sdes *acceptor_time_rec = time_rec; 146238104Sdes } 147238104Sdes 148238104Sdes *output_cred_handle = (gss_cred_id_t) new_cred; 149238104Sdes return (GSS_S_COMPLETE); 150238104Sdes} 151238104Sdes