]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Pass through module errors when preauthenticating
authorGreg Hudson <ghudson@mit.edu>
Sun, 28 Oct 2012 15:31:37 +0000 (11:31 -0400)
committerGreg Hudson <ghudson@mit.edu>
Thu, 20 Dec 2012 05:24:32 +0000 (00:24 -0500)
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
src/lib/krb5/krb/int-proto.h
src/lib/krb5/krb/preauth2.c

index 377773e1c2dfef775df516cb0ff3b5ebeaf6cc8a..3bf1b3a1c3add0bad670cb9b535aaae3998582b7 100644 (file)
@@ -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;
 
index 12bee33981a9b61b22ec63d378c0f6eed7cae50a..ca534cdcbfe4150b20442e918fac384714bda464 100644 (file)
@@ -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,
index be560b2c46a5432363ccb0908126ebc37067a5ed..a06233c27d268d548ecef675c6642148da9cbb08 100644 (file)
@@ -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;