krb5 commit: Add err_fmt profile parameter
Greg Hudson
ghudson at mit.edu
Sun Dec 7 23:35:30 EST 2014
https://github.com/krb5/krb5/commit/8c0b9a839fdf8ef1485a85300d82e41654864719
commit 8c0b9a839fdf8ef1485a85300d82e41654864719
Author: Nicolas Williams <nico at cryptonector.com>
Date: Wed Nov 12 15:50:53 2014 -0600
Add err_fmt profile parameter
Support the err_fmt relation in [libdefaults] which allows custom
error message formatting.
[ghudson at mit.edu: maintain alphabetical order in documentation and
reword docs; simplify err_fmt_fmt; expand commit message]
ticket: 8047 (new)
doc/admin/conf_files/krb5_conf.rst | 6 ++++-
src/include/k5-int.h | 2 +
src/lib/krb5/krb/copy_ctx.c | 3 ++
src/lib/krb5/krb/init_ctx.c | 5 ++++
src/lib/krb5/krb/kerrs.c | 44 +++++++++++++++++++++++++++++++++++-
5 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index 6636c2f..3b51905 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -206,6 +206,11 @@ The libdefaults section may contain any of the following relations:
data), and anything the fake KDC sends will not be trusted without
verification using some secret that it won't know.
+**err_fmt**
+ This relation allows for custom error message formatting. If a
+ value is set, error messages will be formatted by substituting a
+ normal error message for %M and an error code for %C in the value.
+
**extra_addresses**
This allows a computer to use multiple local addresses, in order
to allow Kerberos to work in a network that uses NATs while still
@@ -363,7 +368,6 @@ The libdefaults section may contain any of the following relations:
credentials will fail if the client machine does not have a
keytab. The default value is false.
-
.. _realms:
[realms]
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 0970af7..a1ea25a 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -211,6 +211,7 @@ typedef unsigned char u_char;
#define KRB5_CONF_DNS_LOOKUP_REALM "dns_lookup_realm"
#define KRB5_CONF_DOMAIN_REALM "domain_realm"
#define KRB5_CONF_ENABLE_ONLY "enable_only"
+#define KRB5_CONF_ERR_FMT "err_fmt"
#define KRB5_CONF_EXTRA_ADDRESSES "extra_addresses"
#define KRB5_CONF_FORWARDABLE "forwardable"
#define KRB5_CONF_HOST_BASED_SERVICES "host_based_services"
@@ -1187,6 +1188,7 @@ struct _krb5_context {
/* error detail info */
struct errinfo err;
+ char *err_fmt;
/* For Sun iprop code; does this really have to be here? */
struct _kdb_log_context *kdblog_context;
diff --git a/src/lib/krb5/krb/copy_ctx.c b/src/lib/krb5/krb/copy_ctx.c
index 322c288..c09965e 100644
--- a/src/lib/krb5/krb/copy_ctx.c
+++ b/src/lib/krb5/krb/copy_ctx.c
@@ -85,6 +85,9 @@ krb5_copy_context(krb5_context ctx, krb5_context *nctx_out)
nctx->kdblog_context = NULL;
nctx->trace_callback = NULL;
nctx->trace_callback_data = NULL;
+ nctx->err_fmt = NULL;
+ if (ctx->err_fmt != NULL)
+ nctx->err_fmt = strdup(ctx->err_fmt); /* It's OK if this fails */
nctx->plugin_base_dir = NULL;
nctx->os_context.default_ccname = NULL;
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index 6548f36..a393627 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -281,6 +281,10 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
ctx->prompt_types = 0;
ctx->use_conf_ktypes = 0;
ctx->udp_pref_limit = -1;
+
+ /* It's OK if this fails */
+ (void)profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS,
+ KRB5_CONF_ERR_FMT, NULL, NULL, &ctx->err_fmt);
*context_out = ctx;
return 0;
@@ -308,6 +312,7 @@ krb5_free_context(krb5_context ctx)
}
krb5_clear_error_message(ctx);
+ free(ctx->err_fmt);
#ifndef DISABLE_TRACING
if (ctx->trace_callback)
diff --git a/src/lib/krb5/krb/kerrs.c b/src/lib/krb5/krb/kerrs.c
index 9e26335..0146d9a 100644
--- a/src/lib/krb5/krb/kerrs.c
+++ b/src/lib/krb5/krb/kerrs.c
@@ -135,16 +135,58 @@ krb5_copy_error_message(krb5_context dest_ctx, krb5_context src_ctx)
}
}
+/* Re-format msg using the format string err_fmt. Return an allocated result,
+ * or NULL if err_fmt is NULL or on allocation failure. */
+static char *
+err_fmt_fmt(const char *err_fmt, long code, const char *msg)
+{
+ struct k5buf buf;
+ const char *p, *s;
+
+ if (err_fmt == NULL)
+ return NULL;
+
+ k5_buf_init_dynamic(&buf);
+
+ s = err_fmt;
+ while ((p = strchr(s, '%')) != NULL) {
+ k5_buf_add_len(&buf, s, p - s);
+ s = p;
+ if (p[1] == '\0')
+ break;
+ else if (p[1] == 'M')
+ k5_buf_add(&buf, msg);
+ else if (p[1] == 'C')
+ k5_buf_add_fmt(&buf, "%ld", code);
+ else if (p[1] == '%')
+ k5_buf_add(&buf, "%");
+ else
+ k5_buf_add_fmt(&buf, "%%%c", p[1]);
+ s += 2;
+ }
+ k5_buf_add(&buf, s); /* Remainder after last token */
+ return buf.data;
+}
+
const char * KRB5_CALLCONV
krb5_get_error_message(krb5_context ctx, krb5_error_code code)
{
+ const char *std, *custom;
+
#ifdef DEBUG
if (ERROR_MESSAGE_DEBUG())
fprintf(stderr, "krb5_get_error_message(%p, %ld)\n", ctx, (long)code);
#endif
if (ctx == NULL)
return error_message(code);
- return k5_get_error(&ctx->err, code);
+
+ std = k5_get_error(&ctx->err, code);
+ custom = err_fmt_fmt(ctx->err_fmt, code, std);
+ if (custom != NULL) {
+ free((char *)std);
+ return custom;
+ }
+ return std;
}
void KRB5_CALLCONV
More information about the cvs-krb5
mailing list