1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 | #pragma ident "@(#)g_inquire_cred.c 1.17 04/09/08 SMI" 6 | #pragma ident "@(#)g_inquire_cred.c 1.16 04/02/23 SMI" 7 8 /* 9 * glue routine for gss_inquire_cred 10 */ 11 12 #include <mechglueP.h> 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <time.h> 17 18 OM_uint32 19 gss_inquire_cred(minor_status, 20 cred_handle, 21 name, 22 lifetime, 23 cred_usage, 24 mechanisms) 25 26 OM_uint32 *minor_status; 27 const gss_cred_id_t cred_handle; 28 gss_name_t *name; 29 OM_uint32 *lifetime; 30 int *cred_usage; 31 gss_OID_set *mechanisms; 32 33 { 34 OM_uint32 status, elapsed_time, temp_minor_status; 35 gss_union_cred_t union_cred; 36 gss_mechanism mech; 37 gss_name_t internal_name; 38 int i; 39 40 | gss_initialize(); 40 | /* check parms and set to defaults */ 41 + if (minor_status == NULL) 42 + return (GSS_S_CALL_INACCESSIBLE_WRITE); 43 + *minor_status = 0; 44 45 + if (name) 46 + *name = NULL; 47 + 48 + if (mechanisms) 49 + *mechanisms = NULL; 50 + 51 if (cred_handle == GSS_C_NO_CREDENTIAL) { 52 /* 53 * No credential was supplied. This means we can't get a mechanism 54 * pointer to call the mechanism specific gss_inquire_cred. 55 * So, call get_mechanism with an arguement of GSS_C_NULL_OID. 56 * get_mechanism will return the first mechanism in the mech 57 * array, which becomes the default mechanism. 58 */ 59 60 if ((mech = __gss_get_mechanism(GSS_C_NULL_OID)) == NULL) 52 | return (GSS_S_NO_CRED); 61 | return (GSS_S_DEFECTIVE_CREDENTIAL); 62 63 if (!mech->gss_inquire_cred) 55 | return (GSS_S_FAILURE); 64 | return (GSS_S_UNAVAILABLE); 65 66 status = mech->gss_inquire_cred(mech->context, minor_status, 67 GSS_C_NO_CREDENTIAL, 68 name ? &internal_name : NULL, 69 lifetime, cred_usage, 70 mechanisms); 71 72 if (status != GSS_S_COMPLETE) 73 return (status); 74 75 if (name) { 76 /* 77 * Convert internal_name into a union_name equivalent. 78 */ 79 status = __gss_convert_name_to_union_name( 80 &temp_minor_status, mech, 81 internal_name, name); 74 - if (minor_status) { 82 if (status != GSS_S_COMPLETE) { 83 *minor_status = temp_minor_status; 76 | __gss_release_internal_name( 84 | if (mechanisms && *mechanisms) { 85 + (void) gss_release_oid_set( 86 &temp_minor_status, 78 | &mech->mech_type, 87 | mechanisms); 79 - &internal_name); 88 } 89 return (status); 90 } 91 } 92 return (GSS_S_COMPLETE); 93 } 94 95 /* get the cred_handle cast as a union_credentials structure */ 96 97 union_cred = (gss_union_cred_t)cred_handle; 98 99 /* 100 * get the information out of the union_cred structure that was 101 * placed there during gss_acquire_cred. 102 */ 103 104 if (cred_usage != NULL) 105 *cred_usage = union_cred->auxinfo.cred_usage; 106 107 if (lifetime != NULL) { 108 elapsed_time = time(0) - union_cred->auxinfo.creation_time; 109 *lifetime = union_cred->auxinfo.time_rec < elapsed_time ? 0 : 110 union_cred->auxinfo.time_rec - elapsed_time; 111 } 112 113 /* 114 * if name is non_null, 115 * call gss_import_name() followed by gss_canonicalize_name() 116 * to get a mechanism specific name passed back to the caller. 117 * If this call fails, return failure to our caller. 118 * XXX The cred_handle may contain an array of mechanism OID's 119 * but we only return the MN for the first mechanism to the caller. 120 * In theory, we should modify this to provide an array of MN's 121 * one per mechanism back to the caller. 122 */ 123 124 if (name != NULL) { 125 if ((gss_import_name(minor_status, 126 &union_cred->auxinfo.name, 127 union_cred->auxinfo.name_type, 120 | name) != GSS_S_COMPLETE) 121 | return (GSS_S_DEFECTIVE_CREDENTIAL); 128 | name) != GSS_S_COMPLETE) || 129 | (gss_canonicalize_name(minor_status, *name, 130 + &union_cred->mechs_array[0], 131 + NULL) != GSS_S_COMPLETE)) { 132 + status = GSS_S_DEFECTIVE_CREDENTIAL; 133 + goto error; 134 } 135 + } 136 137 /* 138 * copy the mechanism set in union_cred into an OID set and return in 139 * the mechanisms parameter. 140 */ 141 if (mechanisms != NULL) { 129 | 142 | status = GSS_S_FAILURE; 143 *mechanisms = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)); 144 + if (*mechanisms == NULL) 145 + goto error; 146 132 | (*mechanisms)->count = union_cred->count; 147 | (*mechanisms)->count = 0; 148 (*mechanisms)->elements = 149 (gss_OID) malloc(sizeof (gss_OID_desc) * 150 union_cred->count); 151 152 + if ((*mechanisms)->elements == NULL) { 153 + free(*mechanisms); 154 + *mechanisms = NULL; 155 + goto error; 156 + } 157 + 138 - (*mechanisms)->elements[i].length = 139 - union_cred->mechs_array[i].length; 158 for (i = 0; i < union_cred->count; i++) { 159 (*mechanisms)->elements[i].elements = (void *) 160 malloc(union_cred->mechs_array[i].length); 142 | memcpy((*mechanisms)->elements[i].elements, 143 | union_cred->mechs_array[i].elements, 144 | union_cred->mechs_array[i].length); 161 | if ((*mechanisms)->elements[i].elements == NULL) 162 | goto error; 163 | g_OID_copy(&(*mechanisms)->elements[i], 164 + &union_cred->mechs_array[i]); 165 + (*mechanisms)->count++; 166 } 167 } 168 169 return (GSS_S_COMPLETE); 170 + 171 + error: 172 + /* 173 + * cleanup any allocated memory - we can just call 174 + * gss_release_oid_set, because the set is constructed so that 175 + * count always references the currently copied number of 176 + * elements. 177 + */ 178 + if (mechanisms && *mechanisms != NULL) 179 + (void) gss_release_oid_set(&temp_minor_status, mechanisms); 180 + 181 + if (name && *name != NULL) 182 + (void) gss_release_name(&temp_minor_status, name); 183 + 184 + return (status); 185 } 186 187 OM_uint32 188 gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name, 189 initiator_lifetime, acceptor_lifetime, cred_usage) 190 OM_uint32 *minor_status; 191 const gss_cred_id_t cred_handle; 192 const gss_OID mech_type; 193 gss_name_t *name; 194 OM_uint32 *initiator_lifetime; 195 OM_uint32 *acceptor_lifetime; 196 gss_cred_usage_t *cred_usage; 197 { 198 gss_union_cred_t union_cred; 199 gss_cred_id_t mech_cred; 200 gss_mechanism mech; 201 + OM_uint32 status, temp_minor_status; 202 + gss_name_t internal_name; 203 204 + 205 mech = __gss_get_mechanism(mech_type); 206 if (!mech) 207 return (GSS_S_BAD_MECH); 208 if (!mech->gss_inquire_cred_by_mech) 209 return (GSS_S_UNAVAILABLE); 210 211 union_cred = (gss_union_cred_t)cred_handle; 212 mech_cred = __gss_get_mechanism_cred(union_cred, mech_type); 213 + if (mech_cred == NULL) 214 + return (GSS_S_DEFECTIVE_CREDENTIAL); 215 175 | return (mech->gss_inquire_cred_by_mech(mech->context, minor_status, 216 | status = mech->gss_inquire_cred_by_mech(mech->context, minor_status, 217 mech_cred, mech_type, 177 | name, initiator_lifetime, 218 | name ? &internal_name : NULL, 219 + initiator_lifetime, 220 acceptor_lifetime, cred_usage); 221 + 222 + if (status != GSS_S_COMPLETE) 223 + return (status); 224 + 225 + if (name) { 226 + /* 227 + * Convert internal_name into a union_name equivalent. 228 + */ 229 + status = __gss_convert_name_to_union_name( 230 + &temp_minor_status, mech, 231 + internal_name, name); 232 + if (status != GSS_S_COMPLETE) { 233 + *minor_status = temp_minor_status; 234 + return (status); 235 + } 236 + } 237 + 238 + return (GSS_S_COMPLETE); 239 } ----Unchanged portion omitted----