pull up r24469, r24530, r24533, r24534, r24535, r24537 from trunk
[krb5.git] / src / lib / gssapi / krb5 / set_ccache.c
index 27422017bd9672db839ab807108edc174847fe52..4b6c89065f32fbfe748294e12ab073c43a24d4d0 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
 /*
  * lib/gssapi/krb5/set_ccache.c
  *
@@ -8,7 +9,7 @@
  *   require a specific license from the United States Government.
  *   It is the responsibility of any person or organization contemplating
  *   export to obtain such a license before exporting.
- * 
+ *
  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  * distribute this software and its documentation for any purpose and
  * without fee is hereby granted, provided that the above copyright
 #include <string.h>
 #include "gssapiP_krb5.h"
 
-OM_uint32 KRB5_CALLCONV 
-gss_krb5_ccache_name(minor_status, name, out_name)
-       OM_uint32 *minor_status;
-       const char *name;
-       const char **out_name;
+OM_uint32
+gss_krb5int_ccache_name(OM_uint32 *minor_status,
+                        const gss_OID desired_mech,
+                        const gss_OID desired_object,
+                        gss_buffer_t value)
 {
     char *old_name = NULL;
     OM_uint32 err = 0;
     OM_uint32 minor = 0;
-
     char *gss_out_name;
+    struct krb5_gss_ccache_name_req *req;
 
-    err = gssint_initialize_library();
+    err = gss_krb5int_initialize_library();
     if (err) {
-       *minor_status = err;
-       return GSS_S_FAILURE;
+        *minor_status = err;
+        return GSS_S_FAILURE;
     }
 
+    assert(value->length == sizeof(*req));
+
+    if (value->length != sizeof(*req))
+        return GSS_S_FAILURE;
+
+    req = (struct krb5_gss_ccache_name_req *)value->value;
+
     gss_out_name = k5_getspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME);
 
-    if (out_name) {
+    if (req->out_name) {
         const char *tmp_name = NULL;
 
         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);
-            }
+            kg_get_ccache_name (&err, &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;
+            old_name = gss_out_name;
+            gss_out_name = (char *)tmp_name;
         }
     }
+    /* If out_name was NULL, we keep the same gss_out_name value, and
+       don't free up any storage (leave old_name NULL).  */
+
+    if (!err)
+        kg_set_ccache_name (&err, req->name);
 
     minor = k5_setspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, gss_out_name);
     if (minor) {
-       /* Um.  Now what?  */
-       if (err == 0) {
-           err = minor;
-           if (out_name != NULL) {
-               *out_name = NULL;
-               out_name = NULL;
-           }
-       }
-       free(gss_out_name);
+        /* Um.  Now what?  */
+        if (err == 0) {
+            err = minor;
+        }
+        free(gss_out_name);
+        gss_out_name = NULL;
     }
 
     if (!err) {
-        if (out_name) {
-            *out_name = gss_out_name;
+        if (req->out_name) {
+            *(req->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;
 }