Fix preauth looping in krb5_get_init_creds
authorGreg Hudson <ghudson@mit.edu>
Tue, 13 Oct 2009 19:43:17 +0000 (19:43 +0000)
committerGreg Hudson <ghudson@mit.edu>
Tue, 13 Oct 2009 19:43:17 +0000 (19:43 +0000)
In 1.7, krb5_get_init_creds will continue attempting the same built-in
preauth mechanism (e.g. encrypted timestamp) until the loop counter
maxes out.  Until the preauth framework can remember not to retry
built-in mechanisms, only continue with preauth after a PREAUTH_FAILED
error resulting from optimistic preauth.

ticket: 6573
tags: pullup
target_version: 1.7.1

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22890 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/krb/get_in_tkt.c

index b4d729fbcb29c4ec57a8854ab3da9c12634eee25..a381c5c7e2072fb543863a523ee9a58588842b8d 100644 (file)
@@ -1055,6 +1055,21 @@ build_in_tkt_name(krb5_context context,
     return ret;
 }
 
+/* Decide whether to continue trying AS-REQ preauthentication. */
+static krb5_boolean
+should_continue_preauth(krb5_ui_4 error, int loopcount)
+{
+    /*
+     * Continue on PREAUTH_FAILED only on the first iteration, which
+     * would imply that we did optimistic preauth unsuccessfully.  We
+     * could continue on later iterations if the preauth framework
+     * reliably remembered what mechanisms had been tried, but
+     * currently it does not do so for built-in mechanisms.
+     */
+    return (error == KDC_ERR_PREAUTH_REQUIRED ||
+           (error == KDC_ERR_PREAUTH_FAILED && loopcount == 0));
+}
+
 krb5_error_code KRB5_CALLCONV
 krb5_get_init_creds(krb5_context context,
                    krb5_creds *creds,
@@ -1412,8 +1427,7 @@ krb5_get_init_creds(krb5_context context,
                                           &out_padata, &retry);
          if (ret !=0)
            goto cleanup;
-         if ((err_reply->error == KDC_ERR_PREAUTH_REQUIRED ||err_reply->error == KDC_ERR_PREAUTH_FAILED)
-&& retry) {
+         if (should_continue_preauth(err_reply->error, loopcount) && retry) {
                /* reset the list of preauth types to try */
                if (preauth_to_use) {
                    krb5_free_pa_data(context, preauth_to_use);