From 4b94a2e754b34b9a17c44ba9a71a8660dff57786 Mon Sep 17 00:00:00 2001 From: Alexandra Ellwood Date: Thu, 11 Dec 2003 22:17:27 +0000 Subject: [PATCH] Added kg_sync_ccache_name(), kg_get_ccache_name, and kg_set_ccache_name() and rewrote gss_krb5_ccache_name() and added a call to kg_sync_ccache_name() to acquire_init_cred() to fix a bug where on systems with multiple ccaches that GSSAPI gets stuck on the ccache that was default when it launched ticket: 2060 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15879 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/krb5/ChangeLog | 9 +++ src/lib/gssapi/krb5/acquire_cred.c | 7 +- src/lib/gssapi/krb5/gssapiP_krb5.h | 10 ++- src/lib/gssapi/krb5/gssapi_krb5.c | 107 ++++++++++++++++++++++++++++- src/lib/gssapi/krb5/set_ccache.c | 77 +++++++++++++-------- 5 files changed, 177 insertions(+), 33 deletions(-) diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog index 0fea901d3..d02374809 100644 --- a/src/lib/gssapi/krb5/ChangeLog +++ b/src/lib/gssapi/krb5/ChangeLog @@ -1,3 +1,12 @@ +2003-12-11 Alexandra Ellwood + + * acquire_cred.c, gssapi_krb5.c, gssapiP_krb5.h, set_ccache.c: + Added kg_sync_ccache_name(), kg_get_ccache_name, and + kg_set_ccache_name() and rewrote gss_krb5_ccache_name() and + added a call to kg_sync_ccache_name() to acquire_init_cred() + to fix a bug where on systems with multiple ccaches that GSSAPI + gets stuck on the ccache that was default when it launched. + 2003-07-19 Ezra Peisach * acquire_cred.c (krb5_gss_register_acceptor_identity): Allocate diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index 391575ddc..0a0de14b9 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -190,8 +190,13 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred) cred->ccache = NULL; - /* open the default credential cache */ + /* load the GSS ccache name into the kg_context */ + + if (GSS_ERROR(kg_sync_ccache_name(minor_status))) + return(GSS_S_FAILURE); + /* open the default credential cache */ + if ((code = krb5int_cc_default(context, &ccache))) { *minor_status = code; return(GSS_S_CRED_UNAVAIL); diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index 1215b1a9a..fc4cf2fcd 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -288,7 +288,15 @@ krb5_error_code kg_ctx_internalize (krb5_context kcontext, OM_uint32 kg_get_context (OM_uint32 *minor_status, krb5_context *context); - + +OM_uint32 kg_sync_ccache_name (OM_uint32 *minor_status); + +OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status, + const char **out_name); + +OM_uint32 kg_set_ccache_name (OM_uint32 *minor_status, + const char *name); + /** declarations of internal name mechanism functions **/ OM_uint32 krb5_gss_acquire_cred diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index 2c7803bc5..be750a749 100644 --- a/src/lib/gssapi/krb5/gssapi_krb5.c +++ b/src/lib/gssapi/krb5/gssapi_krb5.c @@ -125,6 +125,7 @@ const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+1; const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2; void *kg_vdb = NULL; +static char *kg_ccache_name = NULL; /** default credential support */ @@ -137,9 +138,9 @@ kg_get_defcred(minor_status, cred) OM_uint32 *minor_status; gss_cred_id_t *cred; { - OM_uint32 major; - - if ((major = krb5_gss_acquire_cred(minor_status, + OM_uint32 major; + + if ((major = krb5_gss_acquire_cred(minor_status, (gss_name_t) NULL, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, GSS_C_INITIATE, cred, NULL, NULL)) && GSS_ERROR(major)) { @@ -181,3 +182,103 @@ fail: *minor_status = (OM_uint32) code; return GSS_S_FAILURE; } + +OM_uint32 +kg_sync_ccache_name (OM_uint32 *minor_status) +{ + krb5_context context = NULL; + OM_uint32 err = 0; + OM_uint32 minor; + + /* + * Sync up the kg_context ccache name with the GSSAPI ccache name. + * If kg_ccache_name is NULL -- normal unless someone has called + * gss_krb5_ccache_name() -- then the system default ccache will + * be picked up and used by resetting the context default ccache. + * This is needed for platforms which support multiple ccaches. + */ + + if (!err) { + if (GSS_ERROR(kg_get_context (&minor, &context))) { + err = minor; + } + } + + if (!err) { + /* kg_ccache_name == NULL resets the context default ccache */ + err = krb5_cc_set_default_name(context, kg_ccache_name); + } + + *minor_status = err; + return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; +} + +OM_uint32 +kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name) +{ + krb5_context context = NULL; + const char *name = NULL; + OM_uint32 err = 0; + OM_uint32 minor; + + if (!err) { + if (GSS_ERROR(kg_get_context (&minor, &context))) { + err = minor; + } + } + + if (!err) { + if (kg_ccache_name != NULL) { + name = kg_ccache_name; + } else { + /* reset the context default ccache (see text above) */ + err = krb5_cc_set_default_name (context, NULL); + if (!err) { + name = krb5_cc_default_name(context); + } + } + } + + if (!err) { + if (out_name) { + *out_name = name; + } + } + + *minor_status = err; + return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; +} + +OM_uint32 +kg_set_ccache_name (OM_uint32 *minor_status, const char *name) +{ + char *new_name = NULL; + OM_uint32 err = 0; + + if (!err) { + if (name) { + new_name = malloc(strlen(name) + 1); + if (new_name == NULL) { + err = ENOMEM; + } else { + strcpy(new_name, name); + } + } + } + + if (!err) { + char *swap = NULL; + + swap = kg_ccache_name; + kg_ccache_name = new_name; + new_name = swap; + } + + if (new_name != NULL) { + free (new_name); + } + + *minor_status = err; + return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; +} + diff --git a/src/lib/gssapi/krb5/set_ccache.c b/src/lib/gssapi/krb5/set_ccache.c index 236a83aff..9a6cdda70 100644 --- a/src/lib/gssapi/krb5/set_ccache.c +++ b/src/lib/gssapi/krb5/set_ccache.c @@ -36,34 +36,55 @@ gss_krb5_ccache_name(minor_status, name, out_name) const char *name; const char **out_name; { - krb5_context context; - krb5_error_code retval; - static char *oldname = NULL; - const char *tmpname = NULL; + static char *gss_out_name = NULL; + + char *old_name = NULL; + OM_uint32 err = 0; + OM_uint32 minor = 0; - if (GSS_ERROR(kg_get_context(minor_status, &context))) - return (GSS_S_FAILURE); + if (out_name) { + const char *tmp_name = NULL; - if (out_name) { - if (oldname != NULL) - free(oldname); - /* - * Save copy of previous default ccname, since - * cc_set_default_name will free it and we don't want - * to hang on to a pointer to freed memory. - */ - tmpname = krb5_cc_default_name(context); - oldname = malloc(strlen(tmpname) + 1); - if (oldname == NULL) - return GSS_S_FAILURE; - strcpy(oldname, tmpname); - *out_name = oldname; - } - - retval = krb5_cc_set_default_name(context, name); - if (retval) { - *minor_status = retval; - return GSS_S_FAILURE; - } - return GSS_S_COMPLETE; + if (!err) { + if (GSS_ERROR(kg_get_ccache_name (&minor, &tmp_name))) { + err = minor; + } + } + + if (!err) { + old_name = malloc(strlen(tmp_name) + 1); + if (old_name == NULL) { + err = ENOMEM; + } else { + strcpy(old_name, tmp_name); + } + } + + if (!err) { + char *swap = NULL; + + swap = gss_out_name; + gss_out_name = old_name; + old_name = swap; + } + } + + if (!err) { + if (GSS_ERROR(kg_set_ccache_name (&minor, name))) { + err = minor; + } + } + + if (!err) { + if (out_name) { + *out_name = gss_out_name; + } + } + + if (old_name != NULL) { + free (old_name); + } + + *minor_status = err; + return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; } -- 2.26.2