From fcdd2de143971b0f020531479ad18f57874aef30 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Wed, 4 Jul 2007 05:46:24 +0000 Subject: [PATCH] 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 --- src/lib/gssapi/gss_libinit.c | 4 + src/lib/gssapi/krb5/Makefile.in | 14 ++- src/lib/gssapi/krb5/accept_sec_context.c | 8 +- src/lib/gssapi/krb5/acquire_cred.c | 21 ++-- src/lib/gssapi/krb5/add_cred.c | 13 ++- src/lib/gssapi/krb5/context_time.c | 1 + src/lib/gssapi/krb5/copy_ccache.c | 12 +- src/lib/gssapi/krb5/delete_sec_context.c | 6 +- src/lib/gssapi/krb5/disp_name.c | 1 + src/lib/gssapi/krb5/disp_status.c | 133 ++++++++++++++++++++++- src/lib/gssapi/krb5/duplicate_name.c | 3 +- src/lib/gssapi/krb5/export_name.c | 3 +- src/lib/gssapi/krb5/export_sec_context.c | 7 +- src/lib/gssapi/krb5/gssapiP_krb5.h | 22 +++- src/lib/gssapi/krb5/gssapi_krb5.c | 4 +- src/lib/gssapi/krb5/import_name.c | 2 + src/lib/gssapi/krb5/import_sec_context.c | 4 +- src/lib/gssapi/krb5/init_sec_context.c | 14 ++- src/lib/gssapi/krb5/inq_context.c | 3 + src/lib/gssapi/krb5/inq_cred.c | 3 +- src/lib/gssapi/krb5/k5seal.c | 2 + src/lib/gssapi/krb5/k5sealv3.c | 3 +- src/lib/gssapi/krb5/k5unseal.c | 18 +-- src/lib/gssapi/krb5/rel_cred.c | 4 +- src/lib/gssapi/krb5/val_cred.c | 3 +- 25 files changed, 260 insertions(+), 48 deletions(-) diff --git a/src/lib/gssapi/gss_libinit.c b/src/lib/gssapi/gss_libinit.c index f075fe481..b96eb9e7a 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 b4b4d7d3c..198a0190d 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 7dcdd1a51..1100b1732 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 43d21220c..af17e6742 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 611019395..3ac32fc2e 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 8b7930ffd..adaa62506 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 195be0f84..8ade9c5da 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 1bc6799e3..60755d251 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 5d3a042d4..1f67d5129 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 1988d50c6..9a0399d78 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 +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 cb2ca71c7..5d352bdf3 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 ce19b04d8..2d27ba46c 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 fb57b882a..867d4d6f5 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 86ec771e1..57c2ed9ea 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 a0953e0b2..224484f44 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 db63c4b24..58bc19f91 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 1255ecc6c..7563dc0d7 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 4f14e598b..ce4b5d78d 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 0954ddc5d..28c49f72c 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 58425d80d..aa50d1231 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 7a904d065..4557194fa 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 4c6df2744..019f668c8 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 8c999868e..72afb4576 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 416d51a9e..efd9a4f4d 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 de4b0637f..fb0f15c9d 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; } -- 2.26.2