krb5_data *out)
{
krb5_error_code code;
- krb5_boolean got_real;
char random_buf[4];
krb5_data random_data;
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 {
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;
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;
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,
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;
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
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;
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;
}
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;