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"
|
#include "gsskrb5_locl.h"
|
||||||
|
|
||||||
char *last_out_name;
|
static heim_base_atomic(char *) last_out_name; /* XXX should be thread-specific */
|
||||||
|
|
||||||
OM_uint32
|
OM_uint32
|
||||||
_gsskrb5_krb5_ccache_name(OM_uint32 *minor_status,
|
_gsskrb5_krb5_ccache_name(OM_uint32 *minor_status,
|
||||||
@@ -48,25 +48,26 @@ _gsskrb5_krb5_ccache_name(OM_uint32 *minor_status,
|
|||||||
GSSAPI_KRB5_INIT(&context);
|
GSSAPI_KRB5_INIT(&context);
|
||||||
|
|
||||||
if (out_name) {
|
if (out_name) {
|
||||||
const char *n;
|
const char *def_name;
|
||||||
|
|
||||||
if (last_out_name) {
|
*out_name = NULL;
|
||||||
free(last_out_name);
|
|
||||||
last_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);
|
||||||
|
|
||||||
n = krb5_cc_default_name(context);
|
|
||||||
if (n == 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;
|
*out_name = last_out_name;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*out_name == NULL) {
|
||||||
|
*minor_status = ENOMEM;
|
||||||
|
return GSS_S_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
kret = krb5_cc_set_default_name(context, name);
|
kret = krb5_cc_set_default_name(context, name);
|
||||||
if (kret) {
|
if (kret) {
|
||||||
|
@@ -145,4 +145,9 @@ extern HEIMDAL_MUTEX gssapi_keytab_mutex;
|
|||||||
#define SC_ORDER 0x0080
|
#define SC_ORDER 0x0080
|
||||||
#define SC_AUTHENTICATOR 0x0100
|
#define SC_AUTHENTICATOR 0x0100
|
||||||
|
|
||||||
|
struct gsskrb5_ccache_name_args {
|
||||||
|
const char *name;
|
||||||
|
const char *out_name;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -294,23 +294,6 @@ _gsskrb5_set_sec_context_option
|
|||||||
*minor_status = EINVAL;
|
*minor_status = EINVAL;
|
||||||
return GSS_S_FAILURE;
|
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)) {
|
} else if (gss_oid_equal(desired_object, GSS_KRB5_SET_TIME_OFFSET_X)) {
|
||||||
OM_uint32 offset;
|
OM_uint32 offset;
|
||||||
time_t t;
|
time_t t;
|
||||||
@@ -352,6 +335,15 @@ _gsskrb5_set_sec_context_option
|
|||||||
|
|
||||||
*minor_status = 0;
|
*minor_status = 0;
|
||||||
return GSS_S_COMPLETE;
|
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)) {
|
} else if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_RFC4121_CONTEXT_X)) {
|
||||||
return make_rfc4121_context(minor_status, context, context_handle, value);
|
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;
|
struct _gss_mech_switch *m;
|
||||||
gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
|
gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
|
||||||
OM_uint32 junk;
|
OM_uint32 major_status;
|
||||||
|
struct gsskrb5_ccache_name_args args;
|
||||||
|
|
||||||
_gss_load_mech();
|
_gss_load_mech();
|
||||||
|
|
||||||
|
*minor_status = 0;
|
||||||
|
|
||||||
if (out_name)
|
if (out_name)
|
||||||
*out_name = NULL;
|
*out_name = NULL;
|
||||||
|
|
||||||
buffer.value = rk_UNCONST(name);
|
args.name = name;
|
||||||
if (name) {
|
args.out_name = NULL;
|
||||||
buffer.length = strlen(name);
|
|
||||||
}
|
buffer.value = &args;
|
||||||
|
buffer.length = sizeof(args);
|
||||||
|
|
||||||
|
major_status = GSS_S_UNAVAILABLE;
|
||||||
|
|
||||||
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
|
||||||
|
OM_uint32 mech_major, mech_minor;
|
||||||
|
|
||||||
if (m->gm_mech.gm_set_sec_context_option == NULL)
|
if (m->gm_mech.gm_set_sec_context_option == NULL)
|
||||||
continue;
|
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