diff options
author | Tom Yu <tlyu@mit.edu> | 2011-07-11 17:53:25 +0000 |
---|---|---|
committer | Tom Yu <tlyu@mit.edu> | 2011-07-11 17:53:25 +0000 |
commit | 478addb5c6b8b0cdb2454614d5226a23e7b0b356 (patch) | |
tree | 0def747888225f3eba4d3daac84604a54706989e /src | |
parent | 99fbb4c5d5956428db3ae1307ffc29911e45aff5 (diff) | |
download | krb5-478addb5c6b8b0cdb2454614d5226a23e7b0b356.tar.gz krb5-478addb5c6b8b0cdb2454614d5226a23e7b0b356.tar.xz krb5-478addb5c6b8b0cdb2454614d5226a23e7b0b356.zip |
use timegm() for krb5int_gmt_mktime() when available
Use timegm() if it is available, so that krb5int_gmt_mktime()
functions correctly on systems configured with a "right"
(leap-second-aware) time zone. It is arguably an OS bug if a "right"
time zone can be configured on a system that lacks timegm().
Due to a current lack of evidence of affected systems, the additional
workaround of replacing gmtime() with a version that always ignores
leap seconds is deferred.
ticket: 6928
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25018 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r-- | src/configure.in | 2 | ||||
-rw-r--r-- | src/util/support/gmt_mktime.c | 36 |
2 files changed, 36 insertions, 2 deletions
diff --git a/src/configure.in b/src/configure.in index 641a0f364d..8789de75b7 100644 --- a/src/configure.in +++ b/src/configure.in @@ -201,7 +201,7 @@ AC_CONFIG_HEADERS(include/autoconf.h, [echo timestamp > include/autoconf.stamp]) AC_PROG_LEX AC_C_CONST AC_HEADER_DIRENT -AC_CHECK_FUNCS(strdup setvbuf inet_ntoa inet_aton seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strftime strptime geteuid setenv unsetenv getenv gmtime_r localtime_r bswap16 bswap64 mkstemp getusershell access getcwd srand48 srand srandom stat strchr strerror strerror_r) +AC_CHECK_FUNCS(strdup setvbuf inet_ntoa inet_aton seteuid setresuid setreuid setegid setresgid setregid setsid flock fchmod chmod strftime strptime geteuid setenv unsetenv getenv gmtime_r localtime_r bswap16 bswap64 mkstemp getusershell access getcwd srand48 srand srandom stat strchr strerror strerror_r timegm) AC_CHECK_FUNC(mkstemp, [MKSTEMP_ST_OBJ= diff --git a/src/util/support/gmt_mktime.c b/src/util/support/gmt_mktime.c index 2047a8a010..f7f717e9e2 100644 --- a/src/util/support/gmt_mktime.c +++ b/src/util/support/gmt_mktime.c @@ -18,6 +18,38 @@ #include "k5-gmt_mktime.h" +/* + * Use the nonstandard timegm() (if available) to convert broken-down + * UTC times into time_t values. Use our custom gmt_mktime() if + * timegm() is not available. + * + * We use gmtime() (or gmtime_r()) when encoding ASN.1 GeneralizedTime + * values. On systems where a "right" (leap-second-aware) time zone + * is configured, gmtime() adjusts for the presence of accumulated + * leap seconds in the input time_t value. POSIX requires that time_t + * values omit leap seconds; systems configured to include leap + * seconds in their time_t values are non-conforming and will have + * difficulties exchanging timestamp information with other systems. + * + * We use krb5int_gmt_mktime() for decoding ASN.1 GeneralizedTime + * values. If timegm() is not available, krb5int_gmt_mktime() won't + * be the inverse of gmtime() on a system that counts leap seconds. A + * system configured with a "right" time zone probably has timegm() + * available; without it, an application would have no reliable way of + * converting broken-down UTC times into time_t values. + */ +time_t +krb5int_gmt_mktime(struct tm *t) +{ +#if HAVE_TIMEGM + return timegm(t); +#else + return gmt_mktime(t); +#endif +} + +#if !HAVE_TIMEGM || TEST_LEAP + /* take a struct tm, return seconds from GMT epoch */ /* like mktime, this ignores tm_wday and tm_yday. */ /* unlike mktime, this does not set them... it only passes a return value. */ @@ -39,7 +71,8 @@ static const int days_in_month[12] = { #define hasleapday(year) (year%400?(year%100?(year%4?0:1):0):1) -time_t krb5int_gmt_mktime(struct tm *t) +static time_t +gmt_mktime(struct tm *t) { time_t accum; @@ -94,6 +127,7 @@ time_t krb5int_gmt_mktime(struct tm *t) return accum; } +#endif /* !HAVE_TIMEGM || TEST_LEAP */ #ifdef TEST_LEAP int |