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
76OM_uint32
77krb5_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);
211fail:
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 */
222OM_uint32
223krb5_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