Ticket lifetimes > 10 hrs?

Ben Cox cox-work at djehuti.com
Fri Nov 15 16:09:42 EST 2002


On Fri, 2002-11-15 at 12:19, Ken Hornstein wrote:
> >> - The MIT client side library wont get you a new service ticket if you
> >>   have one already cached, even if it's expired.
> >
> >Is this just a matter of someone leaving out a KRB5_TC_MATCH_TIMES flag
> >somewhere?
> 
> TC_MATCH_TIMES is already set in my reading of the code, and it's been
> in there for a while.  But you have to fill in endtime in the source
> credentials, and I guess in most of the cases the application code
> doesn't.  All the code I've ever seen just memset(0,...)s out the whole
> creds structure that it passes in, and just fills in things like client
> and server principal.

I just did some testing with this.  You're right; TC_MATCH_TIMES is
there but if the entdime is 0, then it doesn't help.

  * krb5_mk_req() can't ever do the right thing if you have an
    expired service ticket in your ccache, since it always
    passes in source creds with endtime=0 (via memset).  If you
    have an expired service ticket in your ccache, this will try
    (and fail) to use it.  Notice that a caller of krb5_mk_req
    doesn't even have the option of doing the right thing here.
    (The caller could use krb5_mk_req_extended instead, but then
    you have to call krb5_get_credentials and fall into the next
    pit:)

  * krb5_get_credentials can be made to do the right thing, but
    only if you pass in source creds with an endtime that's in
    the future.  If you pass in source creds with an endtime of
    "now", and you have an expired service ticket in your ccache,
    then it will get you a new one --- but with the endtime set
    to now.  If you take "now" and add some time, it will get
    you one with however much time you asked for, gated by the
    various policies and your TGT lifetime, etc.  (I.e., if my
    service principal's maxlife is 5 minutes and I ask for "now
    plus an hour", it does the right thing and gets me a ticket
    that's good for 5 minutes.  I could see an argument for it
    failing outright, too, but that seems less useful.)

If one says "no problem, just use krb5_get_credentials and pass in an
endtime that's a few seconds into the future" (i.e., just long enough to
do the current operation) then I disagree.  First, since it will really
go ahead and get you a ticket that's good only a few seconds into the
future, that means that the client app is constantly contacting the KDC
to get a fresh service ticket every time it wants to do something. 
Second, since krb5_get_credentials doesn't replace an existing expired
ticket in the ccache (it leaves the litter), the ccache file can get
quite large.  And third, it doesn't help callers out there that are
coded to just memset the input cred structure and fill in the
principals.  (Like krb5_mk_req().)

I think the fix is to change krb5_get_credentials_core to use "now" (as
obtained from krb5_timeofday, of course) as the endtime in the match
cred (mcred->times.endtime in the code) if the input credential's
endtime is 0 (and honor the input cred's endtime if it's not 0).  Quick
testing with that modification seems to do the intuitively-right thing.

This would mean, of course, that if anyone was using get_credentials and
was passing in a cred with an endtime of 0 because they really *did*
want to get an expired cred from their ccache, it would no longer work. 
Since that seems like a pretty contrived example, I doubt it's
important.  But if it is, then we could gate the new behavior on the
"options" flags (but again, that doesn't help fix existing code).

I have attached a tiny patch (unified diff) against 1.2.6 that
implements the above change.

-- Ben

-------------- next part --------------
--- get_creds.c.orig	2002-02-28 12:08:29.000000000 -0500
+++ get_creds.c	2002-11-15 16:06:36.000000000 -0500
@@ -61,7 +61,13 @@
 
     memset((char *)mcreds, 0, sizeof(krb5_creds));
     mcreds->magic = KV5M_CREDS;
-    mcreds->times.endtime = in_creds->times.endtime;
+    if (in_creds->times.endtime != 0) {
+	mcreds->times.endtime = in_creds->times.endtime;
+    } else {
+	krb5_error_code retval;
+	retval = krb5_timeofday(context, &mcreds->times.endtime);
+	if (retval != 0) return retval;
+    }
 #ifdef HAVE_C_STRUCTURE_ASSIGNMENT
     mcreds->keyblock = in_creds->keyblock;
 #else


More information about the Kerberos mailing list