+2003-12-11 Alexandra Ellwood <lxs@mit.edu>
+
+ * 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 <epeisach@mit.edu>
* acquire_cred.c (krb5_gss_register_acceptor_identity): Allocate
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);
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
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 */
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)) {
*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;
+}
+
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;
}