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