[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Kaserver interface sometimes fails on requests with small lifetimes




Hi, I ran into a problem with the Heimdal's kdc kaserver interface. On some
clients, klog requests with small lifetimes were sometimes failing with
the following error:

$ klog -lifetime 00:00:01
Password:
Unable to authenticate to AFS because AuthServer returned incorrect response.
$

I first noticed this when some client's AFS PAM module was sometimes failing to
verify AFS user's passwords if the 'use_klog' option was set (telling the
module to exec off a klog binary) without the 'set_token' option (thus the
short lifetime requests).

When talking to an AFS kaserver, I wasn't getting this error, instead
a token with a 5 minute lifetime was obtained. After looking into the
Heimdal code, I found that due to slight time skew between client and
server (although not enough to produce a KACLOCKSKEW error) was causing
this. It seems as though the max_time is computed by taking the requested
end time and subtracting the kdc's time, but if the time skew is
greater than the requested end time (but not enough to cause a KACLOCKSKEW
error), the max_time can be non-postive, which was causing my problems.

I put in a check to make sure that the initial computation of max_time was
never less than one and it seemed to clear up my problems. Another approach
might be to get the initial max_time from subtracting the challenge time (or
start time) from the end time - not sure which is better.  Here is the
diff for the first approach:

--- kaserver.c.dist     Mon Sep  9 10:03:02 2002
+++ kaserver.c  Tue Oct 15 16:08:03 2002
@@ -476,7 +476,10 @@
     }

     /* life */
-    max_life = end_time - kdc_time;
+    /* end_time - kdc_time can sometimes be non-positive due to slight
+       time skew between client and server. Let's make sure it is postive */
+    if ( (max_life = end_time - kdc_time) < 1 )
+       max_life = 1;
     if (client_entry->max_life)
        max_life = min(max_life, *client_entry->max_life);
     if (server_entry->max_life)
@@ -709,7 +712,10 @@
     }

     /* life */
-    max_life = end_time - kdc_time;
+    /* end_time - kdc_time can sometimes be non-positive due to slight
+       time skew between client and server. Let's make sure it is postive */
+    if ( (max_life = end_time - kdc_time) < 1 )
+       max_life = 1;
     if (krbtgt_entry->max_life)
        max_life = min(max_life, *krbtgt_entry->max_life);
     if (server_entry->max_life)


Anyone see any problem in doing this or a better solution to my problem?

Thanks,

John