1 /* #pragma ident "@(#)g_inquire_cred.c 1.16 04/02/23 SMI" */
2
3 /*
4 * Copyright 1996 by Sun Microsystems, Inc.
5 *
6 * Permission to use, copy, modify, distribute, and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appears in all copies and
9 * that both that copyright notice and this permission notice appear in
10 * supporting documentation, and that the name of Sun Microsystems not be used
11 * in advertising or publicity pertaining to distribution of the software
12 * without specific, written prior permission. Sun Microsystems makes no
13 * representations about the suitability of this software for any
14 * purpose. It is provided "as is" without express or implied warranty.
15 *
16 * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 */
24
25 /*
26 * glue routine for gss_inquire_cred
27 */
28
29 #include "mglueP.h"
30 #include <stdio.h>
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34 #include <string.h>
35 #include <time.h>
36
37 OM_uint32 KRB5_CALLCONV
gss_inquire_cred(minor_status,cred_handle,name,lifetime,cred_usage,mechanisms)38 gss_inquire_cred(minor_status,
39 cred_handle,
40 name,
41 lifetime,
42 cred_usage,
43 mechanisms)
44
45 OM_uint32 * minor_status;
46 gss_cred_id_t cred_handle;
47 gss_name_t * name;
48 OM_uint32 * lifetime;
49 int * cred_usage;
50 gss_OID_set * mechanisms;
51
52 {
53 OM_uint32 status, temp_minor_status;
54 gss_union_cred_t union_cred;
55 gss_mechanism mech;
56 gss_cred_id_t mech_cred;
57 gss_name_t mech_name;
58 gss_OID_set mechs = NULL;
59
60 /* Initialize outputs. */
61
62 if (minor_status != NULL)
63 *minor_status = 0;
64
65 if (name != NULL)
66 *name = GSS_C_NO_NAME;
67
68 if (mechanisms != NULL)
69 *mechanisms = GSS_C_NO_OID_SET;
70
71 /* Validate arguments. */
72 if (minor_status == NULL)
73 return (GSS_S_CALL_INACCESSIBLE_WRITE);
74
75 /*
76 * XXX We should iterate over all mechanisms in the credential and
77 * aggregate the results. This requires a union name structure containing
78 * multiple mechanism names, which we don't currently have. For now,
79 * inquire the first mechanism in the credential; this is consistent with
80 * our historical behavior.
81 */
82
83 /* Determine mechanism and mechanism credential. */
84 if (cred_handle != GSS_C_NO_CREDENTIAL) {
85 union_cred = (gss_union_cred_t) cred_handle;
86 if (union_cred->count <= 0)
87 return (GSS_S_DEFECTIVE_CREDENTIAL);
88 mech_cred = union_cred->cred_array[0];
89 mech = gssint_get_mechanism(&union_cred->mechs_array[0]);
90 } else {
91 union_cred = NULL;
92 mech_cred = GSS_C_NO_CREDENTIAL;
93 mech = gssint_get_mechanism(GSS_C_NULL_OID);
94 }
95
96 /* Skip the call into the mech if the caller doesn't care about any of the
97 * values we would ask for. */
98 if (name != NULL || lifetime != NULL || cred_usage != NULL) {
99 if (mech == NULL)
100 return (GSS_S_DEFECTIVE_CREDENTIAL);
101 if (!mech->gss_inquire_cred)
102 return (GSS_S_UNAVAILABLE);
103
104 status = mech->gss_inquire_cred(minor_status, mech_cred,
105 name ? &mech_name : NULL,
106 lifetime, cred_usage, NULL);
107 if (status != GSS_S_COMPLETE) {
108 map_error(minor_status, mech);
109 return(status);
110 }
111
112 if (name) {
113 /* Convert mech_name into a union_name equivalent. */
114 status = gssint_convert_name_to_union_name(&temp_minor_status,
115 mech, mech_name, name);
116 if (status != GSS_S_COMPLETE) {
117 *minor_status = temp_minor_status;
118 map_error(minor_status, mech);
119 return (status);
120 }
121 }
122 }
123
124 /*
125 * copy the mechanism set in union_cred into an OID set and return in
126 * the mechanisms parameter.
127 */
128
129 if(mechanisms != NULL) {
130 if (union_cred) {
131 status = gssint_make_public_oid_set(minor_status,
132 union_cred->mechs_array,
133 union_cred->count, &mechs);
134 if (GSS_ERROR(status))
135 goto error;
136 } else {
137 status = gss_create_empty_oid_set(minor_status, &mechs);
138 if (GSS_ERROR(status))
139 goto error;
140
141 status = gss_add_oid_set_member(minor_status,
142 &mech->mech_type, &mechs);
143 if (GSS_ERROR(status))
144 goto error;
145 }
146 *mechanisms = mechs;
147 }
148
149 return(GSS_S_COMPLETE);
150
151 error:
152 if (mechs != NULL)
153 (void) gss_release_oid_set(&temp_minor_status, &mechs);
154
155 if (name && *name != NULL)
156 (void) gss_release_name(&temp_minor_status, name);
157
158 return (status);
159 }
160
161 OM_uint32 KRB5_CALLCONV
gss_inquire_cred_by_mech(minor_status,cred_handle,mech_type,name,initiator_lifetime,acceptor_lifetime,cred_usage)162 gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name,
163 initiator_lifetime, acceptor_lifetime, cred_usage)
164 OM_uint32 *minor_status;
165 gss_cred_id_t cred_handle;
166 gss_OID mech_type;
167 gss_name_t *name;
168 OM_uint32 *initiator_lifetime;
169 OM_uint32 *acceptor_lifetime;
170 gss_cred_usage_t *cred_usage;
171 {
172 gss_union_cred_t union_cred;
173 gss_cred_id_t mech_cred;
174 gss_mechanism mech;
175 OM_uint32 status, temp_minor_status;
176 gss_name_t internal_name;
177 gss_OID selected_mech, public_mech;
178
179 if (minor_status != NULL)
180 *minor_status = 0;
181
182 if (name != NULL)
183 *name = GSS_C_NO_NAME;
184
185 if (minor_status == NULL)
186 return (GSS_S_CALL_INACCESSIBLE_WRITE);
187
188 status = gssint_select_mech_type(minor_status, mech_type, &selected_mech);
189 if (status != GSS_S_COMPLETE)
190 return (status);
191
192 mech = gssint_get_mechanism(selected_mech);
193 if (!mech)
194 return (GSS_S_BAD_MECH);
195 if (!mech->gss_inquire_cred_by_mech)
196 return (GSS_S_BAD_BINDINGS);
197
198 union_cred = (gss_union_cred_t) cred_handle;
199 mech_cred = gssint_get_mechanism_cred(union_cred, selected_mech);
200 if (cred_handle != GSS_C_NO_CREDENTIAL && mech_cred == GSS_C_NO_CREDENTIAL)
201 return (GSS_S_NO_CRED);
202
203 public_mech = gssint_get_public_oid(selected_mech);
204 status = mech->gss_inquire_cred_by_mech(minor_status,
205 mech_cred, public_mech,
206 name ? &internal_name : NULL,
207 initiator_lifetime,
208 acceptor_lifetime, cred_usage);
209
210 if (status != GSS_S_COMPLETE) {
211 map_error(minor_status, mech);
212 return (status);
213 }
214
215 if (name) {
216 /*
217 * Convert internal_name into a union_name equivalent.
218 */
219 status = gssint_convert_name_to_union_name(
220 &temp_minor_status, mech,
221 internal_name, name);
222 if (status != GSS_S_COMPLETE) {
223 *minor_status = temp_minor_status;
224 map_error(minor_status, mech);
225 return (status);
226 }
227 }
228
229 return (GSS_S_COMPLETE);
230 }
231