From: Nicolas Williams Date: Wed, 12 Nov 2014 21:47:53 +0000 (-0600) Subject: Add new error message wrapping APIs X-Git-Tag: krb5-1.14-alpha1~200 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=12bf3e3f3ecd58f53d4a604e318766e4264b02c1;p=thirdparty%2Fkrb5.git Add new error message wrapping APIs Add four new public APIs for wrapping error messages: krb5_prepend_error_message, krb5_vprepend_error_message, krb5_wrap_error_message, and krb5_vwrap_error_message. The first two functions are from Heimdal and allow a prefix to be added to the existing message for a code. The latter two functions also allow the code to be changed. [ghudson@mit.edu: rename krb5_prepend_error_message2 to krb5_wrap_error_message; clarify doxygen comments and put them in the proper form; implement krb5_prepend_error_message in terms of krb5_wrap_error_message; fix leak and null context handling in krb5_wrap_error_message; rewrite commit message] ticket: 8046 (new) --- diff --git a/doc/appdev/refs/api/index.rst b/doc/appdev/refs/api/index.rst index b1a580a6aa..64774b30ef 100644 --- a/doc/appdev/refs/api/index.rst +++ b/doc/appdev/refs/api/index.rst @@ -254,6 +254,7 @@ Rarely used public interfaces krb5_pac_parse.rst krb5_pac_sign.rst krb5_pac_verify.rst + krb5_prepend_error_message.rst krb5_principal2salt.rst krb5_rd_cred.rst krb5_rd_error.rst @@ -285,7 +286,10 @@ Rarely used public interfaces krb5_verify_init_creds.rst krb5_verify_init_creds_opt_init.rst krb5_verify_init_creds_opt_set_ap_req_nofail.rst + krb5_vprepend_error_message.rst krb5_vset_error_message.rst + krb5_vwrap_error_message.rst + krb5_wrap_error_message.rst Public interfaces that should not be called directly diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin index d0cccb3bec..6f7cff4217 100644 --- a/src/include/krb5/krb5.hin +++ b/src/include/krb5/krb5.hin @@ -7785,6 +7785,85 @@ krb5_vset_error_message(krb5_context ctx, krb5_error_code code, #endif ; +/** + * Add a prefix to the message for an error code. + * + * @param [in] ctx Library context + * @param [in] code Error code + * @param [in] fmt Format string for error message prefix + * @param [in] ... printf(3) style parameters + * + * Format a message and prepend it to the current message for @a code. The + * prefix will be separated from the old message with a colon and space. + */ +void KRB5_CALLCONV_C +krb5_prepend_error_message(krb5_context ctx, krb5_error_code code, + const char *fmt, ...) +#if !defined(__cplusplus) && (__GNUC__ > 2) + __attribute__((__format__(__printf__, 3, 4))) +#endif + ; + +/** + * Add a prefix to the message for an error code using a va_list. + * + * @param [in] ctx Library context + * @param [in] code Error code + * @param [in] fmt Format string for error message prefix + * @param [in] args List of vprintf(3) style arguments + * + * This function is similar to krb5_prepend_error_message(), but uses a + * va_list instead of variadic arguments. + */ +void KRB5_CALLCONV +krb5_vprepend_error_message(krb5_context ctx, krb5_error_code code, + const char *fmt, va_list args) +#if !defined(__cplusplus) && (__GNUC__ > 2) + __attribute__((__format__(__printf__, 3, 0))) +#endif + ; + +/** + * Add a prefix to a different error code's message. + * + * @param [in] ctx Library context + * @param [in] old_code Previous error code + * @param [in] code Error code + * @param [in] fmt Format string for error message prefix + * @param [in] ... printf(3) style parameters + * + * Format a message and prepend it to the message for @a old_code. The prefix + * will be separated from the old message with a colon and space. Set the + * resulting message as the extended error message for @a code. + */ +void KRB5_CALLCONV_C +krb5_wrap_error_message(krb5_context ctx, krb5_error_code old_code, + krb5_error_code code, const char *fmt, ...) +#if !defined(__cplusplus) && (__GNUC__ > 2) + __attribute__((__format__(__printf__, 4, 5))) +#endif + ; + +/** + * Add a prefix to a different error code's message using a va_list. + * + * @param [in] ctx Library context + * @param [in] old_code Previous error code + * @param [in] code Error code + * @param [in] fmt Format string for error message prefix + * @param [in] args List of vprintf(3) style arguments + * + * This function is similar to krb5_wrap_error_message(), but uses a + * va_list instead of variadic arguments. + */ +void KRB5_CALLCONV +krb5_vwrap_error_message(krb5_context ctx, krb5_error_code old_code, + krb5_error_code code, const char *fmt, va_list args) +#if !defined(__cplusplus) && (__GNUC__ > 2) + __attribute__((__format__(__printf__, 4, 0))) +#endif + ; + /** * Copy the most recent extended error message from one context to another. * diff --git a/src/lib/krb5/krb/kerrs.c b/src/lib/krb5/krb/kerrs.c index c5d6c81010..9e263356d1 100644 --- a/src/lib/krb5/krb/kerrs.c +++ b/src/lib/krb5/krb/kerrs.c @@ -77,6 +77,50 @@ krb5_vset_error_message(krb5_context ctx, krb5_error_code code, #endif } +void KRB5_CALLCONV +krb5_prepend_error_message(krb5_context ctx, krb5_error_code code, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + krb5_vwrap_error_message(ctx, code, code, fmt, ap); + va_end(ap); +} + +void KRB5_CALLCONV +krb5_vprepend_error_message(krb5_context ctx, krb5_error_code code, + const char *fmt, va_list ap) +{ + krb5_wrap_error_message(ctx, code, code, fmt, ap); +} + +void KRB5_CALLCONV +krb5_wrap_error_message(krb5_context ctx, krb5_error_code old_code, + krb5_error_code code, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + krb5_vwrap_error_message(ctx, old_code, code, fmt, ap); + va_end(ap); +} + +void KRB5_CALLCONV +krb5_vwrap_error_message(krb5_context ctx, krb5_error_code old_code, + krb5_error_code code, const char *fmt, va_list ap) +{ + const char *prev_msg; + char *prepend; + + if (ctx == NULL || vasprintf(&prepend, fmt, ap) < 0) + return; + prev_msg = k5_get_error(&ctx->err, old_code); + k5_set_error(&ctx->err, code, "%s: %s", prepend, prev_msg); + k5_free_error(&ctx->err, prev_msg); + free(prepend); +} + /* Set the error message state of dest_ctx to that of src_ctx. */ void KRB5_CALLCONV krb5_copy_error_message(krb5_context dest_ctx, krb5_context src_ctx) diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports index b7d574c2ba..c119a34e26 100644 --- a/src/lib/krb5/libkrb5.exports +++ b/src/lib/krb5/libkrb5.exports @@ -467,6 +467,7 @@ krb5_pac_sign krb5_pac_verify krb5_parse_name krb5_parse_name_flags +krb5_prepend_error_message krb5_principal2salt krb5_principal2salt_norealm krb5_principal_compare @@ -601,8 +602,11 @@ krb5_verify_authdata_kdc_issued krb5_verify_init_creds krb5_verify_init_creds_opt_init krb5_verify_init_creds_opt_set_ap_req_nofail +krb5_vprepend_error_message krb5_vset_error_message +krb5_vwrap_error_message krb5_walk_realm_tree +krb5_wrap_error_message krb5_write_message krb5int_accessor krb5int_cc_default diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def index 3530ae157b..226155f20e 100644 --- a/src/lib/krb5_32.def +++ b/src/lib/krb5_32.def @@ -455,3 +455,9 @@ EXPORTS ; new in 1.13 k5_change_error_message_code @426 ; PRIVATE GSSAPI + +; new in 1.14 + krb5_prepend_error_message @427 + krb5_vprepend_error_message @428 + krb5_wrap_error_message @429 + krb5_vwrap_error_message @430