1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3 * Copyright 2000, 2007 by the Massachusetts Institute of Technology.
4 * All Rights Reserved.
5 *
6 * Export of this software from the United States of America may
7 * require a specific license from the United States Government.
8 * It is the responsibility of any person or organization contemplating
9 * export to obtain such a license before exporting.
10 *
11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12 * distribute this software and its documentation for any purpose and
13 * without fee is hereby granted, provided that the above copyright
14 * notice appear in all copies and that both that copyright notice and
15 * this permission notice appear in supporting documentation, and that
16 * the name of M.I.T. not be used in advertising or publicity pertaining
17 * to distribution of the software without specific, written prior
18 * permission. Furthermore if you modify this software you must label
19 * your software as modified software and not distribute it in such a
20 * fashion that it might be confused with the original M.I.T. software.
21 * M.I.T. makes no representations about the suitability of
22 * this software for any purpose. It is provided "as is" without express
23 * or implied warranty.
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
75 OM_uint32 KRB5_CALLCONV
krb5_gss_inquire_cred(OM_uint32 * minor_status,gss_cred_id_t cred_handle,gss_name_t * name,OM_uint32 * lifetime_ret,gss_cred_usage_t * cred_usage,gss_OID_set * mechanisms)76 krb5_gss_inquire_cred(OM_uint32 *minor_status, gss_cred_id_t cred_handle,
77 gss_name_t *name, OM_uint32 *lifetime_ret,
78 gss_cred_usage_t *cred_usage, gss_OID_set *mechanisms)
79 {
80 krb5_context context;
81 gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL;
82 krb5_gss_cred_id_t cred = NULL;
83 krb5_error_code code;
84 krb5_timestamp now;
85 krb5_deltat lifetime;
86 krb5_gss_name_t ret_name;
87 krb5_principal princ;
88 gss_OID_set mechs = GSS_C_NO_OID_SET;
89 OM_uint32 major, tmpmin, ret;
90
91 ret = GSS_S_FAILURE;
92 ret_name = NULL;
93
94 code = krb5_gss_init_context(&context);
95 if (code) {
96 *minor_status = code;
97 return GSS_S_FAILURE;
98 }
99
100 if (name) *name = NULL;
101 if (mechanisms) *mechanisms = NULL;
102
103 /* check for default credential */
104 /*SUPPRESS 29*/
105 if (cred_handle == GSS_C_NO_CREDENTIAL) {
106 major = kg_get_defcred(minor_status, &defcred);
107 if (GSS_ERROR(major)) {
108 krb5_free_context(context);
109 return(major);
110 }
111 cred_handle = defcred;
112 }
113
114 major = kg_cred_resolve(minor_status, context, cred_handle, GSS_C_NO_NAME);
115 if (GSS_ERROR(major)) {
116 krb5_gss_release_cred(minor_status, &defcred);
117 krb5_free_context(context);
118 return(major);
119 }
120 cred = (krb5_gss_cred_id_t)cred_handle;
121
122 if ((code = krb5_timeofday(context, &now))) {
123 *minor_status = code;
124 ret = GSS_S_FAILURE;
125 goto cleanup;
126 }
127
128 if (cred->expire != 0) {
129 lifetime = ts_interval(now, cred->expire);
130 if (lifetime < 0)
131 lifetime = 0;
132 }
133 else
134 lifetime = GSS_C_INDEFINITE;
135
136 if (name) {
137 if (cred->name) {
138 code = kg_duplicate_name(context, cred->name, &ret_name);
139 } else if ((cred->usage == GSS_C_ACCEPT || cred->usage == GSS_C_BOTH)
140 && cred->keytab != NULL) {
141 /* This is a default acceptor cred; use a name from the keytab if
142 * we can. */
143 code = k5_kt_get_principal(context, cred->keytab, &princ);
144 if (code == 0) {
145 code = kg_init_name(context, princ, NULL, NULL, NULL,
146 KG_INIT_NAME_NO_COPY, &ret_name);
147 if (code)
148 krb5_free_principal(context, princ);
149 } else if (code == KRB5_KT_NOTFOUND)
150 code = 0;
151 }
152 if (code) {
153 *minor_status = code;
154 save_error_info(*minor_status, context);
155 ret = GSS_S_FAILURE;
156 goto cleanup;
157 }
158 }
159
160 if (mechanisms) {
161 if (GSS_ERROR(ret = generic_gss_create_empty_oid_set(minor_status,
162 &mechs)) ||
163 GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
164 gss_mech_krb5_old,
165 &mechs)) ||
166 GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
167 gss_mech_krb5,
168 &mechs))) {
169 if (ret_name)
170 kg_release_name(context, &ret_name);
171 /* *minor_status set above */
172 goto cleanup;
173 }
174 }
175
176 if (name) {
177 if (ret_name != NULL)
178 *name = (gss_name_t) ret_name;
179 else
180 *name = GSS_C_NO_NAME;
181 }
182
183 if (lifetime_ret)
184 *lifetime_ret = lifetime;
185
186 if (cred_usage)
187 *cred_usage = cred->usage;
188
189 if (mechanisms) {
190 *mechanisms = mechs;
191 mechs = GSS_C_NO_OID_SET;
192 }
193
194 *minor_status = 0;
195 ret = (lifetime == 0) ? GSS_S_CREDENTIALS_EXPIRED : GSS_S_COMPLETE;
196
197 cleanup:
198 k5_mutex_unlock(&cred->lock);
199 krb5_gss_release_cred(&tmpmin, &defcred);
200 krb5_free_context(context);
201 (void)generic_gss_release_oid_set(&tmpmin, &mechs);
202 return ret;
203 }
204
205 /* V2 interface */
206 OM_uint32 KRB5_CALLCONV
krb5_gss_inquire_cred_by_mech(OM_uint32 * minor_status,gss_cred_id_t cred_handle,gss_OID mech_type,gss_name_t * name,OM_uint32 * initiator_lifetime,OM_uint32 * acceptor_lifetime,gss_cred_usage_t * cred_usage)207 krb5_gss_inquire_cred_by_mech(OM_uint32 *minor_status,
208 gss_cred_id_t cred_handle, gss_OID mech_type,
209 gss_name_t *name, OM_uint32 *initiator_lifetime,
210 OM_uint32 *acceptor_lifetime,
211 gss_cred_usage_t *cred_usage)
212 {
213 krb5_gss_cred_id_t cred;
214 OM_uint32 lifetime;
215 OM_uint32 mstat;
216
217 cred = (krb5_gss_cred_id_t) cred_handle;
218 mstat = krb5_gss_inquire_cred(minor_status,
219 cred_handle,
220 name,
221 &lifetime,
222 cred_usage,
223 (gss_OID_set *) NULL);
224 if (mstat == GSS_S_COMPLETE) {
225 if (cred &&
226 ((cred->usage == GSS_C_INITIATE) ||
227 (cred->usage == GSS_C_BOTH)) &&
228 initiator_lifetime)
229 *initiator_lifetime = lifetime;
230 if (cred &&
231 ((cred->usage == GSS_C_ACCEPT) ||
232 (cred->usage == GSS_C_BOTH)) &&
233 acceptor_lifetime)
234 *acceptor_lifetime = lifetime;
235 }
236 return(mstat);
237 }
238
239 OM_uint32
gss_krb5int_get_cred_impersonator(OM_uint32 * minor_status,const gss_cred_id_t cred_handle,const gss_OID desired_object,gss_buffer_set_t * data_set)240 gss_krb5int_get_cred_impersonator(OM_uint32 *minor_status,
241 const gss_cred_id_t cred_handle,
242 const gss_OID desired_object,
243 gss_buffer_set_t *data_set)
244 {
245 krb5_gss_cred_id_t cred = (krb5_gss_cred_id_t)cred_handle;
246 gss_buffer_desc rep = GSS_C_EMPTY_BUFFER;
247 krb5_context context = NULL;
248 char *impersonator = NULL;
249 krb5_error_code ret;
250 OM_uint32 major;
251
252 *data_set = GSS_C_NO_BUFFER_SET;
253
254 /* Return an empty buffer set if no impersonator is present */
255 if (cred->impersonator == NULL)
256 return generic_gss_create_empty_buffer_set(minor_status, data_set);
257
258 ret = krb5_gss_init_context(&context);
259 if (ret) {
260 *minor_status = ret;
261 return GSS_S_FAILURE;
262 }
263
264 ret = krb5_unparse_name(context, cred->impersonator, &impersonator);
265 if (ret) {
266 krb5_free_context(context);
267 *minor_status = ret;
268 return GSS_S_FAILURE;
269 }
270
271 rep.value = impersonator;
272 rep.length = strlen(impersonator);
273 major = generic_gss_add_buffer_set_member(minor_status, &rep, data_set);
274
275 krb5_free_unparsed_name(context, impersonator);
276 krb5_free_context(context);
277 return major;
278 }
279