krb5 commit: Pass through module errors when preauthenticating

Greg Hudson ghudson at MIT.EDU
Thu Dec 20 00:30:56 EST 2012


https://github.com/krb5/krb5/commit/632260bd1fccfb420f0827b59c85c329203eafc9
commit 632260bd1fccfb420f0827b59c85c329203eafc9
Author: Greg Hudson <ghudson at mit.edu>
Date:   Sun Oct 28 11:31:37 2012 -0400

    Pass through module errors when preauthenticating
    
    If we are responding to a KDC_ERR_PREAUTH_REQUIRED and cannot
    preauthenticate, report the error from the first real preauth type we
    tried.
    
    k5_preauth() now accepts a boolean input indicating that it must
    succeed on a real preauth type, instead of returning a boolean saying
    whether or not it did.
    
    ticket: 7517 (new)

 src/lib/krb5/krb/get_in_tkt.c |    9 +++------
 src/lib/krb5/krb/int-proto.h  |    2 +-
 src/lib/krb5/krb/preauth2.c   |   33 ++++++++++++++++++++++-----------
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 377773e..3bf1b3a 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1219,7 +1219,6 @@ init_creds_step_request(krb5_context context,
                         krb5_data *out)
 {
     krb5_error_code code;
-    krb5_boolean got_real;
     char random_buf[4];
     krb5_data random_data;
 
@@ -1267,9 +1266,7 @@ init_creds_step_request(krb5_context context,
                           ctx->inner_request_body,
                           ctx->encoded_previous_request, ctx->preauth_to_use,
                           ctx->prompter, ctx->prompter_data,
-                          &ctx->request->padata, &got_real);
-        if (code == 0 && !got_real && ctx->preauth_required)
-            code = KRB5_PREAUTH_FAILED;
+                          ctx->preauth_required, &ctx->request->padata);
         if (code != 0)
             goto cleanup;
     } else {
@@ -1419,7 +1416,7 @@ init_creds_step_reply(krb5_context context,
     int canon_flag = 0;
     krb5_keyblock *strengthen_key = NULL;
     krb5_keyblock encrypting_key;
-    krb5_boolean fast_avail, got_real;
+    krb5_boolean fast_avail;
 
     encrypting_key.length = 0;
     encrypting_key.contents = NULL;
@@ -1535,7 +1532,7 @@ init_creds_step_reply(krb5_context context,
     code = k5_preauth(context, ctx->opte, &ctx->preauth_rock, ctx->request,
                       ctx->inner_request_body, ctx->encoded_previous_request,
                       ctx->reply->padata, ctx->prompter, ctx->prompter_data,
-                      &kdc_padata, &got_real);
+                      FALSE, &kdc_padata);
     if (code != 0)
         goto cleanup;
 
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
index 12bee33..ca534cd 100644
--- a/src/lib/krb5/krb/int-proto.h
+++ b/src/lib/krb5/krb/int-proto.h
@@ -208,7 +208,7 @@ k5_preauth(krb5_context context, krb5_gic_opt_ext *opte,
            krb5_clpreauth_rock rock, krb5_kdc_req *req,
            krb5_data *req_body, krb5_data *prev_req, krb5_pa_data **in_padata,
            krb5_prompter_fct prompter, void *prompter_data,
-           krb5_pa_data ***padata_out, krb5_boolean *got_real_out);
+           krb5_boolean must_preauth, krb5_pa_data ***padata_out);
 
 krb5_error_code
 k5_preauth_tryagain(krb5_context context, krb5_gic_opt_ext *opte,
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index be560b2..a06233c 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -580,10 +580,11 @@ process_pa_data(krb5_context context, krb5_get_init_creds_opt *opt,
                 krb5_clpreauth_rock rock, krb5_kdc_req *req,
                 krb5_data *req_body, krb5_data *prev_req,
                 krb5_pa_data **in_pa_list, krb5_prompter_fct prompter,
-                void *prompter_data, krb5_pa_data ***out_pa_list,
-                int *out_pa_list_size, krb5_boolean *got_real_out)
+                void *prompter_data, krb5_boolean must_preauth,
+                krb5_pa_data ***out_pa_list, int *out_pa_list_size)
 {
     struct krb5_preauth_context_st *pctx = context->preauth_context;
+    struct errinfo save = EMPTY_ERRINFO;
     krb5_pa_data *pa, **pa_ptr, **mod_pa;
     krb5_error_code ret;
     clpreauth_handle h;
@@ -620,20 +621,31 @@ process_pa_data(krb5_context context, krb5_get_init_creds_opt *opt,
                 ret = grow_pa_list(out_pa_list, out_pa_list_size, mod_pa, i);
                 if (ret) {
                     krb5_free_pa_data(context, mod_pa);
-                    return ret;
+                    goto cleanup;
                 }
                 free(mod_pa);
             }
             if (ret == 0 && real) {
-                /* Record which real padata type we answered. */
+                /* Stop now and record which real padata type we answered. */
                 if (rock->selected_preauth_type != NULL)
                     *rock->selected_preauth_type = pa->pa_type;
-                *got_real_out = TRUE;
-                break;
+                goto cleanup;
+            } else if (real && save.code == 0) {
+                /* Save the first error we get from a real preauth type. */
+                k5_save_ctx_error(context, ret, &save);
             }
         }
     }
-    return 0;
+
+    if (must_preauth) {
+        /* No real preauth types succeeded and we needed to preauthenticate. */
+        ret = (save.code != 0) ? k5_restore_ctx_error(context, &save) :
+            KRB5_PREAUTH_FAILED;
+    }
+
+cleanup:
+    k5_clear_error(&save);
+    return ret;
 }
 
 static inline krb5_data
@@ -915,7 +927,7 @@ k5_preauth(krb5_context context, krb5_gic_opt_ext *opte,
            krb5_clpreauth_rock rock, krb5_kdc_req *req,
            krb5_data *req_body, krb5_data *prev_req, krb5_pa_data **in_padata,
            krb5_prompter_fct prompter, void *prompter_data,
-           krb5_pa_data ***padata_out, krb5_boolean *got_real_out)
+           krb5_boolean must_preauth, krb5_pa_data ***padata_out)
 {
     int out_pa_list_size = 0;
     krb5_pa_data **out_pa_list = NULL;
@@ -924,7 +936,6 @@ k5_preauth(krb5_context context, krb5_gic_opt_ext *opte,
     krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)opte;
 
     *padata_out = NULL;
-    *got_real_out = FALSE;
 
     if (in_padata == NULL)
         return 0;
@@ -973,8 +984,8 @@ k5_preauth(krb5_context context, krb5_gic_opt_ext *opte,
     }
 
     ret = process_pa_data(context, opt, rock, req, req_body, prev_req,
-                          in_padata, prompter, prompter_data, &out_pa_list,
-                          &out_pa_list_size, got_real_out);
+                          in_padata, prompter, prompter_data, must_preauth,
+                          &out_pa_list, &out_pa_list_size);
     if (ret)
         goto error;
 


More information about the cvs-krb5 mailing list