Skip Menu |

Subject: Re: Ticket lifetimes > 10 hrs?
From: Ben Cox <>
To: Ken Hornstein <>
Date: 15 Nov 2002 16:09:42 -0500
Download (untitled) / with headers
text/plain 3.5KiB
On Fri, 2002-11-15 at 12:19, Ken Hornstein wrote:
Show quoted text
> >> - 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

* 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
--- 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;
+ }
mcreds->keyblock = in_creds->keyblock;
Subject: CVS Commit
Patch to get new service tickets in preference to using expired
service tickets in krb5_get_credentials.

To generate a diff of this commit:

cvs diff -r5.365 -r5.366 krb5/src/lib/krb5/krb/ChangeLog
cvs diff -r5.41 -r5.42 krb5/src/lib/krb5/krb/get_creds.c