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