diff options
Diffstat (limited to 'src/lib/gssapi/krb5/disp_status.c')
-rw-r--r-- | src/lib/gssapi/krb5/disp_status.c | 133 |
1 files changed, 131 insertions, 2 deletions
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); |