gss krb5 mech enhanced error messages
authorKen Raeburn <raeburn@mit.edu>
Wed, 4 Jul 2007 05:46:24 +0000 (05:46 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 4 Jul 2007 05:46:24 +0000 (05:46 +0000)
Save detailed error messages (usually from the krb5 library) in
per-thread storage, mapping each error code to the most recently
produced message for it.  Return the message from display_status.

Currently not implemented for a few cases where the krb5 mechanism
returns a minor status code of 0, or another value different from the
libkrb5 error code.

Other functions are available to store a generic string or formatted
message, but aren't used much at present.

Tested with these errors in context establishment:
 * missing ccache (libkrb5 shows pathname if FILE: type)
 * missing keytab (libkrb5 shows pathname if FILE: type)
 * server principal unknown (libkrb5 shows server principal)

ticket: new

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

25 files changed:
src/lib/gssapi/gss_libinit.c
src/lib/gssapi/krb5/Makefile.in
src/lib/gssapi/krb5/accept_sec_context.c
src/lib/gssapi/krb5/acquire_cred.c
src/lib/gssapi/krb5/add_cred.c
src/lib/gssapi/krb5/context_time.c
src/lib/gssapi/krb5/copy_ccache.c
src/lib/gssapi/krb5/delete_sec_context.c
src/lib/gssapi/krb5/disp_name.c
src/lib/gssapi/krb5/disp_status.c
src/lib/gssapi/krb5/duplicate_name.c
src/lib/gssapi/krb5/export_name.c
src/lib/gssapi/krb5/export_sec_context.c
src/lib/gssapi/krb5/gssapiP_krb5.h
src/lib/gssapi/krb5/gssapi_krb5.c
src/lib/gssapi/krb5/import_name.c
src/lib/gssapi/krb5/import_sec_context.c
src/lib/gssapi/krb5/init_sec_context.c
src/lib/gssapi/krb5/inq_context.c
src/lib/gssapi/krb5/inq_cred.c
src/lib/gssapi/krb5/k5seal.c
src/lib/gssapi/krb5/k5sealv3.c
src/lib/gssapi/krb5/k5unseal.c
src/lib/gssapi/krb5/rel_cred.c
src/lib/gssapi/krb5/val_cred.c

index f075fe481e40cdf694a4627c39780fbe58272930..b96eb9e7aa99b244b4ff2515d35f6cfffe8896d5 100644 (file)
@@ -40,6 +40,10 @@ int gssint_lib_init(void)
     err = k5_key_register(K5_KEY_GSS_KRB5_CCACHE_NAME, free);
     if (err)
        return err;
+    err = k5_key_register(K5_KEY_GSS_KRB5_ERROR_MESSAGE,
+                         krb5_gss_delete_error_info);
+    if (err)
+       return err;
 #ifndef _WIN32
     err = k5_mutex_finish_init(&kg_kdc_flag_mutex);
     if (err)
index b4b4d7d3c664eb72ace166b074d61111e872e598..198a0190d7064c1c2969f00ae755aea0fccc9efc 100644 (file)
@@ -195,9 +195,18 @@ $(GSSAPI_KRB5_HDR): gssapi_krb5.h
 all-unix:: $(SRCS) $(HDRS) $(GSSAPI_KRB5_HDR) includes
 all-unix:: all-libobjs
 
+error_map.h: $(SRCTOP)/util/gen-map.pl Makefile
+       $(PERL) -I$(SRCTOP)/util $(SRCTOP)/util/gen-map.pl -oerror_map.new \
+               NAME=gsserrmap \
+               KEY=OM_uint32 \
+               VALUE="char *" \
+               COMPARE=compare_OM_uint32 \
+               FREEVALUE=free_string
+       $(MV) error_map.new error_map.h
+
 clean-unix::
        $(RM) $(BUILDTOP)/include/gssapi/gssapi_krb5.h
-       -$(RM) gssapi_krb5.h
+       -$(RM) gssapi_krb5.h error_map.h
 
 clean-unix:: clean-libobjs
        $(RM) $(ETHDRS) $(ETSRCS)
@@ -355,7 +364,8 @@ disp_status.so disp_status.po $(OUTPRE)disp_status.$(OBJEXT): \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
   $(srcdir)/../generic/gssapiP_generic.h $(srcdir)/../generic/gssapi_generic.h \
   $(srcdir)/../gss_libinit.h ../generic/gssapi_err_generic.h \
-  disp_status.c gssapiP_krb5.h gssapi_err_krb5.h gssapi_krb5.h
+  disp_status.c error_map.h gssapiP_krb5.h gssapi_err_krb5.h \
+  gssapi_krb5.h
 duplicate_name.so duplicate_name.po $(OUTPRE)duplicate_name.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/gssapi/gssapi.h \
   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
index 7dcdd1a51a5b895f7e481ef4f6256f8a5b075606..1100b1732534cc75a90a163a347ce004e0fd78b6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000, 2004  by the Massachusetts Institute of Technology.
+ * Copyright 2000, 2004, 2007  by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -292,7 +292,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
     */
    /*SUPPRESS 29*/
    if (*context_handle != GSS_C_NO_CONTEXT) {
-      *minor_status = 0;
+      *minor_status = EINVAL;
+      save_error_string(EINVAL, "accept_sec_context called with existing context handle");
       krb5_free_context(context);
       return(GSS_S_FAILURE);
    }
@@ -391,6 +392,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
 
    if ((code = krb5_auth_con_init(context, &auth_context))) {
        major_status = GSS_S_FAILURE;
+       save_error_info(code, context);
        goto fail;
    }
    if (cred->rcache) {
@@ -993,6 +995,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
    if (!verifier_cred_handle && cred_handle) {
           krb5_gss_release_cred(minor_status, &cred_handle);
    }
+   if (major_status && *minor_status && context)
+       save_error_info(*minor_status, context);
    krb5_free_context(context);
    return (major_status);
 }
index 43d21220cebda70e63e41db34c462332bb54d648..af17e6742fe8c43b2d423916a2aff54b51436c4d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000 by the Massachusetts Institute of Technology.
+ * Copyright 2000, 2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -93,7 +93,6 @@ static char *krb5_gss_keytab = NULL;
 OM_uint32 KRB5_CALLCONV
 krb5_gss_register_acceptor_identity(const char *keytab)
 {
-    size_t     len;
     char *new, *old;
     int err;
 
@@ -104,11 +103,9 @@ krb5_gss_register_acceptor_identity(const char *keytab)
     if (keytab == NULL)
        return GSS_S_FAILURE;
 
-    len = strlen(keytab);
-    new = malloc(len + 1);
+    new = strdup(keytab);
     if (new == NULL)
        return GSS_S_FAILURE;
-    strcpy(new, keytab);
 
     err = k5_mutex_lock(&gssint_krb5_keytab_lock);
     if (err) {
@@ -175,9 +172,12 @@ acquire_accept_cred(context, minor_status, desired_name, output_princ, cred)
       princ = (krb5_principal) desired_name;
       if ((code = krb5_kt_get_entry(context, kt, princ, 0, 0, &entry))) {
         (void) krb5_kt_close(context, kt);
-        if (code == KRB5_KT_NOTFOUND)
-           *minor_status = KG_KEYTAB_NOMATCH;
-        else
+        if (code == KRB5_KT_NOTFOUND) {
+            char *errstr = krb5_get_error_message(context, code);
+            krb5_set_error_message(context, KG_KEYTAB_NOMATCH, "%s", errstr);
+            krb5_free_error_message(context, errstr);
+            *minor_status = KG_KEYTAB_NOMATCH;
+        } else
            *minor_status = code;
         return(GSS_S_CRED_UNAVAIL);
       }
@@ -538,6 +538,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
          k5_mutex_destroy(&cred->lock);
          xfree(cred);
         /* minor_status set by acquire_accept_cred() */
+        save_error_info(*minor_status, context);
         krb5_free_context(context);
         return(ret);
       }
@@ -560,6 +561,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
          k5_mutex_destroy(&cred->lock);
          xfree(cred);
         /* minor_status set by acquire_init_cred() */
+        save_error_info(*minor_status, context);
         krb5_free_context(context);
         return(ret);
       }
@@ -576,6 +578,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
          k5_mutex_destroy(&cred->lock);
          xfree(cred);
         *minor_status = code;
+        save_error_info(*minor_status, context);
         krb5_free_context(context);
         return(GSS_S_FAILURE);
       }
