[28654] in CVS-changelog-for-Kerberos-V5

home help back first fref pref prev next nref lref last post

krb5 commit: Add err_fmt profile parameter

daemon@ATHENA.MIT.EDU (Greg Hudson)
Sun Dec 7 23:35:36 2014

Date: Sun, 7 Dec 2014 23:35:30 -0500
From: Greg Hudson <ghudson@mit.edu>
Message-Id: <201412080435.sB84ZUin001753@drugstore.mit.edu>
To: cvs-krb5@mit.edu
Reply-To: krbdev@mit.edu
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: cvs-krb5-bounces@mit.edu

https://github.com/krb5/krb5/commit/8c0b9a839fdf8ef1485a85300d82e41654864719
commit 8c0b9a839fdf8ef1485a85300d82e41654864719
Author: Nicolas Williams <nico@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@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
_______________________________________________
cvs-krb5 mailing list
cvs-krb5@mit.edu
https://mailman.mit.edu/mailman/listinfo/cvs-krb5

home help back first fref pref prev next nref lref last post