Added kg_sync_ccache_name(), kg_get_ccache_name, and kg_set_ccache_name() and rewrote...
authorAlexandra Ellwood <lxs@mit.edu>
Thu, 11 Dec 2003 22:17:27 +0000 (22:17 +0000)
committerAlexandra Ellwood <lxs@mit.edu>
Thu, 11 Dec 2003 22:17:27 +0000 (22:17 +0000)
ticket: 2060

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15879 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/gssapi/krb5/ChangeLog
src/lib/gssapi/krb5/acquire_cred.c
src/lib/gssapi/krb5/gssapiP_krb5.h
src/lib/gssapi/krb5/gssapi_krb5.c
src/lib/gssapi/krb5/set_ccache.c

index 0fea901d3b6c873709bc8a7f057e758b3ada7d8c..d02374809387ef37771e5b56e7d40111371f9050 100644 (file)
@@ -1,3 +1,12 @@
+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
index 391575ddc97e476c9865e05b63d703597bffd864..0a0de14b99a87d5dc1ff6d20094a318d8b9651f9 100644 (file)
@@ -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);
index 1215b1a9a6374ee83793b45afb33f02cc4e870ce..fc4cf2fcd0d062b7981e843ea48bafab5b07bc74 100644 (file)
@@ -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
index 2c7803bc5502e2cc0927f9a87e90c50fa9d2f27c..be750a74902425a212bee576f48e25bb53697fd8 100644 (file)
@@ -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;
+}
+
index 236a83afff14452bbb4c27f2e90de1ced3eb4c9f..9a6cdda702a31525310d4a8aa4b111546a0124cd 100644 (file)
@@ -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;
 }