@@ -600,6 +603,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
          k5_mutex_destroy(&cred->lock);
          xfree(cred);
         *minor_status = code;
+        save_error_info(*minor_status, context);
         krb5_free_context(context);
         return(GSS_S_FAILURE);
       }
@@ -649,6 +653,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
       k5_mutex_destroy(&cred->lock);
       xfree(cred);
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      save_error_string(*minor_status, "error saving credentials");
       krb5_free_context(context);
       return(GSS_S_FAILURE);
    }
index 6110193953f1b32b9628851c897f93b56dd1fd03..3ac32fc2e76d724754c79f595371eab431a8abe0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000 by the Massachusetts Institute of Technology.
+ * Copyright 2000, 2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -122,6 +122,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
     major_status = krb5_gss_validate_cred_1(minor_status, input_cred_handle,
                                            context);
     if (GSS_ERROR(major_status)) {
+       save_error_info(*minor_status, context);
        krb5_free_context(context);
        return major_status;
     }
@@ -150,6 +151,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
     }
 
     if (GSS_ERROR(kg_sync_ccache_name(context, minor_status))) {
+       save_error_info(*minor_status, context);
        krb5_free_context(context);
        return GSS_S_FAILURE;
     }
@@ -203,6 +205,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
            xfree(new_cred);
 
            *minor_status = code;
