1 /* $NetBSD: gss_krb5.c,v 1.1.1.2 2014/04/24 12:45:29 pettai Exp $ */
4 * Copyright (c) 2005 Doug Rabson
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $FreeBSD: src/lib/libgssapi/gss_krb5.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
31 #include "mech_locl.h"
33 #include <krb5/krb5.h>
34 #include <krb5/roken.h>
37 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
38 gss_krb5_copy_ccache(OM_uint32
*minor_status
,
42 gss_buffer_set_t data_set
= GSS_C_NO_BUFFER_SET
;
49 ret
= gss_inquire_cred_by_oid(minor_status
,
51 GSS_KRB5_COPY_CCACHE_X
,
56 if (data_set
== GSS_C_NO_BUFFER_SET
|| data_set
->count
< 1) {
57 gss_release_buffer_set(minor_status
, &data_set
);
58 *minor_status
= EINVAL
;
62 kret
= krb5_init_context(&context
);
65 gss_release_buffer_set(minor_status
, &data_set
);
69 kret
= asprintf(&str
, "%.*s", (int)data_set
->elements
[0].length
,
70 (char *)data_set
->elements
[0].value
);
71 gss_release_buffer_set(minor_status
, &data_set
);
72 if (kret
< 0 || str
== NULL
) {
73 *minor_status
= ENOMEM
;
77 kret
= krb5_cc_resolve(context
, str
, &id
);
84 kret
= krb5_cc_copy_cache(context
, id
, out
);
85 krb5_cc_close(context
, id
);
86 krb5_free_context(context
);
95 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
96 gss_krb5_import_cred(OM_uint32
*minor_status
,
98 krb5_principal keytab_principal
,
102 gss_buffer_desc buffer
;
103 OM_uint32 major_status
;
104 krb5_context context
;
110 *cred
= GSS_C_NO_CREDENTIAL
;
112 ret
= krb5_init_context(&context
);
115 return GSS_S_FAILURE
;
118 sp
= krb5_storage_emem();
120 *minor_status
= ENOMEM
;
121 major_status
= GSS_S_FAILURE
;
126 ret
= krb5_cc_get_full_name(context
, id
, &str
);
128 ret
= krb5_store_string(sp
, str
);
132 ret
= krb5_store_string(sp
, "");
135 major_status
= GSS_S_FAILURE
;
139 if (keytab_principal
) {
140 ret
= krb5_unparse_name(context
, keytab_principal
, &str
);
142 ret
= krb5_store_string(sp
, str
);
146 krb5_store_string(sp
, "");
149 major_status
= GSS_S_FAILURE
;
155 ret
= krb5_kt_get_full_name(context
, keytab
, &str
);
157 ret
= krb5_store_string(sp
, str
);
161 krb5_store_string(sp
, "");
164 major_status
= GSS_S_FAILURE
;
168 ret
= krb5_storage_to_data(sp
, &data
);
171 major_status
= GSS_S_FAILURE
;
175 buffer
.value
= data
.data
;
176 buffer
.length
= data
.length
;
178 major_status
= gss_set_cred_option(minor_status
,
180 GSS_KRB5_IMPORT_CRED_X
,
182 krb5_data_free(&data
);
185 krb5_storage_free(sp
);
186 krb5_free_context(context
);
190 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
191 gsskrb5_register_acceptor_identity(const char *identity
)
193 gssapi_mech_interface m
;
194 gss_buffer_desc buffer
;
199 buffer
.value
= rk_UNCONST(identity
);
200 buffer
.length
= strlen(identity
);
202 m
= __gss_get_mechanism(GSS_KRB5_MECHANISM
);
203 if (m
== NULL
|| m
->gm_set_sec_context_option
== NULL
)
204 return GSS_S_FAILURE
;
206 return m
->gm_set_sec_context_option(&junk
, NULL
,
207 GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X
, &buffer
);
210 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
211 krb5_gss_register_acceptor_identity(const char *identity
)
213 return gsskrb5_register_acceptor_identity(identity
);
217 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
218 gsskrb5_set_dns_canonicalize(int flag
)
220 struct _gss_mech_switch
*m
;
221 gss_buffer_desc buffer
;
223 char b
= (flag
!= 0);
228 buffer
.length
= sizeof(b
);
230 HEIM_SLIST_FOREACH(m
, &_gss_mechs
, gm_link
) {
231 if (m
->gm_mech
.gm_set_sec_context_option
== NULL
)
233 m
->gm_mech
.gm_set_sec_context_option(&junk
, NULL
,
234 GSS_KRB5_SET_DNS_CANONICALIZE_X
, &buffer
);
237 return (GSS_S_COMPLETE
);
242 static krb5_error_code
243 set_key(krb5_keyblock
*keyblock
, gss_krb5_lucid_key_t
*key
)
245 key
->type
= keyblock
->keytype
;
246 key
->length
= keyblock
->keyvalue
.length
;
247 key
->data
= malloc(key
->length
);
248 if (key
->data
== NULL
&& key
->length
!= 0)
250 memcpy(key
->data
, keyblock
->keyvalue
.data
, key
->length
);
255 free_key(gss_krb5_lucid_key_t
*key
)
257 memset(key
->data
, 0, key
->length
);
259 memset(key
, 0, sizeof(*key
));
262 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
263 gss_krb5_export_lucid_sec_context(OM_uint32
*minor_status
,
264 gss_ctx_id_t
*context_handle
,
268 krb5_context context
= NULL
;
270 gss_buffer_set_t data_set
= GSS_C_NO_BUFFER_SET
;
271 OM_uint32 major_status
;
272 gss_krb5_lucid_context_v1_t
*ctx
= NULL
;
273 krb5_storage
*sp
= NULL
;
276 if (context_handle
== NULL
277 || *context_handle
== GSS_C_NO_CONTEXT
280 *minor_status
= EINVAL
;
281 return GSS_S_FAILURE
;
285 gss_inquire_sec_context_by_oid (minor_status
,
287 GSS_KRB5_EXPORT_LUCID_CONTEXT_V1_X
,
292 if (data_set
== GSS_C_NO_BUFFER_SET
|| data_set
->count
!= 1) {
293 gss_release_buffer_set(minor_status
, &data_set
);
294 *minor_status
= EINVAL
;
295 return GSS_S_FAILURE
;
298 ret
= krb5_init_context(&context
);
302 ctx
= calloc(1, sizeof(*ctx
));
308 sp
= krb5_storage_from_mem(data_set
->elements
[0].value
,
309 data_set
->elements
[0].length
);
315 ret
= krb5_ret_uint32(sp
, &num
);
323 ret
= krb5_ret_uint32(sp
, &ctx
->initiate
);
326 ret
= krb5_ret_uint32(sp
, &ctx
->endtime
);
329 ret
= krb5_ret_uint32(sp
, &num
);
331 ctx
->send_seq
= ((uint64_t)num
) << 32;
332 ret
= krb5_ret_uint32(sp
, &num
);
334 ctx
->send_seq
|= num
;
336 ret
= krb5_ret_uint32(sp
, &num
);
338 ctx
->recv_seq
= ((uint64_t)num
) << 32;
339 ret
= krb5_ret_uint32(sp
, &num
);
341 ctx
->recv_seq
|= num
;
343 ret
= krb5_ret_uint32(sp
, &ctx
->protocol
);
345 if (ctx
->protocol
== 0) {
349 ret
= krb5_ret_uint32(sp
, &ctx
->rfc1964_kd
.sign_alg
);
352 ret
= krb5_ret_uint32(sp
, &ctx
->rfc1964_kd
.seal_alg
);
355 ret
= krb5_ret_keyblock(sp
, &key
);
357 ret
= set_key(&key
, &ctx
->rfc1964_kd
.ctx_key
);
358 krb5_free_keyblock_contents(context
, &key
);
360 } else if (ctx
->protocol
== 1) {
363 /* acceptor_subkey */
364 ret
= krb5_ret_uint32(sp
, &ctx
->cfx_kd
.have_acceptor_subkey
);
367 ret
= krb5_ret_keyblock(sp
, &key
);
369 ret
= set_key(&key
, &ctx
->cfx_kd
.ctx_key
);
370 krb5_free_keyblock_contents(context
, &key
);
372 /* acceptor_subkey */
373 if (ctx
->cfx_kd
.have_acceptor_subkey
) {
374 ret
= krb5_ret_keyblock(sp
, &key
);
376 ret
= set_key(&key
, &ctx
->cfx_kd
.acceptor_subkey
);
377 krb5_free_keyblock_contents(context
, &key
);
388 gss_release_buffer_set(minor_status
, &data_set
);
390 krb5_storage_free(sp
);
392 krb5_free_context(context
);
396 gss_krb5_free_lucid_sec_context(NULL
, ctx
);
399 return GSS_S_FAILURE
;
402 return GSS_S_COMPLETE
;
405 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
406 gss_krb5_free_lucid_sec_context(OM_uint32
*minor_status
, void *c
)
408 gss_krb5_lucid_context_v1_t
*ctx
= c
;
410 if (ctx
->version
!= 1) {
413 return GSS_S_FAILURE
;
416 if (ctx
->protocol
== 0) {
417 free_key(&ctx
->rfc1964_kd
.ctx_key
);
418 } else if (ctx
->protocol
== 1) {
419 free_key(&ctx
->cfx_kd
.ctx_key
);
420 if (ctx
->cfx_kd
.have_acceptor_subkey
)
421 free_key(&ctx
->cfx_kd
.acceptor_subkey
);
426 return GSS_S_COMPLETE
;
433 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
434 gss_krb5_set_allowable_enctypes(OM_uint32
*minor_status
,
436 OM_uint32 num_enctypes
,
440 OM_uint32 maj_status
;
441 gss_buffer_desc buffer
;
446 sp
= krb5_storage_emem();
448 *minor_status
= ENOMEM
;
449 maj_status
= GSS_S_FAILURE
;
453 for (i
= 0; i
< num_enctypes
; i
++) {
454 ret
= krb5_store_int32(sp
, enctypes
[i
]);
457 maj_status
= GSS_S_FAILURE
;
462 ret
= krb5_storage_to_data(sp
, &data
);
465 maj_status
= GSS_S_FAILURE
;
469 buffer
.value
= data
.data
;
470 buffer
.length
= data
.length
;
472 maj_status
= gss_set_cred_option(minor_status
,
474 GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X
,
476 krb5_data_free(&data
);
479 krb5_storage_free(sp
);
487 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
488 gsskrb5_set_send_to_kdc(struct gsskrb5_send_to_kdc
*c
)
490 struct _gss_mech_switch
*m
;
491 gss_buffer_desc buffer
;
498 buffer
.length
= sizeof(*c
);
504 HEIM_SLIST_FOREACH(m
, &_gss_mechs
, gm_link
) {
505 if (m
->gm_mech
.gm_set_sec_context_option
== NULL
)
507 m
->gm_mech
.gm_set_sec_context_option(&junk
, NULL
,
508 GSS_KRB5_SEND_TO_KDC_X
, &buffer
);
511 return (GSS_S_COMPLETE
);
518 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
519 gss_krb5_ccache_name(OM_uint32
*minor_status
,
521 const char **out_name
)
523 struct _gss_mech_switch
*m
;
524 gss_buffer_desc buffer
;
532 buffer
.value
= rk_UNCONST(name
);
533 buffer
.length
= strlen(name
);
535 HEIM_SLIST_FOREACH(m
, &_gss_mechs
, gm_link
) {
536 if (m
->gm_mech
.gm_set_sec_context_option
== NULL
)
538 m
->gm_mech
.gm_set_sec_context_option(&junk
, NULL
,
539 GSS_KRB5_CCACHE_NAME_X
, &buffer
);
542 return (GSS_S_COMPLETE
);
550 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
551 gsskrb5_extract_authtime_from_sec_context(OM_uint32
*minor_status
,
552 gss_ctx_id_t context_handle
,
555 gss_buffer_set_t data_set
= GSS_C_NO_BUFFER_SET
;
558 if (context_handle
== GSS_C_NO_CONTEXT
) {
559 *minor_status
= EINVAL
;
560 return GSS_S_FAILURE
;
564 gss_inquire_sec_context_by_oid (minor_status
,
566 GSS_KRB5_GET_AUTHTIME_X
,
571 if (data_set
== GSS_C_NO_BUFFER_SET
) {
572 gss_release_buffer_set(minor_status
, &data_set
);
573 *minor_status
= EINVAL
;
574 return GSS_S_FAILURE
;
577 if (data_set
->count
!= 1) {
578 gss_release_buffer_set(minor_status
, &data_set
);
579 *minor_status
= EINVAL
;
580 return GSS_S_FAILURE
;
583 if (data_set
->elements
[0].length
!= 4) {
584 gss_release_buffer_set(minor_status
, &data_set
);
585 *minor_status
= EINVAL
;
586 return GSS_S_FAILURE
;
590 unsigned char *buf
= data_set
->elements
[0].value
;
591 *authtime
= (buf
[3] <<24) | (buf
[2] << 16) |
592 (buf
[1] << 8) | (buf
[0] << 0);
595 gss_release_buffer_set(minor_status
, &data_set
);
598 return GSS_S_COMPLETE
;
605 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
606 gsskrb5_extract_authz_data_from_sec_context(OM_uint32
*minor_status
,
607 gss_ctx_id_t context_handle
,
609 gss_buffer_t ad_data
)
611 gss_buffer_set_t data_set
= GSS_C_NO_BUFFER_SET
;
613 gss_OID_desc oid_flat
;
614 heim_oid baseoid
, oid
;
617 if (context_handle
== GSS_C_NO_CONTEXT
) {
618 *minor_status
= EINVAL
;
619 return GSS_S_FAILURE
;
622 /* All this to append an integer to an oid... */
624 if (der_get_oid(GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X
->elements
,
625 GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X
->length
,
626 &baseoid
, NULL
) != 0) {
627 *minor_status
= EINVAL
;
628 return GSS_S_FAILURE
;
631 oid
.length
= baseoid
.length
+ 1;
632 oid
.components
= calloc(oid
.length
, sizeof(*oid
.components
));
633 if (oid
.components
== NULL
) {
634 der_free_oid(&baseoid
);
636 *minor_status
= ENOMEM
;
637 return GSS_S_FAILURE
;
640 memcpy(oid
.components
, baseoid
.components
,
641 baseoid
.length
* sizeof(*baseoid
.components
));
643 der_free_oid(&baseoid
);
645 oid
.components
[oid
.length
- 1] = ad_type
;
647 oid_flat
.length
= der_length_oid(&oid
);
648 oid_flat
.elements
= malloc(oid_flat
.length
);
649 if (oid_flat
.elements
== NULL
) {
650 free(oid
.components
);
651 *minor_status
= ENOMEM
;
652 return GSS_S_FAILURE
;
655 if (der_put_oid((unsigned char *)oid_flat
.elements
+ oid_flat
.length
- 1,
656 oid_flat
.length
, &oid
, &size
) != 0) {
657 free(oid
.components
);
658 free(oid_flat
.elements
);
659 *minor_status
= EINVAL
;
660 return GSS_S_FAILURE
;
662 if (oid_flat
.length
!= size
)
665 free(oid
.components
);
667 /* FINALLY, we have the OID */
669 maj_stat
= gss_inquire_sec_context_by_oid (minor_status
,
674 free(oid_flat
.elements
);
679 if (data_set
== GSS_C_NO_BUFFER_SET
|| data_set
->count
!= 1) {
680 gss_release_buffer_set(minor_status
, &data_set
);
681 *minor_status
= EINVAL
;
682 return GSS_S_FAILURE
;
685 ad_data
->value
= malloc(data_set
->elements
[0].length
);
686 if (ad_data
->value
== NULL
) {
687 gss_release_buffer_set(minor_status
, &data_set
);
688 *minor_status
= ENOMEM
;
689 return GSS_S_FAILURE
;
692 ad_data
->length
= data_set
->elements
[0].length
;
693 memcpy(ad_data
->value
, data_set
->elements
[0].value
, ad_data
->length
);
694 gss_release_buffer_set(minor_status
, &data_set
);
697 return GSS_S_COMPLETE
;
705 gsskrb5_extract_key(OM_uint32
*minor_status
,
706 gss_ctx_id_t context_handle
,
708 krb5_keyblock
**keyblock
)
711 gss_buffer_set_t data_set
= GSS_C_NO_BUFFER_SET
;
712 OM_uint32 major_status
;
713 krb5_context context
= NULL
;
714 krb5_storage
*sp
= NULL
;
716 if (context_handle
== GSS_C_NO_CONTEXT
) {
717 *minor_status
= EINVAL
;
718 return GSS_S_FAILURE
;
721 ret
= krb5_init_context(&context
);
724 return GSS_S_FAILURE
;
728 gss_inquire_sec_context_by_oid (minor_status
,
735 if (data_set
== GSS_C_NO_BUFFER_SET
|| data_set
->count
!= 1) {
736 gss_release_buffer_set(minor_status
, &data_set
);
737 *minor_status
= EINVAL
;
738 return GSS_S_FAILURE
;
741 sp
= krb5_storage_from_mem(data_set
->elements
[0].value
,
742 data_set
->elements
[0].length
);
748 *keyblock
= calloc(1, sizeof(**keyblock
));
749 if (keyblock
== NULL
) {
754 ret
= krb5_ret_keyblock(sp
, *keyblock
);
757 gss_release_buffer_set(minor_status
, &data_set
);
759 krb5_storage_free(sp
);
760 if (ret
&& keyblock
) {
761 krb5_free_keyblock(context
, *keyblock
);
765 krb5_free_context(context
);
769 return GSS_S_FAILURE
;
771 return GSS_S_COMPLETE
;
778 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
779 gsskrb5_extract_service_keyblock(OM_uint32
*minor_status
,
780 gss_ctx_id_t context_handle
,
781 krb5_keyblock
**keyblock
)
783 return gsskrb5_extract_key(minor_status
,
785 GSS_KRB5_GET_SERVICE_KEYBLOCK_X
,
789 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
790 gsskrb5_get_initiator_subkey(OM_uint32
*minor_status
,
791 gss_ctx_id_t context_handle
,
792 krb5_keyblock
**keyblock
)
794 return gsskrb5_extract_key(minor_status
,
796 GSS_KRB5_GET_INITIATOR_SUBKEY_X
,
800 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
801 gsskrb5_get_subkey(OM_uint32
*minor_status
,
802 gss_ctx_id_t context_handle
,
803 krb5_keyblock
**keyblock
)
805 return gsskrb5_extract_key(minor_status
,
807 GSS_KRB5_GET_SUBKEY_X
,
811 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
812 gsskrb5_set_default_realm(const char *realm
)
814 struct _gss_mech_switch
*m
;
815 gss_buffer_desc buffer
;
820 buffer
.value
= rk_UNCONST(realm
);
821 buffer
.length
= strlen(realm
);
823 HEIM_SLIST_FOREACH(m
, &_gss_mechs
, gm_link
) {
824 if (m
->gm_mech
.gm_set_sec_context_option
== NULL
)
826 m
->gm_mech
.gm_set_sec_context_option(&junk
, NULL
,
827 GSS_KRB5_SET_DEFAULT_REALM_X
, &buffer
);
830 return (GSS_S_COMPLETE
);
833 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
834 gss_krb5_get_tkt_flags(OM_uint32
*minor_status
,
835 gss_ctx_id_t context_handle
,
836 OM_uint32
*tkt_flags
)
839 OM_uint32 major_status
;
840 gss_buffer_set_t data_set
= GSS_C_NO_BUFFER_SET
;
842 if (context_handle
== GSS_C_NO_CONTEXT
) {
843 *minor_status
= EINVAL
;
844 return GSS_S_FAILURE
;
848 gss_inquire_sec_context_by_oid (minor_status
,
850 GSS_KRB5_GET_TKT_FLAGS_X
,
855 if (data_set
== GSS_C_NO_BUFFER_SET
||
856 data_set
->count
!= 1 ||
857 data_set
->elements
[0].length
< 4) {
858 gss_release_buffer_set(minor_status
, &data_set
);
859 *minor_status
= EINVAL
;
860 return GSS_S_FAILURE
;
864 const u_char
*p
= data_set
->elements
[0].value
;
865 *tkt_flags
= (p
[0] << 0) | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
868 gss_release_buffer_set(minor_status
, &data_set
);
869 return GSS_S_COMPLETE
;
872 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
873 gsskrb5_set_time_offset(int offset
)
875 struct _gss_mech_switch
*m
;
876 gss_buffer_desc buffer
;
883 buffer
.length
= sizeof(o
);
885 HEIM_SLIST_FOREACH(m
, &_gss_mechs
, gm_link
) {
886 if (m
->gm_mech
.gm_set_sec_context_option
== NULL
)
888 m
->gm_mech
.gm_set_sec_context_option(&junk
, NULL
,
889 GSS_KRB5_SET_TIME_OFFSET_X
, &buffer
);
892 return (GSS_S_COMPLETE
);
895 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
896 gsskrb5_get_time_offset(int *offset
)
898 struct _gss_mech_switch
*m
;
899 gss_buffer_desc buffer
;
900 OM_uint32 maj_stat
, junk
;
906 buffer
.length
= sizeof(o
);
908 HEIM_SLIST_FOREACH(m
, &_gss_mechs
, gm_link
) {
909 if (m
->gm_mech
.gm_set_sec_context_option
== NULL
)
911 maj_stat
= m
->gm_mech
.gm_set_sec_context_option(&junk
, NULL
,
912 GSS_KRB5_GET_TIME_OFFSET_X
, &buffer
);
914 if (maj_stat
== GSS_S_COMPLETE
) {
920 return (GSS_S_UNAVAILABLE
);
923 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
924 gsskrb5_plugin_register(struct gsskrb5_krb5_plugin
*c
)
926 struct _gss_mech_switch
*m
;
927 gss_buffer_desc buffer
;
933 buffer
.length
= sizeof(*c
);
935 HEIM_SLIST_FOREACH(m
, &_gss_mechs
, gm_link
) {
936 if (m
->gm_mech
.gm_set_sec_context_option
== NULL
)
938 m
->gm_mech
.gm_set_sec_context_option(&junk
, NULL
,
939 GSS_KRB5_PLUGIN_REGISTER_X
, &buffer
);
942 return (GSS_S_COMPLETE
);