1 /* 2 * Copyright (c) 1997, 2003 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "krb5/gsskrb5_locl.h" 35 36 RCSID("$Id: inquire_cred.c 20688 2007-05-17 18:44:31Z lha $"); 37 38 OM_uint32 _gsskrb5_inquire_cred 39 (OM_uint32 * minor_status, 40 const gss_cred_id_t cred_handle, 41 gss_name_t * output_name, 42 OM_uint32 * lifetime, 43 gss_cred_usage_t * cred_usage, 44 gss_OID_set * mechanisms 45 ) 46 { 47 krb5_context context; 48 gss_cred_id_t aqcred_init = GSS_C_NO_CREDENTIAL; 49 gss_cred_id_t aqcred_accept = GSS_C_NO_CREDENTIAL; 50 gsskrb5_cred acred = NULL, icred = NULL; 51 OM_uint32 ret; 52 53 *minor_status = 0; 54 55 if (output_name) 56 *output_name = NULL; 57 if (mechanisms) 58 *mechanisms = GSS_C_NO_OID_SET; 59 60 GSSAPI_KRB5_INIT (&context); 61 62 if (cred_handle == GSS_C_NO_CREDENTIAL) { 63 ret = _gsskrb5_acquire_cred(minor_status, 64 GSS_C_NO_NAME, 65 GSS_C_INDEFINITE, 66 GSS_C_NO_OID_SET, 67 GSS_C_ACCEPT, 68 &aqcred_accept, 69 NULL, 70 NULL); 71 if (ret == GSS_S_COMPLETE) 72 acred = (gsskrb5_cred)aqcred_accept; 73 74 ret = _gsskrb5_acquire_cred(minor_status, 75 GSS_C_NO_NAME, 76 GSS_C_INDEFINITE, 77 GSS_C_NO_OID_SET, 78 GSS_C_INITIATE, 79 &aqcred_init, 80 NULL, 81 NULL); 82 if (ret == GSS_S_COMPLETE) 83 icred = (gsskrb5_cred)aqcred_init; 84 85 if (icred == NULL && acred == NULL) { 86 *minor_status = 0; 87 return GSS_S_NO_CRED; 88 } 89 } else 90 acred = (gsskrb5_cred)cred_handle; 91 92 if (acred) 93 HEIMDAL_MUTEX_lock(&acred->cred_id_mutex); 94 if (icred) 95 HEIMDAL_MUTEX_lock(&icred->cred_id_mutex); 96 97 if (output_name != NULL) { 98 if (icred && icred->principal != NULL) { 99 gss_name_t name; 100 101 if (acred && acred->principal) 102 name = (gss_name_t)acred->principal; 103 else 104 name = (gss_name_t)icred->principal; 105 106 ret = _gsskrb5_duplicate_name(minor_status, name, output_name); 107 if (ret) 108 goto out; 109 } else if (acred && acred->usage == GSS_C_ACCEPT) { 110 krb5_principal princ; 111 *minor_status = krb5_sname_to_principal(context, NULL, 112 NULL, KRB5_NT_SRV_HST, 113 &princ); 114 if (*minor_status) { 115 ret = GSS_S_FAILURE; 116 goto out; 117 } 118 *output_name = (gss_name_t)princ; 119 } else { 120 krb5_principal princ; 121 *minor_status = krb5_get_default_principal(context, 122 &princ); 123 if (*minor_status) { 124 ret = GSS_S_FAILURE; 125 goto out; 126 } 127 *output_name = (gss_name_t)princ; 128 } 129 } 130 if (lifetime != NULL) { 131 OM_uint32 alife = GSS_C_INDEFINITE, ilife = GSS_C_INDEFINITE; 132 133 if (acred) alife = acred->lifetime; 134 if (icred) ilife = icred->lifetime; 135 136 ret = _gsskrb5_lifetime_left(minor_status, 137 context, 138 min(alife,ilife), 139 lifetime); 140 if (ret) 141 goto out; 142 } 143 if (cred_usage != NULL) { 144 if (acred && icred) 145 *cred_usage = GSS_C_BOTH; 146 else if (acred) 147 *cred_usage = GSS_C_ACCEPT; 148 else if (icred) 149 *cred_usage = GSS_C_INITIATE; 150 else 151 abort(); 152 } 153 154 if (mechanisms != NULL) { 155 ret = gss_create_empty_oid_set(minor_status, mechanisms); 156 if (ret) 157 goto out; 158 if (acred) 159 ret = gss_add_oid_set_member(minor_status, 160 &acred->mechanisms->elements[0], 161 mechanisms); 162 if (ret == GSS_S_COMPLETE && icred) 163 ret = gss_add_oid_set_member(minor_status, 164 &icred->mechanisms->elements[0], 165 mechanisms); 166 if (ret) 167 goto out; 168 } 169 ret = GSS_S_COMPLETE; 170 out: 171 if (acred) 172 HEIMDAL_MUTEX_unlock(&acred->cred_id_mutex); 173 if (icred) 174 HEIMDAL_MUTEX_unlock(&icred->cred_id_mutex); 175 176 if (aqcred_init != GSS_C_NO_CREDENTIAL) 177 ret = _gsskrb5_release_cred(minor_status, &aqcred_init); 178 if (aqcred_accept != GSS_C_NO_CREDENTIAL) 179 ret = _gsskrb5_release_cred(minor_status, &aqcred_accept); 180 181 return ret; 182 } 183