+           save_error_info(*minor_status, context);
            krb5_free_context(context);
            return(GSS_S_FAILURE);
        }
@@ -232,6 +235,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
                xfree(new_cred);
 
                *minor_status = code;
+               save_error_info(*minor_status, context);
                krb5_free_context(context);
                return(GSS_S_FAILURE);
            }
@@ -243,6 +247,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
                xfree(new_cred);
 
                *minor_status = code;
+               save_error_info(*minor_status, context);
                krb5_free_context(context);
                return(GSS_S_FAILURE);
            }
@@ -261,8 +266,9 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
                    krb5_free_principal(context, new_cred->princ);
                xfree(new_cred);
 
-               krb5_free_context(context);
                *minor_status = code;
+               save_error_info(*minor_status, context);
+               krb5_free_context(context);
                return(GSS_S_FAILURE);
            }
        } else {
@@ -301,9 +307,10 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
                if (new_cred->princ)
                    krb5_free_principal(context, new_cred->princ);
                xfree(new_cred);
-               krb5_free_context(context);
 
                *minor_status = code;
+               save_error_info(*minor_status, context);
+               krb5_free_context(context);
                return(GSS_S_FAILURE);
            }
        } else {
index 8b7930ffd96f12d8b07e9e6fe502727bb9d7d423..adaa6250693a98c4d774e679876358555a9be9b3 100644 (file)
@@ -52,6 +52,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec)
 
    if ((code = krb5_timeofday(ctx->k5_context, &now))) {
       *minor_status = code;
+      save_error_info(*minor_status, ctx->k5_context);
       return(GSS_S_FAILURE);
    }
 
index 195be0f84299ded14ce72aaef82fbb85f2a419a1..8ade9c5da85e015460fa1404948dc18089cc76cf 100644 (file)
@@ -41,6 +41,7 @@ gss_krb5int_copy_ccache(minor_status, cred_handle, out_ccache)
    if (code) {
        k5_mutex_unlock(&k5creds->lock);
        *minor_status = code;
+       save_error_info(*minor_status, context);
        krb5_free_context(context);
        return(GSS_S_FAILURE);
    }
