xref: /illumos-gate/usr/src/lib/gss_mechs/mech_krb5/mech/inq_cred.c (revision cb6207858a9fcc2feaee22e626912fba281ac969)
1 /*
2  * Copyright 2007 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 (cred->princ &&
174       (code = krb5_copy_principal(context, cred->princ, &ret_name))) {
175 	 *minor_status = code;
176 	 return(GSS_S_FAILURE);
177       }
178    }
179 
180    if (mechanisms) {
181        if (GSS_ERROR(ret = gss_create_empty_oid_set(minor_status,
182 							    &mechs)) ||
183 	   (cred->prerfc_mech &&
184 	    GSS_ERROR(ret = gss_add_oid_set_member(minor_status,
185 					(gss_OID) gss_mech_krb5_old,
186 							   &mechs))) ||
187 	   (cred->rfc_mech &&
188 	    GSS_ERROR(ret = gss_add_oid_set_member(minor_status,
189 					(gss_OID) gss_mech_krb5,
190 							   &mechs)))) {
191 	   krb5_free_principal(context, ret_name);
192 	   /* *minor_status set above */
193 	   return(ret);
194        }
195    }
196 
197    /* Solaris Kerberos:
198     * Don't set name to ret_name if cred->princ is NULL.
199     * If cred->princ is NULL, ret_name is uninitialized and
200     * name already points to NULL.
201     */
202    if (name && cred->princ) {
203       if (! kg_save_name((gss_name_t) ret_name)) {
204 	 (void) gss_release_oid_set(minor_status, &mechs);
205 	 krb5_free_principal(context, ret_name);
206 	 *minor_status = (OM_uint32) G_VALIDATE_FAILED;
207 	 return(GSS_S_FAILURE);
208       }
209       *name = (gss_name_t) ret_name;
210    }
211 
212    if (lifetime_ret)
213       *lifetime_ret = lifetime;
214 
215    if (cred_usage)
216       *cred_usage = cred->usage;
217 
218    if (mechanisms)
219       *mechanisms = mechs;
220 
221    *minor_status = 0;
222    return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE);
223 }
224 
225 /* V2 interface */
226 OM_uint32
227 krb5_gss_inquire_cred_by_mech(ctx, minor_status, cred_handle,
228 			      mech_type, name, initiator_lifetime,
229 			      acceptor_lifetime, cred_usage)
230     void		*ctx;
231     OM_uint32		*minor_status;
232     gss_cred_id_t	cred_handle;
233     gss_OID		mech_type;
234     gss_name_t		*name;
235     OM_uint32		*initiator_lifetime;
236     OM_uint32		*acceptor_lifetime;
237     gss_cred_usage_t *cred_usage;
238 {
239     krb5_context	context;
240     krb5_gss_cred_id_t	cred;
241     OM_uint32		lifetime;
242     OM_uint32		mstat;
243 
244    /* Solaris Kerberos:  for MT safety, we avoid the use of a default
245     * context via kg_get_context() */
246 #if 0
247     if (GSS_ERROR(kg_get_context(minor_status, &context)))
248        return(GSS_S_FAILURE);
249 #endif
250 
251     mutex_lock(&krb5_mutex);
252     context = ctx;
253 
254     /*
255      * We only know how to handle our own creds.
256      */
257     if ((mech_type != GSS_C_NULL_OID) &&
258 	!g_OID_equal(gss_mech_krb5_old, mech_type) &&
259 	!g_OID_equal(gss_mech_krb5, mech_type) &&
260 	!g_OID_equal(gss_mech_krb5_v2, mech_type)) {
261 	*minor_status = 0;
262 	mutex_unlock(&krb5_mutex);
263 	return(GSS_S_NO_CRED);
264     }
265 
266     cred = (krb5_gss_cred_id_t) cred_handle;
267     mstat = krb5_gss_inquire_cred_no_lock(context, minor_status,
268 				  cred_handle,
269 				  name,
270 				  &lifetime,
271 				  cred_usage,
272 				  (gss_OID_set *) NULL);
273     if (mstat == GSS_S_COMPLETE) {
274 	if (cred &&
275 	    ((cred->usage == GSS_C_INITIATE) ||
276 	     (cred->usage == GSS_C_BOTH)) &&
277 	    initiator_lifetime)
278 	    *initiator_lifetime = lifetime;
279 	if (cred &&
280 	    ((cred->usage == GSS_C_ACCEPT) ||
281 	     (cred->usage == GSS_C_BOTH)) &&
282 	    acceptor_lifetime)
283 	    *acceptor_lifetime = lifetime;
284     }
285     mutex_unlock(&krb5_mutex);
286     return(mstat);
287 }
288