summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2011-10-15 15:03:17 +0000
committerGreg Hudson <ghudson@mit.edu>2011-10-15 15:03:17 +0000
commit5f8d6146a69b3afe6bf8a83d40e811c8a6d8f96b (patch)
treeed41e6d23d16f0263e8da0e0b6fe806dfc0a213d
parentd73edc318a0020baa3f4f7300bad7b1c5723168c (diff)
downloadkrb5-5f8d6146a69b3afe6bf8a83d40e811c8a6d8f96b.tar.gz
krb5-5f8d6146a69b3afe6bf8a83d40e811c8a6d8f96b.tar.xz
krb5-5f8d6146a69b3afe6bf8a83d40e811c8a6d8f96b.zip
Make get_preauth_hint_list respond via callback
From npmccallum@redhat.com with changes. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25347 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/kdc/do_as_req.c64
-rw-r--r--src/kdc/kdc_preauth.c9
-rw-r--r--src/kdc/kdc_util.h4
3 files changed, 48 insertions, 29 deletions
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index 8419a8cfc..15263b348 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -124,6 +124,8 @@ struct as_req_state {
char *sname, *cname;
void *pa_context;
const krb5_fulladdr *from;
+
+ krb5_error_code preauth_err;
};
static void
@@ -147,20 +149,6 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
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))) {
@@ -418,21 +406,46 @@ egress:
}
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*/
@@ -761,8 +774,9 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
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);
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index d0a081914..13b51e329 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -746,7 +746,8 @@ const char *missing_required_preauth(krb5_db_entry *client,
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;
@@ -758,8 +759,10 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock,
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++) {
@@ -801,7 +804,7 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_kdcpreauth_rock rock,
errout:
krb5_free_pa_data(kdc_context, pa_data);
- return;
+ (*respond)(arg);
}
/*
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index e33f606b8..a31eec568 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -166,9 +166,11 @@ const char *
missing_required_preauth (krb5_db_entry *client,
krb5_db_entry *server,
krb5_enc_tkt_part *enc_tkt_reply);
+typedef void (*kdc_hint_respond_fn)(void *arg);
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);
void
load_preauth_plugins(krb5_context context);
void