@@ -48,12 +49,9 @@ gss_krb5int_copy_ccache(minor_status, cred_handle, out_ccache)
        code = krb5_cc_store_cred(context, out_ccache, &creds);
    krb5_cc_end_seq_get(context, k5creds->ccache, &cursor);
    k5_mutex_unlock(&k5creds->lock);
+   *minor_status = code;
+   if (code)
+       save_error_info(*minor_status, context);
    krb5_free_context(context);
-   if (code) {
-       *minor_status = code;
-       return(GSS_S_FAILURE);
-   } else {
-       *minor_status = 0;
-       return(GSS_S_COMPLETE);
-   }
+   return code ? GSS_S_FAILURE : GSS_S_COMPLETE;
 }
index 1bc6799e335c8c6e21fd7dcbc280f677ab2df253..60755d2519d90fa0c6204c525908ea4bcbd1b5c4 100644 (file)
@@ -65,8 +65,10 @@ krb5_gss_delete_sec_context(minor_status, context_handle, output_token)
 
       if ((major = kg_seal(minor_status, *context_handle, 0,
                           GSS_C_QOP_DEFAULT,
-                          &empty, NULL, output_token, KG_TOK_DEL_CTX)))
-        return(major);
+                          &empty, NULL, output_token, KG_TOK_DEL_CTX))) {
+         save_error_info(*minor_status, context);
+         return(major);
+      }
    }
 
    /* invalidate the context handle */
index 5d3a042d43fdce85ef36af6a5817393808437a03..1f67d512993e021ad0c9413df44caa8cfd95178b 100644 (file)
@@ -52,6 +52,7 @@ krb5_gss_display_name(minor_status, input_name, output_name_buffer,
    if ((code = krb5_unparse_name(context,
                                 (krb5_principal) input_name, &str))) {
       *minor_status = code;
+      save_error_info(*minor_status, context);
       krb5_free_context(context);
       return(GSS_S_FAILURE);
    }
index 1988d50c67798721358a56e1db0d09462625094b..9a0399d78beb542245878ed388e09c7aef1876a6 100644 (file)
 
 /* XXXX internationalization!! */
 
+static inline int
+compare_OM_uint32 (OM_uint32 a, OM_uint32 b)
+{
+    if (a < b)
+       return -1;
+    else if (a == b)
+       return 0;
+    else
+       return 1;
+}
+static inline void
+free_string (char *s)
+{
+    free(s);
+}
+#include "error_map.h"
+#include <stdio.h>
+char *get_error_message(OM_uint32 minor_code)
+{
+    gsserrmap *p = k5_getspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE);
+    char *msg = 0;
+#ifdef DEBUG
+    fprintf(stderr, "%s(%lu, p=%p)", __func__, (unsigned long) minor_code,
+           (void *) p);
+#endif
+    if (p) {
+       char **v = gsserrmap_find(p, minor_code);
+       if (v) {
+           msg = *v;
+#ifdef DEBUG
+           fprintf(stderr, " FOUND!");
+#endif
+       }
+    }
+    if (msg == 0)
+       msg = error_message(minor_code);
+#ifdef DEBUG
+    fprintf(stderr, " -> %p/%s\n", (void *) msg, msg);
+#endif
+    return msg;
+}
+#define save_error_string_nocopy gss_krb5_save_error_string_nocopy
+static int save_error_string_nocopy(OM_uint32 minor_code, char *msg)
+{
+    gsserrmap *p;
+    int ret;
+
+#ifdef DEBUG
+    fprintf(stderr, "%s(%lu, %s)", __func__, (unsigned long) minor_code, msg);
+#endif
+    p = k5_getspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE);
+    if (!p) {
+       p = malloc(sizeof(*p));
+       if (p == NULL) {
+           ret = 1;
+           goto fail;
+       }
+       if (gsserrmap_init(p) != 0) {
+           free(p);
+           p = NULL;
+           ret = 1;
+           goto fail;
+       }
+       if (k5_setspecific(K5_KEY_GSS_KRB5_ERROR_MESSAGE, p) != 0) {
+           gsserrmap_destroy(p);
+           free(p);
+           p = NULL;
+           ret = 1;
+           goto fail;
+       }
+    }
+    ret = gsserrmap_replace_or_insert(p, minor_code, msg);
+fail:
+#ifdef DEBUG
+    fprintf(stderr, " p=%p %s\n", (void *)p, ret ? "FAIL" : "SUCCESS");
+#endif
+    return ret;
+}
+void save_error_string(OM_uint32 minor_code, char *msg)
+{
+    char *s = strdup(msg);
+    if (s) {
+       if (save_error_string_nocopy(minor_code, s) != 0)
+           free(s);
+    }
+}
+void save_error_message(OM_uint32 minor_code, const char *format, ...)
+{
+    char *s;
+    int n;
+    va_list ap;
+
+    va_start(ap, format);
+    n = vasprintf(&s, format, ap);
+    va_end(ap);
+    if (n >= 0) {
+       if (save_error_string_nocopy(minor_code, s) != 0)
+           free(s);
+    }
+}
+void krb5_gss_save_error_info(OM_uint32 minor_code, krb5_context ctx)
+{
+    char *s;
+
+#ifdef DEBUG
+    fprintf(stderr, "%s(%lu, ctx=%p)\n", __func__,
+           (unsigned long) minor_code, (void *)ctx);
+#endif
+    s = krb5_get_error_message(ctx, minor_code);
+#ifdef DEBUG
+    fprintf(stderr, "%s(%lu, ctx=%p) saving: %s\n", __func__,
+           (unsigned long) minor_code, (void *)ctx, s);
+#endif
+    save_error_string(minor_code, s);
+    /* The get_error_message call above resets the error message in
+       ctx.  Put it back, in case we make this call again *sigh*.  */
+    krb5_set_error_message(ctx, minor_code, "%s", s);
+    krb5_free_error_message(ctx, s);
+}
+void krb5_gss_delete_error_info(void *p)
+{
+    gsserrmap_destroy(p);
+}
+
 /**/
 
 OM_uint32
