xref: /freebsd/crypto/krb5/src/lib/gssapi/mechglue/g_inq_cred.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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