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.
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.
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]
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
26 * glue routine for gss_inquire_cred
29 #include <mechglueP.h>
30 #include "gssapiP_generic.h"
37 gss_inquire_cred(minor_status
,
44 OM_uint32
*minor_status
;
45 const gss_cred_id_t cred_handle
;
49 gss_OID_set
*mechanisms
;
52 OM_uint32 status
, elapsed_time
, temp_minor_status
;
53 gss_union_cred_t union_cred
;
55 gss_name_t internal_name
;
58 /* Initialize outputs. */
60 if (minor_status
!= NULL
)
64 *name
= GSS_C_NO_NAME
;
66 if (mechanisms
!= NULL
)
67 *mechanisms
= GSS_C_NO_OID_SET
;
69 /* Validate arguments. */
70 if (minor_status
== NULL
)
71 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
73 if (cred_handle
== GSS_C_NO_CREDENTIAL
) {
75 * No credential was supplied. This means we can't get a mechanism
76 * pointer to call the mechanism specific gss_inquire_cred.
77 * So, call get_mechanism with an arguement of GSS_C_NULL_OID.
78 * get_mechanism will return the first mechanism in the mech
79 * array, which becomes the default mechanism.
82 if ((mech
= __gss_get_mechanism(GSS_C_NULL_OID
)) == NULL
)
83 return (GSS_S_DEFECTIVE_CREDENTIAL
);
85 if (!mech
->gss_inquire_cred
)
86 return (GSS_S_UNAVAILABLE
);
88 status
= mech
->gss_inquire_cred(mech
->context
, minor_status
,
90 name
? &internal_name
: NULL
,
94 if (status
!= GSS_S_COMPLETE
) {
95 map_error(minor_status
, mech
);
101 * Convert internal_name into a union_name equivalent.
103 status
= __gss_convert_name_to_union_name(
104 &temp_minor_status
, mech
,
105 internal_name
, name
);
106 if (status
!= GSS_S_COMPLETE
) {
107 *minor_status
= temp_minor_status
;
108 map_error(minor_status
, mech
);
109 if (mechanisms
&& *mechanisms
) {
110 (void) gss_release_oid_set(
117 return (GSS_S_COMPLETE
);
120 /* get the cred_handle cast as a union_credentials structure */
122 union_cred
= (gss_union_cred_t
)cred_handle
;
125 * get the information out of the union_cred structure that was
126 * placed there during gss_acquire_cred.
129 if (cred_usage
!= NULL
)
130 *cred_usage
= union_cred
->auxinfo
.cred_usage
;
132 if (lifetime
!= NULL
) {
133 elapsed_time
= time(0) - union_cred
->auxinfo
.creation_time
;
134 *lifetime
= union_cred
->auxinfo
.time_rec
< elapsed_time
? 0 :
135 union_cred
->auxinfo
.time_rec
- elapsed_time
;
139 * if name is non_null,
140 * call gss_import_name() followed by gss_canonicalize_name()
141 * to get a mechanism specific name passed back to the caller.
142 * If this call fails, return failure to our caller.
143 * XXX The cred_handle may contain an array of mechanism OID's
144 * but we only return the MN for the first mechanism to the caller.
145 * In theory, we should modify this to provide an array of MN's
146 * one per mechanism back to the caller.
150 if (union_cred
->auxinfo
.name
.length
== 0) {
151 *name
= GSS_C_NO_NAME
;
152 } else if ((gss_import_name(minor_status
,
153 &union_cred
->auxinfo
.name
,
154 union_cred
->auxinfo
.name_type
,
155 name
) != GSS_S_COMPLETE
) ||
156 (gss_canonicalize_name(minor_status
, *name
,
157 &union_cred
->mechs_array
[0],
158 NULL
) != GSS_S_COMPLETE
)) {
159 status
= GSS_S_DEFECTIVE_CREDENTIAL
;
165 * copy the mechanism set in union_cred into an OID set and return in
166 * the mechanisms parameter.
168 if (mechanisms
!= NULL
) {
169 status
= GSS_S_FAILURE
;
170 *mechanisms
= (gss_OID_set
) malloc(sizeof (gss_OID_set_desc
));
171 if (*mechanisms
== NULL
)
174 (*mechanisms
)->count
= 0;
175 (*mechanisms
)->elements
=
176 (gss_OID
) malloc(sizeof (gss_OID_desc
) *
179 if ((*mechanisms
)->elements
== NULL
) {
185 for (i
= 0; i
< union_cred
->count
; i
++) {
186 (*mechanisms
)->elements
[i
].elements
= (void *)
187 malloc(union_cred
->mechs_array
[i
].length
);
188 if ((*mechanisms
)->elements
[i
].elements
== NULL
)
190 g_OID_copy(&(*mechanisms
)->elements
[i
],
191 &union_cred
->mechs_array
[i
]);
192 (*mechanisms
)->count
++;
196 return (GSS_S_COMPLETE
);
200 * cleanup any allocated memory - we can just call
201 * gss_release_oid_set, because the set is constructed so that
202 * count always references the currently copied number of
205 if (mechanisms
&& *mechanisms
!= NULL
)
206 (void) gss_release_oid_set(&temp_minor_status
, mechanisms
);
208 if (name
&& *name
!= NULL
)
209 (void) gss_release_name(&temp_minor_status
, name
);
215 gss_inquire_cred_by_mech(minor_status
, cred_handle
, mech_type
, name
,
216 initiator_lifetime
, acceptor_lifetime
, cred_usage
)
217 OM_uint32
*minor_status
;
218 const gss_cred_id_t cred_handle
;
219 const gss_OID mech_type
;
221 OM_uint32
*initiator_lifetime
;
222 OM_uint32
*acceptor_lifetime
;
223 gss_cred_usage_t
*cred_usage
;
225 gss_union_cred_t union_cred
;
226 gss_cred_id_t mech_cred
;
228 OM_uint32 status
, temp_minor_status
;
229 gss_name_t internal_name
;
231 if (minor_status
!= NULL
)
235 *name
= GSS_C_NO_NAME
;
237 if (minor_status
== NULL
)
238 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
240 mech
= __gss_get_mechanism(mech_type
);
242 return (GSS_S_BAD_MECH
);
243 if (!mech
->gss_inquire_cred_by_mech
)
244 return (GSS_S_UNAVAILABLE
);
246 union_cred
= (gss_union_cred_t
)cred_handle
;
247 mech_cred
= __gss_get_mechanism_cred(union_cred
, mech_type
);
248 if (mech_cred
== NULL
)
249 return (GSS_S_DEFECTIVE_CREDENTIAL
);
251 if (mech
->gss_inquire_cred_by_mech
!= NULL
) {
252 status
= mech
->gss_inquire_cred_by_mech(mech
->context
,
254 mech_cred
, mech_type
,
255 name
? &internal_name
: NULL
,
257 acceptor_lifetime
, cred_usage
);
259 if (status
!= GSS_S_COMPLETE
) {
260 map_error(minor_status
, mech
);
266 * Convert internal_name into a union_name equivalent.
268 status
= __gss_convert_name_to_union_name(
269 &temp_minor_status
, mech
,
270 internal_name
, name
);
271 if (status
!= GSS_S_COMPLETE
) {
272 *minor_status
= temp_minor_status
;
273 map_error(minor_status
, mech
);
278 return (GSS_S_UNAVAILABLE
);
281 return (GSS_S_COMPLETE
);