summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2007-07-04 05:46:24 +0000
committerKen Raeburn <raeburn@mit.edu>2007-07-04 05:46:24 +0000
commitfcdd2de143971b0f020531479ad18f57874aef30 (patch)
tree8bec355041d9241b90822a13548ca2ec45a9a884 /src/lib
parente0845c95210ca7cf4a03be23b034a2f29fc078c6 (diff)
downloadkrb5-fcdd2de143971b0f020531479ad18f57874aef30.tar.gz
krb5-fcdd2de143971b0f020531479ad18f57874aef30.tar.xz
krb5-fcdd2de143971b0f020531479ad18f57874aef30.zip
gss krb5 mech enhanced error messages
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
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/gssapi/gss_libinit.c4
-rw-r--r--src/lib/gssapi/krb5/Makefile.in14
-rw-r--r--src/lib/gssapi/krb5/accept_sec_context.c8
-rw-r--r--src/lib/gssapi/krb5/acquire_cred.c21
-rw-r--r--src/lib/gssapi/krb5/add_cred.c13
-rw-r--r--src/lib/gssapi/krb5/context_time.c1
-rw-r--r--src/lib/gssapi/krb5/copy_ccache.c12
-rw-r--r--src/lib/gssapi/krb5/delete_sec_context.c6
-rw-r--r--src/lib/gssapi/krb5/disp_name.c1
-rw-r--r--src/lib/gssapi/krb5/disp_status.c133
-rw-r--r--src/lib/gssapi/krb5/duplicate_name.c3
-rw-r--r--src/lib/gssapi/krb5/export_name.c3
-rw-r--r--src/lib/gssapi/krb5/export_sec_context.c7
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h22
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.c4
-rw-r--r--src/lib/gssapi/krb5/import_name.c2
-rw-r--r--src/lib/gssapi/krb5/import_sec_context.c4
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c14
-rw-r--r--src/lib/gssapi/krb5/inq_context.c3
-rw-r--r--src/lib/gssapi/krb5/inq_cred.c3
-rw-r--r--src/lib/gssapi/krb5/k5seal.c2
-rw-r--r--src/lib/gssapi/krb5/k5sealv3.c3
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c18
-rw-r--r--src/lib/gssapi/krb5/rel_cred.c4
-rw-r--r--src/lib/gssapi/krb5/val_cred.c3
25 files changed, 260 insertions, 48 deletions
diff --git a/src/lib/gssapi/gss_libinit.c b/src/lib/gssapi/gss_libinit.c
index f075fe481e..b96eb9e7aa 100644
--- a/src/lib/gssapi/gss_libinit.c
+++ b/src/lib/gssapi/gss_libinit.c
@@ -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)
diff --git a/src/lib/gssapi/krb5/Makefile.in b/src/lib/gssapi/krb5/Makefile.in
index b4b4d7d3c6..198a0190d7 100644
--- a/src/lib/gssapi/krb5/Makefile.in
+++ b/src/lib/gssapi/krb5/Makefile.in
@@ -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 \
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 7dcdd1a51a..1100b17325 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index 43d21220ce..af17e6742f 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/add_cred.c b/src/lib/gssapi/krb5/add_cred.c
index 6110193953..3ac32fc2e7 100644
--- a/src/lib/gssapi/krb5/add_cred.c
+++ b/src/lib/gssapi/krb5/add_cred.c
@@ -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 {
diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c
index 8b7930ffd9..adaa625069 100644
--- a/src/lib/gssapi/krb5/context_time.c
+++ b/src/lib/gssapi/krb5/context_time.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/copy_ccache.c b/src/lib/gssapi/krb5/copy_ccache.c
index 195be0f842..8ade9c5da8 100644
--- a/src/lib/gssapi/krb5/copy_ccache.c
+++ b/src/lib/gssapi/krb5/copy_ccache.c
@@ -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;
}
diff --git a/src/lib/gssapi/krb5/delete_sec_context.c b/src/lib/gssapi/krb5/delete_sec_context.c
index 1bc6799e33..60755d2519 100644
--- a/src/lib/gssapi/krb5/delete_sec_context.c
+++ b/src/lib/gssapi/krb5/delete_sec_context.c
@@ -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 */
diff --git a/src/lib/gssapi/krb5/disp_name.c b/src/lib/gssapi/krb5/disp_name.c
index 5d3a042d43..1f67d51299 100644
--- a/src/lib/gssapi/krb5/disp_name.c
+++ b/src/lib/gssapi/krb5/disp_name.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/disp_status.c b/src/lib/gssapi/krb5/disp_status.c
index 1988d50c67..9a0399d78b 100644
--- a/src/lib/gssapi/krb5/disp_status.c
+++ b/src/lib/gssapi/krb5/disp_status.c
@@ -26,6 +26,130 @@
/* 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);
diff --git a/src/lib/gssapi/krb5/duplicate_name.c b/src/lib/gssapi/krb5/duplicate_name.c
index cb2ca71c7d..5d352bdf36 100644
--- a/src/lib/gssapi/krb5/duplicate_name.c
+++ b/src/lib/gssapi/krb5/duplicate_name.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/export_name.c b/src/lib/gssapi/krb5/export_name.c
index ce19b04d8d..2d27ba46c8 100644
--- a/src/lib/gssapi/krb5/export_name.c
+++ b/src/lib/gssapi/krb5/export_name.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/export_sec_context.c b/src/lib/gssapi/krb5/export_sec_context.c
index fb57b882a2..867d4d6f50 100644
--- a/src/lib/gssapi/krb5/export_sec_context.c
+++ b/src/lib/gssapi/krb5/export_sec_context.c
@@ -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);
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 86ec771e1e..57c2ed9ea6 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -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_ */
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
index a0953e0b23..224484f44b 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/import_name.c b/src/lib/gssapi/krb5/import_name.c
index db63c4b24f..58bc19f918 100644
--- a/src/lib/gssapi/krb5/import_name.c
+++ b/src/lib/gssapi/krb5/import_name.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/import_sec_context.c b/src/lib/gssapi/krb5/import_sec_context.c
index 1255ecc6cf..7563dc0d7d 100644
--- a/src/lib/gssapi/krb5/import_sec_context.c
+++ b/src/lib/gssapi/krb5/import_sec_context.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 4f14e598b9..ce4b5d78d6 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -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 */
diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
index 0954ddc5dd..28c49f72cd 100644
--- a/src/lib/gssapi/krb5/inq_context.c
+++ b/src/lib/gssapi/krb5/inq_context.c
@@ -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)) {
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
index 58425d80d7..aa50d12313 100644
--- a/src/lib/gssapi/krb5/inq_cred.c
+++ b/src/lib/gssapi/krb5/inq_cred.c
@@ -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;
}
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
index 7a904d0650..4557194faa 100644
--- a/src/lib/gssapi/krb5/k5seal.c
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
index 4c6df27443..019f668c8c 100644
--- a/src/lib/gssapi/krb5/k5sealv3.c
+++ b/src/lib/gssapi/krb5/k5sealv3.c
@@ -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) {
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index 8c999868ef..72afb45763 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -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;
}
diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c
index 416d51a9e3..efd9a4f4dc 100644
--- a/src/lib/gssapi/krb5/rel_cred.c
+++ b/src/lib/gssapi/krb5/rel_cred.c
@@ -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);
}
diff --git a/src/lib/gssapi/krb5/val_cred.c b/src/lib/gssapi/krb5/val_cred.c
index de4b0637ff..fb0f15c9d3 100644
--- a/src/lib/gssapi/krb5/val_cred.c
+++ b/src/lib/gssapi/krb5/val_cred.c
@@ -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;
}