@@ -59,8 +183,13 @@ krb5_gss_display_status(minor_status, status_value, status_type,
         return(GSS_S_FAILURE);
       }
 
-      return(g_display_com_err_status(minor_status, status_value,
-                                     status_string));
+      /* If this fails, there's not much we can do...  */
+      if (g_make_string_buffer(krb5_gss_get_error_message(status_value),
+                              status_string) != 0)
+         *minor_status = ENOMEM;
+      else
+         *minor_status = 0;
+      return 0;
    } else {
       *minor_status = 0;
       return(GSS_S_BAD_STATUS);
index cb2ca71c7dd15efd1b073b1b8640b48fcc9df2e7..5d352bdf364a70af9dc793efc43395a47e08ddaf 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/gssapi/krb5/duplicate_name.c
  *
- * Copyright 1997 by the Massachusetts Institute of Technology.
+ * Copyright 1997,2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -55,6 +55,7 @@ OM_uint32 krb5_gss_duplicate_name(OM_uint32  *minor_status,
        princ = (krb5_principal)input_name;
        if ((code = krb5_copy_principal(context, princ, &outprinc))) {
                *minor_status = code;
+               save_error_info(*minor_status, context);
                krb5_free_context(context);
                return(GSS_S_FAILURE);
        }
index ce19b04d8d7333a709c4fbc2add1e8e3adb01d0e..2d27ba46c8996e7523dcefba0c6bf6c0c95e8ceb 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/gssapi/krb5/export_name.c
  *
- * Copyright 1997 by the Massachusetts Institute of Technology.
+ * Copyright 1997, 2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -60,6 +60,7 @@ OM_uint32 krb5_gss_export_name(OM_uint32  *minor_status,
                                      &str))) {
                if (minor_status)
                        *minor_status = code;
+               save_error_info(code, context);
                krb5_free_context(context);
                return(GSS_S_FAILURE);
        }
index fb57b882a275061717f46486655829cedb9fff02..867d4d6f5027733713638ad515c01a135f90cd15 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/gssapi/krb5/export_sec_context.c
  *
