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

Problems with kadmin date parsing in heimdal 0.6.1 on NetBSD



I'm forwarding the following from an associate since I'm on this list and he 
isn't.

cheers
mark

From: Duncan McEwan <duncan@mcs.vuw.ac.nz>
To: mark@mcs.vuw.ac.nz

When you specify a date to kadmin, it ignores any HH:MM:SS portion.  So if I
do a

   kadmin -l modify --expiration-time="2004-07-01 23:59:59" duncan

a 'kadmin -l get duncan' shows

   ...
   Principal expires: 2004-07-01 00:00:00 UTC
   ...

On examining the date parsing routines in kadmin/util.c, the routine
 str2time_t contains two calls to strptime().  The first parses "%Y-%m-%d"
 which works fine.  The 2nd attempts to parse "%H:%M:%S" but fails because
 the first character in the string it is passed is a " ".  If the format is
 changed to be " %H:%M:%S" the right thing happens.

This problem doesn't occur on a Solaris 8 system, so it could be argued that
the problem lies with NetBSD's strptime() routine.  I'm not sure about the
other BSD's or other systems. [My reading of posix.1-2003 strptime() indicates 
that the " " or a %n or %t is required to eat the leading space - mark]

Also looking at the code in that routine, it is attempting to default to the
end of the day if a time is not specified.  But that doesn't work because
the assignment of the default is done to the tm2 structure rather than tm.

The following patch fixes these two problems.

*** util.c.orig	Mon Apr 14 23:55:27 2003
--- util.c	Wed May  5 15:44:09 2004
***************
*** 195,205 ****
  	return -1;

      /* Do it on the end of the day */
!     tm2.tm_hour = 23;
!     tm2.tm_min  = 59;
!     tm2.tm_sec  = 59;

!     if(strptime (p, "%H:%M:%S", &tm2) != NULL) {
  	tm.tm_hour = tm2.tm_hour;
  	tm.tm_min  = tm2.tm_min;
  	tm.tm_sec  = tm2.tm_sec;
--- 195,205 ----
  	return -1;

      /* Do it on the end of the day */
!     tm.tm_hour = 23;
!     tm.tm_min  = 59;
!     tm.tm_sec  = 59;

!     if(strptime (p, " %H:%M:%S", &tm2) != NULL) {
  	tm.tm_hour = tm2.tm_hour;
  	tm.tm_min  = tm2.tm_min;
  	tm.tm_sec  = tm2.tm_sec;


A third related "issue" may be a misunderstanding about how this should work,
rather than a bug, but I'll describe it anyway...

The call made to tm2time() by str2time_t gets its 2nd parameter (local) as 0.

AFAICS this has the effect of telling tm2time() that the struct tm passed to
it is in UTC rather than local time.

But the decision as to whether the struct tm should be interpreted as being
in daylight savings time is made by mktime based on the local timezone.

The effect of this is that if you set an expiration date to a date that *in
your local timezone* is in daylight savings time, the resulting UTC date is
shifted by one hour.

As an example, the date I set above ended up offset by 24 hours from what
"kadmin get" showed.  If I repeat those commands, but with a date that is in
New Zealand's daylight savings time I see the following.

   kadmin -l modify --expiration-time="2004-11-01 23:59:59" duncan

   kadmin -l get duncan

   ...
   Principal expires: 2004-10-31 23:00:00 UTC
   ...

Ie: an offset of 25 hours.  This seems wrong to me.

Now I admit that my brain starts to hurt when I have to think about timezone
differences, particularly when I have to take into account daylight savings
time.  But it seems to me that either:

(a) str2time_t should call tm2time() with 1 as the last parameter, which
 would mean that the date specified to kadmin would be interpreted as being
 in your local time zone and take into account daylight savings when
 converting it to a time_t; or

(b) tm2time() should set tm.tm_isdst to 0 which I think would make mktime()
ignore daylight savings time.

Comments?

Duncan