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).
This commit is contained in:

committed by
Nico Williams

parent
134b53ead1
commit
e6d1c10808
159
lib/gssapi/krb5/duplicate_cred.c
Normal file
159
lib/gssapi/krb5/duplicate_cred.c
Normal file
@@ -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;
|
||||
}
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user