- * Copyright 1995 by the Massachusetts Institute of Technology.
+ * Copyright 1995, 2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -36,7 +36,7 @@ krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token)
     gss_ctx_id_t       *context_handle;
     gss_buffer_t       interprocess_token;
 {
-    krb5_context       context;
+    krb5_context       context = NULL;
     krb5_error_code    kret;
     OM_uint32          retval;
     size_t             bufsize, blen;
@@ -92,6 +92,9 @@ krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token)
     return (GSS_S_COMPLETE);
 
 error_out:
+    if (retval != GSS_S_COMPLETE)
+       if (kret != 0 && context != 0)
+           save_error_info(kret, context);
     if (obuffer && bufsize) {
            memset(obuffer, 0, bufsize);
            xfree(obuffer);
index 86ec771e1e7e25dd41f5f961d195de2e620c9f33..57c2ed9ea6a835f32bc384af461eb10be2bb3677 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000 by the Massachusetts Institute of Technology.
+ * Copyright 2000, 2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -683,4 +683,24 @@ krb5_error_code krb5_gss_init_context (krb5_context *ctxp);
 
 krb5_error_code krb5_gss_use_kdc_context(void);
 
+/* For error message handling.  */
+/* Returns a shared string, not a private copy!  */
+extern char *
+krb5_gss_get_error_message(OM_uint32 minor_code);
+extern void
+krb5_gss_save_error_string(OM_uint32 minor_code, char *msg);
+extern void
+krb5_gss_save_error_message(OM_uint32 minor_code, const char *format, ...)
+#if !defined(__cplusplus) && (__GNUC__ > 2)
+    __attribute__((__format__(__printf__, 2, 3)))
+#endif
+    ;
+extern void
+krb5_gss_save_error_info(OM_uint32 minor_code, krb5_context ctx);
+#define get_error_message krb5_gss_get_error_message
+#define save_error_string krb5_gss_save_error_string
+#define save_error_message krb5_gss_save_error_message
+#define save_error_info krb5_gss_save_error_info
+extern void krb5_gss_delete_error_info(void *p);
+
 #endif /* _GSSAPIP_KRB5_H_ */
index a0953e0b2387a9405ebe47d9be0864250329e213..224484f44bf64221b062eda4e9fa5d9653072779 100644 (file)
@@ -186,7 +186,7 @@ int *out_caller_provided_name)
         *out_caller_provided_name = 
          (k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME) != NULL);
     }
-    
+
     *minor_status = 0;
     return GSS_S_COMPLETE;
 }
@@ -220,6 +220,8 @@ kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name)
                    err = errno;
            }
        }
+       if (err && context)
+           save_error_info(err, context);
        if (context)
            krb5_free_context(context);
     }
index db63c4b24f8ff33f6aa89df91f37b7022c1fd2a2..58bc19f91879eb0bbc261c5a1b8420303e64a77e 100644 (file)
@@ -113,6 +113,7 @@ krb5_gss_import_name(minor_status, input_name_buffer,
 
       if ((code = krb5_copy_principal(context, input, &princ))) {
         *minor_status = code;
+        save_error_info(*minor_status, context);
         krb5_free_context(context);
         return(GSS_S_FAILURE);
       }
@@ -215,6 +216,7 @@ krb5_gss_import_name(minor_status, input_name_buffer,
 
    if (code) {
       *minor_status = (OM_uint32) code;
+      save_error_info(*minor_status, context);
       krb5_free_context(context);
       return(GSS_S_BAD_NAME);
    }
index 1255ecc6cf4b78f692585fe093971b3e323ab787..7563dc0d7d74ed7de9ab6eeb01475f43c7ac286c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/gssapi/krb5/import_sec_context.c
  *
- * Copyright 1995,2004 by the Massachusetts Institute of Technology.
+ * Copyright 1995,2004,2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -93,6 +93,7 @@ krb5_gss_import_sec_context(minor_status, interprocess_token, context_handle)
     if (kret) {
        krb5_free_context(context);
        *minor_status = kret;
+       save_error_info(*minor_status, context);
        return GSS_S_FAILURE;
     }
 
@@ -107,6 +108,7 @@ krb5_gss_import_sec_context(minor_status, interprocess_token, context_handle)
     krb5_free_context(context);
     if (kret) {
        *minor_status = (OM_uint32) kret;
+       save_error_info(*minor_status, context);
        return(GSS_S_FAILURE);
     }
 
index 4f14e598b9b6ca1ca09e42b4509c471b5cf5b1ac..ce4b5d78d64cbee211cd9c2089266aa410429dd2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000,2002, 2003 by the Massachusetts Institute of Technology.
+ * Copyright 2000,2002, 2003, 2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -853,8 +853,11 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
           *minor_status = kerr;
           return GSS_S_FAILURE;
        }
-       if (GSS_ERROR(kg_sync_ccache_name(context, minor_status)))
+       if (GSS_ERROR(kg_sync_ccache_name(context, minor_status))) {
+          save_error_info(*minor_status, context);
+          krb5_free_context(context);
           return GSS_S_FAILURE;
+       }
    } else {
        context = ((krb5_gss_ctx_id_rec *)*context_handle)->k5_context;
    }
