diff options
author | Russ Allbery <rra@stanford.edu> | 2008-04-24 01:17:48 +0000 |
---|---|---|
committer | Russ Allbery <rra@stanford.edu> | 2008-04-24 01:17:48 +0000 |
commit | 23b711ebacb2371915bfa4d9e0d386fa4e7cb35e (patch) | |
tree | 5041a42d5d48526322d827ef0e956f061e8064cc /util/messages-krb5.c | |
parent | d509c915c9c3adc3b61eae84bdca0b612f25df96 (diff) |
Switch to messages-krb5 in util instead of the one built in the client
library and start the transition of coding style.
Diffstat (limited to 'util/messages-krb5.c')
-rw-r--r-- | util/messages-krb5.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/util/messages-krb5.c b/util/messages-krb5.c new file mode 100644 index 0000000..314f96a --- /dev/null +++ b/util/messages-krb5.c @@ -0,0 +1,119 @@ +/* $Id$ + * + * Error handling for Kerberos v5. + * + * Provides versions of die and warn that take a Kerberos context and a + * Kerberos error code and append the Kerberos error message to the provided + * formatted message. + * + * Written by Russ Allbery <rra@stanford.edu> + * Copyright 2006, 2007, 2008 + * Board of Trustees, Leland Stanford Jr. University + * + * See LICENSE for licensing terms. + */ + +#include <config.h> +#include <system.h> + +#include <krb5.h> +#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) && !defined(HAVE_KRB5_GET_ERR_TEXT) +# if defined(HAVE_IBM_SVC_KRB5_SVC_H) +# include <ibm_svc/krb5_svc.h> +# elif defined(HAVE_ET_COM_ERR_H) +# include <et/com_err.h> +# else +# include <com_err.h> +# endif +#endif + +#include <util/util.h> + +/* + * This string is returned for unknown error messages. We use a static + * variable so that we can be sure not to free it. + */ +static const char error_unknown[] = "unknown error"; + + +/* + * Given a Kerberos error code, return the corresponding error. Prefer the + * Kerberos interface if available since it will provide context-specific + * error information, whereas the error_message() call will only provide a + * fixed message. + */ +static const char * +get_error(krb5_context ctx UNUSED, krb5_error_code code) +{ + const char *msg = NULL; + +#if defined(HAVE_KRB5_GET_ERROR_MESSAGE) + msg = krb5_get_error_message(ctx, code); +#elif defined(HAVE_KRB5_GET_ERR_TEXT) + msg = krb5_get_err_text(ctx, code); +#elif defined(HAVE_KRB5_SVC_GET_MSG) + krb5_svc_get_msg(code, &msg); +#else + msg = error_message(code); +#endif + if (msg == NULL) + return error_unknown; + else + return msg; +} + + +/* + * Free an error string if necessary. + */ +static void +free_error(krb5_context ctx UNUSED, const char *msg) +{ + if (msg == error_unknown) + return; +#if defined(HAVE_KRB5_FREE_ERROR_MESSAGE) + krb5_free_error_message(ctx, msg); +#elif defined(HAVE_KRB5_SVC_GET_MSG) + krb5_free_string((char *) msg); +#endif +} + + +/* + * Report a Kerberos error and exit. + */ +void +die_krb5(krb5_context ctx, krb5_error_code code, const char *format, ...) +{ + const char *k5_msg = NULL; + char *message; + va_list args; + + k5_msg = get_error(ctx, code); + va_start(args, format); + if (xvasprintf(&message, format, args) < 0) + die("internal error: unable to format error message"); + va_end(args); + die("%s: %s", message, k5_msg); +} + + +/* + * Report a Kerberos error. + */ +void +warn_krb5(krb5_context ctx, krb5_error_code code, const char *format, ...) +{ + const char *k5_msg = NULL; + char *message; + va_list args; + + k5_msg = get_error(ctx, code); + va_start(args, format); + if (xvasprintf(&message, format, args) < 0) + die("internal error: unable to format error message"); + va_end(args); + warn("%s: %s", message, k5_msg); + free(message); + free_error(ctx, k5_msg); +} |