dict.c \
$(IMPLEMENT_TLS) \
error.c \
+ error_string.c \
expand_path.c \
heimbase.c \
heimbasepriv.h \
dict.c \
dll.c \
error.c \
+ error_string.c \
expand_path.c \
heimbase.c \
json.c \
$(OBJ)\dict.obj \
$(OBJ)\dll.obj \
$(OBJ)\error.obj \
+ $(OBJ)\error_string.obj \
$(OBJ)\expand_path.obj \
$(OBJ)\heimbase.obj \
$(OBJ)\json.obj \
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: =
#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;
+};
#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)
{
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;
}
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
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)
{
/*
- * 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.
*
* 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;
-
- 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);
+ 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);
} 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
* 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, "<unknown error: %d>", (int)code) == -1 || str == NULL)
- return NULL;
-
+ return NULL;
return str;
}
-
-/**
- * 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)
+const char *
+heim_get_error_string(heim_context context)
{
- free(rk_UNCONST(msg));
+ if (context && context->error_string)
+ return strdup(context->error_string);
+ return NULL;
}
-
-/**
- * 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")
+int
+heim_have_error_string(heim_context context)
{
- 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;
+ return context->error_string != NULL;
}
+void
+heim_free_error_message(heim_context context, const char *msg)
+{
+ free(rk_UNCONST(msg));
+}
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 {
heim_abort;
heim_abortv;
heim_add_debug_dest;
+ heim_add_et_list;
heim_addlog_dest;
heim_addlog_func;
heim_add_warn_dest;
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;
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;
heim_get_tid;
heim_get_warn_dest;
heim_have_debug;
+ heim_have_error_string;
heim_initlog;
heim_json_copy_serialize;
heim_json_create;
*/
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);
}
#include <assert.h>
#include <com_err.h>
+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)
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
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);
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);
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) {
goto out;
/* XXX should copy */
- krb5_init_ets(p);
+ _krb5_init_ets(p);
cc_ops_copy(p, context);
kt_ops_copy(p, 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);
hx509_context_free(&context->hx509ctx);
#endif
- HEIMDAL_MUTEX_destroy(&context->mutex);
if (context->flags & KRB5_CTX_F_SOCKETS_INITIALIZED) {
rk_SOCK_EXIT();
}
}
#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
*/
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
- }
}
/**
if(!p)
return ENOMEM;
- HEIMDAL_MUTEX_init(&p->mutex);
-
*context = p;
return 0;
}
{
krb5_clear_error_message(context);
- HEIMDAL_MUTEX_destroy(&context->mutex);
if (context->flags & KRB5_CTX_F_SOCKETS_INITIALIZED) {
rk_SOCK_EXIT();
}
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 {
--- /dev/null
+/*
+ * 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);
+}
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;
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 */