From e8441212d1347992ba6a096981aabd46a3830694 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Thu, 23 Apr 2020 14:30:42 -0500 Subject: [PATCH] Move error functions from krb5 to base --- lib/base/Makefile.am | 1 + lib/base/NTMakefile | 4 +- lib/base/baselocl.h | 12 ++ lib/base/context.c | 89 ++---------- lib/base/error_string.c | 264 +++++++++--------------------------- lib/base/heimbase.h | 8 -- lib/base/version-script.map | 4 +- lib/krb5/add_et_list.c | 6 +- lib/krb5/context.c | 103 +++----------- lib/krb5/crypto-stubs.c | 3 - lib/krb5/deprecated.c | 14 +- lib/krb5/error_string.c | 235 ++++++++++++++++++++++++++++++++ lib/krb5/krb5_locl.h | 3 - 13 files changed, 350 insertions(+), 396 deletions(-) create mode 100644 lib/krb5/error_string.c diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am index 3a462caf7..bd829312e 100644 --- a/lib/base/Makefile.am +++ b/lib/base/Makefile.am @@ -47,6 +47,7 @@ dist_libheimbase_la_SOURCES = \ dict.c \ $(IMPLEMENT_TLS) \ error.c \ + error_string.c \ expand_path.c \ heimbase.c \ heimbasepriv.h \ diff --git a/lib/base/NTMakefile b/lib/base/NTMakefile index 2b40715a0..a9ac842f2 100644 --- a/lib/base/NTMakefile +++ b/lib/base/NTMakefile @@ -56,6 +56,7 @@ libheimbase_SOURCES = \ dict.c \ dll.c \ error.c \ + error_string.c \ expand_path.c \ heimbase.c \ json.c \ @@ -78,6 +79,7 @@ libheimbase_OBJS = \ $(OBJ)\dict.obj \ $(OBJ)\dll.obj \ $(OBJ)\error.obj \ + $(OBJ)\error_string.obj \ $(OBJ)\expand_path.obj \ $(OBJ)\heimbase.obj \ $(OBJ)\json.obj \ @@ -91,7 +93,7 @@ libheimbase_OBJS = \ libheimbase_gen_OBJS= $(OBJ)\heim_err.obj $(LIBHEIMBASE): $(libheimbase_OBJS) $(libheimbase_gen_OBJS) - $(LIBCON_C) -OUT:$@ $(LIBROKEN) $(PTHREAD_LIB) Secur32.lib Shell32.lib Advapi32.lib Shlwapi.lib @<< + $(LIBCON_C) -OUT:$@ $(LIBROKEN) $(LIBCOMERR) $(PTHREAD_LIB) Secur32.lib Shell32.lib Advapi32.lib Shlwapi.lib @<< $(libheimbase_OBJS: = ) $(libheimbase_gen_OBJS: = diff --git a/lib/base/baselocl.h b/lib/base/baselocl.h index 7cc1734b6..7ca6439b3 100644 --- a/lib/base/baselocl.h +++ b/lib/base/baselocl.h @@ -84,3 +84,15 @@ #define HEIMDAL_NORETURN_ATTRIBUTE #undef HEIMDAL_PRINTF_ATTRIBUTE #define HEIMDAL_PRINTF_ATTRIBUTE(x) + +struct heim_context_s { + heim_log_facility *log_dest; + heim_log_facility *warn_dest; + heim_log_facility *debug_dest; + char *time_fmt; + unsigned int log_utc:1; + unsigned int homedir_access:1; + struct et_list *et_list; + char *error_string; + heim_error_code error_code; +}; diff --git a/lib/base/context.c b/lib/base/context.c index ee55adc60..bbbb7ed89 100644 --- a/lib/base/context.c +++ b/lib/base/context.c @@ -36,22 +36,6 @@ #undef __attribute__ #define __attribute__(X) -struct heim_context_s { - heim_log_facility *log_dest; - heim_log_facility *warn_dest; - heim_log_facility *debug_dest; - char *time_fmt; - unsigned int log_utc:1; - unsigned int homedir_access:1; - heim_err_cb_context error_context; - heim_err_cb_clear_msg clear_error_message; - heim_err_cb_free_msg free_error_message; - heim_err_cb_get_msg get_error_message; - heim_err_cb_set_msg set_error_message; - const char *unknown_error; - const char *success; -}; - heim_context heim_context_init(void) { @@ -61,17 +45,12 @@ heim_context_init(void) return NULL; context->log_utc = 1; - context->clear_error_message = NULL; - context->free_error_message = NULL; - context->get_error_message = NULL; - context->set_error_message = NULL; - context->error_context = NULL; - context->unknown_error = "Unknown error"; - context->success = "Success"; + context->error_string = NULL; context->debug_dest = NULL; context->warn_dest = NULL; context->log_dest = NULL; context->time_fmt = NULL; + context->et_list = NULL; return context; } @@ -86,23 +65,17 @@ heim_context_free(heim_context *contextp) heim_closelog(context, context->debug_dest); heim_closelog(context, context->warn_dest); heim_closelog(context, context->log_dest); + free_error_table(context->et_list); free(context->time_fmt); + free(context->error_string); free(context); } -void -heim_context_set_msg_cb(heim_context context, - heim_err_cb_context cb_context, - heim_err_cb_clear_msg cb_clear_msg, - heim_err_cb_free_msg cb_free_msg, - heim_err_cb_get_msg cb_get_msg, - heim_err_cb_set_msg cb_set_msg) +heim_error_code +heim_add_et_list(heim_context context, void (*func)(struct et_list **)) { - context->error_context = cb_context; - context->clear_error_message = cb_clear_msg; - context->free_error_message = cb_free_msg; - context->set_error_message = cb_set_msg; - context->get_error_message = cb_get_msg; + (*func)(&context->et_list); + return 0; } heim_error_code @@ -157,52 +130,6 @@ heim_context_get_homedir_access(heim_context context) return context->homedir_access; } -void -heim_clear_error_message(heim_context context) -{ - if (context != NULL && context->clear_error_message != NULL) - context->clear_error_message(context->error_context); -} - -void -heim_free_error_message(heim_context context, const char *msg) -{ - if (context != NULL && context->free_error_message != NULL && - msg != context->unknown_error && msg != context->success) - context->free_error_message(context->error_context, msg); -} - -const char * -heim_get_error_message(heim_context context, heim_error_code ret) -{ - if (context != NULL && context->get_error_message != NULL) - return context->get_error_message(context->error_context, ret); - if (ret) - return context->unknown_error; - return context->success; -} - -void -heim_set_error_message(heim_context context, heim_error_code ret, - const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 3, 4))) -{ - va_list ap; - - va_start(ap, fmt); - heim_vset_error_message(context, ret, fmt, ap); - va_end(ap); -} - -void -heim_vset_error_message(heim_context context, heim_error_code ret, - const char *fmt, va_list args) - __attribute__ ((__format__ (__printf__, 3, 0))) -{ - if (context != NULL && context->set_error_message != NULL) - context->set_error_message(context->error_context, ret, fmt, args); -} - heim_error_code heim_enomem(heim_context context) { diff --git a/lib/base/error_string.c b/lib/base/error_string.c index fa181733d..5c787ba2c 100644 --- a/lib/base/error_string.c +++ b/lib/base/error_string.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2003, 2005 - 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2001, 2003, 2005 - 2020 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,190 +31,99 @@ * SUCH DAMAGE. */ -#include "krb5_locl.h" +#include "baselocl.h" #undef __attribute__ #define __attribute__(x) -/** - * Clears the error message from the Kerberos 5 context. - * - * @param context The Kerberos 5 context to clear - * - * @ingroup krb5_error - */ - -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -krb5_clear_error_message(krb5_context context) +void +heim_clear_error_message(heim_context context) { - HEIMDAL_MUTEX_lock(&context->mutex); if (context->error_string) - free(context->error_string); + free(context->error_string); context->error_code = 0; context->error_string = NULL; - HEIMDAL_MUTEX_unlock(&context->mutex); } -/** - * Set the context full error string for a specific error code. - * The error that is stored should be internationalized. - * - * The if context is NULL, no error string is stored. - * - * @param context Kerberos 5 context - * @param ret The error code - * @param fmt Error string for the error code - * @param ... printf(3) style parameters. - * - * @ingroup krb5_error - */ - -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -krb5_set_error_message(krb5_context context, krb5_error_code ret, - const char *fmt, ...) +void +heim_set_error_message(heim_context context, heim_error_code ret, + const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))) { va_list ap; va_start(ap, fmt); - krb5_vset_error_message (context, ret, fmt, ap); + heim_vset_error_message(context, ret, fmt, ap); va_end(ap); } -/** - * Set the context full error string for a specific error code. - * - * The if context is NULL, no error string is stored. - * - * @param context Kerberos 5 context - * @param ret The error code - * @param fmt Error string for the error code - * @param args printf(3) style parameters. - * - * @ingroup krb5_error - */ - - -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -krb5_vset_error_message (krb5_context context, krb5_error_code ret, - const char *fmt, va_list args) +void +heim_vset_error_message(heim_context context, heim_error_code ret, + const char *fmt, va_list args) __attribute__ ((__format__ (__printf__, 3, 0))) { int r; if (context == NULL) - return; - - HEIMDAL_MUTEX_lock(&context->mutex); + return; if (context->error_string) { - free(context->error_string); - context->error_string = NULL; + free(context->error_string); + context->error_string = NULL; } context->error_code = ret; r = vasprintf(&context->error_string, fmt, args); if (r < 0) - context->error_string = NULL; - HEIMDAL_MUTEX_unlock(&context->mutex); + context->error_string = NULL; if (context->error_string) - _krb5_debug(context, 100, "error message: %s: %d", context->error_string, ret); + heim_debug(context, 200, "error message: %s: %d", context->error_string, ret); } -/** - * Prepend the context full error string for a specific error code. - * The error that is stored should be internationalized. - * - * The if context is NULL, no error string is stored. - * - * @param context Kerberos 5 context - * @param ret The error code - * @param fmt Error string for the error code - * @param ... printf(3) style parameters. - * - * @ingroup krb5_error - */ - -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -krb5_prepend_error_message(krb5_context context, krb5_error_code ret, - const char *fmt, ...) +void +heim_prepend_error_message(heim_context context, heim_error_code ret, + const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))) { va_list ap; va_start(ap, fmt); - krb5_vprepend_error_message(context, ret, fmt, ap); + heim_vprepend_error_message(context, ret, fmt, ap); va_end(ap); } -/** - * Prepend the contexts's full error string for a specific error code. - * - * The if context is NULL, no error string is stored. - * - * @param context Kerberos 5 context - * @param ret The error code - * @param fmt Error string for the error code - * @param args printf(3) style parameters. - * - * @ingroup krb5_error - */ - -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -krb5_vprepend_error_message(krb5_context context, krb5_error_code ret, - const char *fmt, va_list args) +void +heim_vprepend_error_message(heim_context context, heim_error_code ret, + const char *fmt, va_list args) __attribute__ ((__format__ (__printf__, 3, 0))) { char *str = NULL, *str2 = NULL; - if (context == NULL) - return; - - HEIMDAL_MUTEX_lock(&context->mutex); - if (context->error_code != ret) { - HEIMDAL_MUTEX_unlock(&context->mutex); - return; - } - if (vasprintf(&str, fmt, args) < 0 || str == NULL) { - HEIMDAL_MUTEX_unlock(&context->mutex); - return; - } + if (context == NULL || context->error_code != ret || + vasprintf(&str, fmt, args) < 0 || str == NULL) + return; if (context->error_string) { - int e; + int e; - e = asprintf(&str2, "%s: %s", str, context->error_string); - free(context->error_string); - if (e < 0 || str2 == NULL) - context->error_string = NULL; - else - context->error_string = str2; - free(str); + e = asprintf(&str2, "%s: %s", str, context->error_string); + free(context->error_string); + if (e < 0 || str2 == NULL) + context->error_string = NULL; + else + context->error_string = str2; + free(str); } else - context->error_string = str; - HEIMDAL_MUTEX_unlock(&context->mutex); + context->error_string = str; } -/** - * Return the error message for `code' in context. On memory - * allocation error the function returns NULL. - * - * @param context Kerberos 5 context - * @param code Error code related to the error - * - * @return an error string, needs to be freed with - * krb5_free_error_message(). The functions return NULL on error. - * - * @ingroup krb5_error - */ - -KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL -krb5_get_error_message(krb5_context context, krb5_error_code code) +const char * +heim_get_error_message(heim_context context, heim_error_code code) { - char *str = NULL; const char *cstr = NULL; + char *str = NULL; char buf[128]; int free_context = 0; if (code == 0) - return strdup("Success"); + return strdup("Success"); /* * The MIT version of this function ignores the krb5_context @@ -224,87 +133,42 @@ krb5_get_error_message(krb5_context context, krb5_error_code code) * might be provided is if the krb5_init_context() call itself * failed. */ - if (context) - { - HEIMDAL_MUTEX_lock(&context->mutex); - if (context->error_string && - (code == context->error_code || context->error_code == 0)) - { - str = strdup(context->error_string); - } - HEIMDAL_MUTEX_unlock(&context->mutex); - - if (str) - return str; - } - else - { - if (krb5_init_context(&context) == 0) - free_context = 1; - } + if (context && + context->error_string && + (code == context->error_code || context->error_code == 0) && + (cstr = strdup(context->error_string))) + return cstr; + if (context == NULL && (context = heim_context_init())) + free_context = 1; if (context) cstr = com_right_r(context->et_list, code, buf, sizeof(buf)); - if (free_context) - krb5_free_context(context); + heim_context_free(&context); - if (cstr) + if (cstr || (cstr = error_message(code))) return strdup(cstr); - - cstr = error_message(code); - if (cstr) - return strdup(cstr); - if (asprintf(&str, "", (int)code) == -1 || str == NULL) - return NULL; - + return NULL; return str; } +const char * +heim_get_error_string(heim_context context) +{ + if (context && context->error_string) + return strdup(context->error_string); + return NULL; +} -/** - * Free the error message returned by krb5_get_error_message(). - * - * @param context Kerberos context - * @param msg error message to free, returned byg - * krb5_get_error_message(). - * - * @ingroup krb5_error - */ +int +heim_have_error_string(heim_context context) +{ + return context->error_string != NULL; +} -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -krb5_free_error_message(krb5_context context, const char *msg) +void +heim_free_error_message(heim_context context, const char *msg) { free(rk_UNCONST(msg)); } - - -/** - * Return the error string for the error code. The caller must not - * free the string. - * - * This function is deprecated since its not threadsafe. - * - * @param context Kerberos 5 context. - * @param code Kerberos error code. - * - * @return the error message matching code - * - * @ingroup krb5 - */ - -KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL -krb5_get_err_text(krb5_context context, krb5_error_code code) - KRB5_DEPRECATED_FUNCTION("Use krb5_get_error_message instead") -{ - const char *p = NULL; - if(context != NULL) - p = com_right(context->et_list, code); - if(p == NULL) - p = strerror(code); - if (p == NULL) - p = "Unknown error"; - return p; -} - diff --git a/lib/base/heimbase.h b/lib/base/heimbase.h index 16f40c819..a0141fd13 100644 --- a/lib/base/heimbase.h +++ b/lib/base/heimbase.h @@ -120,14 +120,6 @@ struct heim_plugin_data { heim_get_instance_func_t get_instance; }; -typedef struct heim_err_cb_context_s *heim_err_cb_context; -typedef void (*heim_err_cb_clear_msg)(heim_err_cb_context); -typedef void (*heim_err_cb_free_msg)(heim_err_cb_context, const char *); -typedef const char * (*heim_err_cb_get_msg)(heim_err_cb_context, int32_t); -typedef void (*heim_err_cb_set_msg)(heim_err_cb_context, int32_t, - const char *, va_list) - __attribute__ ((__format__ (__printf__, 3, 0))); - typedef struct heim_config_binding heim_config_binding; struct heim_config_binding { enum { diff --git a/lib/base/version-script.map b/lib/base/version-script.map index ecf2e7d4c..0cd0c8444 100644 --- a/lib/base/version-script.map +++ b/lib/base/version-script.map @@ -10,6 +10,7 @@ HEIMDAL_BASE_1.0 { heim_abort; heim_abortv; heim_add_debug_dest; + heim_add_et_list; heim_addlog_dest; heim_addlog_func; heim_add_warn_dest; @@ -81,7 +82,6 @@ HEIMDAL_BASE_1.0 { heim_context_init; heim_context_set_homedir_access; heim_context_set_log_utc; - heim_context_set_msg_cb; heim_context_set_time_fmt; _heim_create_type; heim_data_create; @@ -127,6 +127,7 @@ HEIMDAL_BASE_1.0 { heim_get_debug_dest; heim_get_default_config_files; heim_get_error_message; + heim_get_error_string; heim_get_hash; _heim_get_isa; _heim_get_isaextra; @@ -134,6 +135,7 @@ HEIMDAL_BASE_1.0 { heim_get_tid; heim_get_warn_dest; heim_have_debug; + heim_have_error_string; heim_initlog; heim_json_copy_serialize; heim_json_create; diff --git a/lib/krb5/add_et_list.c b/lib/krb5/add_et_list.c index 082014e10..1a289eeae 100644 --- a/lib/krb5/add_et_list.c +++ b/lib/krb5/add_et_list.c @@ -48,9 +48,7 @@ */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_add_et_list (krb5_context context, - void (*func)(struct et_list **)) +krb5_add_et_list(krb5_context context, void (*func)(struct et_list **)) { - (*func)(&context->et_list); - return 0; + return heim_add_et_list(context->hcontext, func); } diff --git a/lib/krb5/context.c b/lib/krb5/context.c index 43c5d79fc..0d5ad3c07 100644 --- a/lib/krb5/context.c +++ b/lib/krb5/context.c @@ -37,6 +37,8 @@ #include #include +static void _krb5_init_ets(krb5_context); + #define INIT_FIELD(C, T, E, D, F) \ (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \ "libdefaults", F, NULL) @@ -401,32 +403,6 @@ init_context_once(void *ctx) bindtextdomain(HEIMDAL_TEXTDOMAIN, HEIMDAL_LOCALEDIR); } -static void -clear_error_message_cb(heim_err_cb_context ctx) -{ - krb5_clear_error_message((krb5_context)ctx); -} - -static void -free_error_message_cb(heim_err_cb_context ctx, const char *msg) -{ - krb5_free_error_message((krb5_context)ctx, msg); -} - -static const char * -get_error_message_cb(heim_err_cb_context ctx, int32_t ret) -{ - return krb5_get_error_message((krb5_context)ctx, ret); -} - -static void -set_error_message_cb(heim_err_cb_context ctx, int32_t ret, - const char *fmt, va_list args) -{ - krb5_vset_error_message((krb5_context)ctx, ret, fmt, args); -} - - /** * Initializes the context structure and reads the configuration file * /etc/krb5.conf. The structure should be freed by calling @@ -471,18 +447,11 @@ krb5_init_context(krb5_context *context) if(!p) return ENOMEM; - HEIMDAL_MUTEX_init(&p->mutex); if ((p->hcontext = heim_context_init()) == NULL) { ret = ENOMEM; goto out; } - heim_context_set_msg_cb(p->hcontext, (void *)p, - clear_error_message_cb, - free_error_message_cb, - get_error_message_cb, - set_error_message_cb); - p->flags |= KRB5_CTX_F_HOMEDIR_ACCESS; ret = krb5_get_default_config_files(&files); @@ -497,7 +466,7 @@ krb5_init_context(krb5_context *context) heim_base_once_f(&init_context, p, init_context_once); /* init error tables */ - krb5_init_ets(p); + _krb5_init_ets(p); cc_ops_register(p); kt_ops_register(p); @@ -576,19 +545,12 @@ krb5_copy_context(krb5_context context, krb5_context *out) if (p == NULL) return krb5_enomem(context); - HEIMDAL_MUTEX_init(&p->mutex); - if ((p->hcontext = heim_context_init()) == NULL) { ret = ENOMEM; goto out; } heim_context_set_log_utc(p->hcontext, context->log_utc); - heim_context_set_msg_cb(p->hcontext, (void *)p, - clear_error_message_cb, - free_error_message_cb, - get_error_message_cb, - set_error_message_cb); if (context->default_cc_name && (p->default_cc_name = strdup(context->default_cc_name)) == NULL) { @@ -636,7 +598,7 @@ krb5_copy_context(krb5_context context, krb5_context *out) goto out; /* XXX should copy */ - krb5_init_ets(p); + _krb5_init_ets(p); cc_ops_copy(p, context); kt_ops_copy(p, context); @@ -689,7 +651,6 @@ krb5_free_context(krb5_context context) free(context->as_etypes); krb5_free_host_realm (context, context->default_realms); krb5_config_file_free (context, context->cf); - free_error_table (context->et_list); free(rk_UNCONST(context->cc_ops)); free(context->kt_types); krb5_clear_error_message(context); @@ -702,7 +663,6 @@ krb5_free_context(krb5_context context) hx509_context_free(&context->hx509ctx); #endif - HEIMDAL_MUTEX_destroy(&context->mutex); if (context->flags & KRB5_CTX_F_SOCKETS_INITIALIZED) { rk_SOCK_EXIT(); } @@ -774,32 +734,6 @@ krb5_set_config(krb5_context context, const char *config) } #endif -static krb5_error_code -add_file(char ***pfilenames, int *len, char *file) -{ - char **pp = *pfilenames; - int i; - - for(i = 0; i < *len; i++) { - if(strcmp(pp[i], file) == 0) { - free(file); - return 0; - } - } - - pp = realloc(*pfilenames, (*len + 2) * sizeof(*pp)); - if (pp == NULL) { - free(file); - return ENOMEM; - } - - pp[*len] = file; - pp[*len + 1] = NULL; - *pfilenames = pp; - *len += 1; - return 0; -} - /* * `pq' isn't free, it's up the the caller */ @@ -1065,28 +999,31 @@ krb5_get_default_in_tkt_etypes(krb5_context context, KRB5_LIB_FUNCTION void KRB5_LIB_CALL krb5_init_ets(krb5_context context) { - if(context->et_list == NULL){ - krb5_add_et_list(context, initialize_krb5_error_table_r); - krb5_add_et_list(context, initialize_asn1_error_table_r); - krb5_add_et_list(context, initialize_heim_error_table_r); +} - krb5_add_et_list(context, initialize_k524_error_table_r); - krb5_add_et_list(context, initialize_k5e1_error_table_r); +static void +_krb5_init_ets(krb5_context context) +{ + heim_add_et_list(context->hcontext, initialize_krb5_error_table_r); + heim_add_et_list(context->hcontext, initialize_asn1_error_table_r); + heim_add_et_list(context->hcontext, initialize_heim_error_table_r); + + heim_add_et_list(context->hcontext, initialize_k524_error_table_r); + heim_add_et_list(context->hcontext, initialize_k5e1_error_table_r); #ifdef COM_ERR_BINDDOMAIN_krb5 - bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR); - bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR); - bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR); - bindtextdomain(COM_ERR_BINDDOMAIN_k524, HEIMDAL_LOCALEDIR); + bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR); + bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR); + bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR); + bindtextdomain(COM_ERR_BINDDOMAIN_k524, HEIMDAL_LOCALEDIR); #endif #ifdef PKINIT - krb5_add_et_list(context, initialize_hx_error_table_r); + heim_add_et_list(context->hcontext, initialize_hx_error_table_r); #ifdef COM_ERR_BINDDOMAIN_hx - bindtextdomain(COM_ERR_BINDDOMAIN_hx, HEIMDAL_LOCALEDIR); + bindtextdomain(COM_ERR_BINDDOMAIN_hx, HEIMDAL_LOCALEDIR); #endif #endif - } } /** diff --git a/lib/krb5/crypto-stubs.c b/lib/krb5/crypto-stubs.c index 2398a4630..5251f8857 100644 --- a/lib/krb5/crypto-stubs.c +++ b/lib/krb5/crypto-stubs.c @@ -49,8 +49,6 @@ krb5_init_context(krb5_context *context) if(!p) return ENOMEM; - HEIMDAL_MUTEX_init(&p->mutex); - *context = p; return 0; } @@ -60,7 +58,6 @@ krb5_free_context(krb5_context context) { krb5_clear_error_message(context); - HEIMDAL_MUTEX_destroy(&context->mutex); if (context->flags & KRB5_CTX_F_SOCKETS_INITIALIZED) { rk_SOCK_EXIT(); } diff --git a/lib/krb5/deprecated.c b/lib/krb5/deprecated.c index 5530e841b..074903ca4 100644 --- a/lib/krb5/deprecated.c +++ b/lib/krb5/deprecated.c @@ -622,24 +622,14 @@ KRB5_LIB_FUNCTION char * KRB5_LIB_CALL krb5_get_error_string(krb5_context context) KRB5_DEPRECATED_FUNCTION("Use krb5_get_error_message instead") { - char *ret = NULL; - - HEIMDAL_MUTEX_lock(&context->mutex); - if (context->error_string) - ret = strdup(context->error_string); - HEIMDAL_MUTEX_unlock(&context->mutex); - return ret; + return heim_get_error_string(context->hcontext); } KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL krb5_have_error_string(krb5_context context) KRB5_DEPRECATED_FUNCTION("Use krb5_get_error_message instead") { - char *str; - HEIMDAL_MUTEX_lock(&context->mutex); - str = context->error_string; - HEIMDAL_MUTEX_unlock(&context->mutex); - return str != NULL; + return heim_have_error_string(context->hcontext); } struct send_to_kdc { diff --git a/lib/krb5/error_string.c b/lib/krb5/error_string.c new file mode 100644 index 000000000..0e42f51bc --- /dev/null +++ b/lib/krb5/error_string.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2001, 2003, 2005 - 2020 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5_locl.h" + +#undef __attribute__ +#define __attribute__(x) + +/** + * Clears the error message from the Kerberos 5 context. + * + * @param context The Kerberos 5 context to clear + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION void KRB5_LIB_CALL +krb5_clear_error_message(krb5_context context) +{ + heim_clear_error_message(context->hcontext); +} + +/** + * Set the context full error string for a specific error code. + * The error that is stored should be internationalized. + * + * The if context is NULL, no error string is stored. + * + * @param context Kerberos 5 context + * @param ret The error code + * @param fmt Error string for the error code + * @param ... printf(3) style parameters. + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION void KRB5_LIB_CALL +krb5_set_error_message(krb5_context context, krb5_error_code ret, + const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 3, 4))) +{ + va_list ap; + + va_start(ap, fmt); + krb5_vset_error_message (context, ret, fmt, ap); + va_end(ap); +} + +/** + * Set the context full error string for a specific error code. + * + * The if context is NULL, no error string is stored. + * + * @param context Kerberos 5 context + * @param ret The error code + * @param fmt Error string for the error code + * @param args printf(3) style parameters. + * + * @ingroup krb5_error + */ + + +KRB5_LIB_FUNCTION void KRB5_LIB_CALL +krb5_vset_error_message(krb5_context context, krb5_error_code ret, + const char *fmt, va_list args) + __attribute__ ((__format__ (__printf__, 3, 0))) +{ + if (context) { + const char *msg; + + heim_vset_error_message(context->hcontext, ret, fmt, args); + msg = heim_get_error_message(context->hcontext, ret); + if (msg) { + _krb5_debug(context, 100, "error message: %s: %d", msg, ret); + heim_free_error_message(context->hcontext, msg); + } + } +} + +/** + * Prepend the context full error string for a specific error code. + * The error that is stored should be internationalized. + * + * The if context is NULL, no error string is stored. + * + * @param context Kerberos 5 context + * @param ret The error code + * @param fmt Error string for the error code + * @param ... printf(3) style parameters. + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION void KRB5_LIB_CALL +krb5_prepend_error_message(krb5_context context, krb5_error_code ret, + const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 3, 4))) +{ + va_list ap; + + va_start(ap, fmt); + krb5_vprepend_error_message(context, ret, fmt, ap); + va_end(ap); +} + +/** + * Prepend the contexts's full error string for a specific error code. + * + * The if context is NULL, no error string is stored. + * + * @param context Kerberos 5 context + * @param ret The error code + * @param fmt Error string for the error code + * @param args printf(3) style parameters. + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION void KRB5_LIB_CALL +krb5_vprepend_error_message(krb5_context context, krb5_error_code ret, + const char *fmt, va_list args) + __attribute__ ((__format__ (__printf__, 3, 0))) +{ + if (context) + heim_vprepend_error_message(context->hcontext, ret, fmt, args); +} + +/** + * Return the error message for `code' in context. On memory + * allocation error the function returns NULL. + * + * @param context Kerberos 5 context + * @param code Error code related to the error + * + * @return an error string, needs to be freed with + * krb5_free_error_message(). The functions return NULL on error. + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL +krb5_get_error_message(krb5_context context, krb5_error_code code) +{ + const char *cstr = NULL; + + if (code == 0) + return strdup("Success"); + + /* + * The MIT version of this function ignores the krb5_context + * and several widely deployed applications call krb5_get_error_message() + * with a NULL context in order to translate an error code as a + * replacement for error_message(). Another reason a NULL context + * might be provided is if the krb5_init_context() call itself + * failed. + */ + if (context == NULL && krb5_init_context(&context) == 0) { + cstr = heim_get_error_message(context->hcontext, code); + krb5_free_context(context); + } else if (context) { + cstr = heim_get_error_message(context->hcontext, code); + } else { + cstr = heim_get_error_message(NULL, code); + } + return cstr; +} + + +/** + * Free the error message returned by krb5_get_error_message(). + * + * @param context Kerberos context + * @param msg error message to free, returned byg + * krb5_get_error_message(). + * + * @ingroup krb5_error + */ + +KRB5_LIB_FUNCTION void KRB5_LIB_CALL +krb5_free_error_message(krb5_context context, const char *msg) +{ + heim_free_error_message(context ? context->hcontext : NULL, msg); +} + + +/** + * Return the error string for the error code. The caller must not + * free the string. + * + * This function is deprecated since its not threadsafe. + * + * @param context Kerberos 5 context. + * @param code Kerberos error code. + * + * @return the error message matching code + * + * @ingroup krb5 + */ + +KRB5_LIB_FUNCTION const char* KRB5_LIB_CALL +krb5_get_err_text(krb5_context context, krb5_error_code code) + KRB5_DEPRECATED_FUNCTION("Use krb5_get_error_message instead") +{ + return krb5_get_error_message(context, code); +} diff --git a/lib/krb5/krb5_locl.h b/lib/krb5/krb5_locl.h index 94370b447..738916731 100644 --- a/lib/krb5/krb5_locl.h +++ b/lib/krb5/krb5_locl.h @@ -248,7 +248,6 @@ typedef struct krb5_context_data { int32_t kdc_sec_offset; int32_t kdc_usec_offset; krb5_config_section *cf; - struct et_list *et_list; const krb5_cc_ops **cc_ops; int num_cc_ops; const char *http_proxy; @@ -266,14 +265,12 @@ typedef struct krb5_context_data { int num_kt_types; /* # of registered keytab types */ struct krb5_keytab_data *kt_types; /* registered keytab types */ const char *date_fmt; - char *error_string; krb5_error_code error_code; krb5_addresses *ignore_addresses; char *default_cc_name; char *default_cc_name_env; char *configured_default_cc_name; int default_cc_name_set; - HEIMDAL_MUTEX mutex; /* protects error_string */ int large_msg_size; int max_msg_size; int tgs_negative_timeout; /* timeout for TGS negative cache */