From 735039dbdc3aa58d06afdefd214efe3f5e421244 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Fri, 4 Jan 2019 10:13:03 +1100 Subject: [PATCH] gssapi: implement gss_set_neg_mechs() (#495) Implementation of gss_set_neg_mechs() and gss_get_neg_mechs() as defined in RFC 4178. New gss_release_cred_by_mech() API for dropping a credential from a mechanism glue credential. --- lib/gssapi/Makefile.am | 2 + lib/gssapi/NTMakefile | 4 + lib/gssapi/gssapi/gssapi.h | 18 +++++ lib/gssapi/gssapi_mech.h | 12 +++ lib/gssapi/krb5/external.c | 2 + lib/gssapi/libgssapi-exports.def | 3 + lib/gssapi/mech/cred.c | 38 +++++++++- lib/gssapi/mech/gss_get_neg_mechs.c | 113 ++++++++++++++++++++++++++++ lib/gssapi/mech/gss_mech_switch.c | 2 + lib/gssapi/mech/gss_set_neg_mechs.c | 93 +++++++++++++++++++++++ lib/gssapi/netlogon/external.c | 2 + lib/gssapi/ntlm/external.c | 2 + lib/gssapi/spnego/cred_stubs.c | 61 ++++++++++++++- lib/gssapi/spnego/external.c | 2 + lib/gssapi/version-script.map | 3 + 15 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 lib/gssapi/mech/gss_get_neg_mechs.c create mode 100644 lib/gssapi/mech/gss_set_neg_mechs.c diff --git a/lib/gssapi/Makefile.am b/lib/gssapi/Makefile.am index 554dbf1ac..ab6e7c553 100644 --- a/lib/gssapi/Makefile.am +++ b/lib/gssapi/Makefile.am @@ -110,6 +110,7 @@ mechsrc = \ mech/gss_export_name_composite.c \ mech/gss_export_sec_context.c \ mech/gss_get_mic.c \ + mech/gss_get_neg_mechs.c \ mech/gss_get_name_attribute.c \ mech/gss_import_name.c \ mech/gss_import_sec_context.c \ @@ -140,6 +141,7 @@ mechsrc = \ mech/gss_seal.c \ mech/gss_set_cred_option.c \ mech/gss_set_name_attribute.c \ + mech/gss_set_neg_mechs.c \ mech/gss_set_sec_context_option.c \ mech/gss_sign.c \ mech/gss_store_cred.c \ diff --git a/lib/gssapi/NTMakefile b/lib/gssapi/NTMakefile index c60f6a445..501345825 100644 --- a/lib/gssapi/NTMakefile +++ b/lib/gssapi/NTMakefile @@ -127,6 +127,7 @@ mechsrc = \ mech/gss_export_name_composite.c \ mech/gss_export_sec_context.c \ mech/gss_get_mic.c \ + mech/gss_get_neg_mechs.c \ mech/gss_get_name_attribute.c \ mech/gss_import_name.c \ mech/gss_import_sec_context.c \ @@ -157,6 +158,7 @@ mechsrc = \ mech/gss_seal.c \ mech/gss_set_cred_option.c \ mech/gss_set_name_attribute.c \ + mech/gss_set_neg_mechs.c \ mech/gss_set_sec_context_option.c \ mech/gss_sign.c \ mech/gss_store_cred.c \ @@ -360,6 +362,7 @@ libgssapi_OBJs = \ $(OBJ)\mech/gss_export_name_composite.obj \ $(OBJ)\mech/gss_export_sec_context.obj \ $(OBJ)\mech/gss_get_mic.obj \ + $(OBJ)\mech/gss_get_neg_mechs.obj \ $(OBJ)\mech/gss_get_name_attribute.obj \ $(OBJ)\mech/gss_import_name.obj \ $(OBJ)\mech/gss_import_sec_context.obj \ @@ -390,6 +393,7 @@ libgssapi_OBJs = \ $(OBJ)\mech/gss_seal.obj \ $(OBJ)\mech/gss_set_cred_option.obj \ $(OBJ)\mech/gss_set_name_attribute.obj \ + $(OBJ)\mech/gss_set_neg_mechs.obj \ $(OBJ)\mech/gss_set_sec_context_option.obj \ $(OBJ)\mech/gss_sign.obj \ $(OBJ)\mech/gss_store_cred.obj \ diff --git a/lib/gssapi/gssapi/gssapi.h b/lib/gssapi/gssapi/gssapi.h index 704777a33..f6ab24f16 100644 --- a/lib/gssapi/gssapi/gssapi.h +++ b/lib/gssapi/gssapi/gssapi.h @@ -1187,6 +1187,24 @@ gss_store_cred_into( gss_cred_usage_t * /* cred_usage_stored */ ); +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_CALLCONV +gss_set_neg_mechs( + OM_uint32 * /* minor_status */, + gss_cred_id_t /* cred_handle */, + const gss_OID_set /* mech_list */); + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_CALLCONV +gss_get_neg_mechs( + OM_uint32 * /* minor_status */, + gss_const_cred_id_t /* cred_handle */, + gss_OID_set * /* mech_list */); + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_release_cred_by_mech( + OM_uint32 * /* minor_status */, + gss_cred_id_t /* cred_handle */, + gss_const_OID /* mech */); + GSSAPI_CPP_END #if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__) || defined(__i386__) || defined(__x86_64__)) diff --git a/lib/gssapi/gssapi_mech.h b/lib/gssapi/gssapi_mech.h index ed71c0b4b..a8aa79c5a 100644 --- a/lib/gssapi/gssapi_mech.h +++ b/lib/gssapi/gssapi_mech.h @@ -472,6 +472,16 @@ _gss_store_cred_into_t(OM_uint32 *minor_status, gss_OID_set *elements_stored, gss_cred_usage_t *cred_usage_stored); +typedef OM_uint32 GSSAPI_CALLCONV +_gss_set_neg_mechs_t(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + const gss_OID_set mechs); + +typedef OM_uint32 GSSAPI_CALLCONV +_gss_get_neg_mechs_t(OM_uint32 *minor_status, + gss_const_cred_id_t cred_handle, + gss_OID_set *mechs); + /* * */ @@ -580,6 +590,8 @@ typedef struct gssapi_mech_interface_desc { _gss_duplicate_cred_t *gm_duplicate_cred; _gss_add_cred_from_t *gm_add_cred_from; _gss_store_cred_into_t *gm_store_cred_into; + _gss_set_neg_mechs_t *gm_set_neg_mechs; + _gss_get_neg_mechs_t *gm_get_neg_mechs; struct gss_mech_compat_desc_struct *gm_compat; } gssapi_mech_interface_desc, *gssapi_mech_interface; diff --git a/lib/gssapi/krb5/external.c b/lib/gssapi/krb5/external.c index 2b97f06d5..a3928fed5 100644 --- a/lib/gssapi/krb5/external.c +++ b/lib/gssapi/krb5/external.c @@ -399,6 +399,8 @@ static gssapi_mech_interface_desc krb5_mech = { _gsskrb5_duplicate_cred, _gsskrb5_add_cred_from, _gsskrb5_store_cred_into, + NULL, /* gm_set_neg_mechs */ + NULL, /* gm_get_neg_mechs */ NULL /* gm_compat */ }; diff --git a/lib/gssapi/libgssapi-exports.def b/lib/gssapi/libgssapi-exports.def index 02da963b0..e52fb090b 100644 --- a/lib/gssapi/libgssapi-exports.def +++ b/lib/gssapi/libgssapi-exports.def @@ -40,6 +40,7 @@ EXPORTS gss_export_name_composite gss_export_sec_context gss_get_mic + gss_get_neg_mechs gss_get_name_attribute gss_import_cred gss_import_name @@ -81,6 +82,7 @@ EXPORTS gss_release_buffer gss_release_buffer_set gss_release_cred + gss_release_cred_by_mech gss_release_iov_buffer gss_release_name gss_release_oid @@ -88,6 +90,7 @@ EXPORTS gss_seal gss_set_cred_option gss_set_name_attribute + gss_set_neg_mechs gss_set_sec_context_option gss_sign gss_store_cred diff --git a/lib/gssapi/mech/cred.c b/lib/gssapi/mech/cred.c index 6d811db40..63af0f76f 100644 --- a/lib/gssapi/mech/cred.c +++ b/lib/gssapi/mech/cred.c @@ -37,6 +37,17 @@ #include "heim_threads.h" #include "heimbase.h" +static OM_uint32 +release_mech_cred(OM_uint32 *minor, struct _gss_mechanism_cred *mc) +{ + OM_uint32 major; + + major = mc->gmc_mech->gm_release_cred(minor, &mc->gmc_cred); + free(mc); + + return major; +} + void _gss_mg_release_cred(struct _gss_cred *cred) @@ -47,8 +58,7 @@ _gss_mg_release_cred(struct _gss_cred *cred) while (HEIM_SLIST_FIRST(&cred->gc_mc)) { mc = HEIM_SLIST_FIRST(&cred->gc_mc); HEIM_SLIST_REMOVE_HEAD(&cred->gc_mc, gmc_link); - mc->gmc_mech->gm_release_cred(&junk, &mc->gmc_cred); - free(mc); + release_mech_cred(&junk, mc); } free(cred); } @@ -65,3 +75,27 @@ _gss_mg_alloc_cred(void) return cred; } +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_release_cred_by_mech(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + gss_const_OID mech_oid) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + struct _gss_mechanism_cred *mc; + OM_uint32 major_status; + + HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + if (gss_oid_equal(mech_oid, mc->gmc_mech_oid)) + break; + } + + if (mc) { + HEIM_SLIST_REMOVE(&cred->gc_mc, mc, _gss_mechanism_cred, gmc_link); + major_status = release_mech_cred(minor_status, mc); + } else { + *minor_status = 0; + major_status = GSS_S_NO_CRED; + } + + return major_status; +} diff --git a/lib/gssapi/mech/gss_get_neg_mechs.c b/lib/gssapi/mech/gss_get_neg_mechs.c new file mode 100644 index 000000000..1ef7792d4 --- /dev/null +++ b/lib/gssapi/mech/gss_get_neg_mechs.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_get_neg_mechs (OM_uint32 *minor_status, + gss_const_cred_id_t cred_handle, + gss_OID_set *mechs) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + OM_uint32 major, minor; + gss_cred_id_t tmp_cred = GSS_C_NO_CREDENTIAL; + struct _gss_mechanism_cred *mc; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + *minor_status = 0; + + if (mechs == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + *mechs = GSS_C_NO_OID_SET; + + _gss_load_mech(); + + if (cred == NULL) { + major = gss_acquire_cred(minor_status, GSS_C_NO_NAME, GSS_C_INDEFINITE, + GSS_C_NO_OID_SET, GSS_C_BOTH, + &tmp_cred, NULL, NULL); + if (GSS_ERROR(major)) + return major; + + cred = (struct _gss_cred *)tmp_cred; + } + + major = gss_create_empty_oid_set(minor_status, mechs); + if (GSS_ERROR(major)) + goto cleanup; + + major = GSS_S_UNAVAILABLE; + + HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + gssapi_mech_interface m; + gss_OID_set mechs2 = GSS_C_NO_OID_SET; + size_t i; + + m = mc->gmc_mech; + if (m == NULL) { + major = GSS_S_BAD_MECH; + goto cleanup; + } + + if (m->gm_get_neg_mechs == NULL) + continue; + + major = m->gm_get_neg_mechs(minor_status, mc->gmc_cred, &mechs2); + if (GSS_ERROR(major)) + goto cleanup; + + if (mechs2 == GSS_C_NO_OID_SET) + continue; + + for (i = 0; i < mechs2->count; i++) { + major = gss_add_oid_set_member(minor_status, &mechs2->elements[i], + mechs); + if (GSS_ERROR(major)) { + gss_release_oid_set(&minor, &mechs2); + goto cleanup; + } + } + + gss_release_oid_set(&minor, &mechs2); + } + +cleanup: + if (tmp_cred) + gss_release_cred(&minor, &tmp_cred); + if (major == GSS_S_COMPLETE && *mechs == GSS_C_NO_OID_SET) + major = GSS_S_NO_CRED; + if (GSS_ERROR(major)) + gss_release_oid_set(&minor, mechs); + + return major; +} diff --git a/lib/gssapi/mech/gss_mech_switch.c b/lib/gssapi/mech/gss_mech_switch.c index 1826b278b..ba1cfa1b0 100644 --- a/lib/gssapi/mech/gss_mech_switch.c +++ b/lib/gssapi/mech/gss_mech_switch.c @@ -397,6 +397,8 @@ _gss_load_mech(void) OPTSYM(duplicate_cred); OPTSYM(add_cred_from); OPTSYM(store_cred_into); + OPTSYM(set_neg_mechs); + OPTSYM(get_neg_mechs); OPTSPISYM(authorize_localname); mi = (_gss_mo_init *)dlsym(so, "gss_mo_init"); diff --git a/lib/gssapi/mech/gss_set_neg_mechs.c b/lib/gssapi/mech/gss_set_neg_mechs.c new file mode 100644 index 000000000..c7bcf122d --- /dev/null +++ b/lib/gssapi/mech/gss_set_neg_mechs.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_set_neg_mechs (OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + const gss_OID_set mechs) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + OM_uint32 major; + int found = 0; + + if (minor_status == NULL) + return GSS_S_CALL_INACCESSIBLE_WRITE; + *minor_status = 0; + + if (mechs == GSS_C_NO_OID_SET) + return GSS_S_CALL_INACCESSIBLE_READ; + + _gss_load_mech(); + + major = GSS_S_UNAVAILABLE; + + if (cred == NULL) { + struct _gss_mech_switch *m; + + HEIM_SLIST_FOREACH(m, &_gss_mechs, gm_link) { + if (m->gm_mech.gm_set_neg_mechs == NULL) + continue; + major = m->gm_mech.gm_set_neg_mechs(minor_status, + GSS_C_NO_CREDENTIAL, mechs); + if (major == GSS_S_COMPLETE) + found++; + else + _gss_mg_error(&m->gm_mech, *minor_status); + } + } else { + struct _gss_mechanism_cred *mc; + + HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + gssapi_mech_interface m; + + m = mc->gmc_mech; + if (m == NULL) + return GSS_S_BAD_MECH; + if (m->gm_set_neg_mechs == NULL) + continue; + major = m->gm_set_neg_mechs(minor_status, mc->gmc_cred, mechs); + if (major == GSS_S_COMPLETE) + found++; + else + _gss_mg_error(m, *minor_status); + } + } + + if (found) { + *minor_status = 0; + return GSS_S_COMPLETE; + } + + return major; +} diff --git a/lib/gssapi/netlogon/external.c b/lib/gssapi/netlogon/external.c index 7c0f81b1d..49a37cb82 100644 --- a/lib/gssapi/netlogon/external.c +++ b/lib/gssapi/netlogon/external.c @@ -100,6 +100,8 @@ static gssapi_mech_interface_desc netlogon_mech = { NULL, /* gm_duplicate_cred */ NULL, /* gm_add_cred_from */ NULL, /* gm_store_cred_into */ + NULL, /* gm_set_neg_mechs */ + NULL, /* gm_get_neg_mechs */ NULL /* gm_compat */ }; diff --git a/lib/gssapi/ntlm/external.c b/lib/gssapi/ntlm/external.c index 4d133cfd7..986f9f3df 100644 --- a/lib/gssapi/ntlm/external.c +++ b/lib/gssapi/ntlm/external.c @@ -125,6 +125,8 @@ static gssapi_mech_interface_desc ntlm_mech = { NULL, /* gm_duplicate_cred */ NULL, /* gm_add_cred_from */ NULL, /* gm_store_cred_into */ + NULL, /* gm_set_neg_mechs */ + NULL, /* gm_get_neg_mechs */ NULL, /* gm_compat */ }; diff --git a/lib/gssapi/spnego/cred_stubs.c b/lib/gssapi/spnego/cred_stubs.c index 545b3e8b8..92c97d2b8 100644 --- a/lib/gssapi/spnego/cred_stubs.c +++ b/lib/gssapi/spnego/cred_stubs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, PADL Software Pty Ltd. + * Copyright (c) 2004, 2018, PADL Software Pty Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,6 +31,7 @@ */ #include "spnego_locl.h" +#include OM_uint32 GSSAPI_CALLCONV _gss_spnego_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle) @@ -270,3 +271,61 @@ _gss_spnego_import_cred (OM_uint32 *minor_status, return gss_import_cred(minor_status, value, cred_handle); } + +OM_uint32 GSSAPI_CALLCONV +_gss_spnego_set_neg_mechs (OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + const gss_OID_set mech_list) +{ + OM_uint32 major, minor; + gss_OID_set mechs = GSS_C_NO_OID_SET; + size_t i; + + if (cred_handle != GSS_C_NO_CREDENTIAL) { + major = gss_inquire_cred(minor_status, cred_handle, + NULL, NULL, NULL, &mechs); + if (GSS_ERROR(major)) + return major; + + for (i = 0; i < mechs->count; i++) { + int present; + + major = gss_test_oid_set_member(minor_status, + &mechs->elements[i], + mech_list, &present); + if (GSS_ERROR(major)) + break; + + if (!present) { + major = gss_release_cred_by_mech(minor_status, + cred_handle, + &mechs->elements[i]); + if (GSS_ERROR(major)) + break; + } + } + + /* for inner negotiation mechs, such as NegoEx */ + (void) gss_set_neg_mechs(&minor, cred_handle, mech_list); + } else { + /* + * RFC 4178 says that GSS_Set_neg_mechs() on NULL credential sets + * the negotiable mechs for the default credential, but neither + * MIT nor Heimdal support this presently. + */ + major = GSS_S_NO_CRED; + } + + gss_release_oid_set(&minor, &mechs); + + return major; +} + +OM_uint32 GSSAPI_CALLCONV +_gss_spnego_get_neg_mechs (OM_uint32 *minor_status, + gss_const_cred_id_t cred_handle, + gss_OID_set *mech_list) +{ + return gss_inquire_cred(minor_status, cred_handle, + NULL, NULL, NULL, mech_list); +} diff --git a/lib/gssapi/spnego/external.c b/lib/gssapi/spnego/external.c index 6b818dfe0..add000562 100644 --- a/lib/gssapi/spnego/external.c +++ b/lib/gssapi/spnego/external.c @@ -149,6 +149,8 @@ static gssapi_mech_interface_desc spnego_mech = { NULL, /* gm_duplicate_cred */ gss_add_cred_from, NULL, /* gm_store_cred_into */ + _gss_spnego_set_neg_mechs, + _gss_spnego_get_neg_mechs, NULL /* gm_compat */ }; diff --git a/lib/gssapi/version-script.map b/lib/gssapi/version-script.map index 7359db7ee..326597034 100644 --- a/lib/gssapi/version-script.map +++ b/lib/gssapi/version-script.map @@ -43,6 +43,7 @@ HEIMDAL_GSS_2.0 { gss_export_name_composite; gss_export_sec_context; gss_get_mic; + gss_get_neg_mechs; gss_get_name_attribute; gss_import_cred; gss_import_name; @@ -75,6 +76,7 @@ HEIMDAL_GSS_2.0 { gss_release_buffer; gss_release_buffer_set; gss_release_cred; + gss_release_cred_by_mech; gss_release_iov_buffer; gss_release_name; gss_release_oid; @@ -82,6 +84,7 @@ HEIMDAL_GSS_2.0 { gss_seal; gss_set_cred_option; gss_set_name_attribute; + gss_set_neg_mechs; gss_set_sec_context_option; gss_sign; gss_store_cred;