gss: implement gss_krb5_ccache_name()

Correctly implement gss_krb5_ccache_name() in terms of
gss_set_sec_context_option(GSS_KRB5_CCACHE_NAME_X). The previous implementation
was a NOOP.

Note: global ccache name should really be thread-specific rather than global.

Closes #803.
This commit is contained in:
Luke Howard
2021-09-06 13:22:53 +10:00
parent 971648b71e
commit fc9f9b322a
4 changed files with 52 additions and 38 deletions

View File

@@ -33,7 +33,7 @@
#include "gsskrb5_locl.h"
char *last_out_name;
static heim_base_atomic(char *) last_out_name; /* XXX should be thread-specific */
OM_uint32
_gsskrb5_krb5_ccache_name(OM_uint32 *minor_status,
@@ -48,24 +48,25 @@ _gsskrb5_krb5_ccache_name(OM_uint32 *minor_status,
GSSAPI_KRB5_INIT(&context);
if (out_name) {
const char *n;
const char *def_name;
if (last_out_name) {
free(last_out_name);
last_out_name = NULL;
*out_name = NULL;
def_name = krb5_cc_default_name(context);
if (def_name) {
char *s = strdup(def_name);
if (s) {
s = heim_base_exchange_pointer(&last_out_name, s);
free(s);
*out_name = last_out_name;
}
}
n = krb5_cc_default_name(context);
if (n == NULL) {
if (*out_name == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
last_out_name = strdup(n);
if (last_out_name == NULL) {
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
*out_name = last_out_name;
}
kret = krb5_cc_set_default_name(context, name);

View File

@@ -145,4 +145,9 @@ extern HEIMDAL_MUTEX gssapi_keytab_mutex;
#define SC_ORDER 0x0080
#define SC_AUTHENTICATOR 0x0100
struct gsskrb5_ccache_name_args {
const char *name;
const char *out_name;
};
#endif

View File

@@ -294,23 +294,6 @@ _gsskrb5_set_sec_context_option
*minor_status = EINVAL;
return GSS_S_FAILURE;
} else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) {
char *str;
maj_stat = get_string(minor_status, value, &str);
if (maj_stat != GSS_S_COMPLETE)
return maj_stat;
if (str == NULL) {
*minor_status = 0;
return GSS_S_CALL_INACCESSIBLE_READ;
}
*minor_status = krb5_cc_set_default_name(context, str);
free(str);
if (*minor_status)
return GSS_S_FAILURE;
return GSS_S_COMPLETE;
} else if (gss_oid_equal(desired_object, GSS_KRB5_SET_TIME_OFFSET_X)) {
OM_uint32 offset;
time_t t;
@@ -352,6 +335,15 @@ _gsskrb5_set_sec_context_option
*minor_status = 0;
return GSS_S_COMPLETE;
} else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) {
struct gsskrb5_ccache_name_args *args = value->value;
if (value->length != sizeof(*args)) {
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
return _gsskrb5_krb5_ccache_name(minor_status, args->name, &args->out_name);
} else if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_RFC4121_CONTEXT_X)) {
return make_rfc4121_context(minor_status, context, context_handle, value);
}

View File

@@ -487,26 +487,42 @@ gss_krb5_ccache_name(OM_uint32 *minor_status,
{
struct _gss_mech_switch *m;
gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
OM_uint32 junk;
OM_uint32 major_status;
struct gsskrb5_ccache_name_args args;
_gss_load_mech();
*minor_status = 0;
if (out_name)
*out_name = NULL;
buffer.value = rk_UNCONST(name);
if (name) {
buffer.length = strlen(name);
}
args.name = name;
args.out_name = NULL;
buffer.value = &args;
buffer.length = sizeof(args);
major_status = GSS_S_UNAVAILABLE;
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
OM_uint32 mech_major, mech_minor;
if (m->gm_mech.gm_set_sec_context_option == NULL)
continue;
m->gm_mech.gm_set_sec_context_option(&junk, NULL,
GSS_KRB5_CCACHE_NAME_X, &buffer);
mech_major = m->gm_mech.gm_set_sec_context_option(&mech_minor,
NULL, GSS_KRB5_CCACHE_NAME_X, &buffer);
if (mech_major != GSS_S_UNAVAILABLE) {
major_status = mech_major;
*minor_status = mech_minor;
break;
}
}
return (GSS_S_COMPLETE);
*out_name = args.out_name;
return major_status;
}