[OpenAFS] Bogus ticket lifetimes on Windows client

Jeffrey Hutzelman jhutz@cmu.edu
Wed, 16 Jun 2004 14:04:05 -0400

On Wednesday, June 16, 2004 11:40:57 -0400 Evan Knop 
<jrh-afs@lore.dartmouth.edu> wrote:

> I'm having problems with the OpenAFS windows client and krb524d.  (I
> believe - I'm presuming this based on symptoms and the klog
> documentation).

Sounds likely.  The Kerberos V4 protocol represents lifetimes as an 8-bit 
integer.  The traditional interpretation of this value is in units of 5 
minutes.  For various reasons the maximum usable value with this 
interpretation is 127, which gives a lifetime of 10 hours and 35 minutes.

> If the max. lifetime for AFS tokens is less than 10:40, the results on
> linux and windows are the same.

Yup; that conrresponds to values 0x01-0x7f, for which everyone agrees on 

> If the max. lifetime is greater than 10:40 but less than about 15 hours,
> the Windows client gets progressively longer tickets (up to about 2-4
> weeks!), following the schedule described for the intervals in the AFS
> klog manpage.  The linux client, for the same token lifetimes, gets
> tokens of the correct length.

By the traditional interpretation, values in the range 0x80-0xBF would 
correspond to lifetimes up to 15 hours and 55 minutes.  AFS, however, uses 
an exponential table to interpret these values, allowing lifetimes ranging 
from 10:40 up to 720 hours, or 30 days.

> If the max. lifetime is greater than a certain amount (not sure exactly
> what - 24 hours is too much), then the Windows client will decide that
> its' tokens expire January 1, 1601.  The linux clients (through fakeka)
> continue to work fine.

By the traditional interpretation, values in the range 0xC0-0xFE would 
correspond to lifetimes up to 21 hours, 10 minutes.  Under AFS's 
interpretation, these values are reserved.

The value 0xFF means "never expires".

> My hypothesis is that the Windows client is speaking to the krb524d
> (750/udp) on running on the AFS hosts, and interpreting the kerberos-4
> response to this request as if it were a kaserver response (with the odd
> "scaling").  Linux is speaking to the fakeka (7004/udp), which is doing
> the scaling for the client, so the result comes back with the correct (or
> almost-correct) time on the other side.

Kerberos V5 tickets (and principals, in the KDC) can have more or less 
arbitrary lifetimes.  However, the same is not true of Kerberos V4 tickets. 
So when krb524d or fakeka constructs a ticket, it must coerce the lifetime 
it has to a value which will can be represented by Kerberos V4.  The 
resulting value appears in the encryped part of the ticket, where it will 
be interpreted by the application server.  In the case of AFS, this value 
will _always_ be interpreted by the server according to AFS's rules, which 
allow for longer lifetimes than the traditional interpretation (up to 30 

In addition, the lifetime is included as part of the server's reply, so the 
client will know for how long the tickets are good.  In the case of the 
kaserver protocol, this takes the form of a 32-bit timestamp which is when 
the tickets will expire.  In the case of krb524d, it is the same 8-bit 
value contained in the encrypted part of the ticket.  Again, in AFS, this 
value will _always_ be interpreted by the server according to AFS's rules.

So now you have a lifetime in the ticket, and a lifetime that the client 
knows.  In the case of Linux, the time your client reports is right because 
it is being given a correct time by fakeka, which corresponds to the 
lifetime actually contained in the ticket.  In the case of Windows, the 
time your client reports is _also_ right (well, for lifetimes up to 0xBF), 
because it is being interpreted according to the same rules that the server 
will use.

What this really means is that your windows clients are actually obtaining 
tickets with longer or invalid lifetimes.  The reason for this is simple -- 
krb524d is encoding _the wrong value_.

Recall that both fakeka and krb524d have to bash the actual lifetime into 
one that will fit in the krb4 lifetime code.  They do this by picking the 
largest representable lifetime which is not larger than the actual lifetime 
to be granted (for fakeka, this is computed based on the expiration time of 
the TGT and on the lifetimes of the principals involved; for krb524d, it is 
the remaining life of the krb5 ticket being converted).

As long as the lifetime is less than 10:40, everything is fine.
However, if the lifetime is _larger_ than 10:40, the MIT krb524d applies 
the naive interpretation anyway -- it divides the lifetime by 5 minutes, 
and encodes that result.  I'm pretty sure it will check to be sure it 
doesn't overflow 0xFE, but that's about it.  So now both the AFS server and 
client are going to apply a different (longer) lifetime to that ticket than 
the krb524d intended -- possibly _much_ longer.

There are a couple of possible solutions...

> 1) it is speaking to a Kerberos-4 server, rather than a kaserver

Not relevant.  The problem here is that krb524d (or the krb4 emulation code 
in the KDC, depending on whether you're using klog or aklog) is putting the 
wrong lifetime into the ticket.

> 2) to request a ticket no longer than a certain time (e.g. 10 hours)?

I don't believe there's a way to configure the client not to request a 
ticket with a longer lifetime, but you _can_ configure the KDC not to 
_issue_ such a ticket.  Simply set the max ticket lifetime on the AFS 
service principal to 10 hours.

A third option is to patch the KDC so that it uses the AFS lifetime 
computation when constructing krb4 tickets.  Many sites have done this, 
with quite good results.  Unfortunately, we're not running MIT KDC's any 
more, so I don't have a patch handy to give to you.

-- Jeffrey T. Hutzelman (N3NHS) <jhutz+@cmu.edu>
   Sr. Research Systems Programmer
   School of Computer Science - Research Computing Facility
   Carnegie Mellon University - Pittsburgh, PA