diff options
-rw-r--r-- | src/kdc/kdc_util.c | 20 | ||||
-rw-r--r-- | src/lib/krb5/krb/rd_req_dec.c | 7 |
2 files changed, 18 insertions, 9 deletions
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index 98e19375a..cd276e4a9 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -363,6 +363,10 @@ cleanup: * * This function also implements key rollover support for kvno 0 cross-realm * TGTs issued by AD. + * + * If the ticket was successfully decrypted, it will be returned in *ticket + * even if we return an error because the ticket was invalid (e.g. if it was + * expired). */ static krb5_error_code @@ -371,12 +375,14 @@ kdc_rd_ap_req(kdc_realm_t *kdc_active_realm, krb5_db_entry **server, krb5_keyblock **tgskey, krb5_ticket **ticket) { - krb5_error_code retval; + krb5_error_code retval, ret2; krb5_enctype search_enctype = apreq->ticket->enc_part.enctype; krb5_boolean match_enctype = 1; krb5_kvno kvno; size_t tries = 3; + *ticket = NULL; + /* * When we issue tickets we use the first key in the principals' highest * kvno keyset. For non-cross-realm krbtgt principals we want to only @@ -413,7 +419,17 @@ kdc_rd_ap_req(kdc_realm_t *kdc_active_realm, retval = krb5_rd_req_decoded_anyflag(kdc_context, &auth_context, apreq, apreq->ticket->server, kdc_active_realm->realm_keytab, - NULL, ticket); + NULL, NULL); + + /* If the ticket was decrypted, save it even if it didn't validate, and + * don't try any more keys. */ + if (apreq->ticket->enc_part2 != NULL) { + ret2 = krb5_copy_ticket(kdc_context, apreq->ticket, ticket); + if (!retval) + retval = ret2; + break; + } + } while (retval && apreq->ticket->enc_part.kvno == 0 && kvno-- > 1 && --tries > 0); diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c index fbfe36eb0..df5ba7a35 100644 --- a/src/lib/krb5/krb/rd_req_dec.c +++ b/src/lib/krb5/krb/rd_req_dec.c @@ -791,13 +791,6 @@ cleanup: if (permitted_etypes != NULL && permitted_etypes != (*auth_context)->permitted_etypes) free(permitted_etypes); - if (retval) { - /* only free if we're erroring out...otherwise some - applications will need the output. */ - if (req->ticket->enc_part2) - krb5_free_enc_tkt_part(context, req->ticket->enc_part2); - req->ticket->enc_part2 = NULL; - } if (check_valid_flag) krb5_free_keyblock_contents(context, &decrypt_key); |