Rewrite gss_add_cred() (fix #413)
authorNicolas Williams <nico@twosigma.com>
Wed, 26 Dec 2018 23:24:08 +0000 (17:24 -0600)
committerNico Williams <nico@cryptonector.com>
Sat, 29 Dec 2018 01:26:25 +0000 (19:26 -0600)
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).

17 files changed:
lib/gssapi/Makefile.am
lib/gssapi/NTMakefile
lib/gssapi/gssapi/gssapi.h
lib/gssapi/gssapi_mech.h
lib/gssapi/krb5/duplicate_cred.c [new file with mode: 0644]
lib/gssapi/krb5/external.c
lib/gssapi/krb5/test_acquire_cred.c
lib/gssapi/krb5/test_cred.c
lib/gssapi/mech/gss_add_cred.c
lib/gssapi/mech/gss_duplicate_cred.c [new file with mode: 0644]
lib/gssapi/netlogon/duplicate_cred.c [new file with mode: 0644]
lib/gssapi/netlogon/external.c
lib/gssapi/netlogon/netlogon.h
lib/gssapi/ntlm/duplicate_cred.c [new file with mode: 0644]
lib/gssapi/ntlm/external.c
lib/gssapi/ntlm/ntlm.h
lib/gssapi/spnego/external.c

index ad88f6bf5939ae4d801d9b7af840c69864d20145..3c059afdbad141b6434df6ee4c66b1ceee530ade 100644 (file)
@@ -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 \
index 402b110a1b24d655e5b2fa1dc29ca911a2b76519..9a9f6d728feff1f610bea3bec67c8e89e858c87b 100644 (file)
@@ -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 \
index 1a128cbe4a570748abed15ae2635c8aa46cbd3c3..59eb717ce26909cd410c9cf80af8e9a395cce3fe 100644 (file)
@@ -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.
  *
@@ -1113,6 +1113,16 @@ GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_export_name_composite (
     gss_buffer_t       /* exp_composite_name */
     );
 
+/*
+ * 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*/
+           );
 /*
  *
  */
index 59fd04682937e5b69182215039cdec9f31186a74..06072e20b9fd6afc415130c5c694da71a4f69275 100644 (file)
@@ -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 (file)
index 0000000..d7819ef
--- /dev/null
@@ -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;
+}
index deae016bc96bd1668f214d37da1c4e316841ffe9..bc57da288e24d4cce587d6772e0bdca29488c2c9 100644 (file)
@@ -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
index 9f7c9ef4e4301ebd8fcdf63f3ce93541fd11064d..812fce671f073d9a7ab5055b23350f4c22b2c741 100644 (file)
@@ -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.
  *
@@ -75,6 +75,30 @@ test_add(gss_cred_id_t cred_handle)
        errx(1, "release_cred failed");
 }
 
+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)
 {
@@ -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);
index 06dd6632d0be1630ccba3ff7db82166873c76e08..e0395f04142f3749519c1174bf8e9bc00648f20c 100644 (file)
@@ -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;
index b56e3d760824912a2ecb0531db99082940c611f5..8cbe7bb695d0ea5b4159d3fb4ab2bf1c156162d6 100644 (file)
@@ -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
 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);
+    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
@@ -83,104 +86,122 @@ gss_add_cred(OM_uint32 *minor_status,
     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);
+    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 (file)
index 0000000..6e2672a
--- /dev/null
@@ -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, &copy_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/duplicate_cred.c b/lib/gssapi/netlogon/duplicate_cred.c
new file mode 100644 (file)
index 0000000..0271fb2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010-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:
+ *
+ * 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 "netlogon.h"
+
+OM_uint32
+_netlogon_duplicate_cred(OM_uint32 *minor_status,
+                         gss_const_cred_id_t input_cred_handle,
+                         gss_cred_id_t *output_cred_handle)
+{
+    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)
+}
index 69acd3a63b58c936900b9cbd89441d9925e26af1..4b4799dbea5bca625fad4b36b35b151420946803 100644 (file)
@@ -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
index ef8d6987bfe40591cc94abb0df4826c6f81abdcc..68573e2dd69cdc09e9e83b161fd45152c0659c23 100644 (file)
@@ -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/ntlm/duplicate_cred.c b/lib/gssapi/ntlm/duplicate_cred.c
new file mode 100644 (file)
index 0000000..acb7720
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2006-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 "ntlm.h"
+
+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)
+{
+    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;
+}
index aea76cb783c91d89fb9342b86ed570f5bd7ff34d..f438ad1f473ce9a8f8ee33851179e02ecda8cd18 100644 (file)
@@ -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
index 1ed12d5ca6d7db3f31c99cd3a76175c0fab2c8aa..a0ad815841887283e2d39d8ddabd8f50a34d8c62 100644 (file)
@@ -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;
index 03678f9989b3aff03e75ee874436ab5a7f1db5f5..4bc5030bba2ece0a8a8618d6fd2bf3bb34fb72b0 100644 (file)
@@ -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