From 7a9917db6b72d47cd19fb54dc34fc409353a3ea4 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 9 Jan 2017 11:44:29 -0500
Subject: [PATCH] Document and check init_creds context requirement
To ensure that the same clpreauth plugin modules and moddata pointers
are used for each step of an initial creds operation, the caller must
use the same library context for krb5_init_creds_init(),
krb5_init_creds_step(), and krb5_init_creds_free(). Document and
enforce this requirement.
ticket: 7877
(cherry picked from commit c4beb35c9ac0711ef650abc4f1e44a4c82d5f3d0)
---
src/include/krb5/krb5.hin | 13 +++++++++++++
src/lib/krb5/krb/get_in_tkt.c | 6 +++++-
src/lib/krb5/krb/int-proto.h | 3 +++
src/lib/krb5/krb/preauth2.c | 13 +++++++++++++
4 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index 53ad85384..28557659e 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -7321,6 +7321,9 @@ typedef struct _krb5_init_creds_context *krb5_init_creds_context;
*
* @param [in] context Library context
* @param [in] ctx Initial credentials context
+ *
+ * @a context must be the same as the one passed to krb5_init_creds_init() for
+ * this initial credentials context.
*/
void KRB5_CALLCONV
krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx);
@@ -7335,6 +7338,9 @@ krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx);
* krb5_init_creds_init(). On successful return, the credentials can be
* retrieved with krb5_init_creds_get_creds().
*
+ * @a context must be the same as the one passed to krb5_init_creds_init() for
+ * this initial credentials context.
+ *
* @retval 0 Success; otherwise - Kerberos error codes
*/
krb5_error_code KRB5_CALLCONV
@@ -7385,6 +7391,10 @@ krb5_init_creds_get_error(krb5_context context, krb5_init_creds_context ctx,
* This function creates a new context for acquiring initial credentials. Use
* krb5_init_creds_free() to free @a ctx when it is no longer needed.
*
+ * Any subsequent calls to krb5_init_creds_step(), krb5_init_creds_get(), or
+ * krb5_init_creds_free() for this initial credentials context must use the
+ * same @a context argument as the one passed to this function.
+ *
* @retval 0 Success; otherwise - Kerberos error codes
*/
krb5_error_code KRB5_CALLCONV
@@ -7434,6 +7444,9 @@ krb5_init_creds_set_keytab(krb5_context context, krb5_init_creds_context ctx,
* transmit the next request using TCP rather than UDP. If this function
* returns any other error, the initial credential exchange has failed.
*
+ * @a context must be the same as the one passed to krb5_init_creds_init() for
+ * this initial credentials context.
+ *
* @retval 0 Success; otherwise - Kerberos error codes
*/
krb5_error_code KRB5_CALLCONV
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 80f5e1870..52e07bb67 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1667,7 +1667,7 @@ krb5_init_creds_step(krb5_context context,
krb5_data *realm,
unsigned int *flags)
{
- krb5_error_code code = 0, code2;
+ krb5_error_code code, code2;
*flags = 0;
@@ -1680,6 +1680,10 @@ krb5_init_creds_step(krb5_context context,
if (ctx->complete)
return EINVAL;
+ code = k5_preauth_check_context(context, ctx);
+ if (code)
+ return code;
+
if (in->length != 0) {
code = init_creds_step_reply(context, ctx, in);
if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG) {
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
index f1667c238..628f0baa8 100644
--- a/src/lib/krb5/krb/int-proto.h
+++ b/src/lib/krb5/krb/int-proto.h
@@ -208,6 +208,9 @@ void
k5_preauth_request_context_fini(krb5_context context,
krb5_init_creds_context ctx);
+krb5_error_code
+k5_preauth_check_context(krb5_context context, krb5_init_creds_context ctx);
+
krb5_error_code
k5_response_items_new(k5_response_items **ri_out);
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index 9a178f4e3..9c5d6eaa9 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -296,6 +296,19 @@ k5_preauth_request_context_fini(krb5_context context,
ctx->preauth_reqctx = NULL;
}
+krb5_error_code
+k5_preauth_check_context(krb5_context context, krb5_init_creds_context ctx)
+{
+ krb5_preauth_req_context reqctx = ctx->preauth_reqctx;
+
+ if (reqctx != NULL && reqctx->orig_context != context) {
+ k5_setmsg(context, EINVAL,
+ _("krb5_init_creds calls must use same library context"));
+ return EINVAL;
+ }
+ return 0;
+}
+
/* Return 1 if pa_type is a real preauthentication mechanism according to the
* module h. Return 0 if it is not. */
static int