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:
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user