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