@@ -871,6 +874,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
 
    if (! kg_validate_name(target_name)) {
       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+      save_error_info(*minor_status, context);
       if (*context_handle == GSS_C_NO_CONTEXT)
          krb5_free_context(context);
       return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
@@ -888,6 +892,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
    } else {
       major_status = krb5_gss_validate_cred(minor_status, claimant_cred_handle);
       if (GSS_ERROR(major_status)) {
+         save_error_info(*minor_status, context);
          if (*context_handle == GSS_C_NO_CONTEXT)
              krb5_free_context(context);
          return(major_status);
@@ -947,9 +952,10 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
                                    output_token, ret_flags, time_rec,
                                    context, default_mech);
       k5_mutex_unlock(&cred->lock);
-      if (*context_handle == GSS_C_NO_CONTEXT)
+      if (*context_handle == GSS_C_NO_CONTEXT) {
+         save_error_info (*minor_status, context);
          krb5_free_context(context);
-      else
+      else
          ((krb5_gss_ctx_id_rec *) *context_handle)->k5_context = context;
    } else {
       /* mutual_auth doesn't care about the credentials */
index 0954ddc5dd4b0d3126a57a9ff1852b3db187380d..28c49f72cd19a5424488da711a782ae0bf799c46 100644 (file)
@@ -67,6 +67,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
 
    if ((code = krb5_timeofday(context, &now))) {
       *minor_status = code;
+      save_error_info(*minor_status, context);
       return(GSS_S_FAILURE);
    }
 
@@ -78,6 +79,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
                                      ctx->initiate?ctx->here:ctx->there,
                                      &init))) {
         *minor_status = code;
+        save_error_info(*minor_status, context);
         return(GSS_S_FAILURE);
       }
       if (! kg_save_name((gss_name_t) init)) {
@@ -93,6 +95,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
                                      &accept))) {
         if (init) krb5_free_principal(context, init);
         *minor_status = code;
+        save_error_info(*minor_status, context);
         return(GSS_S_FAILURE);
       }
       if (! kg_save_name((gss_name_t) accept)) {
index 58425d80d709e5f9f44d866f82a2ebf539f0de29..aa50d12313996ae9111816400628bea314ca9a68 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000 by the Massachusetts Institute of Technology.
+ * Copyright 2000, 2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -148,6 +148,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
          (code = krb5_copy_principal(context, cred->princ, &ret_name))) {
         k5_mutex_unlock(&cred->lock);
         *minor_status = code;
+        save_error_info(*minor_status, context);
         ret = GSS_S_FAILURE;
         goto fail;
       }
index 7a904d0650b9b9c73cadca44e81002a21c90b800..4557194faa6c59e5b62c0820609e4b2193f04840 100644 (file)
@@ -362,6 +362,7 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req,
     context = ctx->k5_context;
     if ((code = krb5_timeofday(context, &now))) {
        *minor_status = code;
+       save_error_info(*minor_status, context);
        return(GSS_S_FAILURE);
     }
 
