Blame SOURCES/Make-timestamp-manipulations-y2038-safe.patch

749169
From e7358d93fa1cbe5db52e217d466894b1af96d95c Mon Sep 17 00:00:00 2001
e58a44
From: Greg Hudson <ghudson@mit.edu>
e58a44
Date: Sat, 22 Apr 2017 12:52:17 -0400
e58a44
Subject: [PATCH] Make timestamp manipulations y2038-safe
e58a44
e58a44
Wherever we manipulate krb5_timestamp values using arithmetic,
e58a44
comparison operations, or conversion to time_t, use the new helper
e58a44
functions in k5-int.h to ensure that the operations work after y2038
e58a44
and do not exhibit undefined behavior.  (Relying on
e58a44
implementation-defined conversion to signed values is okay as we test
e58a44
that in configure.in.)
e58a44
e58a44
In printf format strings, use %u instead of signed types.  When
e58a44
exporting creds with k5_json_array_fmt(), use a long long so that
e58a44
timestamps after y2038 aren't marshalled as negative numbers.  When
e58a44
parsing timestamps in test programs, use atoll() instead of atol() so
e58a44
that positive timestamps after y2038 can be used as input.
e58a44
e58a44
In ksu and klist, make printtime() take a krb5_timestamp parameter to
e58a44
avoid an unnecessary conversion to time_t and back.
e58a44
e58a44
As Leash does not use k5-int.h, use time_t values internally and
e58a44
safely convert from libkrb5 timestamp values.
e58a44
e58a44
ticket: 8352
e58a44
(cherry picked from commit a9cbbf0899f270fbb14f63ffbed1b6d542333641)
e58a44
---
665228
 src/clients/kinit/kinit.c                     |  2 +-
665228
 src/clients/klist/klist.c                     | 20 ++++------
665228
 src/clients/ksu/ccache.c                      | 20 +++-------
665228
 src/clients/ksu/ksu.h                         |  2 +-
665228
 src/kadmin/cli/getdate.y                      |  2 +-
665228
 src/kadmin/cli/kadmin.c                       |  5 +--
665228
 src/kadmin/dbutil/dump.c                      | 27 +++++++------
665228
 src/kadmin/dbutil/kdb5_mkey.c                 |  6 +--
665228
 src/kadmin/dbutil/tabdump.c                   |  2 +-
665228
 src/kadmin/testing/util/tcl_kadm5.c           | 12 +++---
665228
 src/kdc/do_as_req.c                           |  2 +-
665228
 src/kdc/do_tgs_req.c                          |  6 +--
665228
 src/kdc/extern.c                              |  4 +-
665228
 src/kdc/fast_util.c                           |  4 +-
665228
 src/kdc/kdc_log.c                             | 14 +++----
665228
 src/kdc/kdc_util.c                            | 20 +++++-----
665228
 src/kdc/kdc_util.h                            |  2 +
665228
 src/kdc/replay.c                              |  2 +-
665228
 src/kdc/tgs_policy.c                          |  7 ++--
665228
 src/lib/gssapi/krb5/accept_sec_context.c      |  8 ++--
665228
 src/lib/gssapi/krb5/acquire_cred.c            | 13 +++---
665228
 src/lib/gssapi/krb5/context_time.c            |  2 +-
665228
 src/lib/gssapi/krb5/export_cred.c             |  5 ++-
665228
 src/lib/gssapi/krb5/iakerb.c                  |  4 +-
665228
 src/lib/gssapi/krb5/init_sec_context.c        |  9 +++--
665228
 src/lib/gssapi/krb5/inq_context.c             |  2 +-
665228
 src/lib/gssapi/krb5/inq_cred.c                |  5 ++-
665228
 src/lib/gssapi/krb5/s4u_gss_glue.c            |  2 +-
665228
 src/lib/kadm5/chpass_util.c                   |  8 +---
665228
 src/lib/kadm5/srv/server_acl.c                |  5 ++-
665228
 src/lib/kadm5/srv/svr_principal.c             | 12 +++---
665228
 src/lib/kdb/kdb5.c                            |  2 +-
665228
 src/lib/krb5/asn.1/asn1_k_encode.c            |  3 +-
665228
 src/lib/krb5/ccache/cc_keyring.c              | 14 ++++---
665228
 src/lib/krb5/ccache/cc_memory.c               |  4 +-
665228
 src/lib/krb5/ccache/cc_retr.c                 |  4 +-
665228
 src/lib/krb5/ccache/ccapi/stdcc_util.c        | 40 +++++++++----------
665228
 src/lib/krb5/ccache/cccursor.c                |  2 +-
665228
 src/lib/krb5/keytab/kt_file.c                 |  6 ++-
665228
 src/lib/krb5/krb/gc_via_tkt.c                 |  7 ++--
665228
 src/lib/krb5/krb/get_creds.c                  |  2 +-
665228
 src/lib/krb5/krb/get_in_tkt.c                 | 38 +++++-------------
665228
 src/lib/krb5/krb/gic_pwd.c                    |  4 +-
665228
 src/lib/krb5/krb/int-proto.h                  |  2 +-
665228
 src/lib/krb5/krb/pac.c                        |  2 +-
665228
 src/lib/krb5/krb/str_conv.c                   |  4 +-
665228
 src/lib/krb5/krb/t_kerb.c                     | 12 +-----
665228
 src/lib/krb5/krb/valid_times.c                |  4 +-
665228
 src/lib/krb5/krb/vfy_increds.c                |  2 +-
665228
 src/lib/krb5/os/timeofday.c                   |  2 +-
665228
 src/lib/krb5/os/toffset.c                     |  2 +-
665228
 src/lib/krb5/os/ustime.c                      |  6 +--
665228
 src/lib/krb5/rcache/rc_dfl.c                  |  3 +-
665228
 src/lib/krb5/rcache/t_replay.c                |  8 ++--
665228
 src/plugins/kdb/db2/lockout.c                 |  8 ++--
665228
 .../kdb/ldap/libkdb_ldap/ldap_principal2.c    |  2 +-
665228
 src/plugins/kdb/ldap/libkdb_ldap/lockout.c    |  8 ++--
665228
 src/windows/cns/tktlist.c                     | 10 +++--
665228
 src/windows/include/leashwin.h                | 12 +++---
665228
 src/windows/leash/KrbListTickets.cpp          | 12 +++---
665228
 src/windows/leash/LeashView.cpp               | 22 +++++-----
665228
 src/windows/leashdll/lshfunc.c                |  2 +-
665228
 src/windows/ms2mit/ms2mit.c                   |  2 +-
e58a44
 63 files changed, 230 insertions(+), 255 deletions(-)
e58a44
e58a44
diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c
e58a44
index f1cd1b73d..50065e32e 100644
e58a44
--- a/src/clients/kinit/kinit.c
e58a44
+++ b/src/clients/kinit/kinit.c
e58a44
@@ -318,7 +318,7 @@ parse_options(argc, argv, opts)
e58a44
                     fprintf(stderr, _("Bad start time value %s\n"), optarg);
e58a44
                     errflg++;
e58a44
                 } else {
e58a44
-                    opts->starttime = abs_starttime - time(0);
e58a44
+                    opts->starttime = ts_delta(abs_starttime, time(NULL));
e58a44
                 }
e58a44
             }
e58a44
             break;
e58a44
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
e58a44
index ba19788a2..ffeecc394 100644
e58a44
--- a/src/clients/klist/klist.c
e58a44
+++ b/src/clients/klist/klist.c
e58a44
@@ -72,7 +72,7 @@ void do_ccache_name (char *);
e58a44
 int show_ccache (krb5_ccache);
e58a44
 int check_ccache (krb5_ccache);
e58a44
 void do_keytab (char *);
e58a44
-void printtime (time_t);
e58a44
+void printtime (krb5_timestamp);
e58a44
 void one_addr (krb5_address *);
e58a44
 void fillit (FILE *, unsigned int, int);
e58a44
 
e58a44
@@ -538,10 +538,10 @@ check_ccache(krb5_ccache cache)
e58a44
     while (!(ret = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
e58a44
         if (is_local_tgt(creds.server, &princ->realm)) {
e58a44
             found_tgt = TRUE;
e58a44
-            if (creds.times.endtime > now)
e58a44
+            if (ts_after(creds.times.endtime, now))
e58a44
                 found_current_tgt = TRUE;
e58a44
         } else if (!krb5_is_config_principal(kcontext, creds.server) &&
e58a44
-                   creds.times.endtime > now) {
e58a44
+                   ts_after(creds.times.endtime, now)) {
e58a44
             found_current_cred = TRUE;
e58a44
         }
e58a44
         krb5_free_cred_contents(kcontext, &creds);
e58a44
@@ -623,19 +623,13 @@ flags_string(cred)
e58a44
 }
e58a44
 
e58a44
 void
e58a44
-printtime(tv)
e58a44
-    time_t tv;
e58a44
+printtime(krb5_timestamp ts)
e58a44
 {
e58a44
-    char timestring[BUFSIZ];
e58a44
-    char fill;
e58a44
+    char timestring[BUFSIZ], fill = ' ';
e58a44
 
e58a44
-    fill = ' ';
e58a44
-    if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv,
e58a44
-                                    timestring,
e58a44
-                                    timestamp_width+1,
e58a44
-                                    &fill)) {
e58a44
+    if (!krb5_timestamp_to_sfstring(ts, timestring, timestamp_width + 1,
e58a44
+                                    &fill))
e58a44
         printf("%s", timestring);
e58a44
-    }
e58a44
 }
e58a44
 
e58a44
 static void
e58a44
diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
e58a44
index a0736f2da..236313b7b 100644
e58a44
--- a/src/clients/ksu/ccache.c
e58a44
+++ b/src/clients/ksu/ccache.c
e58a44
@@ -278,11 +278,11 @@ krb5_error_code krb5_check_exp(context, tkt_time)
e58a44
                 context->clockskew);
e58a44
 
e58a44
         fprintf(stderr,"krb5_check_exp: currenttime - endtime %d \n",
e58a44
-                (currenttime - tkt_time.endtime ));
e58a44
+                ts_delta(currenttime, tkt_time.endtime));
e58a44
 
e58a44
     }
e58a44
 
e58a44
-    if (currenttime - tkt_time.endtime > context->clockskew){
e58a44
+    if (ts_delta(currenttime, tkt_time.endtime) > context->clockskew) {
e58a44
         retval = KRB5KRB_AP_ERR_TKT_EXPIRED ;
e58a44
         return retval;
e58a44
     }
e58a44
@@ -323,21 +323,11 @@ char *flags_string(cred)
e58a44
     return(buf);
e58a44
 }
e58a44
 
