aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2012-10-28 11:31:37 -0400
committerGreg Hudson <ghudson@mit.edu>2012-12-20 00:24:32 -0500
commit632260bd1fccfb420f0827b59c85c329203eafc9 (patch)
tree9260574df3a0f1e6ee347836b6f8486c1cfcd3be /src
parentf730fddc59265ee1621ec39f847ea047116a2127 (diff)
downloadkrb5-632260bd1fccfb420f0827b59c85c329203eafc9.zip
krb5-632260bd1fccfb420f0827b59c85c329203eafc9.tar.gz
krb5-632260bd1fccfb420f0827b59c85c329203eafc9.tar.bz2
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)
Diffstat (limited to 'src')
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c9
-rw-r--r--src/lib/krb5/krb/int-proto.h2
-rw-r--r--src/lib/krb5/krb/preauth2.c33
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;