summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Yu <tlyu@mit.edu>2011-07-11 17:53:25 +0000
committerTom Yu <tlyu@mit.edu>2011-07-11 17:53:25 +0000
commit478addb5c6b8b0cdb2454614d5226a23e7b0b356 (patch)
tree0def747888225f3eba4d3daac84604a54706989e
parent99fbb4c5d5956428db3ae1307ffc29911e45aff5 (diff)
downloadkrb5-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
-rw-r--r--src/configure.in2
-rw-r--r--src/util/support/gmt_mktime.c36
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