@@ -388,6 +389,7 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req,
 
     if (code) {
        *minor_status = code;
+       save_error_info(*minor_status, context);
        return(GSS_S_FAILURE);
     }
 
index 4c6df2744332ef9ff7d08d2b49b586b0604a329c..019f668c8c679489fef06d84959feb25a43d882b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lib/gssapi/krb5/k5sealv3.c
  *
- * Copyright 2003,2004 by the Massachusetts Institute of Technology.
+ * Copyright 2003,2004,2007 by the Massachusetts Institute of Technology.
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -491,6 +491,7 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
        if (err) {
        error:
            *minor_status = err;
+           save_error_info(*minor_status, context);
            return GSS_S_BAD_SIG; /* XXX */
        }
        if (!valid) {
index 8c999868efccf37bad2280bfed3f99e147fadd25..72afb457633b80f582adcee1749a6656cfffa04f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001 by the Massachusetts Institute of Technology.
+ * Copyright 2001, 2007 by the Massachusetts Institute of Technology.
  * Copyright 1993 by OpenVision Technologies, Inc.
  *
  * Permission to use, copy, modify, distribute, and sell this software
@@ -493,6 +493,7 @@ kg_unseal(minor_status, context_handle, input_token_buffer,
     unsigned int bodysize;
     int err;
     int toktype2;
+    OM_uint32 ret;
 
     /* validate the context handle */
     if (! kg_validate_ctx_id(context_handle)) {
@@ -540,11 +541,14 @@ kg_unseal(minor_status, context_handle, input_token_buffer,
     }
 
     if (ctx->proto == 0)
-       return kg_unseal_v1(ctx->k5_context, minor_status, ctx, ptr, bodysize,
-                           message_buffer, conf_state, qop_state,
-                           toktype);
+       ret = kg_unseal_v1(ctx->k5_context, minor_status, ctx, ptr, bodysize,
+                          message_buffer, conf_state, qop_state,
+                          toktype);
     else
-       return gss_krb5int_unseal_token_v3(&ctx->k5_context, minor_status, ctx,
-                                          ptr, bodysize, message_buffer,
-                                          conf_state, qop_state, toktype);
+       ret = gss_krb5int_unseal_token_v3(&ctx->k5_context, minor_status, ctx,
+                                         ptr, bodysize, message_buffer,
+                                         conf_state, qop_state, toktype);
+    if (ret != 0)
+       save_error_info (*minor_status, ctx->k5_context);
+    return ret;
 }
index 416d51a9e35e56ac6d5b0fdb770919e453c416b5..efd9a4f4dc9770492badf96a1d69d19d00a66a9f 100644 (file)
@@ -75,7 +75,6 @@ krb5_gss_release_cred(minor_status, cred_handle)
        free(cred->req_enctypes);
 
    xfree(cred);
-   krb5_free_context(context);
 
    *cred_handle = NULL;
 
@@ -87,5 +86,8 @@ krb5_gss_release_cred(minor_status, cred_handle)
    if (code3)
       *minor_status = code3;
 
+   if (*minor_status)
+       save_error_info(*minor_status, context);
+   krb5_free_context(context);
    return(*minor_status?GSS_S_FAILURE:GSS_S_COMPLETE);
 }
index de4b0637ff16e4ac7f5d84e1356e3930c6d3ac45..fb0f15c9d3e4b8f59894cbe41aff509e3f192e39 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997 by Massachusetts Institute of Technology
+ * Copyright 1997, 2007 by Massachusetts Institute of Technology
  * All Rights Reserved.
  *
  * Export of this software from the United States of America may
@@ -89,6 +89,7 @@ krb5_gss_validate_cred(minor_status, cred_handle)
        k5_mutex_assert_locked(&cred->lock);
        k5_mutex_unlock(&cred->lock);
     }
+    save_error_info(*minor_status, context);
     krb5_free_context(context);
     return maj;
 }