1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 /* 26 * glue routine for gss_store_cred 27 */ 28 29 #include <mechglueP.h> 30 #include "gssapiP_generic.h" 31 #include <errno.h> 32 33 static OM_uint32 34 val_store_cred_args( 35 OM_uint32 *minor_status, 36 const gss_cred_id_t input_cred_handle, 37 gss_cred_usage_t cred_usage, 38 /*LINTED*/ 39 const gss_OID desired_mech, 40 /*LINTED*/ 41 OM_uint32 overwrite_cred, 42 /*LINTED*/ 43 OM_uint32 default_cred, 44 gss_OID_set *elements_stored, 45 /*LINTED*/ 46 gss_cred_usage_t *cred_usage_stored) 47 { 48 49 /* Initialize outputs. */ 50 51 if (minor_status != NULL) 52 *minor_status = 0; 53 54 if (elements_stored != NULL) 55 *elements_stored = GSS_C_NULL_OID_SET; 56 57 /* Validate arguments. */ 58 59 if (minor_status == NULL) 60 return (GSS_S_CALL_INACCESSIBLE_WRITE); 61 62 if (input_cred_handle == GSS_C_NO_CREDENTIAL) 63 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CRED); 64 65 if (cred_usage != GSS_C_ACCEPT 66 && cred_usage != GSS_C_INITIATE 67 && cred_usage != GSS_C_BOTH) { 68 if (minor_status) { 69 *minor_status = EINVAL; 70 map_errcode(minor_status); 71 } 72 return GSS_S_FAILURE; 73 } 74 75 return (GSS_S_COMPLETE); 76 } 77 78 OM_uint32 gss_store_cred(minor_status, 79 input_cred_handle, 80 cred_usage, 81 desired_mech, 82 overwrite_cred, 83 default_cred, 84 elements_stored, 85 cred_usage_stored) 86 87 OM_uint32 *minor_status; 88 const gss_cred_id_t input_cred_handle; 89 gss_cred_usage_t cred_usage; 90 const gss_OID desired_mech; 91 OM_uint32 overwrite_cred; 92 OM_uint32 default_cred; 93 gss_OID_set *elements_stored; 94 gss_cred_usage_t *cred_usage_stored; 95 96 { 97 OM_uint32 major_status = GSS_S_FAILURE; 98 gss_union_cred_t union_cred; 99 gss_cred_id_t mech_cred; 100 gss_mechanism mech; 101 gss_OID dmech; 102 int i; 103 104 major_status = val_store_cred_args(minor_status, 105 input_cred_handle, 106 cred_usage, 107 desired_mech, 108 overwrite_cred, 109 default_cred, 110 elements_stored, 111 cred_usage_stored); 112 if (major_status != GSS_S_COMPLETE) 113 return (major_status); 114 115 /* Initial value needed below. */ 116 major_status = GSS_S_FAILURE; 117 118 if (cred_usage_stored != NULL) 119 *cred_usage_stored = GSS_C_BOTH; /* there's no GSS_C_NEITHER */ 120 121 union_cred = (gss_union_cred_t)input_cred_handle; 122 123 /* desired_mech != GSS_C_NULL_OID -> store one element */ 124 if (desired_mech != GSS_C_NULL_OID) { 125 mech = __gss_get_mechanism(desired_mech); 126 if (mech == NULL) 127 return (GSS_S_BAD_MECH); 128 129 if (mech->gss_store_cred == NULL) 130 return (major_status); 131 132 mech_cred = __gss_get_mechanism_cred(union_cred, desired_mech); 133 if (mech_cred == GSS_C_NO_CREDENTIAL) 134 return (GSS_S_NO_CRED); 135 136 major_status = mech->gss_store_cred(mech->context, 137 minor_status, 138 (gss_cred_id_t)mech_cred, 139 cred_usage, 140 desired_mech, 141 overwrite_cred, 142 default_cred, 143 elements_stored, 144 cred_usage_stored); 145 if (major_status != GSS_S_COMPLETE) 146 map_error(minor_status, mech); 147 return major_status; 148 } 149 150 /* desired_mech == GSS_C_NULL_OID -> store all elements */ 151 152 *minor_status = 0; 153 154 for (i = 0; i < union_cred->count; i++) { 155 /* Get mech and cred element */ 156 dmech = &union_cred->mechs_array[i]; 157 mech = __gss_get_mechanism(dmech); 158 if (mech == NULL) 159 continue; 160 161 if (mech->gss_store_cred == NULL) 162 continue; 163 164 mech_cred = __gss_get_mechanism_cred(union_cred, dmech); 165 if (mech_cred == GSS_C_NO_CREDENTIAL) 166 continue; /* can't happen, but safe to ignore */ 167 168 major_status = mech->gss_store_cred(mech->context, 169 minor_status, 170 (gss_cred_id_t)mech_cred, 171 cred_usage, 172 dmech, 173 overwrite_cred, 174 default_cred, 175 NULL, 176 cred_usage_stored); 177 if (major_status != GSS_S_COMPLETE) { 178 map_error(minor_status, mech); 179 continue; 180 } 181 182 /* Succeeded for at least one mech */ 183 184 if (elements_stored == NULL) 185 continue; 186 187 if (*elements_stored == GSS_C_NULL_OID_SET) { 188 major_status = gss_create_empty_oid_set(minor_status, 189 elements_stored); 190 191 if (GSS_ERROR(major_status)) 192 return (major_status); 193 } 194 195 major_status = gss_add_oid_set_member(minor_status, dmech, 196 elements_stored); 197 198 /* The caller should clean up elements_stored */ 199 if (GSS_ERROR(major_status)) 200 return (major_status); 201 } 202 203 /* 204 * Success with some mechs may mask failure with others, but 205 * that's what elements_stored is for. 206 */ 207 return (major_status); 208 } 209