e58a44
-void printtime(tv)
e58a44
-    time_t tv;
e58a44
+void printtime(krb5_timestamp ts)
e58a44
 {
e58a44
-    char fmtbuf[18];
e58a44
-    char fill;
e58a44
-    krb5_timestamp tstamp;
e58a44
+    char fmtbuf[18], fill = ' ';
e58a44
 
e58a44
-    /* XXXX ASSUMES sizeof(krb5_timestamp) >= sizeof(time_t) */
e58a44
-    (void) localtime((time_t *)&tv;;
e58a44
-    tstamp = tv;
e58a44
-    fill = ' ';
e58a44
-    if (!krb5_timestamp_to_sfstring(tstamp,
e58a44
-                                    fmtbuf,
e58a44
-                                    sizeof(fmtbuf),
e58a44
-                                    &fill))
e58a44
+    if (!krb5_timestamp_to_sfstring(ts, fmtbuf, sizeof(fmtbuf), &fill))
e58a44
         printf("%s", fmtbuf);
e58a44
 }
e58a44
 
e58a44
diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
e58a44
index ee8e9d6a0..3bf0bd438 100644
e58a44
--- a/src/clients/ksu/ksu.h
e58a44
+++ b/src/clients/ksu/ksu.h
e58a44
@@ -150,7 +150,7 @@ extern krb5_boolean krb5_find_princ_in_cred_list
e58a44
 extern krb5_error_code krb5_find_princ_in_cache
e58a44
 (krb5_context, krb5_ccache, krb5_principal, krb5_boolean *);
e58a44
 
e58a44
-extern void printtime (time_t);
e58a44
+extern void printtime (krb5_timestamp);
e58a44
 
e58a44
 /* authorization.c */
e58a44
 extern krb5_boolean fowner (FILE *, uid_t);
e58a44
diff --git a/src/kadmin/cli/getdate.y b/src/kadmin/cli/getdate.y
e58a44
index 4f0c56f7e..0a19c5648 100644
e58a44
--- a/src/kadmin/cli/getdate.y
e58a44
+++ b/src/kadmin/cli/getdate.y
e58a44
@@ -118,7 +118,7 @@ static int getdate_yyerror (char *);
e58a44
 
e58a44
 
e58a44
 #define EPOCH		1970
e58a44
-#define EPOCH_END	2038 /* assumes 32 bits */
e58a44
+#define EPOCH_END	2106 /* assumes unsigned 32-bit range */
e58a44
 #define HOUR(x)		((time_t)(x) * 60)
e58a44
 #define SECSPERDAY	(24L * 60L * 60L)
e58a44
 
e58a44
diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
e58a44
index c53c677a8..aee5c83b9 100644
e58a44
--- a/src/kadmin/cli/kadmin.c
e58a44
+++ b/src/kadmin/cli/kadmin.c
e58a44
@@ -31,8 +31,7 @@
e58a44
  * library */
e58a44
 
e58a44
 /* for "_" macro */
e58a44
-#include "k5-platform.h"
e58a44
-#include <krb5.h>
e58a44
+#include "k5-int.h"
e58a44
 #include <kadm5/admin.h>
e58a44
 #include <adm_proto.h>
e58a44
 #include <errno.h>
e58a44
@@ -144,8 +143,8 @@ strdate(krb5_timestamp when)
e58a44
 {
e58a44
     struct tm *tm;
e58a44
     static char out[40];
e58a44
+    time_t lcltim = ts2tt(when);
e58a44
 
e58a44
-    time_t lcltim = when;
e58a44
     tm = localtime(&lcltim);
e58a44
     strftime(out, sizeof(out), "%a %b %d %H:%M:%S %Z %Y", tm);
e58a44
     return out;
e58a44
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
e58a44
index cad53cfbf..a6fc4ea77 100644
e58a44
--- a/src/kadmin/dbutil/dump.c
e58a44
+++ b/src/kadmin/dbutil/dump.c
e58a44
@@ -379,11 +379,12 @@ k5beta7_common(krb5_context context, krb5_db_entry *entry,
e58a44
     fprintf(fp, "princ\t%d\t%lu\t%d\t%d\t%d\t%s\t", (int)entry->len,
e58a44
             (unsigned long)strlen(name), counter, (int)entry->n_key_data,
e58a44
             (int)entry->e_length, name);
e58a44
-    fprintf(fp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d", entry->attributes,
e58a44
-            entry->max_life, entry->max_renewable_life, entry->expiration,
e58a44
-            entry->pw_expiration,
e58a44
-            omit_nra ? 0 : entry->last_success,
e58a44
-            omit_nra ? 0 : entry->last_failed,
e58a44
+    fprintf(fp, "%d\t%d\t%d\t%u\t%u\t%u\t%u\t%d", entry->attributes,
e58a44
+            entry->max_life, entry->max_renewable_life,
e58a44
+            (unsigned int)entry->expiration,
e58a44
+            (unsigned int)entry->pw_expiration,
e58a44
+            (unsigned int)(omit_nra ? 0 : entry->last_success),
e58a44
+            (unsigned int)(omit_nra ? 0 : entry->last_failed),
e58a44
             omit_nra ? 0 : entry->fail_auth_count);
e58a44
 
e58a44
     /* Write out tagged data. */
e58a44
@@ -717,7 +718,7 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
e58a44
 {
e58a44
     int retval, nread, i, j;
e58a44
     krb5_db_entry *dbentry;
e58a44
-    int t1, t2, t3, t4, t5, t6, t7;
e58a44
+    int t1, t2, t3, t4;
e58a44
     unsigned int u1, u2, u3, u4, u5;
e58a44
     char *name = NULL;
e58a44
     krb5_key_data *kp = NULL, *kd;
e58a44
@@ -773,8 +774,8 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
e58a44
     }
e58a44
 
e58a44
     /* Get the fixed principal attributes */
e58a44
-    nread = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
e58a44
-                   &t1, &t2, &t3, &t4, &t5, &t6, &t7, &u1;;
e58a44
+    nread = fscanf(filep, "%d\t%d\t%d\t%u\t%u\t%d\t%d\t%d\t",
e58a44
+                   &t1, &t2, &t3, &u1, &u2, &u3, &u4, &u5;;
e58a44
     if (nread != 8) {
e58a44
         load_err(fname, *linenop, _("cannot read principal attributes"));
e58a44
         goto fail;
e58a44
@@ -782,11 +783,11 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep,
e58a44
     dbentry->attributes = t1;
e58a44
     dbentry->max_life = t2;
e58a44
     dbentry->max_renewable_life = t3;
e58a44
-    dbentry->expiration = t4;
e58a44
-    dbentry->pw_expiration = t5;
e58a44
-    dbentry->last_success = t6;
e58a44
-    dbentry->last_failed = t7;
e58a44
-    dbentry->fail_auth_count = u1;
e58a44
+    dbentry->expiration = u1;
e58a44
+    dbentry->pw_expiration = u2;
e58a44
+    dbentry->last_success = u3;
e58a44
+    dbentry->last_failed = u4;
e58a44
+    dbentry->fail_auth_count = u5;
e58a44
     dbentry->mask = KADM5_LOAD | KADM5_PRINCIPAL | KADM5_ATTRIBUTES |
e58a44
         KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
e58a44
         KADM5_PRINC_EXPIRE_TIME | KADM5_LAST_SUCCESS |
e58a44
diff --git a/src/kadmin/dbutil/kdb5_mkey.c b/src/kadmin/dbutil/kdb5_mkey.c
e58a44
index 7df8cbc83..2efe3176e 100644
e58a44
--- a/src/kadmin/dbutil/kdb5_mkey.c
e58a44
+++ b/src/kadmin/dbutil/kdb5_mkey.c
e58a44
@@ -44,8 +44,8 @@ static char *strdate(krb5_timestamp when)
e58a44
 {
e58a44
     struct tm *tm;
e58a44
     static char out[40];
e58a44
+    time_t lcltim = ts2tt(when);
e58a44
 
e58a44
-    time_t lcltim = when;
e58a44
     tm = localtime(&lcltim);
e58a44
     strftime(out, sizeof(out), "%a %b %d %H:%M:%S %Z %Y", tm);
e58a44
     return out;
e58a44
@@ -481,7 +481,7 @@ kdb5_use_mkey(int argc, char *argv[])
e58a44
                  cur_actkvno != NULL;
e58a44
                  prev_actkvno = cur_actkvno, cur_actkvno = cur_actkvno->next) {
e58a44
 
e58a44
-                if (new_actkvno->act_time < cur_actkvno->act_time) {
e58a44
+                if (ts_after(cur_actkvno->act_time, new_actkvno->act_time)) {
e58a44
                     if (prev_actkvno) {
e58a44
                         prev_actkvno->next = new_actkvno;
e58a44
                         new_actkvno->next = cur_actkvno;
e58a44
@@ -499,7 +499,7 @@ kdb5_use_mkey(int argc, char *argv[])
e58a44
         }
e58a44
     }
e58a44
 
e58a44
-    if (actkvno_list->act_time > now) {
e58a44
+    if (ts_after(actkvno_list->act_time, now)) {
e58a44
         com_err(progname, EINVAL,
e58a44
                 _("there must be one master key currently active"));
e58a44
         exit_status++;
e58a44
diff --git a/src/kadmin/dbutil/tabdump.c b/src/kadmin/dbutil/tabdump.c
e58a44
index 69a3482ec..fb36b060a 100644
e58a44
--- a/src/kadmin/dbutil/tabdump.c
e58a44
+++ b/src/kadmin/dbutil/tabdump.c
e58a44
@@ -148,7 +148,7 @@ write_date_iso(struct rec_args *args, krb5_timestamp when)
e58a44
     struct tm *tm = NULL;
e58a44
     struct rechandle *h = args->rh;
e58a44
 
e58a44
-    t = when;
e58a44
+    t = ts2tt(when);
e58a44
     tm = gmtime(&t);
e58a44
     if (tm == NULL) {
e58a44
         errno = EINVAL;
e58a44
diff --git a/src/kadmin/testing/util/tcl_kadm5.c b/src/kadmin/testing/util/tcl_kadm5.c
e58a44
index a4997c60c..9dde579ef 100644
e58a44
--- a/src/kadmin/testing/util/tcl_kadm5.c
e58a44
+++ b/src/kadmin/testing/util/tcl_kadm5.c
e58a44
@@ -697,13 +697,13 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ,
e58a44
     } else
e58a44
         Tcl_DStringAppendElement(str, "null");
e58a44
 
e58a44
-    sprintf(buf, "%d", princ->princ_expire_time);
e58a44
+    sprintf(buf, "%u", (unsigned int)princ->princ_expire_time);
e58a44
     Tcl_DStringAppendElement(str, buf);
e58a44
 
e58a44
-    sprintf(buf, "%d", princ->last_pwd_change);
e58a44
+    sprintf(buf, "%u", (unsigned int)princ->last_pwd_change);
e58a44
     Tcl_DStringAppendElement(str, buf);
e58a44
 
e58a44
-    sprintf(buf, "%d", princ->pw_expiration);
e58a44
+    sprintf(buf, "%u", (unsigned int)princ->pw_expiration);
e58a44
     Tcl_DStringAppendElement(str, buf);
e58a44
 
e58a44
     sprintf(buf, "%d", princ->max_life);
e58a44
@@ -722,7 +722,7 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ,
e58a44
     } else
e58a44
         Tcl_DStringAppendElement(str, "null");
e58a44
 
e58a44
-    sprintf(buf, "%d", princ->mod_date);
e58a44
+    sprintf(buf, "%u", (unsigned int)princ->mod_date);
e58a44
     Tcl_DStringAppendElement(str, buf);
e58a44
 
e58a44
     if (mask & KADM5_ATTRIBUTES) {
e58a44
@@ -758,10 +758,10 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ,
e58a44
     sprintf(buf, "%d", princ->max_renewable_life);
e58a44
     Tcl_DStringAppendElement(str, buf);
e58a44
 
e58a44
-    sprintf(buf, "%d", princ->last_success);
e58a44
+    sprintf(buf, "%u", (unsigned int)princ->last_success);
e58a44
     Tcl_DStringAppendElement(str, buf);
e58a44
 
e58a44
-    sprintf(buf, "%d", princ->last_failed);
e58a44
+    sprintf(buf, "%u", (unsigned int)princ->last_failed);
e58a44
     Tcl_DStringAppendElement(str, buf);
e58a44
 
e58a44
     sprintf(buf, "%d", princ->fail_auth_count);
e58a44
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
e58a44
index 712ccb794..59a39cd30 100644
e58a44
--- a/src/kdc/do_as_req.c
e58a44
+++ b/src/kdc/do_as_req.c
e58a44
@@ -87,7 +87,7 @@ get_key_exp(krb5_db_entry *entry)
e58a44
         return entry->pw_expiration;
e58a44
     if (entry->pw_expiration == 0)
e58a44
         return entry->expiration;
e58a44
-    return min(entry->expiration, entry->pw_expiration);
e58a44
+    return ts_min(entry->expiration, entry->pw_expiration);
e58a44
 }
e58a44
 
e58a44
 /*
e58a44
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
e58a44
index 547a41441..aacd2f20d 100644
e58a44
--- a/src/kdc/do_tgs_req.c
e58a44
+++ b/src/kdc/do_tgs_req.c
e58a44
@@ -500,12 +500,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
e58a44
 
e58a44
         old_starttime = enc_tkt_reply.times.starttime ?
e58a44
             enc_tkt_reply.times.starttime : enc_tkt_reply.times.authtime;
e58a44
-        old_life = enc_tkt_reply.times.endtime - old_starttime;
e58a44
+        old_life = ts_delta(enc_tkt_reply.times.endtime, old_starttime);
e58a44
 
e58a44
         enc_tkt_reply.times.starttime = kdc_time;
e58a44
         enc_tkt_reply.times.endtime =
e58a44
-            min(header_ticket->enc_part2->times.renew_till,
e58a44
-                kdc_time + old_life);
e58a44
+            ts_min(header_ticket->enc_part2->times.renew_till,
e58a44
+                   ts_incr(kdc_time, old_life));
e58a44
     } else {
e58a44
         /* not a renew request */
e58a44
         enc_tkt_reply.times.starttime = kdc_time;
e58a44
diff --git a/src/kdc/extern.c b/src/kdc/extern.c
e58a44
index fe627494b..84b5c6ad5 100644
e58a44
--- a/src/kdc/extern.c
e58a44
+++ b/src/kdc/extern.c
e58a44
@@ -37,6 +37,8 @@
e58a44
 kdc_realm_t     **kdc_realmlist = (kdc_realm_t **) NULL;
e58a44
 int             kdc_numrealms = 0;
e58a44
 krb5_data empty_string = {0, 0, ""};
e58a44
-krb5_timestamp kdc_infinity = KRB5_INT32_MAX; /* XXX */
e58a44
 krb5_keyblock   psr_key;
e58a44
 krb5_int32      max_dgram_reply_size = MAX_DGRAM_SIZE;
e58a44
+
e58a44
+/* With ts_after(), this is the largest timestamp value. */
e58a44
+krb5_timestamp kdc_infinity = -1;
e58a44
diff --git a/src/kdc/fast_util.c b/src/kdc/fast_util.c
e58a44
index 9df940219..e05107ef3 100644
e58a44
--- a/src/kdc/fast_util.c
e58a44
+++ b/src/kdc/fast_util.c
e58a44
@@ -607,7 +607,7 @@ kdc_fast_read_cookie(krb5_context context, struct kdc_request_state *state,
e58a44
     ret = krb5_timeofday(context, &now;;
e58a44
     if (ret)
e58a44
         goto cleanup;
e58a44
-    if (now - COOKIE_LIFETIME > cookie->time) {
e58a44
+    if (ts2tt(now) > cookie->time + COOKIE_LIFETIME) {
e58a44
         /* Don't accept the cookie contents.  Only return an error if the
e58a44
          * cookie is relevant to the request. */
e58a44
         if (is_relevant(cookie->data, req->padata))
e58a44
@@ -700,7 +700,7 @@ kdc_fast_make_cookie(krb5_context context, struct kdc_request_state *state,
e58a44
     ret = krb5_timeofday(context, &now;;
e58a44
     if (ret)
e58a44
         goto cleanup;
e58a44
-    cookie.time = now;
e58a44
+    cookie.time = ts2tt(now);
e58a44
     cookie.data = contents;
e58a44
     ret = encode_krb5_secure_cookie(&cookie, &der_cookie);
e58a44
     if (ret)
e58a44
diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c
e58a44
index 94a2a1c87..c044a3553 100644
e58a44
--- a/src/kdc/kdc_log.c
e58a44
+++ b/src/kdc/kdc_log.c
e58a44
@@ -79,9 +79,9 @@ log_as_req(krb5_context context, const krb5_fulladdr *from,
e58a44
         /* success */
e58a44
         char rep_etypestr[128];
e58a44
         rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply);
e58a44
-        krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %d, %s, "
e58a44
+        krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %u, %s, "
e58a44
                                      "%s for %s"),
e58a44
-                         ktypestr, fromstring, authtime,
e58a44
+                         ktypestr, fromstring, (unsigned int)authtime,
e58a44
                          rep_etypestr, cname2, sname2);
e58a44
     } else {
e58a44
         /* fail */
e58a44
@@ -156,10 +156,10 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
e58a44
        name (useful), and doesn't log ktypestr (probably not
e58a44
        important).  */
e58a44
     if (errcode != KRB5KDC_ERR_SERVER_NOMATCH) {
e58a44
-        krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %d, %s%s "
e58a44
+        krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %u, %s%s "
e58a44
                                      "%s for %s%s%s"),
e58a44
-                         ktypestr, fromstring, status, authtime, rep_etypestr,
e58a44
-                         !errcode ? "," : "", logcname, logsname,
e58a44
+                         ktypestr, fromstring, status, (unsigned int)authtime,
e58a44
+                         rep_etypestr, !errcode ? "," : "", logcname, logsname,
e58a44
                          errcode ? ", " : "", errcode ? emsg : "");
e58a44
         if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION))
e58a44
             krb5_klog_syslog(LOG_INFO,
e58a44
@@ -171,9 +171,9 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
e58a44
                              logaltcname);
e58a44
 
e58a44
     } else
e58a44
-        krb5_klog_syslog(LOG_INFO, _("TGS_REQ %s: %s: authtime %d, %s for %s, "
e58a44
+        krb5_klog_syslog(LOG_INFO, _("TGS_REQ %s: %s: authtime %u, %s for %s, "
e58a44
                                      "2nd tkt client %s"),
e58a44
-                         fromstring, status, authtime,
e58a44
+                         fromstring, status, (unsigned int)authtime,
e58a44
                          logcname, logsname, logaltcname);
e58a44
 
e58a44
     /* OpenSolaris: audit_krb5kdc_tgs_req(...)  or
e58a44
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
e58a44
index 29f9dbbf0..778a629e5 100644
e58a44
--- a/src/kdc/kdc_util.c
e58a44
+++ b/src/kdc/kdc_util.c
e58a44
@@ -654,7 +654,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
e58a44
     }
e58a44
 
e58a44
     /* The client must not be expired */
e58a44
-    if (client.expiration && client.expiration < kdc_time) {
e58a44
+    if (client.expiration && ts_after(kdc_time, client.expiration)) {
e58a44
         *status = "CLIENT EXPIRED";
e58a44
         if (vague_errors)
e58a44
             return(KRB_ERR_GENERIC);
e58a44
@@ -664,7 +664,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
e58a44
 
e58a44
     /* The client's password must not be expired, unless the server is
e58a44
        a KRB5_KDC_PWCHANGE_SERVICE. */
e58a44
-    if (client.pw_expiration && client.pw_expiration < kdc_time &&
e58a44
+    if (client.pw_expiration && ts_after(kdc_time, client.pw_expiration) &&
e58a44
         !isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
e58a44
         *status = "CLIENT KEY EXPIRED";
e58a44
         if (vague_errors)
e58a44
@@ -674,7 +674,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
e58a44
     }
e58a44
 
e58a44
     /* The server must not be expired */
e58a44
-    if (server.expiration && server.expiration < kdc_time) {
e58a44
+    if (server.expiration && ts_after(kdc_time, server.expiration)) {
e58a44
         *status = "SERVICE EXPIRED";
e58a44
         return(KDC_ERR_SERVICE_EXP);
e58a44
     }
e58a44
@@ -1765,9 +1765,9 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm,
e58a44
     if (till == 0)
e58a44
         till = kdc_infinity;
e58a44
 
e58a44
-    until = min(till, endtime);
e58a44
+    until = ts_min(till, endtime);
e58a44
 
e58a44
-    life = until - starttime;
e58a44
+    life = ts_delta(until, starttime);
e58a44
 
e58a44
     if (client != NULL && client->max_life != 0)
e58a44
         life = min(life, client->max_life);
e58a44
@@ -1776,7 +1776,7 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm,
e58a44
     if (kdc_active_realm->realm_maxlife != 0)
e58a44
         life = min(life, kdc_active_realm->realm_maxlife);
e58a44
 
e58a44
-    *out_endtime = starttime + life;
e58a44
+    *out_endtime = ts_incr(starttime, life);
e58a44
 }
e58a44
 
e58a44
 /*
e58a44
@@ -1806,22 +1806,22 @@ kdc_get_ticket_renewtime(kdc_realm_t *realm, krb5_kdc_req *request,
e58a44
     if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE))
e58a44
         rtime = request->rtime ? request->rtime : kdc_infinity;
e58a44
     else if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE_OK) &&
e58a44
-             tkt->times.endtime < request->till)
e58a44
+             ts_after(request->till, tkt->times.endtime))
e58a44
         rtime = request->till;
e58a44
     else
e58a44
         return;
e58a44
 
e58a44
     /* Truncate it to the allowable renewable time. */
e58a44
     if (tgt != NULL)
e58a44
-        rtime = min(rtime, tgt->times.renew_till);
e58a44
+        rtime = ts_min(rtime, tgt->times.renew_till);
e58a44
     max_rlife = min(server->max_renewable_life, realm->realm_maxrlife);
e58a44
     if (client != NULL)
e58a44
         max_rlife = min(max_rlife, client->max_renewable_life);
e58a44
-    rtime = min(rtime, tkt->times.starttime + max_rlife);
e58a44
+    rtime = ts_min(rtime, ts_incr(tkt->times.starttime, max_rlife));
e58a44
 
e58a44
     /* Make the ticket renewable if the truncated requested time is larger than
e58a44
      * the ticket end time. */
e58a44
-    if (rtime > tkt->times.endtime) {
e58a44
+    if (ts_after(rtime, tkt->times.endtime)) {
e58a44
         setflag(tkt->flags, TKT_FLG_RENEWABLE);
e58a44
         tkt->times.renew_till = rtime;
e58a44
     }
e58a44
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
e58a44
index bcf05fc27..672f94380 100644
e58a44
--- a/src/kdc/kdc_util.h
e58a44
+++ b/src/kdc/kdc_util.h
e58a44
@@ -452,6 +452,8 @@ struct krb5_kdcpreauth_rock_st {
e58a44
 #define max(a, b)       ((a) > (b) ? (a) : (b))
e58a44
 #endif
e58a44
 
e58a44
+#define ts_min(a, b) (ts_after(a, b) ? (b) : (a))
e58a44
+
e58a44
 #define ADDRTYPE2FAMILY(X)                                              \
e58a44
     ((X) == ADDRTYPE_INET6 ? AF_INET6 : (X) == ADDRTYPE_INET ? AF_INET : -1)
e58a44
 
e58a44
diff --git a/src/kdc/replay.c b/src/kdc/replay.c
e58a44
index 8da7ac19a..fab39cf88 100644
e58a44
--- a/src/kdc/replay.c
e58a44
+++ b/src/kdc/replay.c
e58a44
@@ -61,7 +61,7 @@ static size_t total_size = 0;
e58a44
 static krb5_ui_4 seed;
e58a44
 
e58a44
 #define STALE_TIME      (2*60)            /* two minutes */
e58a44
-#define STALE(ptr, now) (abs((ptr)->timein - (now)) >= STALE_TIME)
e58a44
+#define STALE(ptr, now) (labs(ts_delta((ptr)->timein, now)) >= STALE_TIME)
e58a44
 
e58a44
 /* Return x rotated to the left by r bits. */
e58a44
 static inline krb5_ui_4
e58a44
diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c
e58a44
index a30cacc66..d0f25d1b7 100644
e58a44
--- a/src/kdc/tgs_policy.c
e58a44
+++ b/src/kdc/tgs_policy.c
e58a44
@@ -186,7 +186,7 @@ static int
e58a44
 check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
e58a44
                    krb5_timestamp kdc_time, const char **status)
e58a44
 {
e58a44
-    if (server.expiration && server.expiration < kdc_time) {
e58a44
+    if (server.expiration && ts_after(kdc_time, server.expiration)) {
e58a44
         *status = "SERVICE EXPIRED";
e58a44
         return KDC_ERR_SERVICE_EXP;
e58a44
     }
e58a44
@@ -222,7 +222,7 @@ check_tgs_times(krb5_kdc_req *req, krb5_ticket_times *times,
e58a44
        KDC time. */
e58a44
     if (req->kdc_options & KDC_OPT_VALIDATE) {
e58a44
         starttime = times->starttime ? times->starttime : times->authtime;
e58a44
-        if (starttime > kdc_time) {
e58a44
+        if (ts_after(starttime, kdc_time)) {
e58a44
             *status = "NOT_YET_VALID";
e58a44
             return KRB_AP_ERR_TKT_NYV;
e58a44
         }
e58a44
@@ -231,7 +231,8 @@ check_tgs_times(krb5_kdc_req *req, krb5_ticket_times *times,
e58a44
      * Check the renew_till time.  The endtime was already
e58a44
      * been checked in the initial authentication check.
e58a44
      */
e58a44
-    if ((req->kdc_options & KDC_OPT_RENEW) && times->renew_till < kdc_time) {
e58a44
+    if ((req->kdc_options & KDC_OPT_RENEW) &&
e58a44
+        ts_after(kdc_time, times->renew_till)) {
e58a44
         *status = "TKT_EXPIRED";
e58a44
         return KRB_AP_ERR_TKT_EXPIRED;
e58a44
     }
e58a44
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
e58a44
index 580d08cbf..06967aa27 100644
e58a44
--- a/src/lib/gssapi/krb5/accept_sec_context.c
e58a44
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
e58a44
@@ -351,8 +351,10 @@ kg_accept_dce(minor_status, context_handle, verifier_cred_handle,
e58a44
     if (mech_type)
e58a44
         *mech_type = ctx->mech_used;
e58a44
 
e58a44
-    if (time_rec)
e58a44
-        *time_rec = ctx->krb_times.endtime + ctx->k5_context->clockskew - now;
e58a44
+    if (time_rec) {
e58a44
+        *time_rec = ts_delta(ctx->krb_times.endtime, now) +
e58a44
+            ctx->k5_context->clockskew;
e58a44
+    }
e58a44
 
e58a44
     /* Never return GSS_C_DELEG_FLAG since we don't support DCE credential
e58a44
      * delegation yet. */
e58a44
@@ -1146,7 +1148,7 @@ kg_accept_krb5(minor_status, context_handle,
e58a44
     /* Add the maximum allowable clock skew as a grace period for context
e58a44
      * expiration, just as we do for the ticket. */
e58a44
     if (time_rec)
e58a44
-        *time_rec = ctx->krb_times.endtime + context->clockskew - now;
e58a44
+        *time_rec = ts_delta(ctx->krb_times.endtime, now) + context->clockskew;
e58a44
 
e58a44
     if (ret_flags)
e58a44
         *ret_flags = ctx->gss_flags;
e58a44
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
e58a44
index 03ee25ec1..362ba9d86 100644
e58a44
--- a/src/lib/gssapi/krb5/acquire_cred.c
e58a44
+++ b/src/lib/gssapi/krb5/acquire_cred.c
e58a44
@@ -550,7 +550,7 @@ set_refresh_time(krb5_context context, krb5_ccache ccache,
e58a44
     char buf[128];
e58a44
     krb5_data d;
e58a44
 
e58a44
-    snprintf(buf, sizeof(buf), "%ld", (long)refresh_time);
e58a44
+    snprintf(buf, sizeof(buf), "%u", (unsigned int)ts2tt(refresh_time));
e58a44
     d = string2data(buf);
e58a44
     (void)krb5_cc_set_config(context, ccache, NULL, KRB5_CC_CONF_REFRESH_TIME,
e58a44
                              &d);
e58a44
@@ -566,8 +566,9 @@ kg_cred_time_to_refresh(krb5_context context, krb5_gss_cred_id_rec *cred)
e58a44
 
e58a44
     if (krb5_timeofday(context, &now))
e58a44
         return FALSE;
e58a44
-    if (cred->refresh_time != 0 && now >= cred->refresh_time) {
e58a44
-        set_refresh_time(context, cred->ccache, cred->refresh_time + 30);
e58a44
+    if (cred->refresh_time != 0 && !ts_after(cred->refresh_time, now)) {
e58a44
+        set_refresh_time(context, cred->ccache,
e58a44
+                         ts_incr(cred->refresh_time, 30));
e58a44
         return TRUE;
e58a44
     }
e58a44
     return FALSE;
e58a44
@@ -586,7 +587,8 @@ kg_cred_set_initial_refresh(krb5_context context, krb5_gss_cred_id_rec *cred,
e58a44
         return;
e58a44
 
e58a44
     /* Make a note to refresh these when they are halfway to expired. */
e58a44
-    refresh = times->starttime + (times->endtime - times->starttime) / 2;
e58a44
+    refresh = ts_incr(times->starttime,
e58a44
+                      ts_delta(times->endtime, times->starttime) / 2);
e58a44
     set_refresh_time(context, cred->ccache, refresh);
e58a44
 }
e58a44
 
e58a44
@@ -848,7 +850,8 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
e58a44
                                   GSS_C_NO_NAME);
e58a44
             if (GSS_ERROR(ret))
e58a44
                 goto error_out;
e58a44
-            *time_rec = (cred->expire > now) ? (cred->expire - now) : 0;
e58a44
+            *time_rec = ts_after(cred->expire, now) ?
e58a44
+                ts_delta(cred->expire, now) : 0;
e58a44
             k5_mutex_unlock(&cred->lock);
e58a44
         }
e58a44
     }
e58a44
diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c
e58a44
index 450593288..1fdb5a16f 100644
e58a44
--- a/src/lib/gssapi/krb5/context_time.c
e58a44
+++ b/src/lib/gssapi/krb5/context_time.c
e58a44
@@ -51,7 +51,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec)
e58a44
         return(GSS_S_FAILURE);
e58a44
     }
e58a44
 
e58a44
-    lifetime = ctx->krb_times.endtime - now;
e58a44
+    lifetime = ts_delta(ctx->krb_times.endtime, now);
e58a44
     if (!ctx->initiate)
e58a44
         lifetime += ctx->k5_context->clockskew;
e58a44
     if (lifetime <= 0) {
e58a44
diff --git a/src/lib/gssapi/krb5/export_cred.c b/src/lib/gssapi/krb5/export_cred.c
e58a44
index 652b2604b..8054e4a77 100644
e58a44
--- a/src/lib/gssapi/krb5/export_cred.c
e58a44
+++ b/src/lib/gssapi/krb5/export_cred.c
e58a44
@@ -410,10 +410,11 @@ json_kgcred(krb5_context context, krb5_gss_cred_id_t cred,
e58a44
     if (ret)
e58a44
         goto cleanup;
e58a44
 
e58a44
-    ret = k5_json_array_fmt(&array, "ivvbbvvvvbiivs", cred->usage, name, imp,
e58a44
+    ret = k5_json_array_fmt(&array, "ivvbbvvvvbLLvs", cred->usage, name, imp,
e58a44
                             cred->default_identity, cred->iakerb_mech, keytab,
e58a44
                             rcache, ccache, ckeytab, cred->have_tgt,
e58a44
-                            cred->expire, cred->refresh_time, etypes,
e58a44
+                            (long long)ts2tt(cred->expire),
e58a44
+                            (long long)ts2tt(cred->refresh_time), etypes,
e58a44
                             cred->password);
e58a44
     if (ret)
e58a44
         goto cleanup;
e58a44
diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
e58a44
index 2dc4d0c1a..bb1072fe4 100644
e58a44
--- a/src/lib/gssapi/krb5/iakerb.c
e58a44
+++ b/src/lib/gssapi/krb5/iakerb.c
e58a44
@@ -494,7 +494,7 @@ iakerb_tkt_creds_ctx(iakerb_ctx_id_t ctx,
e58a44
         if (code != 0)
e58a44
             goto cleanup;
e58a44
 
e58a44
-        creds.times.endtime = now + time_req;
e58a44
+        creds.times.endtime = ts_incr(now, time_req);
e58a44
     }
e58a44
 
e58a44
     if (cred->name->ad_context != NULL) {
e58a44
@@ -669,7 +669,7 @@ iakerb_get_initial_state(iakerb_ctx_id_t ctx,
e58a44
         if (code != 0)
e58a44
             goto cleanup;
e58a44
 
e58a44
-        in_creds.times.endtime = now + time_req;
e58a44
+        in_creds.times.endtime = ts_incr(now, time_req);
e58a44
     }
e58a44
 
e58a44
     /* Make an AS request if we have no creds or it's time to refresh them. */
e58a44
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
e58a44
index 70f7955ae..8e5cc37fb 100644
e58a44
--- a/src/lib/gssapi/krb5/init_sec_context.c
e58a44
+++ b/src/lib/gssapi/krb5/init_sec_context.c
e58a44
@@ -214,7 +214,8 @@ static krb5_error_code get_credentials(context, cred, server, now,
e58a44
      * boundaries) because accept_sec_context code is also similarly
e58a44
      * non-forgiving.
e58a44
      */
e58a44
-    if (!krb5_gss_dbg_client_expcreds && result_creds->times.endtime < now) {
e58a44
+    if (!krb5_gss_dbg_client_expcreds &&
e58a44
+        ts_after(now, result_creds->times.endtime)) {
e58a44
         code = KRB5KRB_AP_ERR_TKT_EXPIRED;
e58a44
         goto cleanup;
e58a44
     }
e58a44
@@ -575,7 +576,7 @@ kg_new_connection(
e58a44
     if (time_req == 0 || time_req == GSS_C_INDEFINITE) {
e58a44
         ctx->krb_times.endtime = 0;
e58a44
     } else {
e58a44
-        ctx->krb_times.endtime = now + time_req;
e58a44
+        ctx->krb_times.endtime = ts_incr(now, time_req);
e58a44
     }
e58a44
 
e58a44
     if ((code = kg_duplicate_name(context, cred->name, &ctx->here)))
e58a44
@@ -659,7 +660,7 @@ kg_new_connection(
e58a44
     if (time_rec) {
e58a44
         if ((code = krb5_timeofday(context, &now)))
e58a44
             goto cleanup;
e58a44
-        *time_rec = ctx->krb_times.endtime - now;
e58a44
+        *time_rec = ts_delta(ctx->krb_times.endtime, now);
e58a44
     }
e58a44
 
e58a44
     /* set the other returns */
e58a44
@@ -873,7 +874,7 @@ mutual_auth(
e58a44
     if (time_rec) {
e58a44
         if ((code = krb5_timeofday(context, &now)))
e58a44
             goto fail;
e58a44
-        *time_rec = ctx->krb_times.endtime - now;
e58a44
+        *time_rec = ts_delta(ctx->krb_times.endtime, now);
e58a44
     }
e58a44
 
e58a44
     if (ret_flags)
e58a44
diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
e58a44
index d2e466e60..cac024da1 100644
e58a44
--- a/src/lib/gssapi/krb5/inq_context.c
e58a44
+++ b/src/lib/gssapi/krb5/inq_context.c
e58a44
@@ -120,7 +120,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
e58a44
 
e58a44
         /* Add the maximum allowable clock skew as a grace period for context
e58a44
          * expiration, just as we do for the ticket during authentication. */
e58a44
-        lifetime = ctx->krb_times.endtime - now;
e58a44
+        lifetime = ts_delta(ctx->krb_times.endtime, now);
e58a44
         if (!ctx->initiate)
e58a44
             lifetime += context->clockskew;
e58a44
         if (lifetime < 0)
e58a44
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
e58a44
index 4e35a0563..e662ae53a 100644
e58a44
--- a/src/lib/gssapi/krb5/inq_cred.c
e58a44
+++ b/src/lib/gssapi/krb5/inq_cred.c
e58a44
@@ -130,8 +130,9 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
e58a44
         goto fail;
e58a44
     }
e58a44
 
e58a44
-    if (cred->expire > 0) {
e58a44
-        if ((lifetime = cred->expire - now) < 0)
e58a44
+    if (cred->expire != 0) {
e58a44
+        lifetime = ts_delta(cred->expire, now);
e58a44
+        if (lifetime < 0)
e58a44
             lifetime = 0;
e58a44
     }
e58a44
     else
e58a44
diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c
e58a44
index ff1c310bc..10848c1df 100644
e58a44
--- a/src/lib/gssapi/krb5/s4u_gss_glue.c
e58a44
+++ b/src/lib/gssapi/krb5/s4u_gss_glue.c
e58a44
@@ -284,7 +284,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status,
e58a44
         if (code != 0)
e58a44
             goto cleanup;
e58a44
 
e58a44
-        *time_rec = cred->expire - now;
e58a44
+        *time_rec = ts_delta(cred->expire, now);
e58a44
     }
e58a44
 
e58a44
     major_status = GSS_S_COMPLETE;
e58a44
diff --git a/src/lib/kadm5/chpass_util.c b/src/lib/kadm5/chpass_util.c
e58a44
index 408b0eb31..1680a5504 100644
e58a44
--- a/src/lib/kadm5/chpass_util.c
e58a44
+++ b/src/lib/kadm5/chpass_util.c
e58a44
@@ -4,15 +4,11 @@
e58a44
  */
e58a44
 
e58a44
 
e58a44
-#include "autoconf.h"
e58a44
-#include <stdio.h>
e58a44
-#include <time.h>
e58a44
-#include <string.h>
e58a44
+#include "k5-int.h"
e58a44
 
e58a44
 #include <kadm5/admin.h>
e58a44
 #include "admin_internal.h"
e58a44
 
e58a44
-#include <krb5.h>
e58a44
 
e58a44
 #define string_text error_message
e58a44
 
e58a44
@@ -218,7 +214,7 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
e58a44
         time_t until;
e58a44
         char *time_string, *ptr;
e58a44
 
e58a44
-        until = princ_ent.last_pwd_change + policy_ent.pw_min_life;
e58a44
+        until = ts_incr(princ_ent.last_pwd_change, policy_ent.pw_min_life);
e58a44
 
e58a44
         time_string = ctime(&until);
e58a44
         if (*(ptr = &time_string[strlen(time_string)-1]) == '\n')
e58a44
diff --git a/src/lib/kadm5/srv/server_acl.c b/src/lib/kadm5/srv/server_acl.c
e58a44
index 59ed0b975..656dddff5 100644
e58a44
--- a/src/lib/kadm5/srv/server_acl.c
e58a44
+++ b/src/lib/kadm5/srv/server_acl.c
e58a44
@@ -408,13 +408,14 @@ kadm5int_acl_impose_restrictions(kcontext, recp, maskp, rp)
e58a44
     }
e58a44
     if (rp->mask & KADM5_PRINC_EXPIRE_TIME) {
e58a44
         if (!(*maskp & KADM5_PRINC_EXPIRE_TIME)
e58a44
-            || (recp->princ_expire_time > (now + rp->princ_lifetime)))
e58a44
+            || ts_after(recp->princ_expire_time,
e58a44
+                        ts_incr(now, rp->princ_lifetime)))
e58a44
             recp->princ_expire_time = now + rp->princ_lifetime;
e58a44
         *maskp |= KADM5_PRINC_EXPIRE_TIME;
e58a44
     }
e58a44
     if (rp->mask & KADM5_PW_EXPIRATION) {
e58a44
         if (!(*maskp & KADM5_PW_EXPIRATION)
e58a44
-            || (recp->pw_expiration > (now + rp->pw_lifetime)))
e58a44
+            || ts_after(recp->pw_expiration, ts_incr(now, rp->pw_lifetime)))
e58a44
             recp->pw_expiration = now + rp->pw_lifetime;
e58a44
         *maskp |= KADM5_PW_EXPIRATION;
e58a44
     }
e58a44
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
e58a44
index 0640b47c4..f4a9a2ad2 100644
e58a44
--- a/src/lib/kadm5/srv/svr_principal.c
e58a44
+++ b/src/lib/kadm5/srv/svr_principal.c
e58a44
@@ -400,7 +400,7 @@ kadm5_create_principal_3(void *server_handle,
e58a44
     kdb->pw_expiration = 0;
e58a44
     if (have_polent) {
e58a44
         if(polent.pw_max_life)
e58a44
-            kdb->pw_expiration = now + polent.pw_max_life;
e58a44
+            kdb->pw_expiration = ts_incr(now, polent.pw_max_life);
e58a44
         else
e58a44
             kdb->pw_expiration = 0;
e58a44
     }
e58a44
@@ -612,7 +612,7 @@ kadm5_modify_principal(void *server_handle,
e58a44
                                                   &(kdb->pw_expiration));
e58a44
             if (ret)
e58a44
                 goto done;
e58a44
-            kdb->pw_expiration += pol.pw_max_life;
e58a44
+            kdb->pw_expiration = ts_incr(kdb->pw_expiration, pol.pw_max_life);
e58a44
         } else {
e58a44
             kdb->pw_expiration = 0;
e58a44
         }
e58a44
@@ -1445,7 +1445,7 @@ kadm5_chpass_principal_3(void *server_handle,
e58a44
         }
e58a44
 
e58a44
         if (pol.pw_max_life)
e58a44
-            kdb->pw_expiration = now + pol.pw_max_life;
e58a44
+            kdb->pw_expiration = ts_incr(now, pol.pw_max_life);
e58a44
         else
e58a44
             kdb->pw_expiration = 0;
e58a44
     } else {
e58a44
@@ -1624,7 +1624,7 @@ kadm5_randkey_principal_3(void *server_handle,
e58a44
 #endif
e58a44
 
e58a44
         if (pol.pw_max_life)
e58a44
-            kdb->pw_expiration = now + pol.pw_max_life;
e58a44
+            kdb->pw_expiration = ts_incr(now, pol.pw_max_life);
e58a44
         else
e58a44
             kdb->pw_expiration = 0;
e58a44
     } else {
e58a44
@@ -1774,7 +1774,7 @@ kadm5_setv4key_principal(void *server_handle,
e58a44
 #endif
e58a44
 
e58a44
         if (pol.pw_max_life)
e58a44
-            kdb->pw_expiration = now + pol.pw_max_life;
e58a44
+            kdb->pw_expiration = ts_incr(now, pol.pw_max_life);
e58a44
         else
e58a44
             kdb->pw_expiration = 0;
e58a44
     } else {
e58a44
@@ -2024,7 +2024,7 @@ kadm5_setkey_principal_4(void *server_handle, krb5_principal principal,
e58a44
     }
e58a44
     if (have_pol) {
e58a44
         if (pol.pw_max_life)
e58a44
-            kdb->pw_expiration = now + pol.pw_max_life;
e58a44
+            kdb->pw_expiration = ts_incr(now, pol.pw_max_life);
e58a44
         else
e58a44
             kdb->pw_expiration = 0;
e58a44
     } else {
e58a44
diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c
e58a44
index 4adf0fcbb..7f33c7e68 100644
e58a44
--- a/src/lib/kdb/kdb5.c
e58a44
+++ b/src/lib/kdb/kdb5.c
e58a44
@@ -1296,7 +1296,7 @@ find_actkvno(krb5_actkvno_node *list, krb5_timestamp now)
e58a44
      * are in the future, we will return the first node; if all are in the
e58a44
      * past, we will return the last node.
e58a44
      */
e58a44
-    while (list->next != NULL && list->next->act_time <= now)
e58a44
+    while (list->next != NULL && !ts_after(list->next->act_time, now))
e58a44
         list = list->next;
e58a44
     return list->act_kvno;
e58a44
 }
e58a44
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
e58a44
index a827ca608..889460989 100644
e58a44
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
e58a44
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
e58a44
@@ -158,8 +158,7 @@ static asn1_error_code
e58a44
 encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag,
e58a44
                      size_t *len_out)
e58a44
 {
e58a44
-    /* Range checking for time_t vs krb5_timestamp?  */
e58a44
-    time_t val = *(krb5_timestamp *)p;
e58a44
+    time_t val = ts2tt(*(krb5_timestamp *)p);
e58a44
     rettag->asn1class = UNIVERSAL;
e58a44
     rettag->construction = PRIMITIVE;
e58a44
     rettag->tagnum = ASN1_GENERALTIME;
e58a44
diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c
e58a44
index 4fe3f0d6f..fba710b1b 100644
e58a44
--- a/src/lib/krb5/ccache/cc_keyring.c
e58a44
+++ b/src/lib/krb5/ccache/cc_keyring.c
e58a44
@@ -751,7 +751,7 @@ update_keyring_expiration(krb5_context context, krb5_ccache id)
e58a44
     for (;;) {
e58a44
         if (krcc_next_cred(context, id, &cursor, &creds) != 0)
e58a44
             break;
e58a44
-        if (creds.times.endtime > endtime)
e58a44
+        if (ts_after(creds.times.endtime, endtime))
e58a44
             endtime = creds.times.endtime;
e58a44
         krb5_free_cred_contents(context, &creds);
e58a44
     }
e58a44
@@ -765,7 +765,7 @@ update_keyring_expiration(krb5_context context, krb5_ccache id)
e58a44
 
e58a44
     /* Setting the timeout to zero would reset the timeout, so we set it to one
e58a44
      * second instead if creds are already expired. */
e58a44
-    timeout = (endtime > now) ? endtime - now : 1;
e58a44
+    timeout = ts_after(endtime, now) ? ts_delta(endtime, now) : 1;
e58a44
     (void)keyctl_set_timeout(data->cache_id, timeout);
e58a44
 }
e58a44
 
e58a44
@@ -1316,8 +1316,10 @@ krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds)
e58a44
     if (ret)
e58a44
         goto errout;
e58a44
 
e58a44
-    if (creds->times.endtime > now)
e58a44
-        (void)keyctl_set_timeout(cred_key, creds->times.endtime - now);
e58a44
+    if (ts_after(creds->times.endtime, now)) {
e58a44
+        (void)keyctl_set_timeout(cred_key,
e58a44
+                                 ts_delta(creds->times.endtime, now));
e58a44
+    }
e58a44
 
e58a44
     update_keyring_expiration(context, id);
e58a44
 
e58a44
@@ -1680,8 +1682,8 @@ static void
e58a44
 krcc_update_change_time(krcc_data *data)
e58a44
 {
e58a44
     krb5_timestamp now_time = time(NULL);
e58a44
-    data->changetime = (data->changetime >= now_time) ?
e58a44
-        data->changetime + 1 : now_time;
e58a44
+    data->changetime = ts_after(now_time, data->changetime) ?
e58a44
+        now_time : ts_incr(data->changetime, 1);
e58a44
 }
e58a44
 
e58a44
 /*
e58a44
diff --git a/src/lib/krb5/ccache/cc_memory.c b/src/lib/krb5/ccache/cc_memory.c
e58a44
index 0354575c5..c5425eb3a 100644
e58a44
--- a/src/lib/krb5/ccache/cc_memory.c
e58a44
+++ b/src/lib/krb5/ccache/cc_memory.c
e58a44
@@ -720,8 +720,8 @@ static void
e58a44
 update_mcc_change_time(krb5_mcc_data *d)
e58a44
 {
e58a44
     krb5_timestamp now_time = time(NULL);
e58a44
-    d->changetime = (d->changetime >= now_time) ?
e58a44
-        d->changetime + 1 : now_time;
e58a44
+    d->changetime = ts_after(now_time, d->changetime) ?
e58a44
+        now_time : ts_incr(d->changetime, 1);
e58a44
 }
e58a44
 
e58a44
 static krb5_error_code KRB5_CALLCONV
e58a44
diff --git a/src/lib/krb5/ccache/cc_retr.c b/src/lib/krb5/ccache/cc_retr.c
e58a44
index 1314d24bd..1a32e00c8 100644
e58a44
--- a/src/lib/krb5/ccache/cc_retr.c
e58a44
+++ b/src/lib/krb5/ccache/cc_retr.c
e58a44
@@ -46,11 +46,11 @@ static krb5_boolean
e58a44
 times_match(const krb5_ticket_times *t1, const krb5_ticket_times *t2)
e58a44
 {
e58a44
     if (t1->renew_till) {
e58a44
-        if (t1->renew_till > t2->renew_till)
e58a44
+        if (ts_after(t1->renew_till, t2->renew_till))
e58a44
             return FALSE;               /* this one expires too late */
e58a44
     }
e58a44
     if (t1->endtime) {
e58a44
-        if (t1->endtime > t2->endtime)
e58a44
+        if (ts_after(t1->endtime, t2->endtime))
e58a44
             return FALSE;               /* this one expires too late */
e58a44
     }
e58a44
     /* only care about expiration on a times_match */
e58a44
diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c
e58a44
index 9f44af3d0..6092ee432 100644
e58a44
--- a/src/lib/krb5/ccache/ccapi/stdcc_util.c
e58a44
+++ b/src/lib/krb5/ccache/ccapi/stdcc_util.c
e58a44
@@ -16,8 +16,8 @@
e58a44
 #include <malloc.h>
e58a44
 #endif
e58a44
 
e58a44
+#include "k5-int.h"
e58a44
 #include "stdcc_util.h"
e58a44
-#include "krb5.h"
e58a44
 #ifdef _WIN32                   /* it's part of krb5.h everywhere else */
e58a44
 #include "kv5m_err.h"
e58a44
 #endif
e58a44
@@ -321,10 +321,10 @@ copy_cc_cred_union_to_krb5_creds (krb5_context in_context,
e58a44
         keyblock_contents = NULL;
e58a44
 
e58a44
         /* copy times */
e58a44
-        out_creds->times.authtime   = cv5->authtime     + offset_seconds;
e58a44
-        out_creds->times.starttime  = cv5->starttime    + offset_seconds;
e58a44
-        out_creds->times.endtime    = cv5->endtime      + offset_seconds;
e58a44
-        out_creds->times.renew_till = cv5->renew_till   + offset_seconds;
e58a44
+        out_creds->times.authtime   = ts_incr(cv5->authtime, offset_seconds);
e58a44
+        out_creds->times.starttime  = ts_incr(cv5->starttime, offset_seconds);
e58a44
+        out_creds->times.endtime    = ts_incr(cv5->endtime, offset_seconds);
e58a44
+        out_creds->times.renew_till = ts_incr(cv5->renew_till, offset_seconds);
e58a44
         out_creds->is_skey          = cv5->is_skey;
e58a44
         out_creds->ticket_flags     = cv5->ticket_flags;
e58a44
 
e58a44
@@ -451,11 +451,11 @@ copy_krb5_creds_to_cc_cred_union (krb5_context in_context,
e58a44
         cv5->keyblock.data = keyblock_data;
e58a44
         keyblock_data = NULL;
e58a44
 
e58a44
-        cv5->authtime     = in_creds->times.authtime   - offset_seconds;
e58a44
-        cv5->starttime    = in_creds->times.starttime  - offset_seconds;
e58a44
-        cv5->endtime      = in_creds->times.endtime    - offset_seconds;
e58a44
-        cv5->renew_till   = in_creds->times.renew_till - offset_seconds;
e58a44
-        cv5->is_skey      = in_creds->is_skey;
e58a44
+        cv5->authtime = ts_incr(in_creds->times.authtime, -offset_seconds);
e58a44
+        cv5->starttime = ts_incr(in_creds->times.starttime, -offset_seconds);
e58a44
+        cv5->endtime = ts_incr(in_creds->times.endtime, -offset_seconds);
e58a44
+        cv5->renew_till = ts_incr(in_creds->times.renew_till, -offset_seconds);
e58a44
+        cv5->is_skey = in_creds->is_skey;
e58a44
         cv5->ticket_flags = in_creds->ticket_flags;
e58a44
 
e58a44
         if (in_creds->ticket.data) {
e58a44
@@ -732,10 +732,10 @@ void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest)
e58a44
     err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds);
e58a44
     if (err) return;
e58a44
 #endif
e58a44
-    dest->times.authtime   = src->authtime     + offset_seconds;
e58a44
-    dest->times.starttime  = src->starttime    + offset_seconds;
e58a44
-    dest->times.endtime    = src->endtime      + offset_seconds;
e58a44
-    dest->times.renew_till = src->renew_till   + offset_seconds;
e58a44
+    dest->times.authtime   = ts_incr(src->authtime, offset_seconds);
e58a44
+    dest->times.starttime  = ts_incr(src->starttime, offset_seconds);
e58a44
+    dest->times.endtime    = ts_incr(src->endtime, offset_seconds);
e58a44
+    dest->times.renew_till = ts_incr(src->renew_till, offset_seconds);
e58a44
     dest->is_skey          = src->is_skey;
e58a44
     dest->ticket_flags     = src->ticket_flags;
e58a44
 
e58a44
@@ -804,10 +804,10 @@ void dupK5toCC(krb5_context context, krb5_creds *creds, cred_union **cu)
e58a44
     err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds);
e58a44
     if (err) return;
e58a44
 #endif
e58a44
-    c->authtime     = creds->times.authtime   - offset_seconds;
e58a44
-    c->starttime    = creds->times.starttime  - offset_seconds;
e58a44
-    c->endtime      = creds->times.endtime    - offset_seconds;
e58a44
-    c->renew_till   = creds->times.renew_till - offset_seconds;
e58a44
+    c->authtime     = ts_incr(creds->times.authtime, -offset_seconds);
e58a44
+    c->starttime    = ts_incr(creds->times.starttime, -offset_seconds);
e58a44
+    c->endtime      = ts_incr(creds->times.endtime, -offset_seconds);
e58a44
+    c->renew_till   = ts_incr(creds->times.renew_till, -offset_seconds);
e58a44
     c->is_skey      = creds->is_skey;
e58a44
     c->ticket_flags = creds->ticket_flags;
e58a44
 
e58a44
@@ -925,11 +925,11 @@ times_match(t1, t2)
e58a44
     register const krb5_ticket_times *t2;
e58a44
 {
e58a44
     if (t1->renew_till) {
e58a44
-        if (t1->renew_till > t2->renew_till)
e58a44
+        if (ts_after(t1->renew_till, t2->renew_till))
e58a44
             return FALSE;               /* this one expires too late */
e58a44
     }
e58a44
     if (t1->endtime) {
e58a44
-        if (t1->endtime > t2->endtime)
e58a44
+        if (ts_after(t1->endtime, t2->endtime))
e58a44
             return FALSE;               /* this one expires too late */
e58a44
     }
e58a44
     /* only care about expiration on a times_match */
e58a44
diff --git a/src/lib/krb5/ccache/cccursor.c b/src/lib/krb5/ccache/cccursor.c
e58a44
index c31a3f5f0..e631f2051 100644
e58a44
--- a/src/lib/krb5/ccache/cccursor.c
e58a44
+++ b/src/lib/krb5/ccache/cccursor.c
e58a44
@@ -159,7 +159,7 @@ krb5_cccol_last_change_time(krb5_context context,
e58a44
         ret = krb5_cccol_cursor_next(context, c, &ccache);
e58a44
         if (ccache) {
e58a44
             ret = krb5_cc_last_change_time(context, ccache, &last_time);
e58a44
-            if (!ret && last_time > max_change_time) {
e58a44
+            if (!ret && ts_after(last_time, max_change_time)) {
e58a44
                 max_change_time = last_time;
e58a44
             }
e58a44
             ret = 0;
e58a44
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
e58a44
index 131549ffe..b014abf0b 100644
e58a44
--- a/src/lib/krb5/keytab/kt_file.c
e58a44
+++ b/src/lib/krb5/keytab/kt_file.c
e58a44
@@ -264,9 +264,11 @@ more_recent(const krb5_keytab_entry *k1, const krb5_keytab_entry *k2)
e58a44
      * limitations (8-bit kvno storage), pre-1.14 kadmin protocol limitations
e58a44
      * (8-bit kvno marshalling), or KDB limitations (16-bit kvno storage).
e58a44
      */
e58a44
-    if (k1->timestamp >= k2->timestamp && k1->vno < 128 && k2->vno > 240)
e58a44
+    if (!ts_after(k2->timestamp, k1->timestamp) &&
e58a44
+        k1->vno < 128 && k2->vno > 240)
e58a44
         return TRUE;
e58a44
-    if (k1->timestamp <= k2->timestamp && k1->vno > 240 && k2->vno < 128)
e58a44
+    if (!ts_after(k1->timestamp, k2->timestamp) &&
e58a44
+        k1->vno > 240 && k2->vno < 128)
e58a44
         return FALSE;
e58a44
 
e58a44
     /* Otherwise do a simple version comparison. */
e58a44
diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c
e58a44
index c85d8b8d8..cf1ea361f 100644
e58a44
--- a/src/lib/krb5/krb/gc_via_tkt.c
e58a44
+++ b/src/lib/krb5/krb/gc_via_tkt.c
e58a44
@@ -287,18 +287,19 @@ krb5int_process_tgs_reply(krb5_context context,
e58a44
         retval = KRB5_KDCREP_MODIFIED;
e58a44
 
e58a44
     if ((in_cred->times.endtime != 0) &&
e58a44
-        (dec_rep->enc_part2->times.endtime > in_cred->times.endtime))
e58a44
+        ts_after(dec_rep->enc_part2->times.endtime, in_cred->times.endtime))
e58a44
         retval = KRB5_KDCREP_MODIFIED;
e58a44
 
e58a44
     if ((kdcoptions & KDC_OPT_RENEWABLE) &&
e58a44
         (in_cred->times.renew_till != 0) &&
e58a44
-        (dec_rep->enc_part2->times.renew_till > in_cred->times.renew_till))
e58a44
+        ts_after(dec_rep->enc_part2->times.renew_till,
e58a44
+                 in_cred->times.renew_till))
e58a44
         retval = KRB5_KDCREP_MODIFIED;
e58a44
 
e58a44
     if ((kdcoptions & KDC_OPT_RENEWABLE_OK) &&
e58a44
         (dec_rep->enc_part2->flags & KDC_OPT_RENEWABLE) &&
e58a44
         (in_cred->times.endtime != 0) &&
e58a44
-        (dec_rep->enc_part2->times.renew_till > in_cred->times.endtime))
e58a44
+        ts_after(dec_rep->enc_part2->times.renew_till, in_cred->times.endtime))
e58a44
         retval = KRB5_KDCREP_MODIFIED;
e58a44
 
e58a44
     if (retval != 0)
e58a44
diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c
e58a44
index 110abeb2b..be5b2d18c 100644
e58a44
--- a/src/lib/krb5/krb/get_creds.c
e58a44
+++ b/src/lib/krb5/krb/get_creds.c
e58a44
@@ -816,7 +816,7 @@ get_cached_local_tgt(krb5_context context, krb5_tkt_creds_context ctx,
e58a44
         return code;
e58a44
 
e58a44
     /* Check if the TGT is expired before bothering the KDC with it. */
e58a44
-    if (now > tgt->times.endtime) {
e58a44
+    if (ts_after(now, tgt->times.endtime)) {
e58a44
         krb5_free_creds(context, tgt);
e58a44
         return KRB5KRB_AP_ERR_TKT_EXPIRED;
e58a44
     }
e58a44
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
e58a44
index a058f5bd7..40aba1905 100644
e58a44
--- a/src/lib/krb5/krb/get_in_tkt.c
e58a44
+++ b/src/lib/krb5/krb/get_in_tkt.c
e58a44
@@ -39,24 +39,6 @@ static krb5_error_code sort_krb5_padata_sequence(krb5_context context,
e58a44
                                                  krb5_data *realm,
e58a44
                                                  krb5_pa_data **padata);
e58a44
 
e58a44
-/*
e58a44
- * This function performs 32 bit bounded addition so we can generate
e58a44
- * lifetimes without overflowing krb5_int32
e58a44
- */
e58a44
-static krb5_int32
e58a44
-krb5int_addint32 (krb5_int32 x, krb5_int32 y)
e58a44
-{
e58a44
-    if ((x > 0) && (y > (KRB5_INT32_MAX - x))) {
e58a44
-        /* sum will be be greater than KRB5_INT32_MAX */
e58a44
-        return KRB5_INT32_MAX;
e58a44
-    } else if ((x < 0) && (y < (KRB5_INT32_MIN - x))) {
e58a44
-        /* sum will be less than KRB5_INT32_MIN */
e58a44
-        return KRB5_INT32_MIN;
e58a44
-    }
e58a44
-
e58a44
-    return x + y;
e58a44
-}
e58a44
-
e58a44
 /*
e58a44
  * Decrypt the AS reply in ctx, populating ctx->reply->enc_part2.  If
e58a44
  * strengthen_key is not null, combine it with the reply key as specified in
e58a44
@@ -267,21 +249,21 @@ verify_as_reply(krb5_context            context,
e58a44
             (request->from != 0) &&
e58a44
             (request->from != as_reply->enc_part2->times.starttime))
e58a44
         || ((request->till != 0) &&
e58a44
-            (as_reply->enc_part2->times.endtime > request->till))
e58a44
+            ts_after(as_reply->enc_part2->times.endtime, request->till))
e58a44
         || ((request->kdc_options & KDC_OPT_RENEWABLE) &&
e58a44
             (request->rtime != 0) &&
e58a44
-            (as_reply->enc_part2->times.renew_till > request->rtime))
e58a44
+            ts_after(as_reply->enc_part2->times.renew_till, request->rtime))
e58a44
         || ((request->kdc_options & KDC_OPT_RENEWABLE_OK) &&
e58a44
             !(request->kdc_options & KDC_OPT_RENEWABLE) &&
e58a44
             (as_reply->enc_part2->flags & KDC_OPT_RENEWABLE) &&
e58a44
             (request->till != 0) &&
e58a44
-            (as_reply->enc_part2->times.renew_till > request->till))
e58a44
+            ts_after(as_reply->enc_part2->times.renew_till, request->till))
e58a44
     ) {
e58a44
         return KRB5_KDCREP_MODIFIED;
e58a44
     }
e58a44
 
e58a44
     if (context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) {
e58a44
-        time_offset = as_reply->enc_part2->times.authtime - time_now;
e58a44
+        time_offset = ts_delta(as_reply->enc_part2->times.authtime, time_now);
e58a44
         retval = krb5_set_time_offsets(context, time_offset, 0);
e58a44
         if (retval)
e58a44
             return retval;
e58a44
@@ -790,15 +772,15 @@ set_request_times(krb5_context context, krb5_init_creds_context ctx)
e58a44
         return code;
e58a44
 
e58a44
     /* Omit request start time unless the caller explicitly asked for one. */
e58a44
-    from = krb5int_addint32(now, ctx->start_time);
e58a44
+    from = ts_incr(now, ctx->start_time);
e58a44
     if (ctx->start_time != 0)
e58a44
         ctx->request->from = from;
e58a44
 
e58a44
-    ctx->request->till = krb5int_addint32(from, ctx->tkt_life);
e58a44
+    ctx->request->till = ts_incr(from, ctx->tkt_life);
e58a44
 
e58a44
     if (ctx->renew_life > 0) {
e58a44
         /* Don't ask for a smaller renewable time than the lifetime. */
e58a44
-        ctx->request->rtime = krb5int_addint32(from, ctx->renew_life);
e58a44
+        ctx->request->rtime = ts_incr(from, ctx->renew_life);
e58a44
         if (ctx->request->rtime < ctx->request->till)
e58a44
             ctx->request->rtime = ctx->request->till;
e58a44
         ctx->request->kdc_options &= ~KDC_OPT_RENEWABLE_OK;
e58a44
@@ -1438,7 +1420,7 @@ note_req_timestamp(krb5_context context, krb5_init_creds_context ctx,
e58a44
 
e58a44
     if (k5_time_with_offset(0, 0, &now, &usec) != 0)
e58a44
         return;
e58a44
-    ctx->pa_offset = kdc_time - now;
e58a44
+    ctx->pa_offset = ts_delta(kdc_time, now);
e58a44
     ctx->pa_offset_usec = kdc_usec - usec;
e58a44
     ctx->pa_offset_state = (ctx->fast_state->armor_key != NULL) ?
e58a44
         AUTH_OFFSET : UNAUTH_OFFSET;
e58a44
@@ -1807,6 +1789,7 @@ k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **out,
e58a44
 {
e58a44
     int i;
e58a44
     krb5_int32 starttime;
e58a44
+    krb5_deltat lifetime;
e58a44
     krb5_get_init_creds_opt *opt;
e58a44
     krb5_error_code retval;
e58a44
 
e58a44
@@ -1838,7 +1821,8 @@ k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **out,
e58a44
         if (retval)
e58a44
             goto cleanup;
e58a44
         if (creds->times.starttime) starttime = creds->times.starttime;
e58a44
-        krb5_get_init_creds_opt_set_tkt_life(opt, creds->times.endtime - starttime);
e58a44
+        lifetime = ts_delta(creds->times.endtime, starttime);
e58a44
+        krb5_get_init_creds_opt_set_tkt_life(opt, lifetime);
e58a44
     }
e58a44
     *out = opt;
e58a44
     return 0;
e58a44
diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
e58a44
index 6f3a29f2c..3565a7c4c 100644
e58a44
--- a/src/lib/krb5/krb/gic_pwd.c
e58a44
+++ b/src/lib/krb5/krb/gic_pwd.c
e58a44
@@ -211,7 +211,7 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
e58a44
     if (ret != 0)
e58a44
         return;
e58a44
     if (!is_last_req &&
e58a44
-        (pw_exp < now || (pw_exp - now) > 7 * 24 * 60 * 60))
e58a44
+        (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60))
e58a44
         return;
e58a44
 
e58a44
     if (!prompter)
e58a44
@@ -221,7 +221,7 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
e58a44
     if (ret != 0)
e58a44
         return;
e58a44
 
e58a44
-    delta = pw_exp - now;
e58a44
+    delta = ts_delta(pw_exp, now);
e58a44
     if (delta < 3600) {
e58a44
         snprintf(banner, sizeof(banner),
e58a44
                  _("Warning: Your password will expire in less than one hour "
e58a44
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
e58a44
index 44eca359f..48bd9f8f7 100644
e58a44
--- a/src/lib/krb5/krb/int-proto.h
e58a44
+++ b/src/lib/krb5/krb/int-proto.h
e58a44
@@ -84,7 +84,7 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options,
e58a44
                                  krb5_flags *fields);
e58a44
 
e58a44
 #define in_clock_skew(context, date, now)               \
e58a44
-    (labs((date) - (now)) < (context)->clockskew)
e58a44
+    (labs(ts_delta(date, now)) < (context)->clockskew)
e58a44
 
e58a44
 #define IS_TGS_PRINC(p) ((p)->length == 2 &&                            \
e58a44
                          data_eq_string((p)->data[0], KRB5_TGS_NAME))
e58a44
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
e58a44
index 9098927b5..c70585a9e 100644
e58a44
--- a/src/lib/krb5/krb/pac.c
e58a44
+++ b/src/lib/krb5/krb/pac.c
e58a44
@@ -378,7 +378,7 @@ k5_time_to_seconds_since_1970(int64_t ntTime, krb5_timestamp *elapsedSeconds)
e58a44
 
e58a44
     abstime = ntTime > 0 ? ntTime - NT_TIME_EPOCH : -ntTime;
e58a44
 
e58a44
-    if (abstime > KRB5_INT32_MAX)
e58a44
+    if (abstime > UINT32_MAX)
e58a44
         return ERANGE;
e58a44
 
e58a44
     *elapsedSeconds = abstime;
e58a44
diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c
e58a44
index 3ab7eacac..f0a2ae20b 100644
e58a44
--- a/src/lib/krb5/krb/str_conv.c
e58a44
+++ b/src/lib/krb5/krb/str_conv.c
e58a44
@@ -207,7 +207,7 @@ krb5_error_code KRB5_CALLCONV
e58a44
 krb5_timestamp_to_string(krb5_timestamp timestamp, char *buffer, size_t buflen)
e58a44
 {
e58a44
     size_t ret;
e58a44
-    time_t timestamp2 = timestamp;
e58a44
+    time_t timestamp2 = ts2tt(timestamp);
e58a44
     struct tm tmbuf;
e58a44
     const char *fmt = "%c"; /* This is to get around gcc -Wall warning that
e58a44
                                the year returned might be two digits */
e58a44
@@ -229,7 +229,7 @@ krb5_timestamp_to_sfstring(krb5_timestamp timestamp, char *buffer, size_t buflen
e58a44
     struct tm   *tmp;
e58a44
     size_t i;
e58a44
     size_t      ndone;
e58a44
-    time_t timestamp2 = timestamp;
e58a44
+    time_t timestamp2 = ts2tt(timestamp);
e58a44
     struct tm tmbuf;
e58a44
 
e58a44
     static const char * const sftime_format_table[] = {
e58a44
diff --git a/src/lib/krb5/krb/t_kerb.c b/src/lib/krb5/krb/t_kerb.c
e58a44
index 60cfb5b15..74ac14d9a 100644
e58a44
--- a/src/lib/krb5/krb/t_kerb.c
e58a44
+++ b/src/lib/krb5/krb/t_kerb.c
e58a44
@@ -5,16 +5,8 @@
e58a44
  */
e58a44
 
e58a44
 #include "autoconf.h"
e58a44
-#include "krb5.h"
e58a44
-#include <stdio.h>
e58a44
-#include <string.h>
e58a44
-#include <stdlib.h>
e58a44
-#include <unistd.h>
e58a44
+#include "k5-int.h"
e58a44
 #include <time.h>
e58a44
-#include <sys/types.h>
e58a44
-#include <sys/socket.h>
e58a44
-#include <netinet/in.h>
e58a44
-#include <arpa/inet.h>
e58a44
 
e58a44
 #include "com_err.h"
e58a44
 
e58a44
@@ -37,7 +29,7 @@ test_string_to_timestamp(krb5_context ctx, char *ktime)
e58a44
         com_err("krb5_string_to_timestamp", retval, 0);
e58a44
         return;
e58a44
     }
e58a44
-    t = (time_t) timestamp;
e58a44
+    t = ts2tt(timestamp);
e58a44
     printf("Parsed time was %s", ctime(&t);;
e58a44
 }
e58a44
 
e58a44
diff --git a/src/lib/krb5/krb/valid_times.c b/src/lib/krb5/krb/valid_times.c
e58a44
index d63122183..9e509b2dd 100644
e58a44
--- a/src/lib/krb5/krb/valid_times.c
e58a44
+++ b/src/lib/krb5/krb/valid_times.c
e58a44
@@ -47,10 +47,10 @@ krb5int_validate_times(krb5_context context, krb5_ticket_times *times)
e58a44
     else
e58a44
         starttime = times->authtime;
e58a44
 
e58a44
-    if (starttime - currenttime > context->clockskew)
e58a44
+    if (ts_delta(starttime, currenttime) > context->clockskew)
e58a44
         return KRB5KRB_AP_ERR_TKT_NYV;  /* ticket not yet valid */
e58a44
 
e58a44
-    if ((currenttime - times->endtime) > context->clockskew)
e58a44
+    if (ts_delta(currenttime, times->endtime) > context->clockskew)
e58a44
         return KRB5KRB_AP_ERR_TKT_EXPIRED; /* ticket expired */
e58a44
 
e58a44
     return 0;
e58a44
diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c
e58a44
index 9786d63b5..b4878ba38 100644
e58a44
--- a/src/lib/krb5/krb/vfy_increds.c
e58a44
+++ b/src/lib/krb5/krb/vfy_increds.c
e58a44
@@ -120,7 +120,7 @@ get_vfy_cred(krb5_context context, krb5_creds *creds, krb5_principal server,
e58a44
         ret = krb5_timeofday(context, &in_creds.times.endtime);
e58a44
         if (ret)
e58a44
             goto cleanup;
e58a44
-        in_creds.times.endtime += 5*60;
e58a44
+        in_creds.times.endtime = ts_incr(in_creds.times.endtime, 5 * 60);
e58a44
         ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds);
e58a44
         if (ret)
e58a44
             goto cleanup;
e58a44
diff --git a/src/lib/krb5/os/timeofday.c b/src/lib/krb5/os/timeofday.c
e58a44
index fddb12142..887f24c22 100644
e58a44
--- a/src/lib/krb5/os/timeofday.c
e58a44
+++ b/src/lib/krb5/os/timeofday.c
e58a44
@@ -60,7 +60,7 @@ krb5_check_clockskew(krb5_context context, krb5_timestamp date)
e58a44
     retval = krb5_timeofday(context, &currenttime);
e58a44
     if (retval)
e58a44
         return retval;
e58a44
-    if (!(labs((date)-currenttime) < context->clockskew))
e58a44
+    if (labs(ts_delta(date, currenttime)) >= context->clockskew)
e58a44
         return KRB5KRB_AP_ERR_SKEW;
e58a44
 
e58a44
     return 0;
e58a44
diff --git a/src/lib/krb5/os/toffset.c b/src/lib/krb5/os/toffset.c
e58a44
index 456193a41..37bc69f49 100644
e58a44
--- a/src/lib/krb5/os/toffset.c
e58a44
+++ b/src/lib/krb5/os/toffset.c
e58a44
@@ -47,7 +47,7 @@ krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 micr
e58a44
     if (retval)
e58a44
         return retval;
e58a44
 
e58a44
-    os_ctx->time_offset = seconds - sec;
e58a44
+    os_ctx->time_offset = ts_delta(seconds, sec);
e58a44
     os_ctx->usec_offset = (microseconds > -1) ? microseconds - usec : 0;
e58a44
 
e58a44
     os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) |
e58a44
diff --git a/src/lib/krb5/os/ustime.c b/src/lib/krb5/os/ustime.c
e58a44
index 056357683..1c1b571eb 100644
e58a44
--- a/src/lib/krb5/os/ustime.c
e58a44
+++ b/src/lib/krb5/os/ustime.c
e58a44
@@ -49,13 +49,13 @@ k5_time_with_offset(krb5_timestamp offset, krb5_int32 offset_usec,
e58a44
     usec += offset_usec;
e58a44
     if (usec > 1000000) {
e58a44
         usec -= 1000000;
e58a44
-        sec++;
e58a44
+        sec = ts_incr(sec, 1);
e58a44
     }
e58a44
     if (usec < 0) {
e58a44
         usec += 1000000;
e58a44
-        sec--;
e58a44
+        sec = ts_incr(sec, -1);
e58a44
     }
e58a44
-    sec += offset;
e58a44
+    sec = ts_incr(sec, offset);
e58a44
 
e58a44
     *time_out = sec;
e58a44
     *usec_out = usec;
e58a44
diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c
e58a44
index c0f12ed9d..6b043844d 100644
e58a44
--- a/src/lib/krb5/rcache/rc_dfl.c
e58a44
+++ b/src/lib/krb5/rcache/rc_dfl.c
e58a44
@@ -97,8 +97,7 @@ alive(krb5_int32 mytime, krb5_donot_replay *new1, krb5_deltat t)
e58a44
 {
e58a44
     if (mytime == 0)
e58a44
         return CMP_HOHUM; /* who cares? */
e58a44
-    /* I hope we don't have to worry about overflow */
e58a44
-    if (new1->ctime + t < mytime)
e58a44
+    if (ts_after(mytime, ts_incr(new1->ctime, t)))
e58a44
         return CMP_EXPIRED;
e58a44
     return CMP_HOHUM;
e58a44
 }
e58a44
diff --git a/src/lib/krb5/rcache/t_replay.c b/src/lib/krb5/rcache/t_replay.c
e58a44
index db273ec2f..b99cdf1ab 100644
e58a44
--- a/src/lib/krb5/rcache/t_replay.c
e58a44
+++ b/src/lib/krb5/rcache/t_replay.c
e58a44
@@ -110,7 +110,7 @@ store(krb5_context ctx, char *rcspec, char *client, char *server, char *msg,
e58a44
     krb5_donot_replay rep;
e58a44
     krb5_data d;
e58a44
 
e58a44
-    if (now_timestamp > 0)
e58a44
+    if (now_timestamp != 0)
e58a44
         krb5_set_debugging_time(ctx, now_timestamp, now_usec);
e58a44
     if ((retval = krb5_rc_resolve_full(ctx, &rc, rcspec)))
e58a44
         goto cleanup;
e58a44
@@ -221,13 +221,13 @@ main(int argc, char **argv)
e58a44
             msg = (**argv) ? *argv : NULL;
e58a44
             argc--; argv++;
e58a44
             if (!argc) usage(progname);
e58a44
-            timestamp = (krb5_timestamp) atol(*argv);
e58a44
+            timestamp = (krb5_timestamp) atoll(*argv);
e58a44
             argc--; argv++;
e58a44
             if (!argc) usage(progname);
e58a44
             usec = (krb5_int32) atol(*argv);
e58a44
             argc--; argv++;
e58a44
             if (!argc) usage(progname);
e58a44
-            now_timestamp = (krb5_timestamp) atol(*argv);
e58a44
+            now_timestamp = (krb5_timestamp) atoll(*argv);
e58a44
             argc--; argv++;
e58a44
             if (!argc) usage(progname);
e58a44
             now_usec = (krb5_int32) atol(*argv);
e58a44
@@ -249,7 +249,7 @@ main(int argc, char **argv)
e58a44
             rcspec = *argv;
e58a44
             argc--; argv++;
e58a44
             if (!argc) usage(progname);
e58a44
-            now_timestamp = (krb5_timestamp) atol(*argv);
e58a44
+            now_timestamp = (krb5_timestamp) atoll(*argv);
e58a44
             argc--; argv++;
e58a44
             if (!argc) usage(progname);
e58a44
             now_usec = (krb5_int32) atol(*argv);
e58a44
diff --git a/src/plugins/kdb/db2/lockout.c b/src/plugins/kdb/db2/lockout.c
e58a44
index 7d151b55b..3a4f41821 100644
e58a44
--- a/src/plugins/kdb/db2/lockout.c
e58a44
+++ b/src/plugins/kdb/db2/lockout.c
e58a44
@@ -100,7 +100,7 @@ locked_check_p(krb5_context context,
e58a44
 
e58a44
     /* If the entry was unlocked since the last failure, it's not locked. */
e58a44
     if (krb5_dbe_lookup_last_admin_unlock(context, entry, &unlock_time) == 0 &&
e58a44
-        entry->last_failed <= unlock_time)
e58a44
+        !ts_after(entry->last_failed, unlock_time))
e58a44
         return FALSE;
e58a44
 
e58a44
     if (max_fail == 0 || entry->fail_auth_count < max_fail)
e58a44
@@ -109,7 +109,7 @@ locked_check_p(krb5_context context,
e58a44
     if (lockout_duration == 0)
e58a44
         return TRUE; /* principal permanently locked */
e58a44
 
e58a44
-    return (stamp < entry->last_failed + lockout_duration);
e58a44
+    return ts_after(ts_incr(entry->last_failed, lockout_duration), stamp);
e58a44
 }
e58a44
 
e58a44
 krb5_error_code
e58a44
@@ -200,13 +200,13 @@ krb5_db2_lockout_audit(krb5_context context,
e58a44
                 status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) {
e58a44
         if (krb5_dbe_lookup_last_admin_unlock(context, entry,
e58a44
                                               &unlock_time) == 0 &&
e58a44
-            entry->last_failed <= unlock_time) {
e58a44
+            !ts_after(entry->last_failed, unlock_time)) {
e58a44
             /* Reset fail_auth_count after administrative unlock. */
e58a44
             entry->fail_auth_count = 0;
e58a44
         }
e58a44
 
e58a44
         if (failcnt_interval != 0 &&
e58a44
-            stamp > entry->last_failed + failcnt_interval) {
e58a44
+            ts_after(stamp, ts_incr(entry->last_failed, failcnt_interval))) {
e58a44
             /* Reset fail_auth_count after failcnt_interval. */
e58a44
             entry->fail_auth_count = 0;
e58a44
         }
e58a44
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
e58a44
index 7ba53f959..88a170495 100644
e58a44
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
e58a44
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
e58a44
@@ -1734,7 +1734,7 @@ getstringtime(krb5_timestamp epochtime)
e58a44
 {
e58a44
     struct tm           tme;
e58a44
     char                *strtime=NULL;
e58a44
-    time_t              posixtime = epochtime;
e58a44
+    time_t              posixtime = ts2tt(epochtime);
e58a44
 
e58a44
     strtime = calloc (50, 1);
e58a44
     if (strtime == NULL)
e58a44
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
e58a44
index 0fc56c2fe..1088ecc5a 100644
e58a44
--- a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
e58a44
+++ b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
e58a44
@@ -93,7 +93,7 @@ locked_check_p(krb5_context context,
e58a44
 
e58a44
     /* If the entry was unlocked since the last failure, it's not locked. */
e58a44
     if (krb5_dbe_lookup_last_admin_unlock(context, entry, &unlock_time) == 0 &&
e58a44
-        entry->last_failed <= unlock_time)
e58a44
+        !ts_after(entry->last_failed, unlock_time))
e58a44
         return FALSE;
e58a44
 
e58a44
     if (max_fail == 0 || entry->fail_auth_count < max_fail)
e58a44
@@ -102,7 +102,7 @@ locked_check_p(krb5_context context,
e58a44
     if (lockout_duration == 0)
e58a44
         return TRUE; /* principal permanently locked */
e58a44
 
e58a44
-    return (stamp < entry->last_failed + lockout_duration);
e58a44
+    return ts_after(ts_incr(entry->last_failed, lockout_duration), stamp);
e58a44
 }
e58a44
 
e58a44
 krb5_error_code
e58a44
@@ -196,14 +196,14 @@ krb5_ldap_lockout_audit(krb5_context context,
e58a44
                 status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) {
e58a44
         if (krb5_dbe_lookup_last_admin_unlock(context, entry,
e58a44
                                               &unlock_time) == 0 &&
e58a44
-            entry->last_failed <= unlock_time) {
e58a44
+            !ts_after(entry->last_failed, unlock_time)) {
e58a44
             /* Reset fail_auth_count after administrative unlock. */
e58a44
             entry->fail_auth_count = 0;
e58a44
             entry->mask |= KADM5_FAIL_AUTH_COUNT;
e58a44
         }
e58a44
 
e58a44
         if (failcnt_interval != 0 &&
e58a44
-            stamp > entry->last_failed + failcnt_interval) {
e58a44
+            ts_after(stamp, ts_incr(entry->last_failed, failcnt_interval))) {
e58a44
             /* Reset fail_auth_count after failcnt_interval */
e58a44
             entry->fail_auth_count = 0;
e58a44
             entry->mask |= KADM5_FAIL_AUTH_COUNT;
e58a44
diff --git a/src/windows/cns/tktlist.c b/src/windows/cns/tktlist.c
e58a44
index f2805f5cd..26e699fae 100644
e58a44
--- a/src/windows/cns/tktlist.c
e58a44
+++ b/src/windows/cns/tktlist.c
e58a44
@@ -35,6 +35,8 @@
e58a44
 #include "cns.h"
e58a44
 #include "tktlist.h"
e58a44
 
e58a44
+#define ts2tt(t) (time_t)(uint32_t)(t)
e58a44
+
e58a44
 /*
e58a44
  * Ticket information for a list line
e58a44
  */
e58a44
@@ -167,10 +169,10 @@ ticket_init_list (HWND hwnd)
e58a44
 
e58a44
       ncred++;
e58a44
       strcpy (buf, "  ");
e58a44
-      strncat(buf, short_date (c.times.starttime - kwin_get_epoch()),
e58a44
+      strncat(buf, short_date(ts2tt(c.times.starttime) - kwin_get_epoch()),
e58a44
 	      sizeof(buf) - 1 - strlen(buf));
e58a44
       strncat(buf, "      ", sizeof(buf) - 1 - strlen(buf));
e58a44
-      strncat(buf, short_date (c.times.endtime - kwin_get_epoch()),
e58a44
+      strncat(buf, short_date(ts2tt(c.times.endtime) - kwin_get_epoch()),
e58a44
 	      sizeof(buf) - 1 - strlen(buf));
e58a44
       strncat(buf, "      ", sizeof(buf) - 1 - strlen(buf));
e58a44
 
e58a44
@@ -192,8 +194,8 @@ ticket_init_list (HWND hwnd)
e58a44
 	return -1;
e58a44
 
e58a44
       lpinfo->ticket = TRUE;
e58a44
-      lpinfo->issue_time = c.times.starttime - kwin_get_epoch();
e58a44
-      lpinfo->lifetime = c.times.endtime - c.times.starttime;
e58a44
+      lpinfo->issue_time = ts2tt(c.times.starttime) - kwin_get_epoch();
e58a44
+      lpinfo->lifetime = ts2tt(c.times.endtime) - c.times.starttime;
e58a44
       strcpy(lpinfo->buf, buf);
e58a44
 
e58a44
       rc = ListBox_AddItemData(hwnd, lpinfo);
e58a44
diff --git a/src/windows/include/leashwin.h b/src/windows/include/leashwin.h
e58a44
index 9577365a7..325dce2e9 100644
e58a44
--- a/src/windows/include/leashwin.h
e58a44
+++ b/src/windows/include/leashwin.h
e58a44
@@ -111,9 +111,9 @@ struct TicketList {
e58a44
     TicketList *next;
e58a44
     char *service;
e58a44
     char *encTypes;
e58a44
-    krb5_timestamp issued;
e58a44
-    krb5_timestamp valid_until;
e58a44
-    krb5_timestamp renew_until;
e58a44
+    time_t issued;
e58a44
+    time_t valid_until;
e58a44
+    time_t renew_until;
e58a44
     unsigned long flags;
e58a44
 };
e58a44
 
e58a44
@@ -124,9 +124,9 @@ struct TICKETINFO {
e58a44
     char   *ccache_name;
e58a44
     TicketList *ticket_list;
e58a44
     int     btickets;                 /* Do we have tickets? */
e58a44
-    long    issued;                   /* The issue time */
e58a44
-    long    valid_until;              /* */
e58a44
-    long    renew_until;              /* The Renew time (k5 only) */
e58a44
+    time_t  issued;                   /* The issue time */
e58a44
+    time_t  valid_until;              /* */
e58a44
+    time_t  renew_until;              /* The Renew time (k5 only) */
e58a44
     unsigned long flags;
e58a44
 };
e58a44
 
e58a44
diff --git a/src/windows/leash/KrbListTickets.cpp b/src/windows/leash/KrbListTickets.cpp
e58a44
index beab0ea11..5dd37b05a 100644
e58a44
--- a/src/windows/leash/KrbListTickets.cpp
e58a44
+++ b/src/windows/leash/KrbListTickets.cpp
e58a44
@@ -92,10 +92,10 @@ etype_string(krb5_enctype enctype)
e58a44
 static void
e58a44
 CredToTicketInfo(krb5_creds KRBv5Credentials, TICKETINFO *ticketinfo)
e58a44
 {
e58a44
-    ticketinfo->issued = KRBv5Credentials.times.starttime;
e58a44
-    ticketinfo->valid_until = KRBv5Credentials.times.endtime;
e58a44
+    ticketinfo->issued = (DWORD)KRBv5Credentials.times.starttime;
e58a44
+    ticketinfo->valid_until = (DWORD)KRBv5Credentials.times.endtime;
e58a44
     ticketinfo->renew_until = KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ?
e58a44
-        KRBv5Credentials.times.renew_till : 0;
e58a44
+        (DWORD)KRBv5Credentials.times.renew_till : (DWORD)0;
e58a44
     _tzset();
e58a44
     if ( ticketinfo->valid_until - time(0) <= 0L )
e58a44
         ticketinfo->btickets = EXPD_TICKETS;
e58a44
@@ -137,10 +137,10 @@ CredToTicketList(krb5_context ctx, krb5_creds KRBv5Credentials,
e58a44
         functionName = "calloc()";
e58a44
         goto cleanup;
e58a44
     }
e58a44
-    list->issued = KRBv5Credentials.times.starttime;
e58a44
-    list->valid_until = KRBv5Credentials.times.endtime;
e58a44
+    list->issued = (DWORD)KRBv5Credentials.times.starttime;
e58a44
+    list->valid_until = (DWORD)KRBv5Credentials.times.endtime;
e58a44
     if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE)
e58a44
-        list->renew_until = KRBv5Credentials.times.renew_till;
e58a44
+        list->renew_until = (DWORD)KRBv5Credentials.times.renew_till;
e58a44
     else
e58a44
         list->renew_until = 0;
e58a44
 
e58a44
diff --git a/src/windows/leash/LeashView.cpp b/src/windows/leash/LeashView.cpp
e58a44
index ef2a5a3e0..253ae3f06 100644
e58a44
--- a/src/windows/leash/LeashView.cpp
e58a44
+++ b/src/windows/leash/LeashView.cpp
e58a44
@@ -229,22 +229,22 @@ static HFONT CreateBoldItalicFont(HFONT font)
e58a44
 
e58a44
 bool change_icon_size = true;
e58a44
 
e58a44
-void krb5TimestampToFileTime(krb5_timestamp t, LPFILETIME pft)
e58a44
+void TimestampToFileTime(time_t t, LPFILETIME pft)
e58a44
 {
e58a44
     // Note that LONGLONG is a 64-bit value
e58a44
-    LONGLONG ll;
e58a44
+    ULONGLONG ll;
e58a44
 
e58a44
-    ll = Int32x32To64(t, 10000000) + 116444736000000000;
e58a44
+    ll = UInt32x32To64((DWORD)t, 10000000) + 116444736000000000;
e58a44
     pft->dwLowDateTime = (DWORD)ll;
e58a44
     pft->dwHighDateTime = ll >> 32;
e58a44
 }
e58a44
 
e58a44
 // allocate outstr
e58a44
-void krb5TimestampToLocalizedString(krb5_timestamp t, LPTSTR *outStr)
e58a44
+void TimestampToLocalizedString(time_t t, LPTSTR *outStr)
e58a44
 {
e58a44
     FILETIME ft, lft;
e58a44
     SYSTEMTIME st;
e58a44
-    krb5TimestampToFileTime(t, &ft;;
e58a44
+    TimestampToFileTime(t, &ft;;
e58a44
     FileTimeToLocalFileTime(&ft, &lft;;
e58a44
     FileTimeToSystemTime(&lft, &st);
e58a44
     TCHAR timeFormat[80]; // 80 is max required for LOCALE_STIMEFORMAT
e58a44
@@ -1125,9 +1125,9 @@ void CLeashView::AddDisplayItem(CListCtrl &list,
e58a44
                                 CCacheDisplayData *elem,
e58a44
                                 int iItem,
e58a44
                                 char *principal,
e58a44
-                                long issued,
e58a44
-                                long valid_until,
e58a44
-                                long renew_until,
e58a44
+                                time_t issued,
e58a44
+                                time_t valid_until,
e58a44
+                                time_t renew_until,
e58a44
                                 char *encTypes,
e58a44
                                 unsigned long flags,
e58a44
                                 char *ccache_name)
e58a44
@@ -1145,7 +1145,7 @@ void CLeashView::AddDisplayItem(CListCtrl &list,
e58a44
         if (issued == 0) {
e58a44
             list.SetItemText(iItem, iSubItem++, "Unknown");
e58a44
         } else {
e58a44
-            krb5TimestampToLocalizedString(issued, &localTimeStr);
e58a44
+            TimestampToLocalizedString(issued, &localTimeStr);
e58a44
             list.SetItemText(iItem, iSubItem++, localTimeStr);
e58a44
         }
e58a44
     }
e58a44
@@ -1155,7 +1155,7 @@ void CLeashView::AddDisplayItem(CListCtrl &list,
e58a44
         } else if (valid_until < now) {
e58a44
             list.SetItemText(iItem, iSubItem++, "Expired");
e58a44
         } else if (renew_until) {
e58a44
-            krb5TimestampToLocalizedString(renew_until, &localTimeStr);
e58a44
+            TimestampToLocalizedString(renew_until, &localTimeStr);
e58a44
             DurationToString(renew_until - now, &durationStr);
e58a44
             if (localTimeStr && durationStr) {
e58a44
                 _snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr);
e58a44
@@ -1172,7 +1172,7 @@ void CLeashView::AddDisplayItem(CListCtrl &list,
e58a44
         } else if (valid_until < now) {
e58a44
             list.SetItemText(iItem, iSubItem++, "Expired");
e58a44
         } else {
e58a44
-            krb5TimestampToLocalizedString(valid_until, &localTimeStr);
e58a44
+            TimestampToLocalizedString(valid_until, &localTimeStr);
e58a44
             DurationToString(valid_until - now, &durationStr);
e58a44
             if (localTimeStr && durationStr) {
e58a44
                 _snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr);
e58a44
diff --git a/src/windows/leashdll/lshfunc.c b/src/windows/leashdll/lshfunc.c
e58a44
index 0f76cc334..8dafb7bed 100644
e58a44
--- a/src/windows/leashdll/lshfunc.c
e58a44
+++ b/src/windows/leashdll/lshfunc.c
e58a44
@@ -2898,7 +2898,7 @@ static BOOL cc_have_tickets(krb5_context ctx, krb5_ccache cache)
e58a44
     _tzset();
e58a44
     while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) {
e58a44
         if ((!pkrb5_is_config_principal(ctx, creds.server)) &&
e58a44
-            (creds.times.endtime - time(0) > 0))
e58a44
+            ((time_t)(DWORD)creds.times.endtime - time(0) > 0))
e58a44
             have_tickets = TRUE;
e58a44
 
e58a44
         pkrb5_free_cred_contents(ctx, &creds);
e58a44
diff --git a/src/windows/ms2mit/ms2mit.c b/src/windows/ms2mit/ms2mit.c
e58a44
index c3325034a..2b4373cc1 100644
e58a44
--- a/src/windows/ms2mit/ms2mit.c
e58a44
+++ b/src/windows/ms2mit/ms2mit.c
e58a44
@@ -74,7 +74,7 @@ cc_has_tickets(krb5_context kcontext, krb5_ccache ccache, int *has_tickets)
e58a44
             break;
e58a44
 
e58a44
         if (!krb5_is_config_principal(kcontext, creds.server) &&
e58a44
-            creds.times.endtime > now)
e58a44
+            ts_after(creds.times.endtime, now))
e58a44
             *has_tickets = 1;
e58a44
 
e58a44
         krb5_free_cred_contents(kcontext, &creds);