From e6d1c10808bae4853b005bd981878c42c3432cfe Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Wed, 26 Dec 2018 17:24:08 -0600 Subject: [PATCH] Rewrite gss_add_cred() (fix #413) It turns out gss_add_cred() really needed a complete rewrite. It's much better to first have a gss_duplicate_cred() (which has been needed for other reasons anyways), and use that when the input_cred_handle is not GSS_C_NO_CREDENTIAL and output_cred_handle is not NULL, then mutate that duplicate credential handle (or the input_cred_handle if output_cred_handle is NULL). --- lib/gssapi/Makefile.am | 2 + lib/gssapi/NTMakefile | 10 +- lib/gssapi/gssapi/gssapi.h | 12 +- lib/gssapi/gssapi_mech.h | 9 + lib/gssapi/krb5/duplicate_cred.c | 159 +++++++++ lib/gssapi/krb5/external.c | 17 +- lib/gssapi/krb5/test_acquire_cred.c | 27 +- lib/gssapi/krb5/test_cred.c | 62 +++- lib/gssapi/mech/gss_add_cred.c | 393 +++++++++++---------- lib/gssapi/mech/gss_duplicate_cred.c | 130 +++++++ .../netlogon/{external.c => duplicate_cred.c} | 69 +--- lib/gssapi/netlogon/external.c | 29 +- lib/gssapi/netlogon/netlogon.h | 4 +- .../{netlogon/external.c => ntlm/duplicate_cred.c} | 94 ++--- lib/gssapi/ntlm/external.c | 21 +- lib/gssapi/ntlm/ntlm.h | 3 +- lib/gssapi/spnego/external.c | 21 +- 17 files changed, 728 insertions(+), 334 deletions(-) create mode 100644 lib/gssapi/krb5/duplicate_cred.c rewrite lib/gssapi/mech/gss_add_cred.c (64%) create mode 100644 lib/gssapi/mech/gss_duplicate_cred.c copy lib/gssapi/netlogon/{external.c => duplicate_cred.c} (56%) copy lib/gssapi/{netlogon/external.c => ntlm/duplicate_cred.c} (50%) diff --git a/lib/gssapi/Makefile.am b/lib/gssapi/Makefile.am index ad88f6bf5..3c059afdb 100644 --- a/lib/gssapi/Makefile.am +++ b/lib/gssapi/Makefile.am @@ -37,6 +37,7 @@ krb5src = \ krb5/delete_sec_context.c \ krb5/display_name.c \ krb5/display_status.c \ + krb5/duplicate_cred.c \ krb5/duplicate_name.c \ krb5/encapsulate.c \ krb5/export_name.c \ @@ -99,6 +100,7 @@ mechsrc = \ mech/gss_display_name.c \ mech/gss_display_name_ext.c \ mech/gss_display_status.c \ + mech/gss_duplicate_cred.c \ mech/gss_duplicate_name.c \ mech/gss_duplicate_oid.c \ mech/gss_encapsulate_token.c \ diff --git a/lib/gssapi/NTMakefile b/lib/gssapi/NTMakefile index 402b110a1..9a9f6d728 100644 --- a/lib/gssapi/NTMakefile +++ b/lib/gssapi/NTMakefile @@ -1,6 +1,8 @@ ######################################################################## # -# Copyright (c) 2009-2011, Secure Endpoints Inc. +# Copyright (c) 2009-2011 Secure Endpoints Inc. +# Copyright (c) 2018 Kungliga Tekniska Högskolan +# (Royal Institute of Technology, Stockholm, Sweden). # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -56,6 +58,7 @@ krb5src = \ krb5/display_name.c \ krb5/display_status.c \ krb5/duplicate_name.c \ + krb5/duplicate_cred.c \ krb5/encapsulate.c \ krb5/export_name.c \ krb5/export_sec_context.c \ @@ -115,6 +118,7 @@ mechsrc = \ mech/gss_display_name_ext.c \ mech/gss_display_status.c \ mech/gss_duplicate_name.c \ + mech/gss_duplicate_cred.c \ mech/gss_duplicate_oid.c \ mech/gss_encapsulate_token.c \ mech/gss_export_name.c \ @@ -191,6 +195,7 @@ ntlmsrc = \ ntlm/display_name.c \ ntlm/display_status.c \ ntlm/duplicate_name.c \ + ntlm/duplicate_cred.c \ ntlm/export_name.c \ ntlm/export_sec_context.c \ ntlm/external.c \ @@ -287,6 +292,7 @@ libgssapi_OBJs = \ $(OBJ)\krb5/delete_sec_context.obj \ $(OBJ)\krb5/display_name.obj \ $(OBJ)\krb5/display_status.obj \ + $(OBJ)\krb5/duplicate_cred.obj \ $(OBJ)\krb5/duplicate_name.obj \ $(OBJ)\krb5/encapsulate.obj \ $(OBJ)\krb5/export_name.obj \ @@ -341,6 +347,7 @@ libgssapi_OBJs = \ $(OBJ)\mech/gss_display_name.obj \ $(OBJ)\mech/gss_display_name_ext.obj \ $(OBJ)\mech/gss_display_status.obj \ + $(OBJ)\mech/gss_duplicate_cred.obj \ $(OBJ)\mech/gss_duplicate_name.obj \ $(OBJ)\mech/gss_duplicate_oid.obj \ $(OBJ)\mech/gss_encapsulate_token.obj \ @@ -407,6 +414,7 @@ libgssapi_OBJs = \ $(OBJ)\ntlm/delete_sec_context.obj \ $(OBJ)\ntlm/display_name.obj \ $(OBJ)\ntlm/display_status.obj \ + $(OBJ)\ntlm/duplicate_cred.obj \ $(OBJ)\ntlm/duplicate_name.obj \ $(OBJ)\ntlm/export_name.obj \ $(OBJ)\ntlm/export_sec_context.obj \ diff --git a/lib/gssapi/gssapi/gssapi.h b/lib/gssapi/gssapi/gssapi.h index 1a128cbe4..59eb717ce 100644 --- a/lib/gssapi/gssapi/gssapi.h +++ b/lib/gssapi/gssapi/gssapi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -1114,6 +1114,16 @@ GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_export_name_composite ( ); /* + * Other extensions + */ + + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_duplicate_cred ( + OM_uint32 * /*minor_status*/, + gss_const_cred_id_t /*input_cred_handle*/, + gss_cred_id_t * /*output_cred_handle*/ + ); +/* * */ diff --git a/lib/gssapi/gssapi_mech.h b/lib/gssapi/gssapi_mech.h index 59fd04682..06072e20b 100644 --- a/lib/gssapi/gssapi_mech.h +++ b/lib/gssapi/gssapi_mech.h @@ -1,5 +1,7 @@ /*- * Copyright (c) 2005 Doug Rabson + * Copyright (c) 2018 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -222,6 +224,12 @@ typedef OM_uint32 GSSAPI_CALLCONV _gss_add_cred_t ( OM_uint32 * /* acceptor_time_rec */ ); +typedef OM_uint32 GSSAPI_CALLCONV _gss_duplicate_cred_t ( + OM_uint32 *, /* minor_status */ + gss_const_cred_id_t, /* input_cred_handle */ + gss_cred_id_t * /* output_cred_handle */ + ); + typedef OM_uint32 GSSAPI_CALLCONV _gss_inquire_cred_by_mech_t ( OM_uint32 *, /* minor_status */ gss_const_cred_id_t, /* cred_handle */ @@ -544,6 +552,7 @@ typedef struct gssapi_mech_interface_desc { _gss_set_name_attribute_t *gm_set_name_attribute; _gss_delete_name_attribute_t *gm_delete_name_attribute; _gss_export_name_composite_t *gm_export_name_composite; + _gss_duplicate_cred_t *gm_duplicate_cred; struct gss_mech_compat_desc_struct *gm_compat; } gssapi_mech_interface_desc, *gssapi_mech_interface; diff --git a/lib/gssapi/krb5/duplicate_cred.c b/lib/gssapi/krb5/duplicate_cred.c new file mode 100644 index 000000000..d7819ef32 --- /dev/null +++ b/lib/gssapi/krb5/duplicate_cred.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2018 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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 the Institute 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 THE INSTITUTE 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 THE INSTITUTE 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 "gsskrb5_locl.h" + +OM_uint32 GSSAPI_CALLCONV _gsskrb5_duplicate_cred ( + OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_cred_id_t *output_cred_handle) +{ + krb5_context context; + gsskrb5_cred cred, dup; + OM_uint32 major, junk; + + dup = NULL; + + if (output_cred_handle == NULL) { + *minor_status = EINVAL; + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + GSSAPI_KRB5_INIT (&context); + + if (input_cred_handle == GSS_C_NO_CREDENTIAL) { + /* Duplicate the default credential */ + return _gsskrb5_acquire_cred(minor_status, GSS_C_NO_NAME, + GSS_C_INDEFINITE, + GSS_C_NO_OID_SET, + GSS_C_BOTH, + output_cred_handle, + NULL, NULL); + } + + /* Duplicate the input credential */ + + dup = calloc(1, sizeof(*dup)); + if (dup == NULL) { + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + + *output_cred_handle = (gss_cred_id_t)dup; /* making sure to release on error */ + + cred = (gsskrb5_cred)input_cred_handle; + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); + dup->usage = cred->usage; + dup->endtime = cred->endtime; + dup->principal = NULL; + dup->keytab = NULL; + dup->ccache = NULL; + dup->mechanisms = NULL; + + major = GSS_S_FAILURE; + + HEIMDAL_MUTEX_init(&dup->cred_id_mutex); + *minor_status = krb5_copy_principal(context, cred->principal, + &dup->principal); + if (*minor_status) + goto fail; + + if (cred->keytab) { + char *name = NULL; + + *minor_status = krb5_kt_get_full_name(context, cred->keytab, &name); + if (*minor_status) + goto fail; + *minor_status = krb5_kt_resolve(context, name, &dup->keytab); + krb5_xfree(name); + if (*minor_status) + goto fail; + } + + if (cred->ccache) { + const char *type, *name; + char *type_name = NULL; + + type = krb5_cc_get_type(context, cred->ccache); /* can't fail */ + if (strcmp(type, "MEMORY") == 0) { + *minor_status = krb5_cc_new_unique(context, type, NULL, + &dup->ccache); + if (*minor_status) + goto fail; + + *minor_status = krb5_cc_copy_cache(context, cred->ccache, + dup->ccache); + if (*minor_status) + goto fail; + + } else { + name = krb5_cc_get_name(context, cred->ccache); + if (name == NULL) { + *minor_status = ENOMEM; + goto fail; + } + + if (asprintf(&type_name, "%s:%s", type, name) == -1 || + type_name == NULL) { + *minor_status = ENOMEM; + goto fail; + } + + *minor_status = krb5_cc_resolve(context, type_name, + &dup->ccache); + free(type_name); + if (*minor_status) + goto fail; + } + } + + major = gss_create_empty_oid_set(minor_status, &dup->mechanisms); + if (major != GSS_S_COMPLETE) + goto fail; + + major = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, + &dup->mechanisms); + if (major != GSS_S_COMPLETE) + goto fail; + + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *output_cred_handle = (gss_cred_id_t)dup; + *minor_status = 0; + return major; + +fail: + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *output_cred_handle = (gss_cred_id_t)dup; + _gsskrb5_release_cred(&junk, output_cred_handle); + return major; +} diff --git a/lib/gssapi/krb5/external.c b/lib/gssapi/krb5/external.c index deae016bc..bc57da288 100644 --- a/lib/gssapi/krb5/external.c +++ b/lib/gssapi/krb5/external.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -390,13 +390,14 @@ static gssapi_mech_interface_desc krb5_mech = { sizeof(krb5_mo) / sizeof(krb5_mo[0]), _gsskrb5_localname, _gsskrb5_authorize_localname, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + NULL, /* gm_display_name_ext */ + NULL, /* gm_inquire_name */ + NULL, /* gm_get_name_attribute */ + NULL, /* gm_set_name_attribute */ + NULL, /* gm_delete_name_attribute */ + NULL, /* gm_export_name_composite */ + _gsskrb5_duplicate_cred, + NULL /* gm_compat */ }; gssapi_mech_interface diff --git a/lib/gssapi/krb5/test_acquire_cred.c b/lib/gssapi/krb5/test_acquire_cred.c index 9f7c9ef4e..812fce671 100644 --- a/lib/gssapi/krb5/test_acquire_cred.c +++ b/lib/gssapi/krb5/test_acquire_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2005 Kungliga Tekniska Högskolan + * Copyright (c) 2003-2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -76,6 +76,30 @@ test_add(gss_cred_id_t cred_handle) } static void +test_add_mutate(gss_cred_id_t cred_handle) +{ + OM_uint32 major_status, minor_status; + OM_uint32 time_rec; + + major_status = gss_add_cred (&minor_status, + cred_handle, + GSS_C_NO_NAME, + GSS_KRB5_MECHANISM, + GSS_C_INITIATE, + 0, + 0, + NULL, + NULL, + &time_rec, + NULL); + + if (GSS_ERROR(major_status)) + errx(1, "add_cred failed"); + + print_time(time_rec); +} + +static void copy_cred(void) { OM_uint32 major_status, minor_status; @@ -98,6 +122,7 @@ copy_cred(void) test_add(cred_handle); test_add(cred_handle); test_add(cred_handle); + test_add_mutate(cred_handle); major_status = gss_release_cred(&minor_status, &cred_handle); diff --git a/lib/gssapi/krb5/test_cred.c b/lib/gssapi/krb5/test_cred.c index 06dd6632d..e0395f041 100644 --- a/lib/gssapi/krb5/test_cred.c +++ b/lib/gssapi/krb5/test_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004 Kungliga Tekniska Högskolan + * Copyright (c) 2003-2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -151,6 +151,62 @@ acquire_add_release_add(gss_name_t name, gss_cred_usage_t usage) gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat); } +static void +add_add_release_add(gss_name_t name, gss_cred_usage_t usage) +{ + OM_uint32 maj_stat, min_stat; + gss_cred_id_t cred, cred2; + + maj_stat = gss_add_cred(&min_stat, + GSS_C_NO_CREDENTIAL, + name, + GSS_KRB5_MECHANISM, + usage, + GSS_C_INDEFINITE, + GSS_C_INDEFINITE, + &cred, + NULL, + NULL, + NULL); + if (maj_stat != GSS_S_COMPLETE) + gss_err(1, min_stat, "add_cred %d != GSS_S_COMPLETE", (int)maj_stat); + + maj_stat = gss_add_cred(&min_stat, + cred, + GSS_C_NO_NAME, + GSS_KRB5_MECHANISM, + usage, + GSS_C_INDEFINITE, + GSS_C_INDEFINITE, + &cred2, + NULL, + NULL, + NULL); + + if (maj_stat != GSS_S_COMPLETE) + gss_err(1, min_stat, "add_cred %d != GSS_S_COMPLETE", (int)maj_stat); + + maj_stat = gss_release_cred(&min_stat, &cred); + if (maj_stat != GSS_S_COMPLETE) + gss_err(1, min_stat, "release %d != GSS_S_COMPLETE", (int)maj_stat); + + maj_stat = gss_add_cred(&min_stat, + cred2, + GSS_C_NO_NAME, + GSS_KRB5_MECHANISM, + GSS_C_BOTH, + GSS_C_INDEFINITE, + GSS_C_INDEFINITE, + NULL, + NULL, + NULL, + NULL); + + maj_stat = gss_release_cred(&min_stat, &cred2); + if (maj_stat != GSS_S_COMPLETE) + gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat); +} + static int version_flag = 0; static int help_flag = 0; @@ -211,6 +267,10 @@ main(int argc, char **argv) acquire_add_release_add(name, GSS_C_INITIATE); acquire_add_release_add(name, GSS_C_BOTH); + add_add_release_add(name, GSS_C_ACCEPT); + add_add_release_add(name, GSS_C_INITIATE); + add_add_release_add(name, GSS_C_BOTH); + gss_release_name(&min_stat, &name); return 0; diff --git a/lib/gssapi/mech/gss_add_cred.c b/lib/gssapi/mech/gss_add_cred.c dissimilarity index 64% index b56e3d760..8cbe7bb69 100644 --- a/lib/gssapi/mech/gss_add_cred.c +++ b/lib/gssapi/mech/gss_add_cred.c @@ -1,186 +1,207 @@ -/*- - * Copyright (c) 2005 Doug Rabson - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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. - * - * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ - */ - -#include "mech_locl.h" - -struct _gss_mechanism_cred * -_gss_copy_cred(struct _gss_mechanism_cred *mc) -{ - struct _gss_mechanism_cred *new_mc; - gssapi_mech_interface m = mc->gmc_mech; - OM_uint32 major_status, minor_status; - gss_name_t name; - gss_cred_id_t cred; - OM_uint32 initiator_lifetime, acceptor_lifetime; - gss_cred_usage_t cred_usage; - - major_status = m->gm_inquire_cred_by_mech(&minor_status, - mc->gmc_cred, mc->gmc_mech_oid, - &name, &initiator_lifetime, &acceptor_lifetime, &cred_usage); - if (major_status) { - _gss_mg_error(m, major_status, minor_status); - return (0); - } - - major_status = m->gm_add_cred(&minor_status, - GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid, - cred_usage, initiator_lifetime, acceptor_lifetime, - &cred, 0, 0, 0); - m->gm_release_name(&minor_status, &name); - - if (major_status) { - _gss_mg_error(m, major_status, minor_status); - return (0); - } - - new_mc = malloc(sizeof(struct _gss_mechanism_cred)); - if (!new_mc) { - m->gm_release_cred(&minor_status, &cred); - return (0); - } - new_mc->gmc_mech = m; - new_mc->gmc_mech_oid = &m->gm_mech_oid; - new_mc->gmc_cred = cred; - - return (new_mc); -} - -GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL -gss_add_cred(OM_uint32 *minor_status, - gss_const_cred_id_t input_cred_handle, - gss_const_name_t desired_name, - const gss_OID desired_mech, - gss_cred_usage_t cred_usage, - OM_uint32 initiator_time_req, - OM_uint32 acceptor_time_req, - gss_cred_id_t *output_cred_handle, - gss_OID_set *actual_mechs, - OM_uint32 *initiator_time_rec, - OM_uint32 *acceptor_time_rec) -{ - OM_uint32 major_status; - gssapi_mech_interface m; - struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle; - struct _gss_cred *new_cred; - gss_cred_id_t release_cred; - struct _gss_mechanism_cred *mc, *target_mc, *copy_mc; - struct _gss_mechanism_name *mn; - OM_uint32 junk; - - *minor_status = 0; - *output_cred_handle = GSS_C_NO_CREDENTIAL; - if (initiator_time_rec) - *initiator_time_rec = 0; - if (acceptor_time_rec) - *acceptor_time_rec = 0; - if (actual_mechs) - *actual_mechs = GSS_C_NO_OID_SET; - - new_cred = malloc(sizeof(struct _gss_cred)); - if (!new_cred) { - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - HEIM_SLIST_INIT(&new_cred->gc_mc); - - /* - * We go through all the mc attached to the input_cred_handle - * and check the mechanism. If it matches, we call - * gss_add_cred for that mechanism, otherwise we copy the mc - * to new_cred. - */ - target_mc = 0; - if (cred) { - HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { - if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) { - target_mc = mc; - } - copy_mc = _gss_copy_cred(mc); - if (!copy_mc) { - release_cred = (gss_cred_id_t)new_cred; - gss_release_cred(&junk, &release_cred); - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link); - } - } - - /* - * Figure out a suitable mn, if any. - */ - if (desired_name) { - major_status = _gss_find_mn(minor_status, - (struct _gss_name *) desired_name, - desired_mech, - &mn); - if (major_status != GSS_S_COMPLETE) { - free(new_cred); - return major_status; - } - } else { - mn = 0; - } - - m = __gss_get_mechanism(desired_mech); - - mc = malloc(sizeof(struct _gss_mechanism_cred)); - if (!mc) { - release_cred = (gss_cred_id_t)new_cred; - gss_release_cred(&junk, &release_cred); - *minor_status = ENOMEM; - return (GSS_S_FAILURE); - } - mc->gmc_mech = m; - mc->gmc_mech_oid = &m->gm_mech_oid; - - major_status = m->gm_add_cred(minor_status, - target_mc ? target_mc->gmc_cred : GSS_C_NO_CREDENTIAL, - desired_name ? mn->gmn_name : GSS_C_NO_NAME, - desired_mech, - cred_usage, - initiator_time_req, - acceptor_time_req, - &mc->gmc_cred, - actual_mechs, - initiator_time_rec, - acceptor_time_rec); - - if (major_status) { - _gss_mg_error(m, major_status, *minor_status); - release_cred = (gss_cred_id_t)new_cred; - gss_release_cred(&junk, &release_cred); - free(mc); - return (major_status); - } - HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link); - *output_cred_handle = (gss_cred_id_t) new_cred; - - return (GSS_S_COMPLETE); -} - +/*- + * Copyright (c) 2005 Doug Rabson + * Copyright (c) 2018 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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. + * + * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +struct _gss_mechanism_cred * +_gss_copy_cred(struct _gss_mechanism_cred *mc) +{ + struct _gss_mechanism_cred *new_mc; + gssapi_mech_interface m = mc->gmc_mech; + OM_uint32 major_status, minor_status; + gss_name_t name; + gss_cred_id_t cred; + OM_uint32 initiator_lifetime, acceptor_lifetime; + gss_cred_usage_t cred_usage; + + major_status = m->gm_inquire_cred_by_mech(&minor_status, mc->gmc_cred, + mc->gmc_mech_oid, &name, + &initiator_lifetime, + &acceptor_lifetime, &cred_usage); + if (major_status) { + _gss_mg_error(m, major_status, minor_status); + return 0; + } + + major_status = m->gm_add_cred(&minor_status, + GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid, + cred_usage, initiator_lifetime, acceptor_lifetime, + &cred, 0, 0, 0); + m->gm_release_name(&minor_status, &name); + + if (major_status) { + _gss_mg_error(m, major_status, minor_status); + return 0; + } + + new_mc = malloc(sizeof(struct _gss_mechanism_cred)); + if (!new_mc) { + m->gm_release_cred(&minor_status, &cred); + return 0; + } + new_mc->gmc_mech = m; + new_mc->gmc_mech_oid = &m->gm_mech_oid; + new_mc->gmc_cred = cred; + + return new_mc; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_add_cred(OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_const_name_t desired_name, + const gss_OID desired_mech, + gss_cred_usage_t cred_usage, + OM_uint32 initiator_time_req, + OM_uint32 acceptor_time_req, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *initiator_time_rec, + OM_uint32 *acceptor_time_rec) +{ + OM_uint32 major_status; + gssapi_mech_interface m; + gss_cred_id_t release_cred = GSS_C_NO_CREDENTIAL; + struct _gss_cred *mut_cred; + struct _gss_mechanism_cred *mc; + struct _gss_mechanism_cred *new_mc = NULL; + struct _gss_mechanism_name *mn = NULL; + OM_uint32 junk; + + *minor_status = 0; + + /* Input validation */ + if (output_cred_handle) + *output_cred_handle = GSS_C_NO_CREDENTIAL; + if (initiator_time_rec) + *initiator_time_rec = 0; + if (acceptor_time_rec) + *acceptor_time_rec = 0; + if (actual_mechs) + *actual_mechs = GSS_C_NO_OID_SET; + if ((m = __gss_get_mechanism(desired_mech)) == NULL) + return GSS_S_BAD_MECH; + if (input_cred_handle == GSS_C_NO_CREDENTIAL && + output_cred_handle == NULL) { + return GSS_S_CALL_INACCESSIBLE_WRITE; + } + + /* Setup mut_cred to be the credential we mutate */ + if (input_cred_handle != GSS_C_NO_CREDENTIAL && + output_cred_handle != NULL) { + gss_cred_id_t new_cred; + + /* Duplicate the input credential */ + major_status = gss_duplicate_cred(minor_status, input_cred_handle, + &new_cred); + if (major_status != GSS_S_COMPLETE) + return major_status; + mut_cred = (struct _gss_cred *)new_cred; + release_cred = (gss_cred_id_t)mut_cred; + } else if (input_cred_handle != GSS_C_NO_CREDENTIAL) { + /* Mutate the input credentials */ + mut_cred = rk_UNCONST(input_cred_handle); + } else { + if ((mut_cred = malloc(sizeof(*mut_cred))) == NULL) { + *minor_status = ENOMEM; + return GSS_S_UNAVAILABLE; + } + HEIM_SLIST_INIT(&mut_cred->gc_mc); + release_cred = (gss_cred_id_t)mut_cred; + } + + /* Find an MN, if any */ + if (desired_name) { + major_status = _gss_find_mn(minor_status, + (struct _gss_name *)desired_name, + desired_mech, &mn); + if (major_status != GSS_S_COMPLETE) + goto done; + } + + /* + * We go through all the mc attached to the input_cred_handle and check the + * mechanism. If it matches, we call gss_add_cred for that mechanism, + * otherwise we just add a new mc. + */ + HEIM_SLIST_FOREACH(mc, &mut_cred->gc_mc, gmc_link) { + if (!gss_oid_equal(mc->gmc_mech_oid, desired_mech)) + continue; + major_status = m->gm_add_cred(minor_status, + (gss_const_cred_id_t)mc, + mn ? mn->gmn_name : GSS_C_NO_NAME, + desired_mech, cred_usage, + initiator_time_req, acceptor_time_req, + NULL, NULL, initiator_time_rec, + acceptor_time_rec); + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, major_status, *minor_status); + goto done; + } + + new_mc = malloc(sizeof(struct _gss_mechanism_cred)); + if (!new_mc) { + *minor_status = ENOMEM; + major_status = GSS_S_FAILURE; + goto done; + } + new_mc->gmc_mech = m; + new_mc->gmc_mech_oid = &m->gm_mech_oid; + + major_status = m->gm_add_cred(minor_status, + GSS_C_NO_CREDENTIAL, mn ? mn->gmn_name : GSS_C_NO_NAME, + desired_mech, cred_usage, initiator_time_req, acceptor_time_req, + &new_mc->gmc_cred, NULL, initiator_time_rec, acceptor_time_rec); + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(m, major_status, *minor_status); + goto done; + } + HEIM_SLIST_INSERT_HEAD(&mut_cred->gc_mc, new_mc, gmc_link); + new_mc = NULL; + +done: + /* Lastly, we have to inquire the cred to get the actual_mechs */ + if (major_status == GSS_S_COMPLETE && actual_mechs != NULL) { + major_status = gss_inquire_cred(minor_status, + (gss_const_cred_id_t)mut_cred, NULL, + NULL, NULL, actual_mechs); + if (major_status != GSS_S_COMPLETE) + _gss_mg_error(m, major_status, *minor_status); + } + if (major_status == GSS_S_COMPLETE) { + if (output_cred_handle != NULL) + *output_cred_handle = (gss_cred_id_t)mut_cred; + } else { + gss_release_cred(&junk, &release_cred); + } + free(new_mc); + return major_status; +} + diff --git a/lib/gssapi/mech/gss_duplicate_cred.c b/lib/gssapi/mech/gss_duplicate_cred.c new file mode 100644 index 000000000..6e2672a24 --- /dev/null +++ b/lib/gssapi/mech/gss_duplicate_cred.c @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * Copyright (c) 2018 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 THE AUTHOR 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. + * + * $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +static OM_uint32 +_gss_copy_cred_element(OM_uint32 *minor_status, + struct _gss_mechanism_cred *mc, + struct _gss_mechanism_cred **out) +{ + gssapi_mech_interface m = mc->gmc_mech; + OM_uint32 major_status; + gss_name_t name; + gss_cred_id_t cred; + OM_uint32 initiator_lifetime, acceptor_lifetime; + gss_cred_usage_t cred_usage; + + if (m->gm_duplicate_cred) + return m->gm_duplicate_cred(minor_status, (gss_const_cred_id_t)mc, + (gss_cred_id_t *)out); + + /* This path won't work for ephemeral creds */ + major_status = m->gm_inquire_cred_by_mech(minor_status, mc->gmc_cred, + mc->gmc_mech_oid, &name, + &initiator_lifetime, + &acceptor_lifetime, &cred_usage); + if (major_status) { + _gss_mg_error(m, major_status, *minor_status); + return major_status; + } + + major_status = m->gm_add_cred(minor_status, + GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid, + cred_usage, initiator_lifetime, acceptor_lifetime, + &cred, 0, 0, 0); + m->gm_release_name(minor_status, &name); + + if (major_status) { + _gss_mg_error(m, major_status, *minor_status); + return major_status; + } + + *out = malloc(sizeof(struct _gss_mechanism_cred)); + if (!*out) { + *minor_status = ENOMEM; + m->gm_release_cred(minor_status, &cred); + return GSS_S_FAILURE; + } + (*out)->gmc_mech = m; + (*out)->gmc_mech_oid = &m->gm_mech_oid; + (*out)->gmc_cred = cred; + return GSS_S_COMPLETE; +} + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_duplicate_cred(OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_cred_id_t *output_cred_handle) +{ + struct _gss_mechanism_cred *mc, *copy_mc; + struct _gss_cred *new_cred; + struct _gss_cred *cred = (struct _gss_cred *)input_cred_handle; + OM_uint32 major_status, junk; + + if (input_cred_handle == GSS_C_NO_CREDENTIAL) { + /* + * "Copy" the default credential by acquiring a cred handle for the + * default credential's name, GSS_C_NO_NAME. + */ + return gss_acquire_cred(minor_status, GSS_C_NO_NAME, GSS_C_INDEFINITE, + GSS_C_NO_OID_SET, GSS_C_BOTH, + output_cred_handle, NULL, NULL); + } + + *output_cred_handle = GSS_C_NO_CREDENTIAL; + new_cred = malloc(sizeof(struct _gss_cred)); + if (!new_cred) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + HEIM_SLIST_INIT(&new_cred->gc_mc); + + *minor_status = 0; + major_status = GSS_S_NO_CRED; + + HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + major_status = _gss_copy_cred_element(minor_status, mc, ©_mc); + if (major_status != GSS_S_COMPLETE) { + _gss_mg_error(mc->gmc_mech, major_status, *minor_status); + break; + } + HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link); + } + + if (major_status != GSS_S_COMPLETE) { + gss_cred_id_t release_cred = (gss_cred_id_t)new_cred; + gss_release_cred(&junk, &release_cred); + new_cred = NULL; + } + + *output_cred_handle = (gss_cred_id_t)new_cred; + return major_status; +} diff --git a/lib/gssapi/netlogon/external.c b/lib/gssapi/netlogon/duplicate_cred.c similarity index 56% copy from lib/gssapi/netlogon/external.c copy to lib/gssapi/netlogon/duplicate_cred.c index 69acd3a63..0271fb2b4 100644 --- a/lib/gssapi/netlogon/external.c +++ b/lib/gssapi/netlogon/duplicate_cred.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Kungliga Tekniska Högskolan + * Copyright (c) 2010-2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -35,57 +35,20 @@ #include "netlogon.h" -static gssapi_mech_interface_desc netlogon_mech = { - GMI_VERSION, - "netlogon", - {6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x02") }, - 0, - _netlogon_acquire_cred, - _netlogon_release_cred, - _netlogon_init_sec_context, - _netlogon_accept_sec_context, - _netlogon_process_context_token, - _netlogon_delete_sec_context, - _netlogon_context_time, - _netlogon_get_mic, - _netlogon_verify_mic, - NULL, - NULL, - _netlogon_display_status, - NULL, - _netlogon_compare_name, - _netlogon_display_name, - _netlogon_import_name, - _netlogon_export_name, - _netlogon_release_name, - _netlogon_inquire_cred, - _netlogon_inquire_context, - _netlogon_wrap_size_limit, - _netlogon_add_cred, - _netlogon_inquire_cred_by_mech, - _netlogon_export_sec_context, - _netlogon_import_sec_context, - _netlogon_inquire_names_for_mech, - _netlogon_inquire_mechs_for_name, - _netlogon_canonicalize_name, - _netlogon_duplicate_name, - NULL, - NULL, - NULL, - _netlogon_set_cred_option, - NULL, - _netlogon_wrap_iov, - _netlogon_unwrap_iov, - _netlogon_wrap_iov_length, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -gssapi_mech_interface -__gss_netlogon_initialize(void) +OM_uint32 +_netlogon_duplicate_cred(OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_cred_id_t *output_cred_handle) { - return &netlogon_mech; + gssnetlogon_const_cred src = (gssnetlogon_const_cred)input_cred_handle; + gssnetlogon_cred dst; + + dst = calloc(1, sizeof(*dst)); + if (dst == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + *dst = *src; + return _netlogon_duplicate_name(minor_status, (gss_name_t)&src->Name, &dst->Name) } diff --git a/lib/gssapi/netlogon/external.c b/lib/gssapi/netlogon/external.c index 69acd3a63..4b4799dbe 100644 --- a/lib/gssapi/netlogon/external.c +++ b/lib/gssapi/netlogon/external.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Kungliga Tekniska Högskolan + * Copyright (c) 2010-2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -77,11 +77,28 @@ static gssapi_mech_interface_desc netlogon_mech = { _netlogon_wrap_iov, _netlogon_unwrap_iov, _netlogon_wrap_iov_length, - NULL, - NULL, - NULL, - NULL, - NULL + NULL, /* gm_store_cred */ + NULL, /* gm_export_cred */ + NULL, /* gm_import_cred */ + NULL, /* gm_acquire_cred_ext */ + NULL, /* gm_iter_creds */ + NULL, /* gm_destroy_cred */ + NULL, /* gm_cred_hold */ + NULL, /* gm_cred_unhold */ + NULL, /* gm_cred_label_get */ + NULL, /* gm_cred_label_set */ + NULL, /* gm_mo */ + 0, /* gm_mo_num */ + NULL, /* gm_localname */ + NULL, /* gm_authorize_localname */ + NULL, /* gm_display_name_ext */ + NULL, /* gm_inquire_name */ + NULL, /* gm_get_name_attribute */ + NULL, /* gm_set_name_attribute */ + NULL, /* gm_delete_name_attribute */ + NULL, /* gm_export_name_composite */ + NULL, /* gm_duplicate_cred */ + NULL /* gm_compat */ }; gssapi_mech_interface diff --git a/lib/gssapi/netlogon/netlogon.h b/lib/gssapi/netlogon/netlogon.h index ef8d6987b..68573e2dd 100644 --- a/lib/gssapi/netlogon/netlogon.h +++ b/lib/gssapi/netlogon/netlogon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Kungliga Tekniska Högskolan + * Copyright (c) 2010-2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -121,6 +121,7 @@ typedef struct gssnetlogon_name { gss_buffer_desc NetbiosName; gss_buffer_desc DnsName; } *gssnetlogon_name; +typedef const struct gssnetlogon_name *gssnetlogon_const_name; typedef struct gssnetlogon_cred { gssnetlogon_name *Name; @@ -128,6 +129,7 @@ typedef struct gssnetlogon_cred { uint16_t SealAlgorithm; uint8_t SessionKey[16]; } *gssnetlogon_cred; +typedef const struct gssnetlogon_cred *gssnetlogon_const_cred; typedef struct gssnetlogon_ctx { HEIMDAL_MUTEX Mutex; diff --git a/lib/gssapi/netlogon/external.c b/lib/gssapi/ntlm/duplicate_cred.c similarity index 50% copy from lib/gssapi/netlogon/external.c copy to lib/gssapi/ntlm/duplicate_cred.c index 69acd3a63..acb772043 100644 --- a/lib/gssapi/netlogon/external.c +++ b/lib/gssapi/ntlm/duplicate_cred.c @@ -1,10 +1,8 @@ /* - * Copyright (c) 2010 Kungliga Tekniska Högskolan + * Copyright (c) 2006-2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * - * Portions Copyright (c) 2010 Apple Inc. All rights reserved. - * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -33,59 +31,43 @@ * SUCH DAMAGE. */ -#include "netlogon.h" - -static gssapi_mech_interface_desc netlogon_mech = { - GMI_VERSION, - "netlogon", - {6, rk_UNCONST("\x2a\x85\x70\x2b\x0e\x02") }, - 0, - _netlogon_acquire_cred, - _netlogon_release_cred, - _netlogon_init_sec_context, - _netlogon_accept_sec_context, - _netlogon_process_context_token, - _netlogon_delete_sec_context, - _netlogon_context_time, - _netlogon_get_mic, - _netlogon_verify_mic, - NULL, - NULL, - _netlogon_display_status, - NULL, - _netlogon_compare_name, - _netlogon_display_name, - _netlogon_import_name, - _netlogon_export_name, - _netlogon_release_name, - _netlogon_inquire_cred, - _netlogon_inquire_context, - _netlogon_wrap_size_limit, - _netlogon_add_cred, - _netlogon_inquire_cred_by_mech, - _netlogon_export_sec_context, - _netlogon_import_sec_context, - _netlogon_inquire_names_for_mech, - _netlogon_inquire_mechs_for_name, - _netlogon_canonicalize_name, - _netlogon_duplicate_name, - NULL, - NULL, - NULL, - _netlogon_set_cred_option, - NULL, - _netlogon_wrap_iov, - _netlogon_unwrap_iov, - _netlogon_wrap_iov_length, - NULL, - NULL, - NULL, - NULL, - NULL -}; +#include "ntlm.h" -gssapi_mech_interface -__gss_netlogon_initialize(void) +OM_uint32 GSSAPI_CALLCONV +_gss_ntlm_duplicate_cred(OM_uint32 *minor_status, + gss_const_cred_id_t input_cred_handle, + gss_cred_id_t *output_cred_handle) { - return &netlogon_mech; + ntlm_const_cred cred = (ntlm_const_cred)input_cred_handle; + ntlm_cred new_cred; + OM_uint32 junk; + + if (input_cred_handle == GSS_C_NO_CREDENTIAL) + return _gss_ntlm_acquire_cred(minor_status, GSS_C_NO_NAME, + GSS_C_INDEFINITE, GSS_C_NO_OID_SET, + GSS_C_BOTH, output_cred_handle, NULL, + NULL); + + *output_cred_handle = GSS_C_NO_CREDENTIAL; + if ((new_cred = calloc(1, sizeof(*new_cred))) == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + new_cred->usage = cred->usage; + new_cred->username = strdup(cred->username); + new_cred->domain = strdup(cred->domain); + new_cred->key.data = malloc(cred->key.length); + if (new_cred->username == NULL || new_cred->domain == NULL || + new_cred->key.data == NULL) { + *output_cred_handle = (gss_cred_id_t) new_cred; + _gss_ntlm_release_cred(&junk, output_cred_handle); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + memcpy(new_cred->key.data, cred->key.data, cred->key.length); + new_cred->key.length = cred->key.length; + *output_cred_handle = (gss_cred_id_t) new_cred; + return GSS_S_COMPLETE; } diff --git a/lib/gssapi/ntlm/external.c b/lib/gssapi/ntlm/external.c index aea76cb78..f438ad1f4 100644 --- a/lib/gssapi/ntlm/external.c +++ b/lib/gssapi/ntlm/external.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006-2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -114,15 +114,16 @@ static gssapi_mech_interface_desc ntlm_mech = { NULL, ntlm_mo, sizeof(ntlm_mo) / sizeof(ntlm_mo[0]), - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + NULL, /* gm_localname */ + NULL, /* gm_authorize_localname */ + NULL, /* gm_display_name_ext */ + NULL, /* gm_inquire_name */ + NULL, /* gm_get_name_attribute */ + NULL, /* gm_set_name_attribute */ + NULL, /* gm_delete_name_attribute */ + NULL, /* gm_export_name_composite */ + NULL, /* gm_duplicate_cred */ + NULL, /* gm_compat */ }; gssapi_mech_interface diff --git a/lib/gssapi/ntlm/ntlm.h b/lib/gssapi/ntlm/ntlm.h index 1ed12d5ca..a0ad81584 100644 --- a/lib/gssapi/ntlm/ntlm.h +++ b/lib/gssapi/ntlm/ntlm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan + * Copyright (c) 2006-2018 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -105,6 +105,7 @@ typedef struct ntlm_cred { char *domain; struct ntlm_buf key; } *ntlm_cred; +typedef const struct ntlm_cred *ntlm_const_cred; typedef struct { struct ntlm_server_interface *server; diff --git a/lib/gssapi/spnego/external.c b/lib/gssapi/spnego/external.c index 03678f998..4bc5030bb 100644 --- a/lib/gssapi/spnego/external.c +++ b/lib/gssapi/spnego/external.c @@ -1,5 +1,7 @@ /* * Copyright (c) 2004, PADL Software Pty Ltd. + * Copyright (c) 2018 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -136,15 +138,16 @@ static gssapi_mech_interface_desc spnego_mech = { NULL, spnego_mo, sizeof(spnego_mo) / sizeof(spnego_mo[0]), - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + NULL, /* gm_localname */ + NULL, /* gm_authorize_localname */ + NULL, /* gm_display_name_ext */ + NULL, /* gm_inquire_name */ + NULL, /* gm_get_name_attribute */ + NULL, /* gm_set_name_attribute */ + NULL, /* gm_delete_name_attribute */ + NULL, /* gm_export_name_composite */ + NULL, /* gm_duplicate_cred */ + NULL /* gm_compat */ }; gssapi_mech_interface -- 2.11.4.GIT