1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright 1993 by OpenVision Technologies, Inc.
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without fee,
7 * provided that the above copyright notice appears in all copies and
8 * that both that copyright notice and this permission notice appear in
9 * supporting documentation, and that the name of OpenVision not be used
10 * in advertising or publicity pertaining to distribution of the software
11 * without specific, written prior permission. OpenVision makes no
12 * representations about the suitability of this software for any
13 * purpose. It is provided "as is" without express or implied warranty.
15 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
24 * Copyright (c) 2006-2008, Novell, Inc.
25 * All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions are met:
30 * * Redistributions of source code must retain the above copyright notice,
31 * this list of conditions and the following disclaimer.
32 * * Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * * The copyright holder's name is not used to endorse or promote products
36 * derived from this software without specific prior written permission.
38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
39 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
42 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
43 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
44 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
46 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
48 * POSSIBILITY OF SUCH DAMAGE.
55 #include "gssapiP_krb5.h"
57 OM_uint32 KRB5_CALLCONV
58 gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
59 gss_ctx_id_t context_handle,
60 krb5_flags *ticket_flags)
62 static const gss_OID_desc req_oid = {
63 GSS_KRB5_GET_TKT_FLAGS_OID_LENGTH,
64 GSS_KRB5_GET_TKT_FLAGS_OID };
65 OM_uint32 major_status;
66 gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
68 if (ticket_flags == NULL)
69 return GSS_S_CALL_INACCESSIBLE_WRITE;
71 major_status = gss_inquire_sec_context_by_oid(minor_status,
75 if (major_status != GSS_S_COMPLETE)
78 if (data_set == GSS_C_NO_BUFFER_SET ||
79 data_set->count != 1 ||
80 data_set->elements[0].length != sizeof(*ticket_flags)) {
81 *minor_status = EINVAL;
85 *ticket_flags = *((krb5_flags *)data_set->elements[0].value);
87 gss_release_buffer_set(minor_status, &data_set);
91 return GSS_S_COMPLETE;
94 OM_uint32 KRB5_CALLCONV
95 gss_krb5_copy_ccache(OM_uint32 *minor_status,
96 gss_cred_id_t cred_handle,
97 krb5_ccache out_ccache)
99 static const gss_OID_desc req_oid = {
100 GSS_KRB5_COPY_CCACHE_OID_LENGTH,
101 GSS_KRB5_COPY_CCACHE_OID };
102 OM_uint32 major_status;
103 gss_buffer_desc req_buffer;
105 if (out_ccache == NULL)
106 return GSS_S_CALL_INACCESSIBLE_WRITE;
108 req_buffer.value = out_ccache;
109 req_buffer.length = sizeof(out_ccache);
111 major_status = gss_set_cred_option(minor_status,
119 OM_uint32 KRB5_CALLCONV
120 gss_krb5_import_cred(OM_uint32 *minor_status,
122 krb5_principal keytab_principal,
126 static const gss_OID_desc req_oid = {
127 GSS_KRB5_IMPORT_CRED_OID_LENGTH,
128 GSS_KRB5_IMPORT_CRED_OID };
129 OM_uint32 major_status;
130 struct krb5_gss_import_cred_req req;
131 gss_buffer_desc req_buffer;
134 return GSS_S_CALL_INACCESSIBLE_WRITE;
136 *cred = GSS_C_NO_CREDENTIAL;
139 req.keytab_principal = keytab_principal;
142 req_buffer.value = &req;
143 req_buffer.length = sizeof(req);
145 major_status = gss_set_cred_option(minor_status,
153 OM_uint32 KRB5_CALLCONV
154 gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
155 gss_ctx_id_t *context_handle,
159 unsigned char oid_buf[GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH + 6];
160 gss_OID_desc req_oid;
161 OM_uint32 major_status, minor;
162 gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
165 return GSS_S_CALL_INACCESSIBLE_WRITE;
169 req_oid.elements = oid_buf;
170 req_oid.length = sizeof(oid_buf);
172 major_status = generic_gss_oid_compose(minor_status,
173 GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID,
174 GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH,
177 if (GSS_ERROR(major_status))
180 major_status = gss_inquire_sec_context_by_oid(minor_status,
184 if (GSS_ERROR(major_status))
187 if (data_set == GSS_C_NO_BUFFER_SET ||
188 data_set->count != 1 ||
189 data_set->elements[0].length != sizeof(void *)) {
190 *minor_status = EINVAL;
191 return GSS_S_FAILURE;
194 *kctx = *((void **)data_set->elements[0].value);
196 /* Clean up the context state (it is an error for
197 * someone to attempt to use this context again)
199 (void)gss_delete_sec_context(minor_status, context_handle, NULL);
200 *context_handle = GSS_C_NO_CONTEXT;
202 generic_gss_release_buffer_set(&minor, &data_set);
204 return GSS_S_COMPLETE;
207 OM_uint32 KRB5_CALLCONV
208 gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status,
210 OM_uint32 num_ktypes,
211 krb5_enctype *ktypes)
213 static const gss_OID_desc req_oid = {
214 GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID_LENGTH,
215 GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID };
216 OM_uint32 major_status;
217 struct krb5_gss_set_allowable_enctypes_req req;
218 gss_buffer_desc req_buffer;
220 req.num_ktypes = num_ktypes;
223 req_buffer.length = sizeof(req);
224 req_buffer.value = &req;
226 major_status = gss_set_cred_option(minor_status,
234 OM_uint32 KRB5_CALLCONV
235 gss_krb5_ccache_name(OM_uint32 *minor_status,
237 const char **out_name)
239 static const gss_OID_desc req_oid = {
240 GSS_KRB5_CCACHE_NAME_OID_LENGTH,
241 GSS_KRB5_CCACHE_NAME_OID };
242 OM_uint32 major_status;
243 struct krb5_gss_ccache_name_req req;
244 gss_buffer_desc req_buffer;
247 req.out_name = out_name;
249 req_buffer.length = sizeof(req);
250 req_buffer.value = &req;
252 major_status = gssspi_mech_invoke(minor_status,
253 (gss_OID)gss_mech_krb5,
260 OM_uint32 KRB5_CALLCONV
261 gss_krb5_free_lucid_sec_context(OM_uint32 *minor_status, void *kctx)
263 static const gss_OID_desc req_oid = {
264 GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID_LENGTH,
265 GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID };
266 OM_uint32 major_status;
267 gss_buffer_desc req_buffer;
269 req_buffer.length = sizeof(kctx);
270 req_buffer.value = kctx;
272 major_status = gssspi_mech_invoke(minor_status,
273 (gss_OID)gss_mech_krb5,
280 OM_uint32 KRB5_CALLCONV
281 krb5_gss_register_acceptor_identity(const char *keytab)
283 static const gss_OID_desc req_oid = {
284 GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID_LENGTH,
285 GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID };
286 OM_uint32 major_status;
287 OM_uint32 minor_status;
288 gss_buffer_desc req_buffer;
290 req_buffer.length = (keytab == NULL) ? 0 : strlen(keytab);
291 req_buffer.value = (char *)keytab;
293 major_status = gssspi_mech_invoke(&minor_status,
294 (gss_OID)gss_mech_krb5,
303 krb5_gss_use_kdc_context(void)
305 static const gss_OID_desc req_oid = {
306 GSS_KRB5_USE_KDC_CONTEXT_OID_LENGTH,
307 GSS_KRB5_USE_KDC_CONTEXT_OID };
308 OM_uint32 major_status;
309 OM_uint32 minor_status;
310 gss_buffer_desc req_buffer;
313 req_buffer.length = 0;
314 req_buffer.value = NULL;
316 major_status = gssspi_mech_invoke(&minor_status,
317 (gss_OID)gss_mech_krb5,
321 if (major_status != GSS_S_COMPLETE) {
322 if (minor_status != 0)
323 ret = (krb5_error_code)minor_status;
325 ret = KRB5KRB_ERR_GENERIC;
334 * This API should go away and be replaced with an accessor
337 OM_uint32 KRB5_CALLCONV
338 gsskrb5_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
339 const gss_ctx_id_t context_handle,
341 gss_buffer_t ad_data)
343 gss_OID_desc req_oid;
344 unsigned char oid_buf[GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH + 6];
345 OM_uint32 major_status;
346 gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
349 return GSS_S_CALL_INACCESSIBLE_WRITE;
351 req_oid.elements = oid_buf;
352 req_oid.length = sizeof(oid_buf);
354 major_status = generic_gss_oid_compose(minor_status,
355 GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID,
356 GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH,
359 if (GSS_ERROR(major_status))
362 major_status = gss_inquire_sec_context_by_oid(minor_status,
366 if (major_status != GSS_S_COMPLETE) {
370 if (data_set == GSS_C_NO_BUFFER_SET ||
371 data_set->count != 1) {
372 return GSS_S_FAILURE;
375 ad_data->length = data_set->elements[0].length;
376 ad_data->value = data_set->elements[0].value;
378 data_set->elements[0].length = 0;
379 data_set->elements[0].value = NULL;
383 gss_release_buffer_set(minor_status, &data_set);
385 return GSS_S_COMPLETE;
388 OM_uint32 KRB5_CALLCONV
389 gss_krb5_set_cred_rcache(OM_uint32 *minor_status,
393 static const gss_OID_desc req_oid = {
394 GSS_KRB5_SET_CRED_RCACHE_OID_LENGTH,
395 GSS_KRB5_SET_CRED_RCACHE_OID };
396 OM_uint32 major_status;
397 gss_buffer_desc req_buffer;
399 req_buffer.length = sizeof(rcache);
400 req_buffer.value = rcache;
402 major_status = gss_set_cred_option(minor_status,
410 OM_uint32 KRB5_CALLCONV
411 gsskrb5_extract_authtime_from_sec_context(OM_uint32 *minor_status,
412 gss_ctx_id_t context_handle,
413 krb5_timestamp *authtime)
415 static const gss_OID_desc req_oid = {
416 GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH,
417 GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID };
418 OM_uint32 major_status;
419 gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
421 if (authtime == NULL)
422 return GSS_S_CALL_INACCESSIBLE_WRITE;
424 major_status = gss_inquire_sec_context_by_oid(minor_status,
428 if (major_status != GSS_S_COMPLETE)
431 if (data_set == GSS_C_NO_BUFFER_SET ||
432 data_set->count != 1 ||
433 data_set->elements[0].length != sizeof(*authtime)) {
434 *minor_status = EINVAL;
435 return GSS_S_FAILURE;
438 *authtime = *((krb5_timestamp *)data_set->elements[0].value);
440 gss_release_buffer_set(minor_status, &data_set);
444 return GSS_S_COMPLETE;