char *sname, *cname;
void *pa_context;
const krb5_fulladdr *from;
+
+ krb5_error_code preauth_err;
};
static void
if (errcode)
goto egress;
- /*
- * Final check before handing out ticket: If the client requires
- * preauthentication, verify that the proper kind of
- * preauthentication was carried out.
- */
- state->status = missing_required_preauth(state->client,
- state->server,
- &state->enc_tkt_reply);
- if (state->status) {
- errcode = KRB5KDC_ERR_PREAUTH_REQUIRED;
- get_preauth_hint_list(state->request, &state->rock, &state->e_data);
- goto egress;
- }
-
if ((errcode = validate_forwardable(state->request, *state->client,
*state->server, state->kdc_time,
&state->status))) {
}
static void
-finish_preauth(void *arg, krb5_error_code errcode)
+finish_missing_required_preauth(void *arg)
{
- struct as_req_state *state = arg;
+ struct as_req_state *state = (struct as_req_state *)arg;
- if (errcode) {
- if (errcode == KRB5KDC_ERR_PREAUTH_FAILED)
- get_preauth_hint_list(state->request, &state->rock,
- &state->e_data);
+ finish_process_as_req(state, state->preauth_err);
+}
- state->status = "PREAUTH_FAILED";
+static void
+finish_preauth(void *arg, krb5_error_code code)
+{
+ struct as_req_state *state = arg;
+ krb5_error_code real_code = code;
+
+ if (code) {
if (vague_errors)
- errcode = KRB5KRB_ERR_GENERIC;
+ code = KRB5KRB_ERR_GENERIC;
+ state->status = "PREAUTH_FAILED";
+ if (real_code == KRB5KDC_ERR_PREAUTH_FAILED) {
+ state->preauth_err = code;
+ get_preauth_hint_list(state->request, &state->rock, &state->e_data,
+ finish_missing_required_preauth, state);
+ return;
+ }
+ } else {
+ /*
+ * Final check before handing out ticket: If the client requires
+ * preauthentication, verify that the proper kind of
+ * preauthentication was carried out.
+ */
+ state->status = missing_required_preauth(state->client, state->server,
+ &state->enc_tkt_reply);
+ if (state->status) {
+ state->preauth_err = KRB5KDC_ERR_PREAUTH_REQUIRED;
+ get_preauth_hint_list(state->request, &state->rock, &state->e_data,
+ finish_missing_required_preauth, state);
+ return;
+ }
}
- finish_process_as_req(state, errcode);
+ finish_process_as_req(state, code);
}
/*ARGSUSED*/
state->request, &state->enc_tkt_reply, &state->pa_context,
&state->e_data, &state->typed_e_data, finish_preauth,
state);
- return;
- }
+ } else
+ finish_preauth(state, 0);
+ return;
errout:
finish_process_as_req(state, errcode);
void
get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock,
- krb5_pa_data ***e_data_out)
+ krb5_pa_data ***e_data_out, kdc_hint_respond_fn respond,
+ void *arg)
{
int hw_only;
preauth_system *ap;
hw_only = isflagset(rock->client->attributes, KRB5_KDB_REQUIRES_HW_AUTH);
/* Allocate two extra entries for the cookie and the terminator. */
pa_data = calloc(n_preauth_systems + 2, sizeof(krb5_pa_data *));
- if (pa_data == 0)
+ if (pa_data == 0) {
+ (*respond)(arg);
return;
+ }
pa = pa_data;
for (ap = preauth_systems; ap->type != -1; ap++) {
errout:
krb5_free_pa_data(kdc_context, pa_data);
- return;
+ (*respond)(arg);
}
/*