1 /*
2  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 /*
9  * Copyright 2000 by the Massachusetts Institute of Technology.
10  * All Rights Reserved.
11  *
12  * Export of this software from the United States of America may
13  *   require a specific license from the United States Government.
14  *   It is the responsibility of any person or organization contemplating
15  *   export to obtain such a license before exporting.
16  *
17  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
18  * distribute this software and its documentation for any purpose and
19  * without fee is hereby granted, provided that the above copyright
20  * notice appear in all copies and that both that copyright notice and
21  * this permission notice appear in supporting documentation, and that
22  * the name of M.I.T. not be used in advertising or publicity pertaining
23  * to distribution of the software without specific, written prior
24  * permission.  Furthermore if you modify this software you must label
25  * your software as modified software and not distribute it in such a
26  * fashion that it might be confused with the original M.I.T. software.
27  * M.I.T. makes no representations about the suitability of
28  * this software for any purpose.  It is provided "as is" without express
29  * or implied warranty.
30  *
31  */
32 /*
33  * Copyright 1993 by OpenVision Technologies, Inc.
34  *
35  * Permission to use, copy, modify, distribute, and sell this software
36  * and its documentation for any purpose is hereby granted without fee,
37  * provided that the above copyright notice appears in all copies and
38  * that both that copyright notice and this permission notice appear in
39  * supporting documentation, and that the name of OpenVision not be used
40  * in advertising or publicity pertaining to distribution of the software
41  * without specific, written prior permission. OpenVision makes no
42  * representations about the suitability of this software for any
43  * purpose.  It is provided "as is" without express or implied warranty.
44  *
45  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
46  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
47  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
48  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
49  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
50  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
51  * PERFORMANCE OF THIS SOFTWARE.
52  */
53 
54 /*
55  * Copyright (C) 1998 by the FundsXpress, INC.
56  *
57  * All rights reserved.
58  *
59  * Export of this software from the United States of America may require
60  * a specific license from the United States Government.  It is the
61  * responsibility of any person or organization contemplating export to
62  * obtain such a license before exporting.
63  *
64  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
65  * distribute this software and its documentation for any purpose and
66  * without fee is hereby granted, provided that the above copyright
67  * notice appear in all copies and that both that copyright notice and
68  * this permission notice appear in supporting documentation, and that
69  * the name of FundsXpress. not be used in advertising or publicity pertaining
70  * to distribution of the software without specific, written prior
71  * permission.  FundsXpress makes no representations about the suitability of
72  * this software for any purpose.  It is provided "as is" without express
73  * or implied warranty.
74  *
75  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
76  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
77  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
78  */
79 
80 #include <gssapiP_krb5.h>
81 #include <k5-int.h>
82 
83 extern OM_uint32 gss_copy_oid_set();
84 extern OM_uint32 gss_create_empty_oid_set();
85 extern OM_uint32 gss_add_oid_set_member();
86 
87 
88 OM_uint32
89 krb5_gss_inquire_cred(ctx, minor_status, cred_handle, name, lifetime_ret,
90 		      cred_usage, mechanisms)
91      void	*ctx;
92      OM_uint32 *minor_status;
93      gss_cred_id_t cred_handle;
94      gss_name_t *name;
95      OM_uint32 *lifetime_ret;
96      gss_cred_usage_t *cred_usage;
97      gss_OID_set *mechanisms;
98 {
99    OM_uint32 ret;
100 
101    mutex_lock(&krb5_mutex);
102    ret = krb5_gss_inquire_cred_no_lock(ctx, minor_status, cred_handle, name,
103 	   lifetime_ret, cred_usage, mechanisms);
104    mutex_unlock(&krb5_mutex);
105    return(ret);
106 }
107 
108 OM_uint32
109 krb5_gss_inquire_cred_no_lock(ctx, minor_status, cred_handle, name,
110 			      lifetime_ret, cred_usage, mechanisms)
111      void	*ctx;
112      OM_uint32 *minor_status;
113      gss_cred_id_t cred_handle;
114      gss_name_t *name;
115      OM_uint32 *lifetime_ret;
116      gss_cred_usage_t *cred_usage;
117      gss_OID_set *mechanisms;
118 {
119    krb5_context context;
120    krb5_gss_cred_id_t cred;
121    krb5_error_code code;
122    krb5_timestamp now;
123    krb5_deltat lifetime;
124    krb5_principal ret_name;
125    gss_OID_set mechs = GSS_C_NULL_OID_SET;
126    OM_uint32 ret;
127 
128    /* Solaris Kerberos:  for MT safety, we avoid the use of a default
129     * context via kg_get_context() */
130 #if 0
131    if (GSS_ERROR(kg_get_context(minor_status, &context)))
132       return(GSS_S_FAILURE);
133 #endif
134 
135    context = ctx;
136 
137    if (name) *name = NULL;
138    if (mechanisms) *mechanisms = NULL;
139 
140    /* check for default credential */
141    /*SUPPRESS 29*/
142    if (cred_handle == GSS_C_NO_CREDENTIAL) {
143       OM_uint32 major;
144       if (((major = kg_get_defcred(minor_status, &cred_handle)) != NULL) &&
145 	  GSS_ERROR(major)) {
146 	 return(major);
147       }
148    } else {
149       OM_uint32 major;
150 
151       major = krb5_gss_validate_cred_no_lock(context, minor_status,
152 					     cred_handle);
153       if (GSS_ERROR(major)) {
154 	  return(major);
155       }
156    }
157 
158    cred = (krb5_gss_cred_id_t) cred_handle;
159 
160    if ((code = krb5_timeofday(context, &now))) {
161       *minor_status = code;
162       return(GSS_S_FAILURE);
163    }
164 
165    if (cred->tgt_expire > 0) {
166        if ((lifetime = cred->tgt_expire - now) < 0)
167 	   lifetime = 0;
168    }
169    else
170        lifetime = GSS_C_INDEFINITE;
171 
172    if (name) {
173       if ((code = krb5_copy_principal(context, cred->princ, &ret_name))) {
174 	 *minor_status = code;
175 	 return(GSS_S_FAILURE);
176       }
177    }
178 
179    if (mechanisms) {
180        if (GSS_ERROR(ret = gss_create_empty_oid_set(minor_status,
181 							    &mechs)) ||
182 	   (cred->prerfc_mech &&
183 	    GSS_ERROR(ret = gss_add_oid_set_member(minor_status,
184 					(gss_OID) gss_mech_krb5_old,
185 							   &mechs))) ||
186 	   (cred->rfc_mech &&
187 	    GSS_ERROR(ret = gss_add_oid_set_member(minor_status,
188 					(gss_OID) gss_mech_krb5,
189 							   &mechs)))) {
190 	   krb5_free_principal(context, ret_name);
191 	   /* *minor_status set above */
192 	   return(ret);
193        }
194    }
195 
196    if (name) {
197       if (! kg_save_name((gss_name_t) ret_name)) {
198 	 (void) gss_release_oid_set(minor_status, &mechs);
199 	 krb5_free_principal(context, ret_name);
200 	 *minor_status = (OM_uint32) G_VALIDATE_FAILED;
201 	 return(GSS_S_FAILURE);
202       }
203       *name = (gss_name_t) ret_name;
204    }
205 
206    if (lifetime_ret)
207       *lifetime_ret = lifetime;
208 
209    if (cred_usage)
210       *cred_usage = cred->usage;
211 
212    if (mechanisms)
213       *mechanisms = mechs;
214 
215    *minor_status = 0;
216    return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE);
217 }
218 
219 /* V2 interface */
220 OM_uint32
221 krb5_gss_inquire_cred_by_mech(ctx, minor_status, cred_handle,
222 			      mech_type, name, initiator_lifetime,
223 			      acceptor_lifetime, cred_usage)
224     void		*ctx;
225     OM_uint32		*minor_status;
226     gss_cred_id_t	cred_handle;
227     gss_OID		mech_type;
228     gss_name_t		*name;
229     OM_uint32		*initiator_lifetime;
230     OM_uint32		*acceptor_lifetime;
231     gss_cred_usage_t *cred_usage;
232 {
233     krb5_context	context;
234     krb5_gss_cred_id_t	cred;
235     OM_uint32		lifetime;
236     OM_uint32		mstat;
237 
238    /* Solaris Kerberos:  for MT safety, we avoid the use of a default
239     * context via kg_get_context() */
240 #if 0
241     if (GSS_ERROR(kg_get_context(minor_status, &context)))
242        return(GSS_S_FAILURE);
243 #endif
244 
245     mutex_lock(&krb5_mutex);
246     context = ctx;
247 
248     /*
249      * We only know how to handle our own creds.
250      */
251     if ((mech_type != GSS_C_NULL_OID) &&
252 	!g_OID_equal(gss_mech_krb5_old, mech_type) &&
253 	!g_OID_equal(gss_mech_krb5, mech_type) &&
254 	!g_OID_equal(gss_mech_krb5_v2, mech_type)) {
255 	*minor_status = 0;
256 	mutex_unlock(&krb5_mutex);
257 	return(GSS_S_NO_CRED);
258     }
259 
260     cred = (krb5_gss_cred_id_t) cred_handle;
261     mstat = krb5_gss_inquire_cred_no_lock(context, minor_status,
262 				  cred_handle,
263 				  name,
264 				  &lifetime,
265 				  cred_usage,
266 				  (gss_OID_set *) NULL);
267     if (mstat == GSS_S_COMPLETE) {
268 	if (cred &&
269 	    ((cred->usage == GSS_C_INITIATE) ||
270 	     (cred->usage == GSS_C_BOTH)) &&
271 	    initiator_lifetime)
272 	    *initiator_lifetime = lifetime;
273 	if (cred &&
274 	    ((cred->usage == GSS_C_ACCEPT) ||
275 	     (cred->usage == GSS_C_BOTH)) &&
276 	    acceptor_lifetime)
277 	    *acceptor_lifetime = lifetime;
278     }
279     mutex_unlock(&krb5_mutex);
280     return(mstat);
281 }
282