diff --git a/.gitignore b/.gitignore
index 4f90bbf..ff82334 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-SOURCES/krb5-1.12.2-pdf.tar.xz
-SOURCES/krb5-1.12.2.tar.gz
+SOURCES/krb5-1.13.2-pdf.pax.xz
+SOURCES/krb5-1.13.2.tar.gz
 SOURCES/nss_wrapper-0.0-20140204195100.git3d58327.tar.xz
 SOURCES/socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz
diff --git a/.krb5.metadata b/.krb5.metadata
index 050653a..c837707 100644
--- a/.krb5.metadata
+++ b/.krb5.metadata
@@ -1,4 +1,4 @@
-ad1f5d4fe9b90b4549e639050c278b176df85e0c SOURCES/krb5-1.12.2-pdf.tar.xz
-6f24800d48d36a33305387a9b6340884b05573b1 SOURCES/krb5-1.12.2.tar.gz
+93795fb24ecb84cd2db15c28d67d17990614b693 SOURCES/krb5-1.13.2-pdf.pax.xz
+a81dec5cf59b7a4b51c5be14d65518724ae25d56 SOURCES/krb5-1.13.2.tar.gz
 7e2c80565c726a6be9a62615752196710e2e2faa SOURCES/nss_wrapper-0.0-20140204195100.git3d58327.tar.xz
 ca7b62bd60d45817a059063bb0efd68cd1ecc889 SOURCES/socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz
diff --git a/SOURCES/0000-Refactor-cm-functions-in-sendto_kdc.c.patch b/SOURCES/0000-Refactor-cm-functions-in-sendto_kdc.c.patch
deleted file mode 100644
index ff332b1..0000000
--- a/SOURCES/0000-Refactor-cm-functions-in-sendto_kdc.c.patch
+++ /dev/null
@@ -1,436 +0,0 @@
-Tweaked a bit to apply to 1.12:
-* krb5_int64 hadn't been replaced by int64_t yet.
-
-commit 346883c48f1b9e09b1af2cf73e3b96ee8f934072
-Author: Greg Hudson <ghudson@mit.edu>
-Date:   Wed Mar 26 13:21:45 2014 -0400
-
-    Refactor cm functions in sendto_kdc.c
-    
-    Move get_curtime_ms and the cm functions near the top of the file
-    right after structure definitions.  Except for cm_select_or_poll,
-    define each cm function separately for poll and for select, since the
-    implementations don't share much in common.  Instead of
-    cm_unset_write, define cm_read and cm_write functions to put an fd in
-    read-only or write-only state.  Remove the ssflags argument from
-    cm_add_fd and just expect the caller to make a subsequent call to
-    cm_read or cm_write.  Always select for exceptions when using select.
-    (Polling for exceptions is implicit with poll).
-    
-    With these changes, we no longer select/poll for reading on a TCP
-    connection until we are done writing to it.  So in service_tcp_fd,
-    remove the check for unexpected read events.
-
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index e60a375..e773a0a 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -59,8 +59,7 @@
- 
- typedef krb5_int64 time_ms;
- 
--/* Since fd_set is large on some platforms (8K on AIX 5.2), this probably
-- * shouldn't be allocated in automatic storage. */
-+/* This can be pretty large, so should not be stack-allocated. */
- struct select_state {
- #ifdef USE_POLL
-     struct pollfd fds[MAX_POLLFDS];
-@@ -107,6 +106,183 @@ struct conn_state {
-     time_ms endtime;
- };
- 
-+/* Get current time in milliseconds. */
-+static krb5_error_code
-+get_curtime_ms(time_ms *time_out)
-+{
-+    struct timeval tv;
-+
-+    if (gettimeofday(&tv, 0))
-+        return errno;
-+    *time_out = (time_ms)tv.tv_sec * 1000 + tv.tv_usec / 1000;
-+    return 0;
-+}
-+
-+#ifdef USE_POLL
-+
-+/* Find a pollfd in selstate by fd, or abort if we can't find it. */
-+static inline struct pollfd *
-+find_pollfd(struct select_state *selstate, int fd)
-+{
-+    int i;
-+
-+    for (i = 0; i < selstate->nfds; i++) {
-+        if (selstate->fds[i].fd == fd)
-+            return &selstate->fds[i];
-+    }
-+    abort();
-+}
-+
-+static void
-+cm_init_selstate(struct select_state *selstate)
-+{
-+    selstate->nfds = 0;
-+}
-+
-+static krb5_boolean
-+cm_add_fd(struct select_state *selstate, int fd)
-+{
-+    if (selstate->nfds >= MAX_POLLFDS)
-+        return FALSE;
-+    selstate->fds[selstate->nfds].fd = fd;
-+    selstate->fds[selstate->nfds].events = 0;
-+    selstate->nfds++;
-+    return TRUE;
-+}
-+
-+static void
-+cm_remove_fd(struct select_state *selstate, int fd)
-+{
-+    struct pollfd *pfd = find_pollfd(selstate, fd);
-+
-+    *pfd = selstate->fds[selstate->nfds - 1];
-+    selstate->nfds--;
-+}
-+
-+/* Poll for reading (and not writing) on fd the next time we poll. */
-+static void
-+cm_read(struct select_state *selstate, int fd)
-+{
-+    find_pollfd(selstate, fd)->events = POLLIN;
-+}
-+
-+/* Poll for writing (and not reading) on fd the next time we poll. */
-+static void
-+cm_write(struct select_state *selstate, int fd)
-+{
-+    find_pollfd(selstate, fd)->events = POLLOUT;
-+}
-+
-+/* Get the output events for fd in the form of ssflags. */
-+static unsigned int
-+cm_get_ssflags(struct select_state *selstate, int fd)
-+{
-+    struct pollfd *pfd = find_pollfd(selstate, fd);
-+
-+    return ((pfd->revents & POLLIN) ? SSF_READ : 0) |
-+        ((pfd->revents & POLLOUT) ? SSF_WRITE : 0) |
-+        ((pfd->revents & POLLERR) ? SSF_EXCEPTION : 0);
-+}
-+
-+#else /* not USE_POLL */
-+
-+static void
-+cm_init_selstate(struct select_state *selstate)
-+{
-+    selstate->nfds = 0;
-+    selstate->max = 0;
-+    FD_ZERO(&selstate->rfds);
-+    FD_ZERO(&selstate->wfds);
-+    FD_ZERO(&selstate->xfds);
-+}
-+
-+static krb5_boolean
-+cm_add_fd(struct select_state *selstate, int fd)
-+{
-+#ifndef _WIN32  /* On Windows FD_SETSIZE is a count, not a max value. */
-+    if (fd >= FD_SETSIZE)
-+        return FALSE;
-+#endif
-+    FD_SET(fd, &selstate->xfds);
-+    if (selstate->max <= fd)
-+        selstate->max = fd + 1;
-+    selstate->nfds++;
-+    return TRUE;
-+}
-+
-+static void
-+cm_remove_fd(struct select_state *selstate, int fd)
-+{
-+    FD_CLR(fd, &selstate->rfds);
-+    FD_CLR(fd, &selstate->wfds);
-+    FD_CLR(fd, &selstate->xfds);
-+    if (selstate->max == fd + 1) {
-+        while (selstate->max > 0 &&
-+               !FD_ISSET(selstate->max - 1, &selstate->rfds) &&
-+               !FD_ISSET(selstate->max - 1, &selstate->wfds) &&
-+               !FD_ISSET(selstate->max - 1, &selstate->xfds))
-+            selstate->max--;
-+    }
-+    selstate->nfds--;
-+}
-+
-+/* Select for reading (and not writing) on fd the next time we select. */
-+static void
-+cm_read(struct select_state *selstate, int fd)
-+{
-+    FD_SET(fd, &selstate->rfds);
-+    FD_CLR(fd, &selstate->wfds);
-+}
-+
-+/* Select for writing (and not reading) on fd the next time we select. */
-+static void
-+cm_write(struct select_state *selstate, int fd)
-+{
-+    FD_CLR(fd, &selstate->rfds);
-+    FD_SET(fd, &selstate->wfds);
-+}
-+
-+/* Get the events for fd from selstate after a select. */
-+static unsigned int
-+cm_get_ssflags(struct select_state *selstate, int fd)
-+{
-+    return (FD_ISSET(fd, &selstate->rfds) ? SSF_READ : 0) |
-+        (FD_ISSET(fd, &selstate->wfds) ? SSF_WRITE : 0) |
-+        (FD_ISSET(fd, &selstate->xfds) ? SSF_EXCEPTION : 0);
-+}
-+
-+#endif /* not USE_POLL */
-+
-+static krb5_error_code
-+cm_select_or_poll(const struct select_state *in, time_ms endtime,
-+                  struct select_state *out, int *sret)
-+{
-+#ifndef USE_POLL
-+    struct timeval tv;
-+#endif
-+    krb5_error_code retval;
-+    time_ms curtime, interval;
-+
-+    retval = get_curtime_ms(&curtime);
-+    if (retval != 0)
-+        return retval;
-+    interval = (curtime < endtime) ? endtime - curtime : 0;
-+
-+    /* We don't need a separate copy of the selstate for poll, but use one for
-+     * consistency with how we use select. */
-+    *out = *in;
-+
-+#ifdef USE_POLL
-+    *sret = poll(out->fds, out->nfds, interval);
-+#else
-+    tv.tv_sec = interval / 1000;
-+    tv.tv_usec = interval % 1000 * 1000;
-+    *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, &tv);
-+#endif
-+
-+    return (*sret < 0) ? SOCKET_ERRNO : 0;
-+}
-+
- static int
- in_addrlist(struct server_entry *entry, struct serverlist *list)
- {
-@@ -251,18 +427,6 @@ cleanup:
-     return retval;
- }
- 
--/* Get current time in milliseconds. */
--static krb5_error_code
--get_curtime_ms(time_ms *time_out)
--{
--    struct timeval tv;
--
--    if (gettimeofday(&tv, 0))
--        return errno;
--    *time_out = (time_ms)tv.tv_sec * 1000 + tv.tv_usec / 1000;
--    return 0;
--}
--
- /*
-  * Notes:
-  *
-@@ -283,144 +447,6 @@ get_curtime_ms(time_ms *time_out)
-  *   connections already in progress
-  */
- 
--static void
--cm_init_selstate(struct select_state *selstate)
--{
--    selstate->nfds = 0;
--#ifndef USE_POLL
--    selstate->max = 0;
--    FD_ZERO(&selstate->rfds);
--    FD_ZERO(&selstate->wfds);
--    FD_ZERO(&selstate->xfds);
--#endif
--}
--
--static krb5_boolean
--cm_add_fd(struct select_state *selstate, int fd, unsigned int ssflags)
--{
--#ifdef USE_POLL
--    if (selstate->nfds >= MAX_POLLFDS)
--        return FALSE;
--    selstate->fds[selstate->nfds].fd = fd;
--    selstate->fds[selstate->nfds].events = 0;
--    if (ssflags & SSF_READ)
--        selstate->fds[selstate->nfds].events |= POLLIN;
--    if (ssflags & SSF_WRITE)
--        selstate->fds[selstate->nfds].events |= POLLOUT;
--#else
--#ifndef _WIN32  /* On Windows FD_SETSIZE is a count, not a max value. */
--    if (fd >= FD_SETSIZE)
--        return FALSE;
--#endif
--    if (ssflags & SSF_READ)
--        FD_SET(fd, &selstate->rfds);
--    if (ssflags & SSF_WRITE)
--        FD_SET(fd, &selstate->wfds);
--    if (ssflags & SSF_EXCEPTION)
--        FD_SET(fd, &selstate->xfds);
--    if (selstate->max <= fd)
--        selstate->max = fd + 1;
--#endif
--    selstate->nfds++;
--    return TRUE;
--}
--
--static void
--cm_remove_fd(struct select_state *selstate, int fd)
--{
--#ifdef USE_POLL
--    int i;
--
--    /* Find the FD in the array and move the last entry to its place. */
--    assert(selstate->nfds > 0);
--    for (i = 0; i < selstate->nfds && selstate->fds[i].fd != fd; i++);
--    assert(i < selstate->nfds);
--    selstate->fds[i] = selstate->fds[selstate->nfds - 1];
--#else
--    FD_CLR(fd, &selstate->rfds);
--    FD_CLR(fd, &selstate->wfds);
--    FD_CLR(fd, &selstate->xfds);
--    if (selstate->max == 1 + fd) {
--        while (selstate->max > 0
--               && ! FD_ISSET(selstate->max-1, &selstate->rfds)
--               && ! FD_ISSET(selstate->max-1, &selstate->wfds)
--               && ! FD_ISSET(selstate->max-1, &selstate->xfds))
--            selstate->max--;
--    }
--#endif
--    selstate->nfds--;
--}
--
--static void
--cm_unset_write(struct select_state *selstate, int fd)
--{
--#ifdef USE_POLL
--    int i;
--
--    for (i = 0; i < selstate->nfds && selstate->fds[i].fd != fd; i++);
--    assert(i < selstate->nfds);
--    selstate->fds[i].events &= ~POLLOUT;
--#else
--    FD_CLR(fd, &selstate->wfds);
--#endif
--}
--
--static krb5_error_code
--cm_select_or_poll(const struct select_state *in, time_ms endtime,
--                  struct select_state *out, int *sret)
--{
--#ifndef USE_POLL
--    struct timeval tv;
--#endif
--    krb5_error_code retval;
--    time_ms curtime, interval;
--
--    retval = get_curtime_ms(&curtime);
--    if (retval != 0)
--        return retval;
--    interval = (curtime < endtime) ? endtime - curtime : 0;
--
--    /* We don't need a separate copy of the selstate for poll, but use one for
--     * consistency with how we use select. */
--    *out = *in;
--
--#ifdef USE_POLL
--    *sret = poll(out->fds, out->nfds, interval);
--#else
--    tv.tv_sec = interval / 1000;
--    tv.tv_usec = interval % 1000 * 1000;
--    *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, &tv);
--#endif
--
--    return (*sret < 0) ? SOCKET_ERRNO : 0;
--}
--
--static unsigned int
--cm_get_ssflags(struct select_state *selstate, int fd)
--{
--    unsigned int ssflags = 0;
--#ifdef USE_POLL
--    int i;
--
--    for (i = 0; i < selstate->nfds && selstate->fds[i].fd != fd; i++);
--    assert(i < selstate->nfds);
--    if (selstate->fds[i].revents & POLLIN)
--        ssflags |= SSF_READ;
--    if (selstate->fds[i].revents & POLLOUT)
--        ssflags |= SSF_WRITE;
--    if (selstate->fds[i].revents & POLLERR)
--        ssflags |= SSF_EXCEPTION;
--#else
--    if (FD_ISSET(fd, &selstate->rfds))
--        ssflags |= SSF_READ;
--    if (FD_ISSET(fd, &selstate->wfds))
--        ssflags |= SSF_WRITE;
--    if (FD_ISSET(fd, &selstate->xfds))
--        ssflags |= SSF_EXCEPTION;
--#endif
--    return ssflags;
--}
--
- static int service_tcp_fd(krb5_context context, struct conn_state *conn,
-                           struct select_state *selstate, int ssflags);
- static int service_udp_fd(krb5_context context, struct conn_state *conn,
-@@ -600,7 +626,6 @@ start_connection(krb5_context context, struct conn_state *state,
-                  struct sendto_callback_info *callback_info)
- {
-     int fd, e;
--    unsigned int ssflags;
-     static const int one = 1;
-     static const struct linger lopt = { 0, 0 };
- 
-@@ -676,15 +701,17 @@ start_connection(krb5_context context, struct conn_state *state,
-             state->state = READING;
-         }
-     }
--    ssflags = SSF_READ | SSF_EXCEPTION;
--    if (state->state == CONNECTING || state->state == WRITING)
--        ssflags |= SSF_WRITE;
--    if (!cm_add_fd(selstate, state->fd, ssflags)) {
-+
-+    if (!cm_add_fd(selstate, state->fd)) {
-         (void) closesocket(state->fd);
-         state->fd = INVALID_SOCKET;
-         state->state = FAILED;
-         return -1;
-     }
-+    if (state->state == CONNECTING || state->state == WRITING)
-+        cm_write(selstate, state->fd);
-+    else
-+        cm_read(selstate, state->fd);
- 
-     return 0;
- }
-@@ -768,9 +795,8 @@ service_tcp_fd(krb5_context context, struct conn_state *conn,
-     ssize_t nwritten, nread;
-     SOCKET_WRITEV_TEMP tmp;
- 
--    /* Check for a socket exception or readable data before we expect it. */
--    if (ssflags & SSF_EXCEPTION ||
--        ((ssflags & SSF_READ) && conn->state != READING))
-+    /* Check for a socket exception. */
-+    if (ssflags & SSF_EXCEPTION)
-         goto kill_conn;
- 
-     switch (conn->state) {
-@@ -810,7 +836,7 @@ service_tcp_fd(krb5_context context, struct conn_state *conn,
-         }
-         if (conn->x.out.sg_count == 0) {
-             /* Done writing, switch to reading. */
--            cm_unset_write(selstate, conn->fd);
-+            cm_read(selstate, conn->fd);
-             conn->state = READING;
-             conn->x.in.bufsizebytes_read = 0;
-             conn->x.in.bufsize = 0;
diff --git a/SOURCES/0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch b/SOURCES/0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch
deleted file mode 100644
index ac7baa1..0000000
--- a/SOURCES/0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch
+++ /dev/null
@@ -1,230 +0,0 @@
-From 74e775ac6d937c9d22be4fc1d429e5e62705fb7d Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@redhat.com>
-Date: Thu, 24 Jul 2014 15:39:53 -0400
-Subject: [PATCH 1/7] In ksu, merge krb5_ccache_copy() and _restricted()
-
-Other than whether or not they limit the creds it stores to the new
-ccache based on the principal name of the client for whom the creds were
-issued, there's no meaningful difference between what these two
-functions do.  Merge them.
----
- src/clients/ksu/ccache.c | 106 ++++++-----------------------------------------
- src/clients/ksu/ksu.h    |   6 +--
- src/clients/ksu/main.c   |  27 ++++--------
- 3 files changed, 22 insertions(+), 117 deletions(-)
-
-diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index 9916c75..118fc53 100644
---- a/src/clients/ksu/ccache.c
-+++ b/src/clients/ksu/ccache.c
-@@ -47,12 +47,14 @@ void show_credential();
- */
- 
- krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
--                                  primary_principal, cc_out, stored, target_uid)
-+                                  primary_principal, restrict_creds, cc_out,
-+                                  stored, target_uid)
- /* IN */
-     krb5_context context;
-     krb5_ccache cc_def;
-     char *cc_other_tag;
-     krb5_principal primary_principal;
-+    krb5_boolean restrict_creds;
-     uid_t target_uid;
-     /* OUT */
-     krb5_ccache *cc_out;
-@@ -83,9 +85,6 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
-         }
-     }
- 
--    *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr,
--                                           primary_principal);
--
-     if (!lstat( cc_other_name, &st_temp))
-         return EINVAL;
- 
-@@ -98,8 +97,16 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
-         return retval;
-     }
- 
--    retval = krb5_store_all_creds(context, * cc_other, cc_def_creds_arr,
--                                  cc_other_creds_arr);
-+    if (restrict_creds) {
-+        retval = krb5_store_some_creds(context, *cc_other, cc_def_creds_arr,
-+                                       cc_other_creds_arr, primary_principal,
-+                                       stored);
-+    } else {
-+        *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr,
-+                                               primary_principal);
-+        retval = krb5_store_all_creds(context, *cc_other, cc_def_creds_arr,
-+                                      cc_other_creds_arr);
-+    }
- 
-     if (cc_def_creds_arr){
-         while (cc_def_creds_arr[i]){
-@@ -623,93 +630,6 @@ krb5_error_code krb5_store_some_creds(context, cc, creds_def, creds_other, prst,
-     *stored = temp_stored;
-     return 0;
- }
--/******************************************************************
--krb5_cache_copy_restricted
--
--gets rid of any expired tickets in the secondary cache,
--copies the default cache into the secondary cache,
--only credentials that are for prst are copied.
--
--the algorithm may look a bit funny,
--but I had to do it this way, since cc_remove function did not come
--with k5 beta 3 release.
--************************************************************************/
--
--krb5_error_code krb5_ccache_copy_restricted (context, cc_def, cc_other_tag,
--                                             prst, cc_out, stored, target_uid)
--    krb5_context context;
--    krb5_ccache cc_def;
--    char *cc_other_tag;
--    krb5_principal prst;
--    uid_t target_uid;
--    /* OUT */
--    krb5_ccache *cc_out;
--    krb5_boolean *stored;
--{
--
--    int i=0;
--    krb5_ccache  * cc_other;
--    const char * cc_def_name;
--    const char * cc_other_name;
--    krb5_error_code retval=0;
--    krb5_creds ** cc_def_creds_arr = NULL;
--    krb5_creds ** cc_other_creds_arr = NULL;
--    struct stat st_temp;
--
--    cc_other = (krb5_ccache *)  xcalloc(1, sizeof (krb5_ccache));
--
--    if ((retval = krb5_cc_resolve(context, cc_other_tag, cc_other))){
--        com_err(prog_name, retval, _("resolving ccache %s"), cc_other_tag);
--        return retval;
--    }
--
--    cc_def_name = krb5_cc_get_name(context, cc_def);
--    cc_other_name = krb5_cc_get_name(context, *cc_other);
--
--    if ( ! stat(cc_def_name, &st_temp)){
--        if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
--            return retval;
--        }
--
--    }
--
--    if (!lstat( cc_other_name, &st_temp)) {
--        return EINVAL;
--    }
--
--    if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
--        return errno;
--    }
--
--
--    if ((retval = krb5_cc_initialize(context, *cc_other, prst))){
--        return retval;
--    }
--
--    retval = krb5_store_some_creds(context, * cc_other,
--                                   cc_def_creds_arr, cc_other_creds_arr, prst, stored);
--
--
--
--    if (cc_def_creds_arr){
--        while (cc_def_creds_arr[i]){
--            krb5_free_creds(context, cc_def_creds_arr[i]);
--            i++;
--        }
--    }
--
--    i=0;
--
--    if(cc_other_creds_arr){
--        while (cc_other_creds_arr[i]){
--            krb5_free_creds(context, cc_other_creds_arr[i]);
--            i++;
--        }
--    }
--
--    *cc_out = *cc_other;
--    return retval;
--}
- 
- krb5_error_code krb5_ccache_filter (context, cc, prst)
-     krb5_context context;
-diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
-index f2c0811..9e0c613 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -107,7 +107,7 @@ extern krb5_error_code get_best_principal
- /* ccache.c */
- extern krb5_error_code krb5_ccache_copy
- (krb5_context, krb5_ccache, char *, krb5_principal,
-- krb5_ccache *, krb5_boolean *, uid_t);
-+ krb5_boolean, krb5_ccache *, krb5_boolean *, uid_t);
- 
- extern krb5_error_code krb5_store_all_creds
- (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **);
-@@ -141,10 +141,6 @@ extern krb5_error_code krb5_store_some_creds
- (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **,
-  krb5_principal, krb5_boolean *);
- 
--extern krb5_error_code krb5_ccache_copy_restricted
--(krb5_context, krb5_ccache, char *, krb5_principal,
-- krb5_ccache *, krb5_boolean *, uid_t);
--
- extern krb5_error_code krb5_ccache_refresh
- (krb5_context, krb5_ccache);
- 
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index 233eb52..62f3bc0 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -117,6 +117,7 @@ main (argc, argv)
-     krb5_principal  kdc_server;
-     krb5_boolean zero_password;
-     char * dir_of_cc_target;
-+    krb5_boolean restrict_creds;
- 
-     options.opt = KRB5_DEFAULT_OPTIONS;
-     options.lifetime = KRB5_DEFAULT_TKT_LIFE;
-@@ -464,25 +465,13 @@ main (argc, argv)
-        then only the credentials for that particular user
-        should be copied */
- 
--    if ((source_uid == 0) && (target_uid != 0)) {
--
--        if ((retval = krb5_ccache_copy_restricted(ksu_context,  cc_source,
--                                                  cc_target_tag, client,
--                                                  &cc_target, &stored,
--                                                  target_uid))){
--            com_err(prog_name, retval, _("while copying cache %s to %s"),
--                    krb5_cc_get_name(ksu_context, cc_source), cc_target_tag);
--            exit(1);
--        }
--
--    } else {
--        if ((retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag,
--                                       client,&cc_target, &stored, target_uid))) {
--            com_err(prog_name, retval, _("while copying cache %s to %s"),
--                    krb5_cc_get_name(ksu_context, cc_source), cc_target_tag);
--            exit(1);
--        }
--
-+    restrict_creds = (source_uid == 0) && (target_uid != 0);
-+    retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, client,
-+                              restrict_creds, &cc_target, &stored, target_uid);
-+    if (retval) {
-+        com_err(prog_name, retval, _("while copying cache %s to %s"),
-+                krb5_cc_get_name(ksu_context, cc_source), cc_target_tag);
-+        exit(1);
-     }
- 
-     /* Become root for authentication*/
--- 
-2.0.4
-
diff --git a/SOURCES/0001-Simplify-sendto_kdc.c.patch b/SOURCES/0001-Simplify-sendto_kdc.c.patch
deleted file mode 100644
index 51c512d..0000000
--- a/SOURCES/0001-Simplify-sendto_kdc.c.patch
+++ /dev/null
@@ -1,421 +0,0 @@
-From 42b3c2ed11c1e62c1691f868a6796983f93c3beb Mon Sep 17 00:00:00 2001
-From: Greg Hudson <ghudson@mit.edu>
-Date: Wed, 9 Apr 2014 13:19:03 -0400
-Subject: [PATCH 01/13] Simplify sendto_kdc.c
-
-* Get rid of the "x" member of conn_state, which used to be a union
-  but hasn't been since r14742.
-* Define a structure type for the "out" member of conn_state.
-* Rename incoming_krb5_message to incoming_message for brevity.
-* Make the "pos" member of incoming_message an offset instead of a
-  pointer, simplifying several present and future computations.
-* Use "in" and "out" aliases to the conn_state in and out members
-  where it improves brevity.
-* Rename set_conn_state_msg_length to set_transport_message and give
-  it a descriptive comment.
-* Call set_transport_message from start_connection only, instead of
-  once in add_connection and perhaps again in start_connection.  To
-  make this possible, pass the original message argument to maybe_send
-  and start_connection.
-* Use make_data and empty_data helpers where appropriate.
----
- src/lib/krb5/os/sendto_kdc.c | 159 +++++++++++++++++++++----------------------
- 1 file changed, 79 insertions(+), 80 deletions(-)
-
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index 67e2a60..5f781d3 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -76,30 +76,30 @@ static const char *const state_strings[] = {
- 
- /* connection states */
- enum conn_states { INITIALIZING, CONNECTING, WRITING, READING, FAILED };
--struct incoming_krb5_message {
-+struct incoming_message {
-     size_t bufsizebytes_read;
-     size_t bufsize;
-+    size_t pos;
-     char *buf;
--    char *pos;
-     unsigned char bufsizebytes[4];
-     size_t n_left;
- };
- 
-+struct outgoing_message {
-+    sg_buf sgbuf[2];
-+    sg_buf *sgp;
-+    int sg_count;
-+    unsigned char msg_len_buf[4];
-+};
-+
- struct conn_state {
-     SOCKET fd;
-     enum conn_states state;
-     int (*service)(krb5_context context, struct conn_state *,
-                    struct select_state *, int);
-     struct remote_address addr;
--    struct {
--        struct {
--            sg_buf sgbuf[2];
--            sg_buf *sgp;
--            int sg_count;
--            unsigned char msg_len_buf[4];
--        } out;
--        struct incoming_krb5_message in;
--    } x;
-+    struct incoming_message in;
-+    struct outgoing_message out;
-     krb5_data callback_buffer;
-     size_t server_index;
-     struct conn_state *next;
-@@ -461,30 +461,31 @@ static int service_tcp_fd(krb5_context context, struct conn_state *conn,
- static int service_udp_fd(krb5_context context, struct conn_state *conn,
-                           struct select_state *selstate, int ssflags);
- 
-+/* Set up the actual message we will send across the underlying transport to
-+ * communicate the payload message, using one or both of state->out.sgbuf. */
- static void
--set_conn_state_msg_length (struct conn_state *state, const krb5_data *message)
-+set_transport_message(struct conn_state *state, const krb5_data *message)
- {
--    if (!message || message->length == 0)
-+    struct outgoing_message *out = &state->out;
-+
-+    if (message == NULL || message->length == 0)
-         return;
- 
-     if (state->addr.type == SOCK_STREAM) {
--        store_32_be(message->length, state->x.out.msg_len_buf);
--        SG_SET(&state->x.out.sgbuf[0], state->x.out.msg_len_buf, 4);
--        SG_SET(&state->x.out.sgbuf[1], message->data, message->length);
--        state->x.out.sg_count = 2;
--
-+        store_32_be(message->length, out->msg_len_buf);
-+        SG_SET(&out->sgbuf[0], out->msg_len_buf, 4);
-+        SG_SET(&out->sgbuf[1], message->data, message->length);
-+        out->sg_count = 2;
-     } else {
--
--        SG_SET(&state->x.out.sgbuf[0], message->data, message->length);
--        SG_SET(&state->x.out.sgbuf[1], 0, 0);
--        state->x.out.sg_count = 1;
--
-+        SG_SET(&out->sgbuf[0], message->data, message->length);
-+        SG_SET(&out->sgbuf[1], NULL, 0);
-+        out->sg_count = 1;
-     }
- }
- 
- static krb5_error_code
- add_connection(struct conn_state **conns, struct addrinfo *ai,
--               size_t server_index, const krb5_data *message, char **udpbufp)
-+               size_t server_index, char **udpbufp)
- {
-     struct conn_state *state, **tailptr;
- 
-@@ -492,28 +493,26 @@ add_connection(struct conn_state **conns, struct addrinfo *ai,
-     if (state == NULL)
-         return ENOMEM;
-     state->state = INITIALIZING;
--    state->x.out.sgp = state->x.out.sgbuf;
-+    state->out.sgp = state->out.sgbuf;
-     state->addr.type = ai->ai_socktype;
-     state->addr.family = ai->ai_family;
-     state->addr.len = ai->ai_addrlen;
-     memcpy(&state->addr.saddr, ai->ai_addr, ai->ai_addrlen);
-     state->fd = INVALID_SOCKET;
-     state->server_index = server_index;
--    SG_SET(&state->x.out.sgbuf[1], 0, 0);
-+    SG_SET(&state->out.sgbuf[1], NULL, 0);
-     if (ai->ai_socktype == SOCK_STREAM) {
-         state->service = service_tcp_fd;
--        set_conn_state_msg_length (state, message);
-     } else {
-         state->service = service_udp_fd;
--        set_conn_state_msg_length (state, message);
- 
-         if (*udpbufp == NULL) {
-             *udpbufp = malloc(MAX_DGRAM_SIZE);
-             if (*udpbufp == 0)
-                 return ENOMEM;
-         }
--        state->x.in.buf = *udpbufp;
--        state->x.in.bufsize = MAX_DGRAM_SIZE;
-+        state->in.buf = *udpbufp;
-+        state->in.bufsize = MAX_DGRAM_SIZE;
-     }
- 
-     /* Chain the new state onto the tail of the list. */
-@@ -597,7 +596,7 @@ resolve_server(krb5_context context, const struct serverlist *servers,
-         ai.ai_family = entry->family;
-         ai.ai_addrlen = entry->addrlen;
-         ai.ai_addr = (struct sockaddr *)&entry->addr;
--        return add_connection(conns, &ai, ind, message, udpbufp);
-+        return add_connection(conns, &ai, ind, udpbufp);
-     }
- 
-     memset(&hint, 0, sizeof(hint));
-@@ -617,12 +616,12 @@ resolve_server(krb5_context context, const struct serverlist *servers,
-     /* Add each address with the preferred socktype. */
-     retval = 0;
-     for (a = addrs; a != 0 && retval == 0; a = a->ai_next)
--        retval = add_connection(conns, a, ind, message, udpbufp);
-+        retval = add_connection(conns, a, ind, udpbufp);
-     if (retval == 0 && entry->socktype == 0 && socktype2 != 0) {
-         /* Add each address again with the non-preferred socktype. */
-         for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
-             a->ai_socktype = socktype2;
--            retval = add_connection(conns, a, ind, message, udpbufp);
-+            retval = add_connection(conns, a, ind, udpbufp);
-         }
-     }
-     freeaddrinfo(addrs);
-@@ -631,7 +630,7 @@ resolve_server(krb5_context context, const struct serverlist *servers,
- 
- static int
- start_connection(krb5_context context, struct conn_state *state,
--                 struct select_state *selstate,
-+                 const krb5_data *message, struct select_state *selstate,
-                  struct sendto_callback_info *callback_info)
- {
-     int fd, e;
-@@ -689,13 +688,14 @@ start_connection(krb5_context context, struct conn_state *state,
-             return -3;
-         }
- 
--        set_conn_state_msg_length(state, &state->callback_buffer);
-+        message = &state->callback_buffer;
-     }
-+    set_transport_message(state, message);
- 
-     if (state->addr.type == SOCK_DGRAM) {
-         /* Send it now.  */
-         ssize_t ret;
--        sg_buf *sg = &state->x.out.sgbuf[0];
-+        sg_buf *sg = &state->out.sgbuf[0];
- 
-         TRACE_SENDTO_KDC_UDP_SEND_INITIAL(context, &state->addr);
-         ret = send(state->fd, SG_BUF(sg), SG_LEN(sg), 0);
-@@ -731,14 +731,16 @@ start_connection(krb5_context context, struct conn_state *state,
-    next connection.  */
- static int
- maybe_send(krb5_context context, struct conn_state *conn,
--           struct select_state *selstate,
-+           const krb5_data *message, struct select_state *selstate,
-            struct sendto_callback_info *callback_info)
- {
-     sg_buf *sg;
-     ssize_t ret;
- 
--    if (conn->state == INITIALIZING)
--        return start_connection(context, conn, selstate, callback_info);
-+    if (conn->state == INITIALIZING) {
-+        return start_connection(context, conn, message, selstate,
-+                                callback_info);
-+    }
- 
-     /* Did we already shut down this channel?  */
-     if (conn->state == FAILED) {
-@@ -752,7 +754,7 @@ maybe_send(krb5_context context, struct conn_state *conn,
-     }
- 
-     /* UDP - retransmit after a previous attempt timed out. */
--    sg = &conn->x.out.sgbuf[0];
-+    sg = &conn->out.sgbuf[0];
-     TRACE_SENDTO_KDC_UDP_SEND_RETRY(context, &conn->addr);
-     ret = send(conn->fd, SG_BUF(sg), SG_LEN(sg), 0);
-     if (ret < 0 || (size_t) ret != SG_LEN(sg)) {
-@@ -803,6 +805,8 @@ service_tcp_fd(krb5_context context, struct conn_state *conn,
-     int e = 0;
-     ssize_t nwritten, nread;
-     SOCKET_WRITEV_TEMP tmp;
-+    struct incoming_message *in = &conn->in;
-+    struct outgoing_message *out = &conn->out;
- 
-     /* Check for a socket exception. */
-     if (ssflags & SSF_EXCEPTION)
-@@ -825,68 +829,68 @@ service_tcp_fd(krb5_context context, struct conn_state *conn,
-         /* Fall through. */
-     case WRITING:
-         TRACE_SENDTO_KDC_TCP_SEND(context, &conn->addr);
--        nwritten = SOCKET_WRITEV(conn->fd, conn->x.out.sgp,
--                                 conn->x.out.sg_count, tmp);
-+        nwritten = SOCKET_WRITEV(conn->fd, out->sgp, out->sg_count, tmp);
-         if (nwritten < 0) {
-             TRACE_SENDTO_KDC_TCP_ERROR_SEND(context, &conn->addr,
-                                             SOCKET_ERRNO);
-             goto kill_conn;
-         }
-         while (nwritten) {
--            sg_buf *sgp = conn->x.out.sgp;
-+            sg_buf *sgp = out->sgp;
-             if ((size_t) nwritten < SG_LEN(sgp)) {
-                 SG_ADVANCE(sgp, (size_t) nwritten);
-                 nwritten = 0;
-             } else {
-                 nwritten -= SG_LEN(sgp);
--                conn->x.out.sgp++;
--                conn->x.out.sg_count--;
-+                out->sgp++;
-+                out->sg_count--;
-             }
-         }
--        if (conn->x.out.sg_count == 0) {
-+        if (out->sg_count == 0) {
-             /* Done writing, switch to reading. */
-             cm_read(selstate, conn->fd);
-             conn->state = READING;
--            conn->x.in.bufsizebytes_read = 0;
--            conn->x.in.bufsize = 0;
--            conn->x.in.buf = 0;
--            conn->x.in.pos = 0;
--            conn->x.in.n_left = 0;
-+            in->bufsizebytes_read = 0;
-+            in->bufsize = 0;
-+            in->pos = 0;
-+            in->buf = NULL;
-+            in->n_left = 0;
-         }
-         return 0;
- 
-     case READING:
--        if (conn->x.in.bufsizebytes_read == 4) {
-+        if (in->bufsizebytes_read == 4) {
-             /* Reading data.  */
--            nread = SOCKET_READ(conn->fd, conn->x.in.pos, conn->x.in.n_left);
-+            nread = SOCKET_READ(conn->fd, &in->buf[in->pos], in->n_left);
-             if (nread <= 0) {
-                 e = nread ? SOCKET_ERRNO : ECONNRESET;
-                 TRACE_SENDTO_KDC_TCP_ERROR_RECV(context, &conn->addr, e);
-                 goto kill_conn;
-             }
--            conn->x.in.n_left -= nread;
--            conn->x.in.pos += nread;
--            if (conn->x.in.n_left <= 0)
-+            in->n_left -= nread;
-+            in->pos += nread;
-+            if (in->n_left <= 0)
-                 return 1;
-         } else {
-             /* Reading length.  */
-             nread = SOCKET_READ(conn->fd,
--                                conn->x.in.bufsizebytes + conn->x.in.bufsizebytes_read,
--                                4 - conn->x.in.bufsizebytes_read);
-+                                in->bufsizebytes + in->bufsizebytes_read,
-+                                4 - in->bufsizebytes_read);
-             if (nread <= 0) {
-                 e = nread ? SOCKET_ERRNO : ECONNRESET;
-                 TRACE_SENDTO_KDC_TCP_ERROR_RECV_LEN(context, &conn->addr, e);
-                 goto kill_conn;
-             }
--            conn->x.in.bufsizebytes_read += nread;
--            if (conn->x.in.bufsizebytes_read == 4) {
--                unsigned long len = load_32_be (conn->x.in.bufsizebytes);
-+            in->bufsizebytes_read += nread;
-+            if (in->bufsizebytes_read == 4) {
-+                unsigned long len = load_32_be(in->bufsizebytes);
-                 /* Arbitrary 1M cap.  */
-                 if (len > 1 * 1024 * 1024)
-                     goto kill_conn;
--                conn->x.in.bufsize = conn->x.in.n_left = len;
--                conn->x.in.buf = conn->x.in.pos = malloc(len);
--                if (conn->x.in.buf == 0)
-+                in->bufsize = in->n_left = len;
-+                in->pos = 0;
-+                in->buf = malloc(len);
-+                if (in->buf == NULL)
-                     goto kill_conn;
-             }
-         }
-@@ -915,13 +919,13 @@ service_udp_fd(krb5_context context, struct conn_state *conn,
-     if (conn->state != READING)
-         abort();
- 
--    nread = recv(conn->fd, conn->x.in.buf, conn->x.in.bufsize, 0);
-+    nread = recv(conn->fd, conn->in.buf, conn->in.bufsize, 0);
-     if (nread < 0) {
-         TRACE_SENDTO_KDC_UDP_ERROR_RECV(context, &conn->addr, SOCKET_ERRNO);
-         kill_conn(conn, selstate);
-         return 0;
-     }
--    conn->x.in.pos = conn->x.in.buf + nread;
-+    conn->in.pos = nread;
-     return 1;
- }
- 
-@@ -986,10 +990,7 @@ service_fds(krb5_context context, struct select_state *selstate,
-                 int stop = 1;
- 
-                 if (msg_handler != NULL) {
--                    krb5_data reply;
--
--                    reply.data = state->x.in.buf;
--                    reply.length = state->x.in.pos - state->x.in.buf;
-+                    krb5_data reply = make_data(state->in.buf, state->in.pos);
- 
-                     stop = (msg_handler(context, &reply, msg_handler_data) != 0);
-                 }
-@@ -1051,8 +1052,7 @@ k5_sendto(krb5_context context, const krb5_data *message,
-     char *udpbuf = NULL;
-     krb5_boolean done = FALSE;
- 
--    reply->data = 0;
--    reply->length = 0;
-+    *reply = empty_data();
- 
-     /* One for use here, listing all our fds in use, and one for
-      * temporary use in service_fds, for the fds of interest.  */
-@@ -1077,7 +1077,7 @@ k5_sendto(krb5_context context, const krb5_data *message,
-             /* Contact each new connection whose socktype matches socktype1. */
-             if (state->addr.type != socktype1)
-                 continue;
--            if (maybe_send(context, state, sel_state, callback_info))
-+            if (maybe_send(context, state, message, sel_state, callback_info))
-                 continue;
-             done = service_fds(context, sel_state, 1000, conns, seltemp,
-                                msg_handler, msg_handler_data, &winner);
-@@ -1089,7 +1089,7 @@ k5_sendto(krb5_context context, const krb5_data *message,
-     for (state = conns; state != NULL && !done; state = state->next) {
-         if (state->addr.type != socktype2)
-             continue;
--        if (maybe_send(context, state, sel_state, callback_info))
-+        if (maybe_send(context, state, message, sel_state, callback_info))
-             continue;
-         done = service_fds(context, sel_state, 1000, conns, seltemp,
-                            msg_handler, msg_handler_data, &winner);
-@@ -1105,7 +1105,7 @@ k5_sendto(krb5_context context, const krb5_data *message,
-     delay = 4000;
-     for (pass = 1; pass < MAX_PASS && !done; pass++) {
-         for (state = conns; state != NULL && !done; state = state->next) {
--            if (maybe_send(context, state, sel_state, callback_info))
-+            if (maybe_send(context, state, message, sel_state, callback_info))
-                 continue;
-             done = service_fds(context, sel_state, 1000, conns, seltemp,
-                                msg_handler, msg_handler_data, &winner);
-@@ -1127,10 +1127,9 @@ k5_sendto(krb5_context context, const krb5_data *message,
-         goto cleanup;
-     }
-     /* Success!  */
--    reply->data = winner->x.in.buf;
--    reply->length = winner->x.in.pos - winner->x.in.buf;
-+    *reply = make_data(winner->in.buf, winner->in.pos);
-     retval = 0;
--    winner->x.in.buf = NULL;
-+    winner->in.buf = NULL;
-     if (server_used != NULL)
-         *server_used = winner->server_index;
-     if (remoteaddr != NULL && remoteaddrlen != 0 && *remoteaddrlen > 0)
-@@ -1142,8 +1141,8 @@ cleanup:
-         next = state->next;
-         if (state->fd != INVALID_SOCKET)
-             closesocket(state->fd);
--        if (state->state == READING && state->x.in.buf != udpbuf)
--            free(state->x.in.buf);
-+        if (state->state == READING && state->in.buf != udpbuf)
-+            free(state->in.buf);
-         if (callback_info) {
-             callback_info->pfn_cleanup(callback_info->data,
-                                        &state->callback_buffer);
--- 
-2.1.0
-
diff --git a/SOURCES/0002-Add-helper-to-determine-if-a-KDC-is-the-master.patch b/SOURCES/0002-Add-helper-to-determine-if-a-KDC-is-the-master.patch
deleted file mode 100644
index 50ae55b..0000000
--- a/SOURCES/0002-Add-helper-to-determine-if-a-KDC-is-the-master.patch
+++ /dev/null
@@ -1,233 +0,0 @@
-From f4b1a7e7b80ce68e57912edcd48c39ea62c73e43 Mon Sep 17 00:00:00 2001
-From: Greg Hudson <ghudson@mit.edu>
-Date: Sun, 6 Apr 2014 18:06:14 -0400
-Subject: [PATCH 02/13] Add helper to determine if a KDC is the master
-
-Add a new function k5_kdc_is_master in locate_kdc.c to determine
-whether a KDC matches one of the masters, and use it in
-krb5_sendto_kdc.
----
- src/lib/krb5/os/locate_kdc.c | 110 +++++++++++++++++++++++++++++--------------
- src/lib/krb5/os/os-proto.h   |   3 ++
- src/lib/krb5/os/sendto_kdc.c |  31 +-----------
- 3 files changed, 80 insertions(+), 64 deletions(-)
-
-diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
-index 88d55a8..4479465 100644
---- a/src/lib/krb5/os/locate_kdc.c
-+++ b/src/lib/krb5/os/locate_kdc.c
-@@ -166,6 +166,24 @@ add_host_to_list(struct serverlist *list, const char *hostname, int port,
-     return 0;
- }
- 
-+/* Return true if server is identical to an entry in list. */
-+static krb5_boolean
-+server_list_contains(struct serverlist *list, struct server_entry *server)
-+{
-+    struct server_entry *ent;
-+
-+    for (ent = list->servers; ent < list->servers + list->nservers; ent++) {
-+        if (server->hostname != NULL && ent->hostname != NULL &&
-+            strcmp(server->hostname, ent->hostname) == 0)
-+            return TRUE;
-+        if (server->hostname == NULL && ent->hostname == NULL &&
-+            server->addrlen == ent->addrlen &&
-+            memcmp(&server->addr, &ent->addr, server->addrlen) == 0)
-+            return TRUE;
-+    }
-+    return FALSE;
-+}
-+
- static krb5_error_code
- locate_srv_conf_1(krb5_context context, const krb5_data *realm,
-                   const char * name, struct serverlist *serverlist,
-@@ -529,6 +547,41 @@ dns_locate_server(krb5_context context, const krb5_data *realm,
- }
- #endif /* KRB5_DNS_LOOKUP */
- 
-+static krb5_error_code
-+locate_server(krb5_context context, const krb5_data *realm,
-+              struct serverlist *serverlist, enum locate_service_type svc,
-+              int socktype)
-+{
-+    krb5_error_code ret;
-+    struct serverlist list = SERVERLIST_INIT;
-+
-+    *serverlist = list;
-+
-+    /* Try modules.  If a module returns 0 but leaves the list empty, return an
-+     * empty list. */
-+    ret = module_locate_server(context, realm, &list, svc, socktype);
-+    if (ret != KRB5_PLUGIN_NO_HANDLE)
-+        goto done;
-+
-+    /* Try the profile.  Fall back to DNS if it returns an empty list. */
-+    ret = prof_locate_server(context, realm, &list, svc, socktype);
-+    if (ret)
-+        goto done;
-+
-+#ifdef KRB5_DNS_LOOKUP
-+    if (list.nservers == 0)
-+        ret = dns_locate_server(context, realm, &list, svc, socktype);
-+#endif
-+
-+done:
-+    if (ret) {
-+        k5_free_serverlist(&list);
-+        return ret;
-+    }
-+    *serverlist = list;
-+    return 0;
-+}
-+
- /*
-  * Wrapper function for the various backends
-  */
-@@ -538,54 +591,26 @@ k5_locate_server(krb5_context context, const krb5_data *realm,
-                  struct serverlist *serverlist, enum locate_service_type svc,
-                  int socktype)
- {
--    krb5_error_code code;
--    struct serverlist al = SERVERLIST_INIT;
--
--    *serverlist = al;
-+    krb5_error_code ret;
- 
-+    memset(serverlist, 0, sizeof(*serverlist));
-     if (realm == NULL || realm->data == NULL || realm->data[0] == 0) {
-         krb5_set_error_message(context, KRB5_REALM_CANT_RESOLVE,
-                                "Cannot find KDC for invalid realm name \"\"");
-         return KRB5_REALM_CANT_RESOLVE;
-     }
- 
--    code = module_locate_server(context, realm, &al, svc, socktype);
--    Tprintf("module_locate_server returns %d\n", code);
--    if (code == KRB5_PLUGIN_NO_HANDLE) {
--        /*
--         * We always try the local file before DNS.  Note that there
--         * is no way to indicate "service not available" via the
--         * config file.
--         */
--
--        code = prof_locate_server(context, realm, &al, svc, socktype);
--
--#ifdef KRB5_DNS_LOOKUP
--        if (code == 0 && al.nservers == 0)
--            code = dns_locate_server(context, realm, &al, svc, socktype);
--#endif /* KRB5_DNS_LOOKUP */
-+    ret = locate_server(context, realm, serverlist, svc, socktype);
-+    if (ret)
-+        return ret;
- 
--        /* We could put more heuristics here, like looking up a hostname
--           of "kerberos."+REALM, etc.  */
--    }
--    if (code == 0)
--        Tprintf ("krb5int_locate_server found %d addresses\n",
--                 al.nservers);
--    else
--        Tprintf ("krb5int_locate_server returning error code %d/%s\n",
--                 code, error_message(code));
--    if (code != 0) {
--        k5_free_serverlist(&al);
--        return code;
--    }
--    if (al.nservers == 0) {       /* No good servers */
--        k5_free_serverlist(&al);
-+    if (serverlist->nservers == 0) {
-+        k5_free_serverlist(serverlist);
-         krb5_set_error_message(context, KRB5_REALM_UNKNOWN,
-                                _("Cannot find KDC for realm \"%.*s\""),
-                                realm->length, realm->data);
-         return KRB5_REALM_UNKNOWN;
-     }
--    *serverlist = al;
-     return 0;
- }
- 
-@@ -598,3 +623,18 @@ k5_locate_kdc(krb5_context context, const krb5_data *realm,
-     stype = get_masters ? locate_service_master_kdc : locate_service_kdc;
-     return k5_locate_server(context, realm, serverlist, stype, socktype);
- }
-+
-+krb5_boolean
-+k5_kdc_is_master(krb5_context context, const krb5_data *realm,
-+                 struct server_entry *server)
-+{
-+    struct serverlist list;
-+    krb5_boolean found;
-+
-+    if (locate_server(context, realm, &list, locate_service_master_kdc,
-+                      server->socktype) != 0)
-+        return FALSE;
-+    found = server_list_contains(&list, server);
-+    k5_free_serverlist(&list);
-+    return found;
-+}
-diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
-index c6b730f..9125ba0 100644
---- a/src/lib/krb5/os/os-proto.h
-+++ b/src/lib/krb5/os/os-proto.h
-@@ -76,6 +76,9 @@ krb5_error_code k5_locate_kdc(krb5_context context, const krb5_data *realm,
-                               struct serverlist *serverlist, int get_masters,
-                               int socktype);
- 
-+krb5_boolean k5_kdc_is_master(krb5_context context, const krb5_data *realm,
-+                              struct server_entry *server);
-+
- void k5_free_serverlist(struct serverlist *);
- 
- #ifdef HAVE_NETINET_IN_H
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index 5f781d3..e3855a3 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -293,25 +293,6 @@ cm_select_or_poll(const struct select_state *in, time_ms endtime,
- }
- 
- static int
--in_addrlist(struct server_entry *entry, struct serverlist *list)
--{
--    size_t i;
--    struct server_entry *le;
--
--    for (i = 0; i < list->nservers; i++) {
--        le = &list->servers[i];
--        if (entry->hostname != NULL && le->hostname != NULL &&
--            strcmp(entry->hostname, le->hostname) == 0)
--            return 1;
--        if (entry->hostname == NULL && le->hostname == NULL &&
--            entry->addrlen == le->addrlen &&
--            memcmp(&entry->addr, &le->addr, entry->addrlen) == 0)
--            return 1;
--    }
--    return 0;
--}
--
--static int
- check_for_svc_unavailable (krb5_context context,
-                            const krb5_data *reply,
-                            void *msg_handler_data)
-@@ -418,17 +399,9 @@ krb5_sendto_kdc(krb5_context context, const krb5_data *message,
-     /* Set use_master to 1 if we ended up talking to a master when we didn't
-      * explicitly request to. */
-     if (*use_master == 0) {
--        struct serverlist mservers;
--        struct server_entry *entry = &servers.servers[server_used];
--        retval = k5_locate_kdc(context, realm, &mservers, TRUE,
--                               entry->socktype);
--        if (retval == 0) {
--            if (in_addrlist(entry, &mservers))
--                *use_master = 1;
--            k5_free_serverlist(&mservers);
--        }
-+        *use_master = k5_kdc_is_master(context, realm,
-+                                       &servers.servers[server_used]);
-         TRACE_SENDTO_KDC_MASTER(context, *use_master);
--        retval = 0;
-     }
- 
- cleanup:
--- 
-2.1.0
-
diff --git a/SOURCES/0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch b/SOURCES/0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch
deleted file mode 100644
index 262e7c7..0000000
--- a/SOURCES/0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch
+++ /dev/null
@@ -1,369 +0,0 @@
-From 9ebae7cb434b9b177c0af85c67a6d6267f46bc68 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@redhat.com>
-Date: Fri, 1 Nov 2013 09:48:13 -0400
-Subject: [PATCH 2/7] In ksu, don't stat() not-on-disk ccache residuals
-
-Don't assume that ccache residual names are filenames which we can
-stat() usefully.  Instead, use helper functions to call the library
-routines to try to read the default principal name from caches, and
-use whether or not that succeeds as an indication of whether or not
-there's a ccache in a given location.
-
-ticket: 7728
----
- src/clients/ksu/ccache.c    | 60 ++++++++++++++++++++--------------
- src/clients/ksu/heuristic.c | 13 ++------
- src/clients/ksu/ksu.h       |  8 +++--
- src/clients/ksu/main.c      | 79 +++++++++------------------------------------
- 4 files changed, 60 insertions(+), 100 deletions(-)
-
-diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index 118fc53..5f57279 100644
---- a/src/clients/ksu/ccache.c
-+++ b/src/clients/ksu/ccache.c
-@@ -62,12 +62,9 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
- {
-     int i=0;
-     krb5_ccache  * cc_other;
--    const char * cc_def_name;
--    const char * cc_other_name;
-     krb5_error_code retval=0;
-     krb5_creds ** cc_def_creds_arr = NULL;
-     krb5_creds ** cc_other_creds_arr = NULL;
--    struct stat st_temp;
- 
-     cc_other = (krb5_ccache *)  xcalloc(1, sizeof (krb5_ccache));
- 
-@@ -76,16 +73,13 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
-         return retval;
-     }
- 
--    cc_def_name = krb5_cc_get_name(context, cc_def);
--    cc_other_name = krb5_cc_get_name(context, *cc_other);
--
--    if ( ! stat(cc_def_name, &st_temp)){
-+    if (ks_ccache_is_initialized(context, cc_def)) {
-         if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
-             return retval;
-         }
-     }
- 
--    if (!lstat( cc_other_name, &st_temp))
-+    if (ks_ccache_name_is_initialized(context, cc_other_tag))
-         return EINVAL;
- 
-     if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
-@@ -540,24 +534,18 @@ krb5_error_code krb5_ccache_overwrite(context, ccs, cct, primary_principal)
-     krb5_ccache cct;
-     krb5_principal primary_principal;
- {
--    const char * cct_name;
--    const char * ccs_name;
-     krb5_error_code retval=0;
-     krb5_principal temp_principal;
-     krb5_creds ** ccs_creds_arr = NULL;
-     int i=0;
--    struct stat st_temp;
- 
--    ccs_name = krb5_cc_get_name(context, ccs);
--    cct_name = krb5_cc_get_name(context, cct);
--
--    if ( ! stat(ccs_name, &st_temp)){
-+    if (ks_ccache_is_initialized(context, ccs)) {
-         if ((retval = krb5_get_nonexp_tkts(context,  ccs, &ccs_creds_arr))){
-             return retval;
-         }
-     }
- 
--    if ( ! stat(cct_name, &st_temp)){
-+    if (ks_ccache_is_initialized(context, cct)) {
-         if ((retval = krb5_cc_get_principal(context, cct, &temp_principal))){
-             return retval;
-         }
-@@ -643,12 +631,10 @@ krb5_error_code krb5_ccache_filter (context, cc, prst)
-     krb5_creds ** cc_creds_arr = NULL;
-     const char * cc_name;
-     krb5_boolean stored;
--    struct stat st_temp;
- 
-     cc_name = krb5_cc_get_name(context, cc);
- 
--    if ( ! stat(cc_name, &st_temp)){
--
-+    if (ks_ccache_is_initialized(context, cc)) {
-         if (auth_debug) {
-             fprintf(stderr,"putting cache %s through a filter for -z option\n",                     cc_name);
-         }
-@@ -713,12 +699,8 @@ krb5_error_code  krb5_find_princ_in_cache (context, cc, princ, found)
- {
-     krb5_error_code retval;
-     krb5_creds ** creds_list = NULL;
--    const char * cc_name;
--    struct stat st_temp;
--
--    cc_name = krb5_cc_get_name(context, cc);
- 
--    if ( ! stat(cc_name, &st_temp)){
-+    if (ks_ccache_is_initialized(context, cc)) {
-         if ((retval = krb5_get_nonexp_tkts(context, cc, &creds_list))){
-             return retval;
-         }
-@@ -727,3 +709,33 @@ krb5_error_code  krb5_find_princ_in_cache (context, cc, princ, found)
-     *found = krb5_find_princ_in_cred_list(context, creds_list, princ);
-     return 0;
- }
-+
-+krb5_boolean
-+ks_ccache_name_is_initialized(krb5_context context, const char *cctag)
-+{
-+    krb5_boolean result;
-+    krb5_ccache cc;
-+
-+    if (krb5_cc_resolve(context, cctag, &cc) != 0)
-+        return FALSE;
-+    result = ks_ccache_is_initialized(context, cc);
-+    krb5_cc_close(context, cc);
-+
-+    return result;
-+}
-+
-+krb5_boolean
-+ks_ccache_is_initialized(krb5_context context, krb5_ccache cc)
-+{
-+    krb5_principal princ;
-+    krb5_error_code retval;
-+
-+    if (cc == NULL)
-+        return FALSE;
-+
-+    retval = krb5_cc_get_principal(context, cc, &princ);
-+    if (retval == 0)
-+        krb5_free_principal(context, princ);
-+
-+    return retval == 0;
-+}
-diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c
-index 99b54e5..f73b8eb 100644
---- a/src/clients/ksu/heuristic.c
-+++ b/src/clients/ksu/heuristic.c
-@@ -397,12 +397,8 @@ krb5_error_code find_either_ticket (context, cc, client, end_server, found)
-     krb5_principal kdc_server;
-     krb5_error_code retval;
-     krb5_boolean temp_found = FALSE;
--    const char * cc_source_name;
--    struct stat st_temp;
- 
--    cc_source_name = krb5_cc_get_name(context, cc);
--
--    if ( ! stat(cc_source_name, &st_temp)){
-+    if (ks_ccache_is_initialized(context, cc)) {
- 
-         retval = find_ticket(context, cc, client, end_server, &temp_found);
-         if (retval)
-@@ -539,7 +535,6 @@ krb5_error_code get_best_princ_for_target(context, source_uid, target_uid,
- {
- 
-     princ_info princ_trials[10];
--    const char * cc_source_name;
-     krb5_principal cc_def_princ = NULL;
-     krb5_principal temp_client;
-     krb5_principal target_client;
-@@ -551,7 +546,6 @@ krb5_error_code get_best_princ_for_target(context, source_uid, target_uid,
-     struct stat tb;
-     int count =0;
-     int i;
--    struct stat st_temp;
- 
-     *path_out = 0;
- 
-@@ -559,10 +553,7 @@ krb5_error_code get_best_princ_for_target(context, source_uid, target_uid,
-     if (options->princ)
-         return 0;
- 
--    cc_source_name = krb5_cc_get_name(context, cc_source);
--
--
--    if (! stat(cc_source_name, &st_temp)) {
-+    if (ks_ccache_is_initialized(context, cc_source)) {
-         retval = krb5_cc_get_principal(context, cc_source, &cc_def_princ);
-         if (retval)
-             return retval;
-diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
-index 9e0c613..e1e34f1 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -141,6 +141,12 @@ extern krb5_error_code krb5_store_some_creds
- (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **,
-  krb5_principal, krb5_boolean *);
- 
-+extern krb5_boolean ks_ccache_name_is_initialized
-+(krb5_context, const char *);
-+
-+extern krb5_boolean ks_ccache_is_initialized
-+(krb5_context, krb5_ccache);
-+
- extern krb5_error_code krb5_ccache_refresh
- (krb5_context, krb5_ccache);
- 
-@@ -198,8 +204,6 @@ extern int standard_shell (char *);
- 
- extern krb5_error_code get_params (int *, int, char **, char ***);
- 
--extern char *get_dir_of_file (const char *);
--
- /* heuristic.c */
- extern krb5_error_code get_all_princ_from_file (FILE *, char ***);
- 
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index 62f3bc0..8c49f94 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -51,7 +51,6 @@ static void print_status( const char *fmt, ...)
-     __attribute__ ((__format__ (__printf__, 1, 2)))
- #endif
-     ;
--char * get_dir_of_file();
- 
- /* Note -e and -a options are mutually exclusive */
- /* insure the proper specification of target user as well as catching
-@@ -96,7 +95,6 @@ main (argc, argv)
-     const char * cc_source_tag = NULL;
-     uid_t source_gid;
-     const char * cc_source_tag_tmp = NULL;
--    char * cc_target_tag_tmp=NULL;
-     char * cmd = NULL, * exec_cmd = NULL;
-     int errflg = 0;
-     krb5_boolean auth_val;
-@@ -112,11 +110,9 @@ main (argc, argv)
-     extern char * getpass(), *crypt();
-     int pargc;
-     char ** pargv;
--    struct stat  st_temp;
-     krb5_boolean stored = FALSE;
-     krb5_principal  kdc_server;
-     krb5_boolean zero_password;
--    char * dir_of_cc_target;
-     krb5_boolean restrict_creds;
- 
-     options.opt = KRB5_DEFAULT_OPTIONS;
-@@ -266,9 +262,10 @@ main (argc, argv)
-                 if ( strchr(cc_source_tag, ':')){
-                     cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1;
- 
--                    if( stat( cc_source_tag_tmp, &st_temp)){
-+                    if (!ks_ccache_name_is_initialized(ksu_context,
-+                                                       cc_source_tag)) {
-                         com_err(prog_name, errno,
--                                _("while looking for credentials file %s"),
-+                                _("while looking for credentials cache %s"),
-                                 cc_source_tag_tmp);
-                         exit (1);
-                     }
-@@ -419,32 +416,18 @@ main (argc, argv)
-         exit(1);
-     }
- 
--    if (cc_target_tag == NULL) {
--
--        cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE ,sizeof(char));
--        /* make sure that the new ticket file does not already exist
--           This is run as source_uid because it is reasonable to
--           require the source user to have write to where the target
--           cache will be created.*/
--
--        do {
--            snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s%ld.%d",
--                     KRB5_SECONDARY_CACHE,
--                     (long) target_uid, gen_sym());
--            cc_target_tag_tmp = strchr(cc_target_tag, ':') + 1;
--
--        }while ( !stat ( cc_target_tag_tmp, &st_temp));
--    }
--
--
--    dir_of_cc_target = get_dir_of_file(cc_target_tag_tmp);
--
--    if (access(dir_of_cc_target, R_OK | W_OK )){
--        fprintf(stderr,
--                _("%s does not have correct permissions for %s\n"),
--                source_user, cc_target_tag);
--        exit(1);
--    }
-+    /*
-+     * Make sure that the new ticket file does not already exist.
-+     * This is run as source_uid because it is reasonable to
-+     * require the source user to have write to where the target
-+     * cache will be created.
-+     */
-+    cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE, sizeof(char));
-+    do {
-+        snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s%ld.%d",
-+                 KRB5_SECONDARY_CACHE,
-+                 (long)target_uid, gen_sym());
-+    } while (ks_ccache_name_is_initialized(ksu_context, cc_target_tag));
- 
-     if (auth_debug){
-         fprintf(stderr, " source cache =  %s\n", cc_source_tag);
-@@ -747,13 +730,6 @@ main (argc, argv)
-         exit(1);
-     }
- 
--    if (access( cc_target_tag_tmp, R_OK | W_OK )){
--        com_err(prog_name, errno,
--                _("%s does not have correct permissions for %s, %s aborted"),
--                target_user, cc_target_tag_tmp, prog_name);
--        exit(1);
--    }
--
-     if ( cc_source)
-         krb5_cc_close(ksu_context, cc_source);
- 
-@@ -873,8 +849,6 @@ static void sweep_up(context, cc)
-     krb5_ccache cc;
- {
-     krb5_error_code retval;
--    const char * cc_name;
--    struct stat  st_temp;
- 
-     krb5_seteuid(0);
-     if (krb5_seteuid(target_uid) < 0) {
-@@ -883,8 +857,7 @@ static void sweep_up(context, cc)
-         exit(1);
-     }
- 
--    cc_name = krb5_cc_get_name(context, cc);
--    if ( ! stat(cc_name, &st_temp)){
-+    if (ks_ccache_is_initialized(context, cc)) {
-         if ((retval = krb5_cc_destroy(context, cc)))
-             com_err(prog_name, retval, _("while destroying cache"));
-     }
-@@ -937,26 +910,6 @@ void print_status(const char *fmt, ...)
-     }
- }
- 
--
--char *get_dir_of_file(path)
--    const char *path;
--{
--    char * temp_path;
--    char * ptr;
--
--    temp_path =  xstrdup(path);
--
--    if ((ptr = strrchr( temp_path, '/'))) {
--        *ptr = '\0';
--    } else {
--        free (temp_path);
--        temp_path = xmalloc(MAXPATHLEN);
--        if (temp_path)
--            getcwd(temp_path, MAXPATHLEN);
--    }
--    return temp_path;
--}
--
- krb5_error_code
- ksu_tgtname(context, server, client, tgtprinc)
-     krb5_context context;
--- 
-2.0.4
-
diff --git a/SOURCES/0003-Use-an-intermediate-memory-cache-in-ksu.patch b/SOURCES/0003-Use-an-intermediate-memory-cache-in-ksu.patch
deleted file mode 100644
index 4bef600..0000000
--- a/SOURCES/0003-Use-an-intermediate-memory-cache-in-ksu.patch
+++ /dev/null
@@ -1,417 +0,0 @@
-From dccc80a469b1925fcfe7697406a69912efe4baa1 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Wed, 30 Oct 2013 21:45:35 -0400
-Subject: [PATCH 3/7] Use an intermediate memory cache in ksu
-
-Instead of copying source or obtained creds into the target cache and
-changing ownership if everything succeeds, copy them into a MEMORY:
-cache and then, if everything succeeds, create the target cache as the
-target user.
-
-We no longer need to clean up the temporary ccache when exiting in
-most error cases.
-
-Use a fake principal name ("_ksu/_ksu@_ksu") as the primary holder of
-the temporary cache so that we won't accidentally select it when we
-make a subsequent call to krb5_cc_cache_match() (to be added in a
-later patch) to find the target location where the creds should be
-stored for use while running as the target user.
----
- src/clients/ksu/ccache.c |  10 +--
- src/clients/ksu/ksu.h    |   4 +-
- src/clients/ksu/main.c   | 156 ++++++++++++++++++++++++-----------------------
- 3 files changed, 87 insertions(+), 83 deletions(-)
-
-diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index 5f57279..d0fc389 100644
---- a/src/clients/ksu/ccache.c
-+++ b/src/clients/ksu/ccache.c
-@@ -47,14 +47,15 @@ void show_credential();
- */
- 
- krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
--                                  primary_principal, restrict_creds, cc_out,
--                                  stored, target_uid)
-+                                  primary_principal, restrict_creds,
-+                                  target_principal, cc_out, stored, target_uid)
- /* IN */
-     krb5_context context;
-     krb5_ccache cc_def;
-     char *cc_other_tag;
-     krb5_principal primary_principal;
-     krb5_boolean restrict_creds;
-+    krb5_principal target_principal;
-     uid_t target_uid;
-     /* OUT */
-     krb5_ccache *cc_out;
-@@ -86,10 +87,9 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
-         return errno;
-     }
- 
--
--    if ((retval = krb5_cc_initialize(context, *cc_other, primary_principal))){
-+    retval = krb5_cc_initialize(context, *cc_other, target_principal);
-+    if (retval)
-         return retval;
--    }
- 
-     if (restrict_creds) {
-         retval = krb5_store_some_creds(context, *cc_other, cc_def_creds_arr,
-diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
-index e1e34f1..08bf01b 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -106,8 +106,8 @@ extern krb5_error_code get_best_principal
- 
- /* ccache.c */
- extern krb5_error_code krb5_ccache_copy
--(krb5_context, krb5_ccache, char *, krb5_principal,
-- krb5_boolean, krb5_ccache *, krb5_boolean *, uid_t);
-+(krb5_context, krb5_ccache, char *, krb5_principal, krb5_boolean,
-+ krb5_principal, krb5_ccache *, krb5_boolean *, uid_t);
- 
- extern krb5_error_code krb5_store_all_creds
- (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **);
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index 8c49f94..d1bb8ca 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -42,10 +42,13 @@ char * gb_err = NULL;
- int quiet = 0;
- /***********/
- 
-+#define KS_TEMPORARY_CACHE "MEMORY:_ksu"
-+#define KS_TEMPORARY_PRINC "_ksu/_ksu@_ksu"
- #define _DEF_CSH "/bin/csh"
- static int set_env_var (char *, char *);
- static void sweep_up (krb5_context, krb5_ccache);
- static char * ontty (void);
-+static krb5_error_code set_ccname_env(krb5_context, krb5_ccache);
- static void print_status( const char *fmt, ...)
- #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
-     __attribute__ ((__format__ (__printf__, 1, 2)))
-@@ -84,8 +87,8 @@ main (argc, argv)
-     int option=0;
-     int statusp=0;
-     krb5_error_code retval = 0;
--    krb5_principal client = NULL;
--    krb5_ccache cc_target = NULL;
-+    krb5_principal client = NULL, tmp_princ = NULL;
-+    krb5_ccache cc_tmp = NULL, cc_target = NULL;
-     krb5_context ksu_context;
-     char * cc_target_tag = NULL;
-     char * target_user = NULL;
-@@ -93,7 +96,6 @@ main (argc, argv)
- 
-     krb5_ccache cc_source = NULL;
-     const char * cc_source_tag = NULL;
--    uid_t source_gid;
-     const char * cc_source_tag_tmp = NULL;
-     char * cmd = NULL, * exec_cmd = NULL;
-     int errflg = 0;
-@@ -342,8 +344,6 @@ main (argc, argv)
-     /* allocate space and copy the usernamane there */
-     source_user = xstrdup(pwd->pw_name);
-     source_uid = pwd->pw_uid;
--    source_gid = pwd->pw_gid;
--
- 
-     if (!strcmp(SOURCE_USER_LOGIN, target_user)){
-         target_user = xstrdup (source_user);
-@@ -435,25 +435,32 @@ main (argc, argv)
-     }
- 
-     /*
--      Only when proper authentication and authorization
--      takes place, the target user becomes the owner of the cache.
--    */
--
--    /* we continue to run as source uid until
--       the middle of the copy, when becomewe become the target user
--       The cache is owned by the target user.*/
-+     * After proper authentication and authorization, populate a cache for the
-+     * target user.
-+     */
- 
-+    /*
-+     * We read the set of creds we want to copy from the source ccache as the
-+     * source uid, become root for authentication, and then become the target
-+     * user to handle authorization and creating the target user's cache.
-+     */
- 
-     /* if root ksu's to a regular user, then
-        then only the credentials for that particular user
-        should be copied */
- 
-     restrict_creds = (source_uid == 0) && (target_uid != 0);
--    retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, client,
--                              restrict_creds, &cc_target, &stored, target_uid);
-+    retval = krb5_parse_name(ksu_context, KS_TEMPORARY_PRINC, &tmp_princ);
-+    if (retval) {
-+        com_err(prog_name, retval, _("while parsing temporary name"));
-+        exit(1);
-+    }
-+    retval = krb5_ccache_copy(ksu_context, cc_source, KS_TEMPORARY_CACHE,
-+                              client, restrict_creds, tmp_princ, &cc_tmp,
-+                              &stored, 0);
-     if (retval) {
-         com_err(prog_name, retval, _("while copying cache %s to %s"),
--                krb5_cc_get_name(ksu_context, cc_source), cc_target_tag);
-+                krb5_cc_get_name(ksu_context, cc_source), KS_TEMPORARY_CACHE);
-         exit(1);
-     }
- 
-@@ -473,7 +480,6 @@ main (argc, argv)
-                                       &kdc_server))){
-                 com_err(prog_name, retval,
-                         _("while creating tgt for local realm"));
--                sweep_up(ksu_context, cc_target);
-                 exit(1);
-             }
- 
-@@ -481,13 +487,12 @@ main (argc, argv)
-                               "enter it here and are logged\n"));
-             fprintf(stderr, _("         in remotely using an unsecure "
-                               "(non-encrypted) channel.\n"));
--            if (krb5_get_tkt_via_passwd (ksu_context, &cc_target, client,
--                                         kdc_server, &options,
--                                         &zero_password) == FALSE){
-+            if (krb5_get_tkt_via_passwd(ksu_context, &cc_tmp, client,
-+                                        kdc_server, &options,
-+                                        &zero_password) == FALSE){
- 
-                 if (zero_password == FALSE){
-                     fprintf(stderr, _("Goodbye\n"));
--                    sweep_up(ksu_context, cc_target);
-                     exit(1);
-                 }
- 
-@@ -506,48 +511,20 @@ main (argc, argv)
-     if (source_uid && (source_uid != target_uid)) {
-         char * client_name;
- 
--        auth_val = krb5_auth_check(ksu_context, client, localhostname, &options,
--                                   target_user,cc_target, &path_passwd, target_uid);
-+        auth_val = krb5_auth_check(ksu_context, client, localhostname,
-+                                   &options, target_user, cc_tmp,
-+                                   &path_passwd, target_uid);
- 
-         /* if Kerberos authentication failed then exit */
-         if (auth_val ==FALSE){
-             fprintf(stderr, _("Authentication failed.\n"));
-             syslog(LOG_WARNING, "'%s %s' authentication failed for %s%s",
-                    prog_name,target_user,source_user,ontty());
--            sweep_up(ksu_context, cc_target);
-             exit(1);
-         }
- 
--#if 0
--        /* At best, this avoids a single kdc request
--           It is hard to implement dealing with file permissions and
--           is unnecessary.  It is important
--           to properly handle races in chown if this code is ever re-enabled.
--        */
--        /* cache the tickets if possible in the source cache */
--        if (!path_passwd){
--
--            if ((retval = krb5_ccache_overwrite(ksu_context, cc_target, cc_source,
--                                                client))){
--                com_err (prog_name, retval,
--                         "while copying cache %s to %s",
--                         krb5_cc_get_name(ksu_context, cc_target),
--                         krb5_cc_get_name(ksu_context, cc_source));
--                sweep_up(ksu_context, cc_target);
--                exit(1);
--            }
--            if (chown(cc_source_tag_tmp, source_uid, source_gid)){
--                com_err(prog_name, errno,
--                        "while changing owner for %s",
--                        cc_source_tag_tmp);
--                exit(1);
--            }
--        }
--#endif /*0*/
--
-         if ((retval = krb5_unparse_name(ksu_context, client, &client_name))) {
-             com_err(prog_name, retval, _("When unparsing name"));
--            sweep_up(ksu_context, cc_target);
-             exit(1);
-         }
- 
-@@ -560,7 +537,6 @@ main (argc, argv)
-         if (krb5_seteuid(target_uid)) {
-             com_err(prog_name, errno, _("while switching to target for "
-                                         "authorization check"));
--            sweep_up(ksu_context, cc_target);
-             exit(1);
-         }
- 
-@@ -568,14 +544,12 @@ main (argc, argv)
-                                          cmd, &authorization_val, &exec_cmd))){
-             com_err(prog_name,retval, _("while checking authorization"));
-             krb5_seteuid(0); /*So we have some chance of sweeping up*/
--            sweep_up(ksu_context, cc_target);
-             exit(1);
-         }
- 
-         if (krb5_seteuid(0)) {
-             com_err(prog_name, errno, _("while switching back from target "
-                                         "after authorization check"));
--            sweep_up(ksu_context, cc_target);
-             exit(1);
-         }
-         if (authorization_val == TRUE){
-@@ -617,25 +591,25 @@ main (argc, argv)
- 
-             }
- 
--            sweep_up(ksu_context, cc_target);
-             exit(1);
-         }
-     }
- 
-     if( some_rest_copy){
--        if ((retval = krb5_ccache_filter(ksu_context, cc_target, client))){
-+        retval = krb5_ccache_filter(ksu_context, cc_tmp, client);
-+        if (retval) {
-             com_err(prog_name,retval, _("while calling cc_filter"));
--            sweep_up(ksu_context, cc_target);
-             exit(1);
-         }
-     }
- 
-     if (all_rest_copy){
--        if ((retval = krb5_cc_initialize(ksu_context, cc_target, client))){
-+        retval = krb5_cc_initialize(ksu_context, cc_tmp, tmp_princ);
-+        if (retval) {
-             com_err(prog_name, retval, _("while erasing target cache"));
-             exit(1);
-         }
--
-+        stored = FALSE;
-     }
- 
-     /* get the shell of the user, this will be the shell used by su */
-@@ -653,7 +627,6 @@ main (argc, argv)
- 
-     if (!standard_shell(target_pwd->pw_shell) && source_uid) {
-         fprintf(stderr, _("ksu: permission denied (shell).\n"));
--        sweep_up(ksu_context, cc_target);
-         exit(1);
-     }
- #endif /* HAVE_GETUSERSHELL */
-@@ -663,43 +636,28 @@ main (argc, argv)
-         if(set_env_var("USER", target_pwd->pw_name)){
-             fprintf(stderr,
-                     _("ksu: couldn't set environment variable USER\n"));
--            sweep_up(ksu_context, cc_target);
-             exit(1);
-         }
-     }
- 
-     if(set_env_var( "HOME", target_pwd->pw_dir)){
-         fprintf(stderr, _("ksu: couldn't set environment variable HOME\n"));
--        sweep_up(ksu_context, cc_target);
-         exit(1);
-     }
- 
-     if(set_env_var( "SHELL", shell)){
-         fprintf(stderr, _("ksu: couldn't set environment variable SHELL\n"));
--        sweep_up(ksu_context, cc_target);
--        exit(1);
--    }
--
--    /* set the cc env name to target */
--
--    if(set_env_var( KRB5_ENV_CCNAME, cc_target_tag)){
--        fprintf(stderr, _("ksu: couldn't set environment variable %s\n"),
--                KRB5_ENV_CCNAME);
--        sweep_up(ksu_context, cc_target);
-         exit(1);
-     }
- 
-     /* set permissions */
-     if (setgid(target_pwd->pw_gid) < 0) {
-         perror("ksu: setgid");
--        sweep_up(ksu_context, cc_target);
-         exit(1);
-     }
- 
--
-     if (initgroups(target_user, target_pwd->pw_gid)) {
-         fprintf(stderr, _("ksu: initgroups failed.\n"));
--        sweep_up(ksu_context, cc_target);
-         exit(1);
-     }
- 
-@@ -719,13 +677,36 @@ main (argc, argv)
-      */
-     if (setluid((uid_t) pwd->pw_uid) < 0) {
-         perror("setluid");
--        sweep_up(ksu_context, cc_target);
-         exit(1);
-     }
- #endif  /* HAVE_SETLUID */
- 
-     if (setuid(target_pwd->pw_uid) < 0) {
-         perror("ksu: setuid");
-+        exit(1);
-+    }
-+
-+    retval = krb5_ccache_copy(ksu_context, cc_tmp, cc_target_tag,
-+                              client, FALSE, client, &cc_target, &stored,
-+                              target_pwd->pw_uid);
-+    if (retval) {
-+        com_err(prog_name, retval, _("while copying cache %s to %s"),
-+                KS_TEMPORARY_CACHE, cc_target_tag);
-+        exit(1);
-+    }
-+
-+    if (stored && !ks_ccache_is_initialized(ksu_context, cc_target)) {
-+        com_err(prog_name, errno,
-+                _("%s does not have correct permissions for %s, %s aborted"),
-+                target_user, cc_target_tag, prog_name);
-+        exit(1);
-+    }
-+
-+    free(cc_target_tag);
-+
-+    /* Set the cc env name to target. */
-+    retval = set_ccname_env(ksu_context, cc_target);
-+    if (retval != 0) {
-         sweep_up(ksu_context, cc_target);
-         exit(1);
-     }
-@@ -799,6 +780,29 @@ main (argc, argv)
-     }
- }
- 
-+/* Set KRB5CCNAME in the environment to point to ccache.  Print an error
-+ * message on failure. */
-+static krb5_error_code
-+set_ccname_env(krb5_context ksu_context, krb5_ccache ccache)
-+{
-+    krb5_error_code retval;
-+    char *ccname;
-+
-+    retval = krb5_cc_get_full_name(ksu_context, ccache, &ccname);
-+    if (retval) {
-+        com_err(prog_name, retval, _("while reading cache name from ccache"));
-+        return retval;
-+    }
-+    if (set_env_var(KRB5_ENV_CCNAME, ccname)) {
-+        retval = errno;
-+        fprintf(stderr,
-+                _("ksu: couldn't set environment variable %s\n"),
-+                KRB5_ENV_CCNAME);
-+    }
-+    krb5_free_string(ksu_context, ccname);
-+    return retval;
-+}
-+
- #ifdef HAVE_GETUSERSHELL
- 
- int standard_shell(sh)
--- 
-2.0.4
-
diff --git a/SOURCES/0003-Use-k5_transport-_strategy-enums-for-k5_sendto.patch b/SOURCES/0003-Use-k5_transport-_strategy-enums-for-k5_sendto.patch
deleted file mode 100644
index ba3f91c..0000000
--- a/SOURCES/0003-Use-k5_transport-_strategy-enums-for-k5_sendto.patch
+++ /dev/null
@@ -1,913 +0,0 @@
-From 9c6be00daca0b80aed94ec9680724f95e6be92e1 Mon Sep 17 00:00:00 2001
-From: "Robbie Harwood (frozencemetery)" <rharwood@club.cc.cmu.edu>
-Date: Thu, 15 Aug 2013 15:55:52 -0400
-Subject: [PATCH 03/13] Use k5_transport(_strategy) enums for k5_sendto
-
-In k5_sendto and k5_locate_server, replace "socktype" parameters with
-a new enumerator k5_transport, so that we can add new transports which
-are not in the socket type namespace.  Control the order in which we
-make connections of different types using a new k5_transport_strategy
-enumerator, to simplify the logic for adding new transports later.
-Control the result of k5_locate_server with a no_udp boolean rather
-than a socket type.
-
-[ghudson@mit.edu: renamed type to k5_transport; k5_locate_server
- no_udp change; clarified commit message; fix for Solaris getaddrinfo]
-[kaduk@mit.edu: name variables of type k5_transport 'transport']
-[nalin@redhat.com: use transport rather than sock_type in more places,
- add and use k5_transport_strategy, update the test program]
-
-ticket: 7929
----
- src/lib/krb5/os/changepw.c         |  31 +++++-----
- src/lib/krb5/os/hostrealm_domain.c |   2 +-
- src/lib/krb5/os/locate_kdc.c       |  75 ++++++++++++----------
- src/lib/krb5/os/os-proto.h         |  27 +++++---
- src/lib/krb5/os/sendto_kdc.c       | 123 +++++++++++++++++++++++--------------
- src/lib/krb5/os/t_locate_kdc.c     |  24 ++++----
- src/lib/krb5/os/t_std_conf.c       |   2 +-
- src/lib/krb5/os/t_trace.c          |   6 +-
- src/lib/krb5/os/t_trace.ref        |   4 +-
- src/lib/krb5/os/trace.c            |   6 +-
- 10 files changed, 178 insertions(+), 122 deletions(-)
-
-diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
-index 4d8abd9..a1c9885 100644
---- a/src/lib/krb5/os/changepw.c
-+++ b/src/lib/krb5/os/changepw.c
-@@ -59,25 +59,25 @@ struct sendto_callback_context {
- 
- static krb5_error_code
- locate_kpasswd(krb5_context context, const krb5_data *realm,
--               struct serverlist *serverlist, int socktype)
-+               struct serverlist *serverlist, krb5_boolean no_udp)
- {
-     krb5_error_code code;
- 
-     code = k5_locate_server(context, realm, serverlist, locate_service_kpasswd,
--                            socktype);
-+                            no_udp);
- 
-     if (code == KRB5_REALM_CANT_RESOLVE || code == KRB5_REALM_UNKNOWN) {
-         code = k5_locate_server(context, realm, serverlist,
--                                locate_service_kadmin, SOCK_STREAM);
-+                                locate_service_kadmin, TRUE);
-         if (!code) {
--            /* Success with admin_server but now we need to change the
--               port number to use DEFAULT_KPASSWD_PORT and the socktype.  */
-+            /* Success with admin_server but now we need to change the port
-+             * number to use DEFAULT_KPASSWD_PORT and the transport. */
-             size_t i;
-             for (i = 0; i < serverlist->nservers; i++) {
-                 struct server_entry *s = &serverlist->servers[i];
-                 krb5_ui_2 kpasswd_port = htons(DEFAULT_KPASSWD_PORT);
--                if (socktype != SOCK_STREAM)
--                    s->socktype = socktype;
-+                if (!no_udp && s->transport == TCP)
-+                    s->transport = TCP_OR_UDP;
-                 if (s->hostname != NULL)
-                     s->port = kpasswd_port;
-                 else if (s->family == AF_INET)
-@@ -214,7 +214,7 @@ change_set_password(krb5_context context,
-                     krb5_data *result_string)
- {
-     krb5_data                   chpw_rep;
--    krb5_boolean                use_tcp = 0;
-+    krb5_boolean                no_udp = FALSE;
-     GETSOCKNAME_ARG3_TYPE       addrlen;
-     krb5_error_code             code = 0;
-     char                        *code_string;
-@@ -247,9 +247,10 @@ change_set_password(krb5_context context,
-     callback_ctx.local_seq_num = callback_ctx.auth_context->local_seq_number;
- 
-     do {
--        int socktype = (use_tcp ? SOCK_STREAM : SOCK_DGRAM);
-+        k5_transport_strategy strategy = no_udp ? NO_UDP : UDP_FIRST;
-+
-         code = locate_kpasswd(callback_ctx.context, &creds->server->realm, &sl,
--                              socktype);
-+                              no_udp);
-         if (code)
-             break;
- 
-@@ -260,7 +261,7 @@ change_set_password(krb5_context context,
-         callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup;
-         krb5_free_data_contents(callback_ctx.context, &chpw_rep);
- 
--        code = k5_sendto(callback_ctx.context, NULL, &sl, socktype, 0,
-+        code = k5_sendto(callback_ctx.context, NULL, &sl, strategy,
-                          &callback_info, &chpw_rep, ss2sa(&remote_addr),
-                          &addrlen, NULL, NULL, NULL);
-         if (code) {
-@@ -277,9 +278,9 @@ change_set_password(krb5_context context,
-                                    result_string);
- 
-         if (code) {
--            if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !use_tcp) {
-+            if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !no_udp) {
-                 k5_free_serverlist(&sl);
--                use_tcp = 1;
-+                no_udp = 1;
-                 continue;
-             }
- 
-@@ -305,9 +306,9 @@ change_set_password(krb5_context context,
-             strncpy(result_code_string->data, code_string, result_code_string->length);
-         }
- 
--        if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !use_tcp) {
-+        if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !no_udp) {
-             k5_free_serverlist(&sl);
--            use_tcp = 1;
-+            no_udp = 1;
-         } else {
-             break;
-         }
-diff --git a/src/lib/krb5/os/hostrealm_domain.c b/src/lib/krb5/os/hostrealm_domain.c
-index dc9cc59..2228df0 100644
---- a/src/lib/krb5/os/hostrealm_domain.c
-+++ b/src/lib/krb5/os/hostrealm_domain.c
-@@ -85,7 +85,7 @@ domain_fallback_realm(krb5_context context, krb5_hostrealm_moddata data,
-     suffix = uhost;
-     while (limit-- >= 0 && (dot = strchr(suffix, '.')) != NULL) {
-         drealm = string2data((char *)suffix);
--        if (k5_locate_kdc(context, &drealm, &slist, FALSE, SOCK_DGRAM) == 0) {
-+        if (k5_locate_kdc(context, &drealm, &slist, FALSE, FALSE) == 0) {
-             k5_free_serverlist(&slist);
-             ret = k5_make_realmlist(suffix, realms_out);
-             goto cleanup;
-diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
-index 4479465..4c8aead 100644
---- a/src/lib/krb5/os/locate_kdc.c
-+++ b/src/lib/krb5/os/locate_kdc.c
-@@ -129,7 +129,7 @@ new_server_entry(struct serverlist *list)
- 
- /* Add an address entry to list. */
- static int
--add_addr_to_list(struct serverlist *list, int socktype, int family,
-+add_addr_to_list(struct serverlist *list, k5_transport transport, int family,
-                  size_t addrlen, struct sockaddr *addr)
- {
-     struct server_entry *entry;
-@@ -137,7 +137,7 @@ add_addr_to_list(struct serverlist *list, int socktype, int family,
-     entry = new_server_entry(list);
-     if (entry == NULL)
-         return ENOMEM;
--    entry->socktype = socktype;
-+    entry->transport = transport;
-     entry->family = family;
-     entry->hostname = NULL;
-     entry->addrlen = addrlen;
-@@ -149,14 +149,14 @@ add_addr_to_list(struct serverlist *list, int socktype, int family,
- /* Add a hostname entry to list. */
- static int
- add_host_to_list(struct serverlist *list, const char *hostname, int port,
--                 int socktype, int family)
-+                 k5_transport transport, int family)
- {
-     struct server_entry *entry;
- 
-     entry = new_server_entry(list);
-     if (entry == NULL)
-         return ENOMEM;
--    entry->socktype = socktype;
-+    entry->transport = transport;
-     entry->family = family;
-     entry->hostname = strdup(hostname);
-     if (entry->hostname == NULL)
-@@ -187,7 +187,7 @@ server_list_contains(struct serverlist *list, struct server_entry *server)
- static krb5_error_code
- locate_srv_conf_1(krb5_context context, const krb5_data *realm,
-                   const char * name, struct serverlist *serverlist,
--                  int socktype, int udpport, int sec_udpport)
-+                  k5_transport transport, int udpport, int sec_udpport)
- {
-     const char  *realm_srv_names[4];
-     char **hostlist, *host, *port, *cp;
-@@ -255,12 +255,12 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm,
-             *cp = '\0';
-         }
- 
--        code = add_host_to_list(serverlist, host, p1, socktype, AF_UNSPEC);
-+        code = add_host_to_list(serverlist, host, p1, transport, AF_UNSPEC);
-         /* Second port is for IPv4 UDP only, and should possibly go away as
-          * it was originally a krb4 compatibility measure. */
-         if (code == 0 && p2 != 0 &&
--            (socktype == 0 || socktype == SOCK_DGRAM))
--            code = add_host_to_list(serverlist, host, p2, SOCK_DGRAM, AF_INET);
-+            (transport == TCP_OR_UDP || transport == UDP))
-+            code = add_host_to_list(serverlist, host, p2, UDP, AF_INET);
-         if (code)
-             goto cleanup;
-     }
-@@ -278,7 +278,8 @@ krb5_locate_srv_conf(krb5_context context, const krb5_data *realm,
- {
-     krb5_error_code ret;
- 
--    ret = locate_srv_conf_1(context, realm, name, al, 0, udpport, sec_udpport);
-+    ret = locate_srv_conf_1(context, realm, name, al, TCP_OR_UDP, udpport,
-+                            sec_udpport);
-     if (ret)
-         return ret;
-     if (al->nservers == 0)        /* Couldn't resolve any KDC names */
-@@ -294,7 +295,7 @@ locate_srv_dns_1(const krb5_data *realm, const char *service,
- {
-     struct srv_dns_entry *head = NULL, *entry = NULL;
-     krb5_error_code code = 0;
--    int socktype;
-+    k5_transport transport;
- 
-     code = krb5int_make_srv_query_realm(realm, service, protocol, &head);
-     if (code)
-@@ -310,9 +311,9 @@ locate_srv_dns_1(const krb5_data *realm, const char *service,
-     }
- 
-     for (entry = head; entry != NULL; entry = entry->next) {
--        socktype = (strcmp(protocol, "_tcp") == 0) ? SOCK_STREAM : SOCK_DGRAM;
-+        transport = (strcmp(protocol, "_tcp") == 0) ? TCP : UDP;
-         code = add_host_to_list(serverlist, entry->host, htons(entry->port),
--                                socktype, AF_UNSPEC);
-+                                transport, AF_UNSPEC);
-         if (code)
-             goto cleanup;
-     }
-@@ -341,6 +342,7 @@ module_callback(void *cbdata, int socktype, struct sockaddr *sa)
- {
-     struct module_callback_data *d = cbdata;
-     size_t addrlen;
-+    k5_transport transport;
- 
-     if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM)
-         return 0;
-@@ -350,7 +352,8 @@ module_callback(void *cbdata, int socktype, struct sockaddr *sa)
-         addrlen = sizeof(struct sockaddr_in6);
-     else
-         return 0;
--    if (add_addr_to_list(d->list, socktype, sa->sa_family, addrlen,
-+    transport = (socktype == SOCK_STREAM) ? TCP : UDP;
-+    if (add_addr_to_list(d->list, transport, sa->sa_family, addrlen,
-                          sa) != 0) {
-         /* Assumes only error is ENOMEM.  */
-         d->out_of_mem = 1;
-@@ -362,14 +365,14 @@ module_callback(void *cbdata, int socktype, struct sockaddr *sa)
- static krb5_error_code
- module_locate_server(krb5_context ctx, const krb5_data *realm,
-                      struct serverlist *serverlist,
--                     enum locate_service_type svc, int socktype)
-+                     enum locate_service_type svc, k5_transport transport)
- {
-     struct krb5plugin_service_locate_result *res = NULL;
-     krb5_error_code code;
-     struct krb5plugin_service_locate_ftable *vtbl = NULL;
-     void **ptrs;
-     char *realmz;               /* NUL-terminated realm */
--    int i;
-+    int socktype, i;
-     struct module_callback_data cbdata = { 0, };
-     const char *msg;
- 
-@@ -413,11 +416,11 @@ module_locate_server(krb5_context ctx, const krb5_data *realm,
-         if (code)
-             continue;
- 
--        code = vtbl->lookup(blob, svc, realmz,
--                            (socktype != 0) ? socktype : SOCK_DGRAM, AF_UNSPEC,
-+        socktype = (transport == TCP) ? SOCK_STREAM : SOCK_DGRAM;
-+        code = vtbl->lookup(blob, svc, realmz, socktype, AF_UNSPEC,
-                             module_callback, &cbdata);
-         /* Also ask for TCP addresses if we got UDP addresses and want both. */
--        if (code == 0 && socktype == 0) {
-+        if (code == 0 && transport == TCP_OR_UDP) {
-             code = vtbl->lookup(blob, svc, realmz, SOCK_STREAM, AF_UNSPEC,
-                                 module_callback, &cbdata);
-             if (code == KRB5_PLUGIN_NO_HANDLE)
-@@ -459,7 +462,7 @@ module_locate_server(krb5_context ctx, const krb5_data *realm,
- static krb5_error_code
- prof_locate_server(krb5_context context, const krb5_data *realm,
-                    struct serverlist *serverlist, enum locate_service_type svc,
--                   int socktype)
-+                   k5_transport transport)
- {
-     const char *profname;
-     int dflport1, dflport2 = 0;
-@@ -495,7 +498,7 @@ prof_locate_server(krb5_context context, const krb5_data *realm,
-         return EBUSY;           /* XXX */
-     }
- 
--    return locate_srv_conf_1(context, realm, profname, serverlist, socktype,
-+    return locate_srv_conf_1(context, realm, profname, serverlist, transport,
-                              dflport1, dflport2);
- }
- 
-@@ -503,7 +506,7 @@ prof_locate_server(krb5_context context, const krb5_data *realm,
- static krb5_error_code
- dns_locate_server(krb5_context context, const krb5_data *realm,
-                   struct serverlist *serverlist, enum locate_service_type svc,
--                  int socktype)
-+                  k5_transport transport)
- {
-     const char *dnsname;
-     int use_dns = _krb5_use_dns_kdc(context);
-@@ -533,12 +536,12 @@ dns_locate_server(krb5_context context, const krb5_data *realm,
-     }
- 
-     code = 0;
--    if (socktype == SOCK_DGRAM || socktype == 0) {
-+    if (transport == UDP || transport == TCP_OR_UDP) {
-         code = locate_srv_dns_1(realm, dnsname, "_udp", serverlist);
-         if (code)
-             Tprintf("dns udp lookup returned error %d\n", code);
-     }
--    if ((socktype == SOCK_STREAM || socktype == 0) && code == 0) {
-+    if ((transport == TCP || transport == TCP_OR_UDP) && code == 0) {
-         code = locate_srv_dns_1(realm, dnsname, "_tcp", serverlist);
-         if (code)
-             Tprintf("dns tcp lookup returned error %d\n", code);
-@@ -547,10 +550,16 @@ dns_locate_server(krb5_context context, const krb5_data *realm,
- }
- #endif /* KRB5_DNS_LOOKUP */
- 
-+/*
-+ * Try all of the server location methods in sequence.  transport must be
-+ * TCP_OR_UDP, TCP, or UDP.  It is applied to hostname entries in the profile
-+ * and affects whether we query modules or DNS for UDP or TCP or both, but does
-+ * not restrict a method from returning entries of other transports.
-+ */
- static krb5_error_code
- locate_server(krb5_context context, const krb5_data *realm,
-               struct serverlist *serverlist, enum locate_service_type svc,
--              int socktype)
-+              k5_transport transport)
- {
-     krb5_error_code ret;
-     struct serverlist list = SERVERLIST_INIT;
-@@ -559,18 +568,18 @@ locate_server(krb5_context context, const krb5_data *realm,
- 
-     /* Try modules.  If a module returns 0 but leaves the list empty, return an
-      * empty list. */
--    ret = module_locate_server(context, realm, &list, svc, socktype);
-+    ret = module_locate_server(context, realm, &list, svc, transport);
-     if (ret != KRB5_PLUGIN_NO_HANDLE)
-         goto done;
- 
-     /* Try the profile.  Fall back to DNS if it returns an empty list. */
--    ret = prof_locate_server(context, realm, &list, svc, socktype);
-+    ret = prof_locate_server(context, realm, &list, svc, transport);
-     if (ret)
-         goto done;
- 
- #ifdef KRB5_DNS_LOOKUP
-     if (list.nservers == 0)
--        ret = dns_locate_server(context, realm, &list, svc, socktype);
-+        ret = dns_locate_server(context, realm, &list, svc, transport);
- #endif
- 
- done:
-@@ -589,9 +598,10 @@ done:
- krb5_error_code
- k5_locate_server(krb5_context context, const krb5_data *realm,
-                  struct serverlist *serverlist, enum locate_service_type svc,
--                 int socktype)
-+                 krb5_boolean no_udp)
- {
-     krb5_error_code ret;
-+    k5_transport transport = no_udp ? TCP : TCP_OR_UDP;
- 
-     memset(serverlist, 0, sizeof(*serverlist));
-     if (realm == NULL || realm->data == NULL || realm->data[0] == 0) {
-@@ -600,7 +610,7 @@ k5_locate_server(krb5_context context, const krb5_data *realm,
-         return KRB5_REALM_CANT_RESOLVE;
-     }
- 
--    ret = locate_server(context, realm, serverlist, svc, socktype);
-+    ret = locate_server(context, realm, serverlist, svc, transport);
-     if (ret)
-         return ret;
- 
-@@ -616,12 +626,13 @@ k5_locate_server(krb5_context context, const krb5_data *realm,
- 
- krb5_error_code
- k5_locate_kdc(krb5_context context, const krb5_data *realm,
--              struct serverlist *serverlist, int get_masters, int socktype)
-+              struct serverlist *serverlist, krb5_boolean get_masters,
-+              krb5_boolean no_udp)
- {
-     enum locate_service_type stype;
- 
-     stype = get_masters ? locate_service_master_kdc : locate_service_kdc;
--    return k5_locate_server(context, realm, serverlist, stype, socktype);
-+    return k5_locate_server(context, realm, serverlist, stype, no_udp);
- }
- 
- krb5_boolean
-@@ -632,7 +643,7 @@ k5_kdc_is_master(krb5_context context, const krb5_data *realm,
-     krb5_boolean found;
- 
-     if (locate_server(context, realm, &list, locate_service_master_kdc,
--                      server->socktype) != 0)
-+                      server->transport) != 0)
-         return FALSE;
-     found = server_list_contains(&list, server);
-     k5_free_serverlist(&list);
-diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
-index 9125ba0..3196bca 100644
---- a/src/lib/krb5/os/os-proto.h
-+++ b/src/lib/krb5/os/os-proto.h
-@@ -38,11 +38,23 @@
- 
- #include <krb5/locate_plugin.h>
- 
-+typedef enum {
-+    TCP_OR_UDP = 0,
-+    TCP,
-+    UDP,
-+} k5_transport;
-+
-+typedef enum {
-+    UDP_FIRST = 0,
-+    UDP_LAST,
-+    NO_UDP,
-+} k5_transport_strategy;
-+
- /* A single server hostname or address. */
- struct server_entry {
-     char *hostname;             /* NULL -> use addrlen/addr instead */
-     int port;                   /* Used only if hostname set */
--    int socktype;               /* May be 0 for UDP/TCP if hostname set */
-+    k5_transport transport;     /* May be 0 for UDP/TCP if hostname set */
-     int family;                 /* May be 0 (aka AF_UNSPEC) if hostname set */
-     size_t addrlen;
-     struct sockaddr_storage addr;
-@@ -56,8 +68,8 @@ struct serverlist {
- #define SERVERLIST_INIT { NULL, 0 }
- 
- struct remote_address {
-+    k5_transport transport;
-     int family;
--    int type;
-     socklen_t len;
-     struct sockaddr_storage saddr;
- };
-@@ -69,12 +81,13 @@ struct sendto_callback_info {
- };
- 
- krb5_error_code k5_locate_server(krb5_context, const krb5_data *realm,
--                                 struct serverlist *,
--                                 enum locate_service_type svc, int socktype);
-+                                 struct serverlist *serverlist,
-+                                 enum locate_service_type svc,
-+                                 krb5_boolean no_udp);
- 
- krb5_error_code k5_locate_kdc(krb5_context context, const krb5_data *realm,
--                              struct serverlist *serverlist, int get_masters,
--                              int socktype);
-+                              struct serverlist *serverlist,
-+                              krb5_boolean get_masters, krb5_boolean no_udp);
- 
- krb5_boolean k5_kdc_is_master(krb5_context context, const krb5_data *realm,
-                               struct server_entry *server);
-@@ -103,7 +116,7 @@ int _krb5_conf_boolean (const char *);
- 
- krb5_error_code k5_sendto(krb5_context context, const krb5_data *message,
-                           const struct serverlist *addrs,
--                          int socktype1, int socktype2,
-+                          k5_transport_strategy strategy,
-                           struct sendto_callback_info *callback_info,
-                           krb5_data *reply, struct sockaddr *remoteaddr,
-                           socklen_t *remoteaddrlen, int *server_used,
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index e3855a3..3f99ce8 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -104,6 +104,7 @@ struct conn_state {
-     size_t server_index;
-     struct conn_state *next;
-     time_ms endtime;
-+    krb5_boolean defer;
- };
- 
- /* Get current time in milliseconds. */
-@@ -293,6 +294,19 @@ cm_select_or_poll(const struct select_state *in, time_ms endtime,
- }
- 
- static int
-+socktype_for_transport(k5_transport transport)
-+{
-+    switch (transport) {
-+    case UDP:
-+        return SOCK_DGRAM;
-+    case TCP:
-+        return SOCK_STREAM;
-+    default:
-+        return 0;
-+    }
-+}
-+
-+static int
- check_for_svc_unavailable (krb5_context context,
-                            const krb5_data *reply,
-                            void *msg_handler_data)
-@@ -330,11 +344,12 @@ check_for_svc_unavailable (krb5_context context,
- krb5_error_code
- krb5_sendto_kdc(krb5_context context, const krb5_data *message,
-                 const krb5_data *realm, krb5_data *reply, int *use_master,
--                int tcp_only)
-+                int no_udp)
- {
-     krb5_error_code retval, err;
-     struct serverlist servers;
--    int socktype1 = 0, socktype2 = 0, server_used;
-+    int server_used;
-+    k5_transport_strategy strategy;
- 
-     /*
-      * find KDC location(s) for realm
-@@ -349,9 +364,9 @@ krb5_sendto_kdc(krb5_context context, const krb5_data *message,
-      * should probably be returned as well.
-      */
- 
--    TRACE_SENDTO_KDC(context, message->length, realm, *use_master, tcp_only);
-+    TRACE_SENDTO_KDC(context, message->length, realm, *use_master, no_udp);
- 
--    if (!tcp_only && context->udp_pref_limit < 0) {
-+    if (!no_udp && context->udp_pref_limit < 0) {
-         int tmp;
-         retval = profile_get_integer(context->profile,
-                                      KRB5_CONF_LIBDEFAULTS, KRB5_CONF_UDP_PREFERENCE_LIMIT, 0,
-@@ -368,22 +383,21 @@ krb5_sendto_kdc(krb5_context context, const krb5_data *message,
-         context->udp_pref_limit = tmp;
-     }
- 
--    if (tcp_only)
--        socktype1 = SOCK_STREAM, socktype2 = 0;
-+    if (no_udp)
-+        strategy = NO_UDP;
-     else if (message->length <= (unsigned int) context->udp_pref_limit)
--        socktype1 = SOCK_DGRAM, socktype2 = SOCK_STREAM;
-+        strategy = UDP_FIRST;
-     else
--        socktype1 = SOCK_STREAM, socktype2 = SOCK_DGRAM;
-+        strategy = UDP_LAST;
- 
--    retval = k5_locate_kdc(context, realm, &servers, *use_master,
--                           tcp_only ? SOCK_STREAM : 0);
-+    retval = k5_locate_kdc(context, realm, &servers, *use_master, no_udp);
-     if (retval)
-         return retval;
- 
-     err = 0;
--    retval = k5_sendto(context, message, &servers, socktype1, socktype2,
--                       NULL, reply, NULL, NULL, &server_used,
--                       check_for_svc_unavailable, &err);
-+    retval = k5_sendto(context, message, &servers, strategy, NULL, reply,
-+                       NULL, NULL, &server_used, check_for_svc_unavailable,
-+                       &err);
-     if (retval == KRB5_KDC_UNREACH) {
-         if (err == KDC_ERR_SVC_UNAVAILABLE) {
-             retval = KRB5KDC_ERR_SVC_UNAVAILABLE;
-@@ -444,7 +458,7 @@ set_transport_message(struct conn_state *state, const krb5_data *message)
-     if (message == NULL || message->length == 0)
-         return;
- 
--    if (state->addr.type == SOCK_STREAM) {
-+    if (state->addr.transport == TCP) {
-         store_32_be(message->length, out->msg_len_buf);
-         SG_SET(&out->sgbuf[0], out->msg_len_buf, 4);
-         SG_SET(&out->sgbuf[1], message->data, message->length);
-@@ -457,8 +471,9 @@ set_transport_message(struct conn_state *state, const krb5_data *message)
- }
- 
- static krb5_error_code
--add_connection(struct conn_state **conns, struct addrinfo *ai,
--               size_t server_index, char **udpbufp)
-+add_connection(struct conn_state **conns, k5_transport transport,
-+               krb5_boolean defer, struct addrinfo *ai, size_t server_index,
-+               char **udpbufp)
- {
-     struct conn_state *state, **tailptr;
- 
-@@ -467,14 +482,15 @@ add_connection(struct conn_state **conns, struct addrinfo *ai,
-         return ENOMEM;
-     state->state = INITIALIZING;
-     state->out.sgp = state->out.sgbuf;
--    state->addr.type = ai->ai_socktype;
-+    state->addr.transport = transport;
-     state->addr.family = ai->ai_family;
-     state->addr.len = ai->ai_addrlen;
-     memcpy(&state->addr.saddr, ai->ai_addr, ai->ai_addrlen);
-+    state->defer = defer;
-     state->fd = INVALID_SOCKET;
-     state->server_index = server_index;
-     SG_SET(&state->out.sgbuf[1], NULL, 0);
--    if (ai->ai_socktype == SOCK_STREAM) {
-+    if (transport == TCP) {
-         state->service = service_tcp_fd;
-     } else {
-         state->service = service_udp_fd;
-@@ -549,32 +565,41 @@ translate_ai_error (int err)
-  */
- static krb5_error_code
- resolve_server(krb5_context context, const struct serverlist *servers,
--               size_t ind, int socktype1, int socktype2,
-+               size_t ind, k5_transport_strategy strategy,
-                const krb5_data *message, char **udpbufp,
-                struct conn_state **conns)
- {
-     krb5_error_code retval;
-     struct server_entry *entry = &servers->servers[ind];
-+    k5_transport transport;
-     struct addrinfo *addrs, *a, hint, ai;
-+    krb5_boolean defer;
-     int err, result;
-     char portbuf[64];
- 
--    /* Skip any stray entries of socktypes we don't want. */
--    if (entry->socktype != 0 && entry->socktype != socktype1 &&
--        entry->socktype != socktype2)
-+    /* Skip UDP entries if we don't want UDP. */
-+    if (strategy == NO_UDP && entry->transport == UDP)
-         return 0;
- 
-+    transport = (strategy == UDP_FIRST) ? UDP : TCP;
-     if (entry->hostname == NULL) {
--        ai.ai_socktype = entry->socktype;
-+        /* Added by a module, so transport is either TCP or UDP. */
-+        ai.ai_socktype = socktype_for_transport(entry->transport);
-         ai.ai_family = entry->family;
-         ai.ai_addrlen = entry->addrlen;
-         ai.ai_addr = (struct sockaddr *)&entry->addr;
--        return add_connection(conns, &ai, ind, udpbufp);
-+        defer = (entry->transport != transport);
-+        return add_connection(conns, entry->transport, defer, &ai, ind,
-+                              udpbufp);
-     }
- 
-+    /* If the entry has a specified transport, use it. */
-+    if (entry->transport != TCP_OR_UDP)
-+        transport = entry->transport;
-+
-     memset(&hint, 0, sizeof(hint));
-     hint.ai_family = entry->family;
--    hint.ai_socktype = (entry->socktype != 0) ? entry->socktype : socktype1;
-+    hint.ai_socktype = socktype_for_transport(transport);
-     hint.ai_flags = AI_ADDRCONFIG;
- #ifdef AI_NUMERICSERV
-     hint.ai_flags |= AI_NUMERICSERV;
-@@ -586,15 +611,19 @@ resolve_server(krb5_context context, const struct serverlist *servers,
-     err = getaddrinfo(entry->hostname, portbuf, &hint, &addrs);
-     if (err)
-         return translate_ai_error(err);
--    /* Add each address with the preferred socktype. */
-+
-+    /* Add each address with the specified or preferred transport. */
-     retval = 0;
-     for (a = addrs; a != 0 && retval == 0; a = a->ai_next)
--        retval = add_connection(conns, a, ind, udpbufp);
--    if (retval == 0 && entry->socktype == 0 && socktype2 != 0) {
--        /* Add each address again with the non-preferred socktype. */
-+        retval = add_connection(conns, transport, FALSE, a, ind, udpbufp);
-+
-+    /* For TCP_OR_UDP entries, add each address again with the non-preferred
-+     * transport, unless we are avoiding UDP.  Flag these as deferred. */
-+    if (retval == 0 && entry->transport == TCP_OR_UDP && strategy != NO_UDP) {
-+        transport = (strategy == UDP_FIRST) ? TCP : UDP;
-         for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
--            a->ai_socktype = socktype2;
--            retval = add_connection(conns, a, ind, udpbufp);
-+            a->ai_socktype = socktype_for_transport(transport);
-+            retval = add_connection(conns, transport, TRUE, a, ind, udpbufp);
-         }
-     }
-     freeaddrinfo(addrs);
-@@ -606,17 +635,18 @@ start_connection(krb5_context context, struct conn_state *state,
-                  const krb5_data *message, struct select_state *selstate,
-                  struct sendto_callback_info *callback_info)
- {
--    int fd, e;
-+    int fd, e, type;
-     static const int one = 1;
-     static const struct linger lopt = { 0, 0 };
- 
--    fd = socket(state->addr.family, state->addr.type, 0);
-+    type = socktype_for_transport(state->addr.transport);
-+    fd = socket(state->addr.family, type, 0);
-     if (fd == INVALID_SOCKET)
-         return -1;              /* try other hosts */
-     set_cloexec_fd(fd);
-     /* Make it non-blocking.  */
-     ioctlsocket(fd, FIONBIO, (const void *) &one);
--    if (state->addr.type == SOCK_STREAM) {
-+    if (state->addr.transport == TCP) {
-         setsockopt(fd, SOL_SOCKET, SO_LINGER, &lopt, sizeof(lopt));
-         TRACE_SENDTO_KDC_TCP_CONNECT(context, &state->addr);
-     }
-@@ -665,7 +695,7 @@ start_connection(krb5_context context, struct conn_state *state,
-     }
-     set_transport_message(state, message);
- 
--    if (state->addr.type == SOCK_DGRAM) {
-+    if (state->addr.transport == UDP) {
-         /* Send it now.  */
-         ssize_t ret;
-         sg_buf *sg = &state->out.sgbuf[0];
-@@ -720,7 +750,7 @@ maybe_send(krb5_context context, struct conn_state *conn,
-         return -1;
-     }
- 
--    if (conn->addr.type == SOCK_STREAM) {
-+    if (conn->addr.transport != UDP) {
-         /* The select callback will handle flushing any data we
-            haven't written yet, and we only write it once.  */
-         return -1;
-@@ -910,7 +940,7 @@ get_endtime(time_ms endtime, struct conn_state *conns)
-     struct conn_state *state;
- 
-     for (state = conns; state != NULL; state = state->next) {
--        if (state->addr.type == SOCK_STREAM &&
-+        if (state->addr.transport == TCP &&
-             (state->state == READING || state->state == WRITING) &&
-             state->endtime > endtime)
-             endtime = state->endtime;
-@@ -1008,7 +1038,7 @@ service_fds(krb5_context context, struct select_state *selstate,
- 
- krb5_error_code
- k5_sendto(krb5_context context, const krb5_data *message,
--          const struct serverlist *servers, int socktype1, int socktype2,
-+          const struct serverlist *servers, k5_transport_strategy strategy,
-           struct sendto_callback_info* callback_info, krb5_data *reply,
-           struct sockaddr *remoteaddr, socklen_t *remoteaddrlen,
-           int *server_used,
-@@ -1038,17 +1068,18 @@ k5_sendto(krb5_context context, const krb5_data *message,
-     cm_init_selstate(sel_state);
- 
-     /* First pass: resolve server hosts, communicate with resulting addresses
--     * of the preferred socktype, and wait 1s for an answer from each. */
-+     * of the preferred transport, and wait 1s for an answer from each. */
-     for (s = 0; s < servers->nservers && !done; s++) {
-         /* Find the current tail pointer. */
-         for (tailptr = &conns; *tailptr != NULL; tailptr = &(*tailptr)->next);
--        retval = resolve_server(context, servers, s, socktype1, socktype2,
--                                message, &udpbuf, &conns);
-+        retval = resolve_server(context, servers, s, strategy, message,
-+                                &udpbuf, &conns);
-         if (retval)
-             goto cleanup;
-         for (state = *tailptr; state != NULL && !done; state = state->next) {
--            /* Contact each new connection whose socktype matches socktype1. */
--            if (state->addr.type != socktype1)
-+            /* Contact each new connection, deferring those which use the
-+             * non-preferred RFC 4120 transport. */
-+            if (state->defer)
-                 continue;
-             if (maybe_send(context, state, message, sel_state, callback_info))
-                 continue;
-@@ -1057,10 +1088,10 @@ k5_sendto(krb5_context context, const krb5_data *message,
-         }
-     }
- 
--    /* Complete the first pass by contacting servers of the non-preferred
--     * socktype (if given), waiting 1s for an answer from each. */
-+    /* Complete the first pass by contacting servers of the non-preferred RFC
-+     * 4120 transport (if given), waiting 1s for an answer from each. */
-     for (state = conns; state != NULL && !done; state = state->next) {
--        if (state->addr.type != socktype2)
-+        if (!state->defer)
-             continue;
-         if (maybe_send(context, state, message, sel_state, callback_info))
-             continue;
-diff --git a/src/lib/krb5/os/t_locate_kdc.c b/src/lib/krb5/os/t_locate_kdc.c
-index 5453a4c..300aa71 100644
---- a/src/lib/krb5/os/t_locate_kdc.c
-+++ b/src/lib/krb5/os/t_locate_kdc.c
-@@ -29,18 +29,18 @@ kfatal (krb5_error_code err)
- }
- 
- static const char *
--stypename (int stype)
-+ttypename (k5_transport ttype)
- {
-     static char buf[20];
--    switch (stype) {
--    case SOCK_STREAM:
--        return "stream";
--    case SOCK_DGRAM:
--        return "dgram";
--    case SOCK_RAW:
--        return "raw";
-+    switch (ttype) {
-+    case TCP_OR_UDP:
-+        return "tcp or udp";
-+    case TCP:
-+        return "tcp";
-+    case UDP:
-+        return "udp";
-     default:
--        snprintf(buf, sizeof(buf), "?%d", stype);
-+        snprintf(buf, sizeof(buf), "?%d", ttype);
-         return buf;
-     }
- }
-@@ -58,7 +58,7 @@ print_addrs (void)
- 
-         if (entry->hostname != NULL) {
-             printf("%2d: host %s\t%s\tport %d\n", (int)i, entry->hostname,
--                   stypename(entry->socktype), ntohs(entry->port));
-+                   ttypename(entry->transport), ntohs(entry->port));
-             continue;
-         }
-         err = getnameinfo((struct sockaddr *)&entry->addr, entry->addrlen,
-@@ -69,7 +69,7 @@ print_addrs (void)
-                    gai_strerror(err));
-         } else {
-             printf("%2d: address %s\t%s\tport %s\n", (int)i, hostbuf,
--                   stypename(entry->socktype), srvbuf);
-+                   ttypename(entry->transport), srvbuf);
-         }
-     }
- }
-@@ -129,7 +129,7 @@ main (int argc, char *argv[])
-         break;
- 
-     case LOOKUP_WHATEVER:
--        err = k5_locate_kdc(ctx, &realm, &sl, master, 0);
-+        err = k5_locate_kdc(ctx, &realm, &sl, master, FALSE);
-         break;
-     }
-     if (err) kfatal (err);
-diff --git a/src/lib/krb5/os/t_std_conf.c b/src/lib/krb5/os/t_std_conf.c
-index e2ff572..6ee54d5 100644
---- a/src/lib/krb5/os/t_std_conf.c
-+++ b/src/lib/krb5/os/t_std_conf.c
-@@ -82,7 +82,7 @@ test_locate_kdc(krb5_context ctx, char *realm)
- 
-     rlm.data = realm;
-     rlm.length = strlen(realm);
--    retval = k5_locate_kdc(ctx, &rlm, &servers, get_masters, 0);
-+    retval = k5_locate_kdc(ctx, &rlm, &servers, get_masters, FALSE);
-     if (retval) {
-         com_err("krb5_locate_kdc", retval, 0);
-         return;
-diff --git a/src/lib/krb5/os/t_trace.c b/src/lib/krb5/os/t_trace.c
-index 36044f5..4cb2bd0 100644
---- a/src/lib/krb5/os/t_trace.c
-+++ b/src/lib/krb5/os/t_trace.c
-@@ -112,7 +112,7 @@ main (int argc, char *argv[])
-     TRACE(ctx, "size_t and const char *, as four-character hex hash: "
-           "{hashlenstr}", 1, NULL);
- 
--    ra.type = SOCK_STREAM;
-+    ra.transport = TCP;
-     addr_in = (struct sockaddr_in *)&ra.saddr;
-     addr_in->sin_family = AF_INET;
-     addr_in->sin_addr.s_addr = INADDR_ANY;
-@@ -121,10 +121,10 @@ main (int argc, char *argv[])
-     ra.family = AF_INET;
-     TRACE(ctx, "struct remote_address *, show socket type, address, port: "
-           "{raddr}", &ra);
--    ra.type = SOCK_DGRAM;
-+    ra.transport = UDP;
-     TRACE(ctx, "struct remote_address *, show socket type, address, port: "
-           "{raddr}", &ra);
--    ra.type = 1234;
-+    ra.transport = 1234;
-     addr_in->sin_family = AF_UNSPEC;
-     ra.family = AF_UNSPEC;
-     TRACE(ctx, "struct remote_address *, show socket type, address, port: "
-diff --git a/src/lib/krb5/os/t_trace.ref b/src/lib/krb5/os/t_trace.ref
-index 749d9c9..ca5818a 100644
---- a/src/lib/krb5/os/t_trace.ref
-+++ b/src/lib/krb5/os/t_trace.ref
-@@ -10,8 +10,8 @@ size_t and const char *, as four-character hex hash: 7B9A
- size_t and const char *, as four-character hex hash: (null)
- struct remote_address *, show socket type, address, port: stream 0.0.0.0:88
- struct remote_address *, show socket type, address, port: dgram 0.0.0.0:88
--struct remote_address *, show socket type, address, port: socktype1234 AF_UNSPEC
--struct remote_address *, show socket type, address, port: socktype1234 af5678
-+struct remote_address *, show socket type, address, port: transport1234 AF_UNSPEC
-+struct remote_address *, show socket type, address, port: transport1234 af5678
- krb5_data *, display as counted string: example.data
- krb5_data *, display as counted string: (null)
- krb5_data *, display as hex bytes: 6578616D706C652E64617461
-diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
-index 525742c..8319a86 100644
---- a/src/lib/krb5/os/trace.c
-+++ b/src/lib/krb5/os/trace.c
-@@ -197,12 +197,12 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
-             }
-         } else if (strcmp(tmpbuf, "raddr") == 0) {
-             ra = va_arg(ap, struct remote_address *);
--            if (ra->type == SOCK_DGRAM)
-+            if (ra->transport == UDP)
-                 k5_buf_add(&buf, "dgram");
--            else if (ra->type == SOCK_STREAM)
-+            else if (ra->transport == TCP)
-                 k5_buf_add(&buf, "stream");
-             else
--                k5_buf_add_fmt(&buf, "socktype%d", ra->type);
-+                k5_buf_add_fmt(&buf, "transport%d", ra->transport);
- 
-             if (getnameinfo((struct sockaddr *)&ra->saddr, ra->len,
-                             addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf),
--- 
-2.1.0
-
diff --git a/SOURCES/0004-Build-support-for-TLS-used-by-HTTPS-proxy-support.patch b/SOURCES/0004-Build-support-for-TLS-used-by-HTTPS-proxy-support.patch
deleted file mode 100644
index df4707d..0000000
--- a/SOURCES/0004-Build-support-for-TLS-used-by-HTTPS-proxy-support.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From d0be57ac45ea639baa3cff0dd2108c34e834bfa7 Mon Sep 17 00:00:00 2001
-From: "Robbie Harwood (frozencemetery)" <rharwood@club.cc.cmu.edu>
-Date: Fri, 16 Aug 2013 12:45:03 -0400
-Subject: [PATCH 04/13] Build support for TLS used by HTTPS proxy support
-
-Add a --with-proxy-tls-impl option to configure, taking 'openssl',
-'auto', or invocation as --without-proxy-tls-impl.  Use related CFLAGS
-when building lib/krb5/os, and LIBS when linking libkrb5.  Call the
-OpenSSL library startup functions during library initialization.
-
-ticket: 7929
----
- src/Makefile.in              |  1 +
- src/config/pre.in            |  5 +++++
- src/configure.in             | 40 ++++++++++++++++++++++++++++++++++++++++
- src/lib/krb5/Makefile.in     |  3 ++-
- src/lib/krb5/krb5_libinit.c  |  2 ++
- src/lib/krb5/os/Makefile.in  |  2 +-
- src/lib/krb5/os/os-proto.h   |  1 +
- src/lib/krb5/os/sendto_kdc.c | 14 ++++++++++++++
- 8 files changed, 66 insertions(+), 2 deletions(-)
-
-diff --git a/src/Makefile.in b/src/Makefile.in
-index 1725093..5e2cf4e 100644
---- a/src/Makefile.in
-+++ b/src/Makefile.in
-@@ -553,6 +553,7 @@ pyrunenv.vals: Makefile
- 	for i in $(RUN_VARS); do \
- 		eval echo 'env['\\\'$$i\\\''] = '\\\'\$$$$i\\\'; \
- 	done > $@
-+	echo "proxy_tls_impl = '$(PROXY_TLS_IMPL)'" >> $@
- 
- runenv.py: pyrunenv.vals
- 	echo 'env = {}' > $@
-diff --git a/src/config/pre.in b/src/config/pre.in
-index fbc5c11..e1d7e4b 100644
---- a/src/config/pre.in
-+++ b/src/config/pre.in
-@@ -428,6 +428,11 @@ PKINIT_CRYPTO_IMPL		= @PKINIT_CRYPTO_IMPL@
- PKINIT_CRYPTO_IMPL_CFLAGS	= @PKINIT_CRYPTO_IMPL_CFLAGS@
- PKINIT_CRYPTO_IMPL_LIBS		= @PKINIT_CRYPTO_IMPL_LIBS@
- 
-+# TLS implementation selection for HTTPS proxy support
-+PROXY_TLS_IMPL                  = @PROXY_TLS_IMPL@
-+PROXY_TLS_IMPL_CFLAGS           = @PROXY_TLS_IMPL_CFLAGS@
-+PROXY_TLS_IMPL_LIBS             = @PROXY_TLS_IMPL_LIBS@
-+
- # error table rules
- #
- ### /* these are invoked as $(...) foo.et, which works, but could be better */
-diff --git a/src/configure.in b/src/configure.in
-index 9bc4663..39e3738 100644
---- a/src/configure.in
-+++ b/src/configure.in
-@@ -272,6 +272,46 @@ AC_SUBST(PKINIT_CRYPTO_IMPL)
- AC_SUBST(PKINIT_CRYPTO_IMPL_CFLAGS)
- AC_SUBST(PKINIT_CRYPTO_IMPL_LIBS)
- 
-+# WITH_PROXY_TLS_IMPL
-+
-+AC_ARG_WITH([proxy-tls-impl],
-+AC_HELP_STRING([--with-proxy-tls-impl=IMPL],
-+               [use specified TLS implementation for HTTPS @<:@auto@:>@]),
-+[PROXY_TLS_IMPL=$withval],[PROXY_TLS_IMPL=auto])
-+case "$PROXY_TLS_IMPL" in
-+openssl|auto)
-+  AC_CHECK_LIB(ssl,SSL_CTX_new,[have_lib_ssl=true],[have_lib_ssl=false],
-+               -lcrypto)
-+  AC_MSG_CHECKING([for OpenSSL])
-+  if test x$have_lib_ssl = xtrue ; then
-+    AC_DEFINE(PROXY_TLS_IMPL_OPENSSL,1,
-+              [Define if HTTPS TLS implementation is OpenSSL])
-+    AC_MSG_RESULT([yes])
-+    PROXY_TLS_IMPL_LIBS="-lssl -lcrypto"
-+    PROXY_TLS_IMPL=openssl
-+    AC_MSG_NOTICE(HTTPS support will use TLS from '$PROXY_TLS_IMPL')
-+  else
-+    if test "$PROXY_TLS_IMPL" = openssl ; then
-+      AC_MSG_ERROR([OpenSSL not found!])
-+    else
-+      AC_MSG_WARN([OpenSSL not found!])
-+    fi
-+    PROXY_TLS_IMPL=no
-+    AC_MSG_NOTICE(building without HTTPS support)
-+  fi
-+  ;;
-+no)
-+  AC_MSG_NOTICE(building without HTTPS support)
-+  ;;
-+*)
-+  AC_MSG_ERROR([Unsupported HTTPS proxy TLS implementation $withval])
-+  ;;
-+esac
-+
-+AC_SUBST(PROXY_TLS_IMPL)
-+AC_SUBST(PROXY_TLS_IMPL_CFLAGS)
-+AC_SUBST(PROXY_TLS_IMPL_LIBS)
-+
- AC_ARG_ENABLE([aesni],
- AC_HELP_STRING([--disable-aesni],[Do not build with AES-NI support]), ,
- enable_aesni=check)
-diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in
-index d9cddc1..472c008 100644
---- a/src/lib/krb5/Makefile.in
-+++ b/src/lib/krb5/Makefile.in
-@@ -56,7 +56,8 @@ RELDIR=krb5
- SHLIB_EXPDEPS = \
- 	$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
- 	$(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB)
--SHLIB_EXPLIBS=-lk5crypto -lcom_err $(SUPPORT_LIB) @GEN_LIB@ $(LIBS)
-+SHLIB_EXPLIBS=-lk5crypto -lcom_err $(PROXY_TLS_IMPL_LIBS) $(SUPPORT_LIB) \
-+	@GEN_LIB@ $(LIBS)
- 
- all-unix:: all-liblinks
- 
-diff --git a/src/lib/krb5/krb5_libinit.c b/src/lib/krb5/krb5_libinit.c
-index f83d25b..f2382d1 100644
---- a/src/lib/krb5/krb5_libinit.c
-+++ b/src/lib/krb5/krb5_libinit.c
-@@ -58,6 +58,8 @@ int krb5int_lib_init(void)
-     if (err)
-         return err;
- 
-+    k5_sendto_kdc_initialize();
-+
-     return 0;
- }
- 
-diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in
-index 5add9f9..fb4001a 100644
---- a/src/lib/krb5/os/Makefile.in
-+++ b/src/lib/krb5/os/Makefile.in
-@@ -2,7 +2,7 @@ mydir=lib$(S)krb5$(S)os
- BUILDTOP=$(REL)..$(S)..$(S)..
- DEFINES=-DLIBDIR=\"$(KRB5_LIBDIR)\" -DBINDIR=\"$(CLIENT_BINDIR)\" \
- 	-DSBINDIR=\"$(ADMIN_BINDIR)\"
--LOCALINCLUDES=-I$(top_srcdir)/util/profile
-+LOCALINCLUDES= $(PROXY_TLS_IMPL_CFLAGS) -I$(top_srcdir)/util/profile
- 
- ##DOS##BUILDTOP = ..\..\..
- ##DOS##PREFIXDIR=os
-diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
-index 3196bca..f23dda5 100644
---- a/src/lib/krb5/os/os-proto.h
-+++ b/src/lib/krb5/os/os-proto.h
-@@ -184,5 +184,6 @@ krb5_error_code localauth_k5login_initvt(krb5_context context, int maj_ver,
-                                          krb5_plugin_vtable vtable);
- krb5_error_code localauth_an2ln_initvt(krb5_context context, int maj_ver,
-                                        int min_ver, krb5_plugin_vtable vtable);
-+void k5_sendto_kdc_initialize(void);
- 
- #endif /* KRB5_LIBOS_INT_PROTO__ */
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index 3f99ce8..c6aae8e 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -48,6 +48,10 @@
- #endif
- #endif
- 
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+#include <openssl/ssl.h>
-+#endif
-+
- #define MAX_PASS                    3
- #define DEFAULT_UDP_PREF_LIMIT   1465
- #define HARD_UDP_LIMIT          32700 /* could probably do 64K-epsilon ? */
-@@ -107,6 +111,16 @@ struct conn_state {
-     krb5_boolean defer;
- };
- 
-+void
-+k5_sendto_kdc_initialize(void)
-+{
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+    SSL_library_init();
-+    SSL_load_error_strings();
-+    OpenSSL_add_all_algorithms();
-+#endif
-+}
-+
- /* Get current time in milliseconds. */
- static krb5_error_code
- get_curtime_ms(time_ms *time_out)
--- 
-2.1.0
-
diff --git a/SOURCES/0004-Make-ksu-respect-the-default_ccache_name-setting.patch b/SOURCES/0004-Make-ksu-respect-the-default_ccache_name-setting.patch
deleted file mode 100644
index cb45f1b..0000000
--- a/SOURCES/0004-Make-ksu-respect-the-default_ccache_name-setting.patch
+++ /dev/null
@@ -1,378 +0,0 @@
-From 3a456898af626dcab4e1ab0749ca2ccb9ad6162b Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Wed, 30 Oct 2013 21:47:14 -0400
-Subject: [PATCH 4/7] Make ksu respect the default_ccache_name setting
-
-Move the logic for resolving and initializing a cache that we're
-copying creds into out of krb5_ccache_copy(), and let the caller deal
-with it.  Add a helper functions to select/resolve an output ccache in
-the default location for the target user after we've switched to the
-target user's privileges.  If the destination is a collection, take
-care not to change which subsidiary is its primary, and reuse a
-subsidiary cache if we can.  If the destination is not a collection,
-append a unique value to its name to make a new ccache.
-
-[ghudson@mit.edu: some changes to variable names and comments; move
-responsibility for getting target ccache name from
-resolve_target_ccache to main]
-
-ticket: 7984 (new)
----
- src/clients/ksu/ccache.c |  35 +++------
- src/clients/ksu/ksu.h    |   6 +-
- src/clients/ksu/main.c   | 181 ++++++++++++++++++++++++++++++++++++++---------
- 3 files changed, 157 insertions(+), 65 deletions(-)
-
-diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index d0fc389..4693bd4 100644
---- a/src/clients/ksu/ccache.c
-+++ b/src/clients/ksu/ccache.c
-@@ -46,59 +46,41 @@ void show_credential();
-    with k5 beta 3 release.
- */
- 
--krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
--                                  primary_principal, restrict_creds,
--                                  target_principal, cc_out, stored, target_uid)
-+krb5_error_code krb5_ccache_copy(context, cc_def, target_principal, cc_target,
-+                                 restrict_creds, primary_principal, stored)
- /* IN */
-     krb5_context context;
-     krb5_ccache cc_def;
--    char *cc_other_tag;
--    krb5_principal primary_principal;
--    krb5_boolean restrict_creds;
-     krb5_principal target_principal;
--    uid_t target_uid;
-+    krb5_ccache cc_target;
-+    krb5_boolean restrict_creds;
-+    krb5_principal primary_principal;
-     /* OUT */
--    krb5_ccache *cc_out;
-     krb5_boolean *stored;
- {
-     int i=0;
--    krb5_ccache  * cc_other;
-     krb5_error_code retval=0;
-     krb5_creds ** cc_def_creds_arr = NULL;
-     krb5_creds ** cc_other_creds_arr = NULL;
- 
--    cc_other = (krb5_ccache *)  xcalloc(1, sizeof (krb5_ccache));
--
--    if ((retval = krb5_cc_resolve(context, cc_other_tag, cc_other))){
--        com_err(prog_name, retval, _("resolving ccache %s"), cc_other_tag);
--        return retval;
--    }
--
-     if (ks_ccache_is_initialized(context, cc_def)) {
-         if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
-             return retval;
-         }
-     }
- 
--    if (ks_ccache_name_is_initialized(context, cc_other_tag))
--        return EINVAL;
--
--    if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {
--        return errno;
--    }
--
--    retval = krb5_cc_initialize(context, *cc_other, target_principal);
-+    retval = krb5_cc_initialize(context, cc_target, target_principal);
-     if (retval)
-         return retval;
- 
-     if (restrict_creds) {
--        retval = krb5_store_some_creds(context, *cc_other, cc_def_creds_arr,
-+        retval = krb5_store_some_creds(context, cc_target, cc_def_creds_arr,
-                                        cc_other_creds_arr, primary_principal,
-                                        stored);
-     } else {
-         *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr,
-                                                primary_principal);
--        retval = krb5_store_all_creds(context, *cc_other, cc_def_creds_arr,
-+        retval = krb5_store_all_creds(context, cc_target, cc_def_creds_arr,
-                                       cc_other_creds_arr);
-     }
- 
-@@ -118,7 +100,6 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag,
-         }
-     }
- 
--    *cc_out = *cc_other;
-     return retval;
- }
- 
-diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
-index 08bf01b..fbbf217 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -44,8 +44,6 @@
- #define KRB5_DEFAULT_OPTIONS 0
- #define KRB5_DEFAULT_TKT_LIFE 60*60*12 /* 12 hours */
- 
--#define KRB5_SECONDARY_CACHE "FILE:/tmp/krb5cc_"
--
- #define KRB5_LOGIN_NAME ".k5login"
- #define KRB5_USERS_NAME ".k5users"
- #define USE_DEFAULT_REALM_NAME "."
-@@ -106,8 +104,8 @@ extern krb5_error_code get_best_principal
- 
- /* ccache.c */
- extern krb5_error_code krb5_ccache_copy
--(krb5_context, krb5_ccache, char *, krb5_principal, krb5_boolean,
-- krb5_principal, krb5_ccache *, krb5_boolean *, uid_t);
-+(krb5_context, krb5_ccache, krb5_principal, krb5_ccache,
-+ krb5_boolean, krb5_principal, krb5_boolean *);
- 
- extern krb5_error_code krb5_store_all_creds
- (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **);
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index d1bb8ca..41a3bf8 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -54,6 +54,10 @@ static void print_status( const char *fmt, ...)
-     __attribute__ ((__format__ (__printf__, 1, 2)))
- #endif
-     ;
-+static krb5_error_code resolve_target_cache(krb5_context ksu_context,
-+                                            krb5_principal princ,
-+                                            krb5_ccache *ccache_out,
-+                                            krb5_boolean *ccache_reused);
- 
- /* Note -e and -a options are mutually exclusive */
- /* insure the proper specification of target user as well as catching
-@@ -112,7 +116,7 @@ main (argc, argv)
-     extern char * getpass(), *crypt();
-     int pargc;
-     char ** pargv;
--    krb5_boolean stored = FALSE;
-+    krb5_boolean stored = FALSE, cc_reused = FALSE;
-     krb5_principal  kdc_server;
-     krb5_boolean zero_password;
-     krb5_boolean restrict_creds;
-@@ -416,23 +420,8 @@ main (argc, argv)
-         exit(1);
-     }
- 
--    /*
--     * Make sure that the new ticket file does not already exist.
--     * This is run as source_uid because it is reasonable to
--     * require the source user to have write to where the target
--     * cache will be created.
--     */
--    cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE, sizeof(char));
--    do {
--        snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s%ld.%d",
--                 KRB5_SECONDARY_CACHE,
--                 (long)target_uid, gen_sym());
--    } while (ks_ccache_name_is_initialized(ksu_context, cc_target_tag));
--
--    if (auth_debug){
-+    if (auth_debug)
-         fprintf(stderr, " source cache =  %s\n", cc_source_tag);
--        fprintf(stderr, " target cache =  %s\n", cc_target_tag);
--    }
- 
-     /*
-      * After proper authentication and authorization, populate a cache for the
-@@ -455,14 +444,19 @@ main (argc, argv)
-         com_err(prog_name, retval, _("while parsing temporary name"));
-         exit(1);
-     }
--    retval = krb5_ccache_copy(ksu_context, cc_source, KS_TEMPORARY_CACHE,
--                              client, restrict_creds, tmp_princ, &cc_tmp,
--                              &stored, 0);
-+    retval = krb5_cc_resolve(ksu_context, KS_TEMPORARY_CACHE, &cc_tmp);
-+    if (retval) {
-+        com_err(prog_name, retval, _("while creating temporary cache"));
-+        exit(1);
-+    }
-+    retval = krb5_ccache_copy(ksu_context, cc_source, tmp_princ, cc_tmp,
-+                              restrict_creds, client, &stored);
-     if (retval) {
-         com_err(prog_name, retval, _("while copying cache %s to %s"),
-                 krb5_cc_get_name(ksu_context, cc_source), KS_TEMPORARY_CACHE);
-         exit(1);
-     }
-+    krb5_cc_close(ksu_context, cc_source);
- 
-     /* Become root for authentication*/
- 
-@@ -686,23 +680,38 @@ main (argc, argv)
-         exit(1);
-     }
- 
--    retval = krb5_ccache_copy(ksu_context, cc_tmp, cc_target_tag,
--                              client, FALSE, client, &cc_target, &stored,
--                              target_pwd->pw_uid);
-+    retval = resolve_target_cache(ksu_context, client, &cc_target, &cc_reused);
-+    if (retval)
-+        exit(1);
-+    retval = krb5_cc_get_full_name(ksu_context, cc_target, &cc_target_tag);
-     if (retval) {
--        com_err(prog_name, retval, _("while copying cache %s to %s"),
--                KS_TEMPORARY_CACHE, cc_target_tag);
-+        com_err(prog_name, retval, _("while getting name of target ccache"));
-+        sweep_up(ksu_context, cc_target);
-         exit(1);
-     }
-+    if (auth_debug)
-+        fprintf(stderr, " target cache =  %s\n", cc_target_tag);
-+    if (cc_reused)
-+        keep_target_cache = TRUE;
- 
--    if (stored && !ks_ccache_is_initialized(ksu_context, cc_target)) {
--        com_err(prog_name, errno,
--                _("%s does not have correct permissions for %s, %s aborted"),
--                target_user, cc_target_tag, prog_name);
--        exit(1);
-+    if (stored) {
-+        retval = krb5_ccache_copy(ksu_context, cc_tmp, client, cc_target,
-+                                  FALSE, client, &stored);
-+        if (retval) {
-+            com_err(prog_name, retval, _("while copying cache %s to %s"),
-+                    KS_TEMPORARY_CACHE, cc_target_tag);
-+            exit(1);
-+        }
-+
-+        if (!ks_ccache_is_initialized(ksu_context, cc_target)) {
-+            com_err(prog_name, errno,
-+                    _("%s does not have correct permissions for %s, "
-+                      "%s aborted"), target_user, cc_target_tag, prog_name);
-+            exit(1);
-+        }
-     }
- 
--    free(cc_target_tag);
-+    krb5_free_string(ksu_context, cc_target_tag);
- 
-     /* Set the cc env name to target. */
-     retval = set_ccname_env(ksu_context, cc_target);
-@@ -711,9 +720,6 @@ main (argc, argv)
-         exit(1);
-     }
- 
--    if ( cc_source)
--        krb5_cc_close(ksu_context, cc_source);
--
-     if (cmd){
-         if ((source_uid == 0) || (source_uid == target_uid )){
-             exec_cmd = cmd;
-@@ -803,6 +809,113 @@ set_ccname_env(krb5_context ksu_context, krb5_ccache ccache)
-     return retval;
- }
- 
-+/*
-+ * Get the configured default ccache name.  Unset KRB5CCNAME and force a
-+ * recomputation so we don't use values for the source user.  Print an error
-+ * message on failure.
-+ */
-+static krb5_error_code
-+get_configured_defccname(krb5_context context, char **target_out)
-+{
-+    krb5_error_code retval;
-+    const char *defname;
-+    char *target;
-+
-+    *target_out = NULL;
-+
-+    if (unsetenv(KRB5_ENV_CCNAME) != 0) {
-+        retval = errno;
-+        com_err(prog_name, retval, _("while clearing the value of %s"),
-+                KRB5_ENV_CCNAME);
-+        return retval;
-+    }
-+
-+    /* Make sure we don't have a cached value for a different uid. */
-+    retval = krb5_cc_set_default_name(context, NULL);
-+    if (retval != 0) {
-+        com_err(prog_name, retval, _("while resetting target ccache name"));
-+        return retval;
-+    }
-+
-+    defname = krb5_cc_default_name(context);
-+    target = (defname == NULL) ? NULL : strdup(defname);
-+    if (target == NULL) {
-+        com_err(prog_name, ENOMEM, _("while determining target ccache name"));
-+        return ENOMEM;
-+    }
-+    *target_out = target;
-+    return 0;
-+}
-+
-+/* Determine where the target user's creds should be stored.  Print an error
-+ * message on failure. */
-+static krb5_error_code
-+resolve_target_cache(krb5_context context, krb5_principal princ,
-+                     krb5_ccache *ccache_out, krb5_boolean *ccache_reused)
-+{
-+    krb5_error_code retval;
-+    krb5_boolean switchable, reused = FALSE;
-+    krb5_ccache ccache = NULL;
-+    char *sep, *ccname = NULL, *target;
-+
-+    *ccache_out = NULL;
-+    *ccache_reused = FALSE;
-+
-+    retval = get_configured_defccname(context, &target);
-+    if (retval != 0)
-+        return retval;
-+
-+    /* Check if the configured default name uses a switchable type. */
-+    sep = strchr(target, ':');
-+    *sep = '\0';
-+    switchable = krb5_cc_support_switch(context, target);
-+    *sep = ':';
-+
-+    if (!switchable) {
-+        /* Try to avoid destroying an in-use target ccache by coming up with
-+         * the name of a cache that doesn't exist yet. */
-+        do {
-+            free(ccname);
-+            if (asprintf(&ccname, "%s.%d", target, gen_sym()) < 0) {
-+                retval = ENOMEM;
-+                com_err(prog_name, ENOMEM,
-+                        _("while allocating memory for target ccache name"));
-+                goto cleanup;
-+            }
-+        } while (ks_ccache_name_is_initialized(context, ccname));
-+        retval = krb5_cc_resolve(context, ccname, &ccache);
-+    } else {
-+        /* Look for a cache in the collection that we can reuse. */
-+        retval = krb5_cc_cache_match(context, princ, &ccache);
-+        if (retval == 0) {
-+            reused = TRUE;
-+        } else {
-+            /* There isn't one, so create a new one. */
-+            *sep = '\0';
-+            retval = krb5_cc_new_unique(context, target, NULL, &ccache);
-+            *sep = ':';
-+            if (retval) {
-+                com_err(prog_name, retval,
-+                        _("while creating new target ccache"));
-+                goto cleanup;
-+            }
-+            retval = krb5_cc_initialize(context, ccache, princ);
-+            if (retval) {
-+                com_err(prog_name, retval,
-+                        _("while initializing target cache"));
-+                goto cleanup;
-+            }
-+        }
-+    }
-+
-+    *ccache_out = ccache;
-+    *ccache_reused = reused;
-+
-+cleanup:
-+    free(target);
-+    return retval;
-+}
-+
- #ifdef HAVE_GETUSERSHELL
- 
- int standard_shell(sh)
--- 
-2.0.4
-
diff --git a/SOURCES/0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE.patch b/SOURCES/0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE.patch
deleted file mode 100644
index f650d69..0000000
--- a/SOURCES/0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE.patch
+++ /dev/null
@@ -1,352 +0,0 @@
-From bb89afd7c59deea855d2818fe36ef7472b4abf2e Mon Sep 17 00:00:00 2001
-From: Nathaniel McCallum <npmccallum@redhat.com>
-Date: Mon, 9 Sep 2013 14:23:56 -0400
-Subject: [PATCH 05/13] Add ASN.1 codec for KKDCP's KDC-PROXY-MESSAGE
-
-Handle encoding and decoding [MS-KKDCP] proxy messages, including
-handling of the additional length bytes.  Early versions of [MS-KKDCP]
-incorrectly omit that the size of the proxied message is prepended to
-the proxied message, as it is when we're using plain TCP, before
-encoding the proxy-message structure.  This is fixed at least as of
-version 2.1 of the spec.
-
-[nalin@redhat.com: add tests]
-
-ticket: 7929
----
- src/include/k5-int.h                 | 13 +++++++++++++
- src/lib/krb5/asn.1/asn1_k_encode.c   | 14 ++++++++++++++
- src/lib/krb5/krb/kfree.c             | 10 ++++++++++
- src/lib/krb5/libkrb5.exports         |  3 +++
- src/tests/asn.1/krb5_decode_test.c   | 18 ++++++++++++++++++
- src/tests/asn.1/krb5_encode_test.c   |  8 ++++++++
- src/tests/asn.1/ktest.c              | 23 ++++++++++++++++++++++
- src/tests/asn.1/ktest.h              |  5 +++++
- src/tests/asn.1/ktest_equal.c        | 12 ++++++++++++
- src/tests/asn.1/ktest_equal.h        |  3 +++
- src/tests/asn.1/reference_encode.out |  1 +
- src/tests/asn.1/trval_reference.out  | 37 ++++++++++++++++++++++++++++++++++++
- 12 files changed, 147 insertions(+)
-
-diff --git a/src/include/k5-int.h b/src/include/k5-int.h
-index 096cd14..8f039ee 100644
---- a/src/include/k5-int.h
-+++ b/src/include/k5-int.h
-@@ -518,6 +518,12 @@ typedef struct _krb5_pa_otp_req {
-     krb5_data vendor;
- } krb5_pa_otp_req;
- 
-+typedef struct _krb5_kkdcp_message {
-+    krb5_data kerb_message;
-+    krb5_data target_domain;
-+    krb5_int32 dclocator_hint;
-+} krb5_kkdcp_message;
-+
- #include <stdlib.h>
- #include <string.h>
- 
-@@ -898,6 +904,7 @@ void k5_free_otp_tokeninfo(krb5_context context, krb5_otp_tokeninfo *val);
- void k5_free_pa_otp_challenge(krb5_context context,
-                               krb5_pa_otp_challenge *val);
- void k5_free_pa_otp_req(krb5_context context, krb5_pa_otp_req *val);
-+void k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val);
- 
- /* #include "krb5/wordsize.h" -- comes in through base-defs.h. */
- #include "com_err.h"
-@@ -1438,6 +1445,9 @@ encode_krb5_pa_otp_req(const krb5_pa_otp_req *, krb5_data **);
- krb5_error_code
- encode_krb5_pa_otp_enc_req(const krb5_data *, krb5_data **);
- 
-+krb5_error_code
-+encode_krb5_kkdcp_message(const krb5_kkdcp_message *, krb5_data **);
-+
- /*************************************************************************
-  * End of prototypes for krb5_encode.c
-  *************************************************************************/
-@@ -1608,6 +1618,9 @@ decode_krb5_pa_otp_req(const krb5_data *, krb5_pa_otp_req **);
- krb5_error_code
- decode_krb5_pa_otp_enc_req(const krb5_data *, krb5_data **);
- 
-+krb5_error_code
-+decode_krb5_kkdcp_message(const krb5_data *, krb5_kkdcp_message **);
-+
- struct _krb5_key_data;          /* kdb.h */
- 
- struct ldap_seqof_key_data {
-diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
-index 7b9179d..4dc49c2 100644
---- a/src/lib/krb5/asn.1/asn1_k_encode.c
-+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
-@@ -1711,3 +1711,17 @@ static const struct atype_info *pa_otp_enc_req_fields[] = {
- };
- DEFSEQTYPE(pa_otp_enc_req, krb5_data, pa_otp_enc_req_fields);
- MAKE_CODEC(krb5_pa_otp_enc_req, pa_otp_enc_req);
-+
-+DEFFIELD(kkdcp_message_0, krb5_kkdcp_message,
-+         kerb_message, 0, ostring_data);
-+DEFFIELD(kkdcp_message_1, krb5_kkdcp_message,
-+         target_domain, 1, opt_gstring_data);
-+DEFFIELD(kkdcp_message_2, krb5_kkdcp_message,
-+         dclocator_hint, 2, opt_int32);
-+static const struct atype_info *kkdcp_message_fields[] = {
-+    &k5_atype_kkdcp_message_0, &k5_atype_kkdcp_message_1,
-+    &k5_atype_kkdcp_message_2
-+};
-+DEFSEQTYPE(kkdcp_message, krb5_kkdcp_message,
-+           kkdcp_message_fields);
-+MAKE_CODEC(krb5_kkdcp_message, kkdcp_message);
-diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c
-index 32b2151..f86c619 100644
---- a/src/lib/krb5/krb/kfree.c
-+++ b/src/lib/krb5/krb/kfree.c
-@@ -821,3 +821,13 @@ k5_free_pa_otp_req(krb5_context context, krb5_pa_otp_req *val)
-     free(val->vendor.data);
-     free(val);
- }
-+
-+void
-+k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val)
-+{
-+    if (val == NULL)
-+        return;
-+    free(val->target_domain.data);
-+    free(val->kerb_message.data);
-+    free(val);
-+}
-diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
-index 863ec02..2d0852d 100644
---- a/src/lib/krb5/libkrb5.exports
-+++ b/src/lib/krb5/libkrb5.exports
-@@ -25,6 +25,7 @@ decode_krb5_iakerb_finished
- decode_krb5_iakerb_header
- decode_krb5_kdc_req_body
- decode_krb5_otp_tokeninfo
-+decode_krb5_kkdcp_message
- decode_krb5_pa_enc_ts
- decode_krb5_pa_for_user
- decode_krb5_pa_fx_fast_reply
-@@ -72,6 +73,7 @@ encode_krb5_iakerb_finished
- encode_krb5_iakerb_header
- encode_krb5_kdc_req_body
- encode_krb5_otp_tokeninfo
-+encode_krb5_kkdcp_message
- encode_krb5_pa_enc_ts
- encode_krb5_pa_for_user
- encode_krb5_pa_fx_fast_reply
-@@ -113,6 +115,7 @@ k5_expand_path_tokens
- k5_expand_path_tokens_extra
- k5_free_algorithm_identifier
- k5_free_otp_tokeninfo
-+k5_free_kkdcp_message
- k5_free_pa_otp_challenge
- k5_free_pa_otp_req
- k5_free_serverlist
-diff --git a/src/tests/asn.1/krb5_decode_test.c b/src/tests/asn.1/krb5_decode_test.c
-index 8719978..f12bb16 100644
---- a/src/tests/asn.1/krb5_decode_test.c
-+++ b/src/tests/asn.1/krb5_decode_test.c
-@@ -54,6 +54,8 @@ static void ktest_free_reply_key_pack(krb5_context context,
- static void ktest_free_reply_key_pack_draft9(krb5_context context,
-                                              krb5_reply_key_pack_draft9 *val);
- #endif
-+static void ktest_free_kkdcp_message(krb5_context context,
-+                                     krb5_kkdcp_message *val);
- 
- int main(argc, argv)
-     int argc;
-@@ -1077,6 +1079,13 @@ int main(argc, argv)
-         ktest_empty_data(&ref);
-     }
- 
-+    /****************************************************************/
-+    /* decode_krb5_kkdcp_message */
-+    {
-+        setup(krb5_kkdcp_message,ktest_make_sample_kkdcp_message);
-+        decode_run("kkdcp_message","","30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61",decode_krb5_kkdcp_message,ktest_equal_kkdcp_message,ktest_free_kkdcp_message);
-+    }
-+
- #ifndef DISABLE_PKINIT
- 
-     /****************************************************************/
-@@ -1262,3 +1271,12 @@ ktest_free_reply_key_pack_draft9(krb5_context context,
- }
- 
- #endif /* not DISABLE_PKINIT */
-+
-+static void
-+ktest_free_kkdcp_message(krb5_context context,
-+                         krb5_kkdcp_message *val)
-+{
-+    if (val)
-+        ktest_empty_kkdcp_message(val);
-+    free(val);
-+}
-diff --git a/src/tests/asn.1/krb5_encode_test.c b/src/tests/asn.1/krb5_encode_test.c
-index 638f6fe..3ba8684 100644
---- a/src/tests/asn.1/krb5_encode_test.c
-+++ b/src/tests/asn.1/krb5_encode_test.c
-@@ -734,6 +734,14 @@ main(argc, argv)
-         encode_run(d, "pa_otp_enc_req", "", encode_krb5_pa_otp_enc_req);
-         ktest_empty_data(&d);
-     }
-+    /****************************************************************/
-+    /* encode_krb5_kkdcp_message */
-+    {
-+        krb5_kkdcp_message info;
-+        ktest_make_sample_kkdcp_message(&info);
-+        encode_run(info, "kkdcp_message", "", encode_krb5_kkdcp_message);
-+        ktest_empty_kkdcp_message(&info);
-+    }
- #ifndef DISABLE_PKINIT
-     /****************************************************************/
-     /* encode_krb5_pa_pk_as_req */
-diff --git a/src/tests/asn.1/ktest.c b/src/tests/asn.1/ktest.c
-index aa41fd8..4ce9f70 100644
---- a/src/tests/asn.1/ktest.c
-+++ b/src/tests/asn.1/ktest.c
-@@ -933,6 +933,21 @@ ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data *p)
- }
- #endif
- 
-+void
-+ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p)
-+{
-+    krb5_kdc_req req;
-+    krb5_data *message;
-+
-+    ktest_make_sample_kdc_req(&req);
-+    req.msg_type = KRB5_AS_REQ;
-+    encode_krb5_as_req(&req, &message);
-+    p->kerb_message = *message;
-+    free(message);
-+    ktest_empty_kdc_req(&req);
-+    ktest_make_sample_data(&(p->target_domain));
-+    p->dclocator_hint = 0;
-+}
- 
- /****************************************************************/
- /* destructors */
-@@ -1731,3 +1746,11 @@ ktest_empty_ldap_seqof_key_data(krb5_context ctx, ldap_seqof_key_data *p)
-     free(p->key_data);
- }
- #endif
-+
-+void
-+ktest_empty_kkdcp_message(krb5_kkdcp_message *p)
-+{
-+    ktest_empty_data(&p->kerb_message);
-+    ktest_empty_data(&p->target_domain);
-+    p->dclocator_hint = -1;
-+}
-diff --git a/src/tests/asn.1/ktest.h b/src/tests/asn.1/ktest.h
-index 67a6c69..a9ebb77 100644
---- a/src/tests/asn.1/ktest.h
-+++ b/src/tests/asn.1/ktest.h
-@@ -119,6 +119,9 @@ void ktest_make_sample_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p);
- #ifdef ENABLE_LDAP
- void ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data *p);
- #endif
-+
-+void ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p);
-+
- /*----------------------------------------------------------------------*/
- 
- void ktest_empty_authorization_data(krb5_authdata **ad);
-@@ -200,6 +203,8 @@ void ktest_empty_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p);
- void ktest_empty_ldap_seqof_key_data(krb5_context, ldap_seqof_key_data *p);
- #endif
- 
-+void ktest_empty_kkdcp_message(krb5_kkdcp_message *p);
-+
- extern krb5_context test_context;
- extern char *sample_principal_name;
- 
-diff --git a/src/tests/asn.1/ktest_equal.c b/src/tests/asn.1/ktest_equal.c
-index 4e71242..39c35b5 100644
---- a/src/tests/asn.1/ktest_equal.c
-+++ b/src/tests/asn.1/ktest_equal.c
-@@ -1039,3 +1039,15 @@ ktest_equal_reply_key_pack_draft9(krb5_reply_key_pack_draft9 *ref,
- }
- 
- #endif /* not DISABLE_PKINIT */
-+
-+int
-+ktest_equal_kkdcp_message(krb5_kkdcp_message *ref, krb5_kkdcp_message *var)
-+{
-+    int p = TRUE;
-+    if (ref == var) return TRUE;
-+    else if (ref == NULL || var == NULL) return FALSE;
-+    p = p && data_eq(ref->kerb_message, var->kerb_message);
-+    p = p && data_eq(ref->target_domain, var->target_domain);
-+    p = p && (ref->dclocator_hint == var->dclocator_hint);
-+    return p;
-+}
-diff --git a/src/tests/asn.1/ktest_equal.h b/src/tests/asn.1/ktest_equal.h
-index e75f86a..491653f 100644
---- a/src/tests/asn.1/ktest_equal.h
-+++ b/src/tests/asn.1/ktest_equal.h
-@@ -145,4 +145,7 @@ generic(ktest_equal_reply_key_pack, krb5_reply_key_pack);
- generic(ktest_equal_reply_key_pack_draft9, krb5_reply_key_pack_draft9);
- #endif /* not DISABLE_PKINIT */
- 
-+int ktest_equal_kkdcp_message(krb5_kkdcp_message *ref,
-+                              krb5_kkdcp_message *var);
-+
- #endif
-diff --git a/src/tests/asn.1/reference_encode.out b/src/tests/asn.1/reference_encode.out
-index 315e25b..b737da3 100644
---- a/src/tests/asn.1/reference_encode.out
-+++ b/src/tests/asn.1/reference_encode.out
-@@ -68,3 +68,4 @@ encode_krb5_pa_otp_challenge: 30 81 A5 80 08 6D 61 78 6E 6F 6E 63 65 81 0B 74 65
- encode_krb5_pa_otp_req(optionals NULL): 30 2C 80 05 00 00 00 00 00 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65
- encode_krb5_pa_otp_req: 30 81 B9 80 05 00 60 00 00 00 81 05 6E 6F 6E 63 65 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 0B 06 09 60 86 48 01 65 03 04 02 01 84 02 03 E8 85 05 66 72 6F 67 73 86 0A 6D 79 66 69 72 73 74 70 69 6E 87 05 68 61 72 6B 21 88 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 89 03 33 34 36 8A 01 02 8B 09 79 6F 75 72 74 6F 6B 65 6E 8C 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 8D 0B 45 78 61 6D 70 6C 65 63 6F 72 70
- encode_krb5_pa_otp_enc_req: 30 0A 80 08 6B 72 62 35 64 61 74 61
-+encode_krb5_kkdcp_message: 30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61
-diff --git a/src/tests/asn.1/trval_reference.out b/src/tests/asn.1/trval_reference.out
-index 461021e..599580c 100644
---- a/src/tests/asn.1/trval_reference.out
-+++ b/src/tests/asn.1/trval_reference.out
-@@ -1478,3 +1478,40 @@ encode_krb5_pa_otp_enc_req:
- [Sequence/Sequence Of]
- .  [0] <8>
-       6b 72 62 35 64 61 74 61                             krb5data
-+
-+encode_krb5_kkdcp_message:
-+
-+[Sequence/Sequence Of]
-+.  [0] [Octet String] <488>
-+      6a 82 01 e4 30 82 01 e0 a1 03 02 01 05 a2 03 02     j...0...........
-+      01 0a a3 26 30 24 30 10 a1 03 02 01 0d a2 09 04     ...&0$0.........
-+      07 70 61 2d 64 61 74 61 30 10 a1 03 02 01 0d a2     .pa-data0.......
-+      09 04 07 70 61 2d 64 61 74 61 a4 82 01 aa 30 82     ...pa-data....0.
-+      01 a6 a0 07 03 05 00 fe dc ba 98 a1 1a 30 18 a0     .............0..
-+      03 02 01 01 a1 11 30 0f 1b 06 68 66 74 73 61 69     ......0...hftsai
-+      1b 05 65 78 74 72 61 a2 10 1b 0e 41 54 48 45 4e     ..extra....ATHEN
-+      41 2e 4d 49 54 2e 45 44 55 a3 1a 30 18 a0 03 02     A.MIT.EDU..0....
-+      01 01 a1 11 30 0f 1b 06 68 66 74 73 61 69 1b 05     ....0...hftsai..
-+      65 78 74 72 61 a4 11 18 0f 31 39 39 34 30 36 31     extra....1994061
-+      30 30 36 30 33 31 37 5a a5 11 18 0f 31 39 39 34     0060317Z....1994
-+      30 36 31 30 30 36 30 33 31 37 5a a6 11 18 0f 31     0610060317Z....1
-+      39 39 34 30 36 31 30 30 36 30 33 31 37 5a a7 03     9940610060317Z..
-+      02 01 2a a8 08 30 06 02 01 00 02 01 01 a9 20 30     ..*..0........ 0
-+      1e 30 0d a0 03 02 01 02 a1 06 04 04 12 d0 00 23     .0.............#
-+      30 0d a0 03 02 01 02 a1 06 04 04 12 d0 00 23 aa     0.............#.
-+      25 30 23 a0 03 02 01 00 a1 03 02 01 05 a2 17 04     %0#.............
-+      15 6b 72 62 41 53 4e 2e 31 20 74 65 73 74 20 6d     .krbASN.1 test m
-+      65 73 73 61 67 65 ab 81 bf 30 81 bc 61 5c 30 5a     essage...0..a\0Z
-+      a0 03 02 01 05 a1 10 1b 0e 41 54 48 45 4e 41 2e     .........ATHENA.
-+      4d 49 54 2e 45 44 55 a2 1a 30 18 a0 03 02 01 01     MIT.EDU..0......
-+      a1 11 30 0f 1b 06 68 66 74 73 61 69 1b 05 65 78     ..0...hftsai..ex
-+      74 72 61 a3 25 30 23 a0 03 02 01 00 a1 03 02 01     tra.%0#.........
-+      05 a2 17 04 15 6b 72 62 41 53 4e 2e 31 20 74 65     .....krbASN.1 te
-+      73 74 20 6d 65 73 73 61 67 65 61 5c 30 5a a0 03     st messagea\0Z..
-+      02 01 05 a1 10 1b 0e 41 54 48 45 4e 41 2e 4d 49     .......ATHENA.MI
-+      54 2e 45 44 55 a2 1a 30 18 a0 03 02 01 01 a1 11     T.EDU..0........
-+      30 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 74 72     0...hftsai..extr
-+      61 a3 25 30 23 a0 03 02 01 00 a1 03 02 01 05 a2     a.%0#...........
-+      17 04 15 6b 72 62 41 53 4e 2e 31 20 74 65 73 74     ...krbASN.1 test
-+      20 6d 65 73 73 61 67 65                              message
-+.  [1] [General string] "krb5data"
--- 
-2.1.0
-
diff --git a/SOURCES/0005-Copy-config-entries-to-the-ksu-target-ccache.patch b/SOURCES/0005-Copy-config-entries-to-the-ksu-target-ccache.patch
deleted file mode 100644
index e004136..0000000
--- a/SOURCES/0005-Copy-config-entries-to-the-ksu-target-ccache.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 297496f0938955ba4aaf0ebecf4e393e527b8cbf Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Tue, 29 Oct 2013 16:27:20 -0400
-Subject: [PATCH 5/7] Copy config entries to the ksu target ccache
-
-When we try to screen out expired creds while reading them from one
-ccache to eventually store in another, also keep configuration entries.
-
-ticket: 7986 (new)
----
- src/clients/ksu/ccache.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index 4693bd4..0f9e042 100644
---- a/src/clients/ksu/ccache.c
-+++ b/src/clients/ksu/ccache.c
-@@ -219,7 +219,8 @@ krb5_error_code krb5_get_nonexp_tkts(context, cc, creds_array)
- 
-     while (!(retval = krb5_cc_next_cred(context, cc, &cur, &creds))){
- 
--        if ((retval = krb5_check_exp(context, creds.times))){
-+        if (!krb5_is_config_principal(context, creds.server) &&
-+            (retval = krb5_check_exp(context, creds.times))){
-             if (retval != KRB5KRB_AP_ERR_TKT_EXPIRED){
-                 return retval;
-             }
--- 
-2.0.4
-
diff --git a/SOURCES/0006-Dispatch-style-protocol-switching-for-transport.patch b/SOURCES/0006-Dispatch-style-protocol-switching-for-transport.patch
deleted file mode 100644
index e36544e..0000000
--- a/SOURCES/0006-Dispatch-style-protocol-switching-for-transport.patch
+++ /dev/null
@@ -1,506 +0,0 @@
-From 606e2ccc0a2546a23761f910482a55c5bf0f98ac Mon Sep 17 00:00:00 2001
-From: "Robbie Harwood (frozencemetery)" <rharwood@club.cc.cmu.edu>
-Date: Fri, 16 Aug 2013 14:48:55 -0400
-Subject: [PATCH 06/13] Dispatch-style protocol switching for transport
-
-Switch to using per-transport-type functions when a socket that we're
-using to communicate with a server becomes readable or writable, and add
-them as pointers to the connection state.  The functions are passed the
-name of the realm of the server being contacted, as we expect to need
-this in the near future.
-
-[nalin@redhat.com: replace macros with typedefs]
-[nalin@redhat.com: compare transports with TCP_OR_UDP rather than with 0]
-
-ticket: 7929
----
- src/lib/krb5/os/changepw.c   |   6 +-
- src/lib/krb5/os/os-proto.h   |   1 +
- src/lib/krb5/os/sendto_kdc.c | 297 ++++++++++++++++++++++++-------------------
- 3 files changed, 171 insertions(+), 133 deletions(-)
-
-diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
-index a1c9885..0ee427d 100644
---- a/src/lib/krb5/os/changepw.c
-+++ b/src/lib/krb5/os/changepw.c
-@@ -261,9 +261,9 @@ change_set_password(krb5_context context,
-         callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup;
-         krb5_free_data_contents(callback_ctx.context, &chpw_rep);
- 
--        code = k5_sendto(callback_ctx.context, NULL, &sl, strategy,
--                         &callback_info, &chpw_rep, ss2sa(&remote_addr),
--                         &addrlen, NULL, NULL, NULL);
-+        code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm,
-+                         &sl, strategy, &callback_info, &chpw_rep,
-+                         ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL);
-         if (code) {
-             /*
-              * Here we may want to switch to TCP on some errors.
-diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
-index f23dda5..e60ccd0 100644
---- a/src/lib/krb5/os/os-proto.h
-+++ b/src/lib/krb5/os/os-proto.h
-@@ -115,6 +115,7 @@ int _krb5_use_dns_kdc (krb5_context);
- int _krb5_conf_boolean (const char *);
- 
- krb5_error_code k5_sendto(krb5_context context, const krb5_data *message,
-+                          const krb5_data *realm,
-                           const struct serverlist *addrs,
-                           k5_transport_strategy strategy,
-                           struct sendto_callback_info *callback_info,
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index c6aae8e..28f1c4d 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -96,11 +96,18 @@ struct outgoing_message {
-     unsigned char msg_len_buf[4];
- };
- 
-+struct conn_state;
-+typedef krb5_boolean fd_handler_fn(krb5_context context,
-+                                   const krb5_data *realm,
-+                                   struct conn_state *conn,
-+                                   struct select_state *selstate);
-+
- struct conn_state {
-     SOCKET fd;
-     enum conn_states state;
--    int (*service)(krb5_context context, struct conn_state *,
--                   struct select_state *, int);
-+    fd_handler_fn *service_connect;
-+    fd_handler_fn *service_write;
-+    fd_handler_fn *service_read;
-     struct remote_address addr;
-     struct incoming_message in;
-     struct outgoing_message out;
-@@ -409,9 +416,9 @@ krb5_sendto_kdc(krb5_context context, const krb5_data *message,
-         return retval;
- 
-     err = 0;
--    retval = k5_sendto(context, message, &servers, strategy, NULL, reply,
--                       NULL, NULL, &server_used, check_for_svc_unavailable,
--                       &err);
-+    retval = k5_sendto(context, message, realm, &servers, strategy, NULL,
-+                       reply, NULL, NULL, &server_used,
-+                       check_for_svc_unavailable, &err);
-     if (retval == KRB5_KDC_UNREACH) {
-         if (err == KDC_ERR_SVC_UNAVAILABLE) {
-             retval = KRB5KDC_ERR_SVC_UNAVAILABLE;
-@@ -457,10 +464,10 @@ cleanup:
-  *   connections already in progress
-  */
- 
--static int service_tcp_fd(krb5_context context, struct conn_state *conn,
--                          struct select_state *selstate, int ssflags);
--static int service_udp_fd(krb5_context context, struct conn_state *conn,
--                          struct select_state *selstate, int ssflags);
-+static fd_handler_fn service_tcp_connect;
-+static fd_handler_fn service_tcp_write;
-+static fd_handler_fn service_tcp_read;
-+static fd_handler_fn service_udp_read;
- 
- /* Set up the actual message we will send across the underlying transport to
-  * communicate the payload message, using one or both of state->out.sgbuf. */
-@@ -505,9 +512,13 @@ add_connection(struct conn_state **conns, k5_transport transport,
-     state->server_index = server_index;
-     SG_SET(&state->out.sgbuf[1], NULL, 0);
-     if (transport == TCP) {
--        state->service = service_tcp_fd;
-+        state->service_connect = service_tcp_connect;
-+        state->service_write = service_tcp_write;
-+        state->service_read = service_tcp_read;
-     } else {
--        state->service = service_udp_fd;
-+        state->service_connect = NULL;
-+        state->service_write = NULL;
-+        state->service_read = service_udp_read;
- 
-         if (*udpbufp == NULL) {
-             *udpbufp = malloc(MAX_DGRAM_SIZE);
-@@ -788,9 +799,13 @@ maybe_send(krb5_context context, struct conn_state *conn,
- }
- 
- static void
--kill_conn(struct conn_state *conn, struct select_state *selstate)
-+kill_conn(krb5_context context, struct conn_state *conn,
-+          struct select_state *selstate)
- {
-+    if (socktype_for_transport(conn->addr.transport) == SOCK_STREAM)
-+        TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr);
-     cm_remove_fd(selstate, conn->fd);
-+
-     closesocket(conn->fd);
-     conn->fd = INVALID_SOCKET;
-     conn->state = FAILED;
-@@ -814,136 +829,157 @@ get_so_error(int fd)
-     return sockerr;
- }
- 
--/* Process events on a TCP socket.  Return 1 if we get a complete reply. */
--static int
--service_tcp_fd(krb5_context context, struct conn_state *conn,
--               struct select_state *selstate, int ssflags)
-+/* Perform next step in sending.  Return true on usable data. */
-+static krb5_boolean
-+service_dispatch(krb5_context context, const krb5_data *realm,
-+                 struct conn_state *conn, struct select_state *selstate,
-+                 int ssflags)
- {
--    int e = 0;
--    ssize_t nwritten, nread;
--    SOCKET_WRITEV_TEMP tmp;
--    struct incoming_message *in = &conn->in;
--    struct outgoing_message *out = &conn->out;
--
-     /* Check for a socket exception. */
--    if (ssflags & SSF_EXCEPTION)
--        goto kill_conn;
-+    if (ssflags & SSF_EXCEPTION) {
-+        kill_conn(context, conn, selstate);
-+        return FALSE;
-+    }
- 
-     switch (conn->state) {
-     case CONNECTING:
--        /* Check whether the connection succeeded. */
--        e = get_so_error(conn->fd);
--        if (e) {
--            TRACE_SENDTO_KDC_TCP_ERROR_CONNECT(context, &conn->addr, e);
--            goto kill_conn;
--        }
--        conn->state = WRITING;
-+        assert(conn->service_connect != NULL);
-+        return conn->service_connect(context, realm, conn, selstate);
-+    case WRITING:
-+        assert(conn->service_write != NULL);
-+        return conn->service_write(context, realm, conn, selstate);
-+    case READING:
-+        assert(conn->service_read != NULL);
-+        return conn->service_read(context, realm, conn, selstate);
-+    default:
-+        abort();
-+    }
-+}
- 
--        /* Record this connection's timeout for service_fds. */
--        if (get_curtime_ms(&conn->endtime) == 0)
--            conn->endtime += 10000;
-+/* Initialize TCP transport. */
-+static krb5_boolean
-+service_tcp_connect(krb5_context context, const krb5_data *realm,
-+                    struct conn_state *conn, struct select_state *selstate)
-+{
-+    /* Check whether the connection succeeded. */
-+    int e = get_so_error(conn->fd);
- 
--        /* Fall through. */
--    case WRITING:
--        TRACE_SENDTO_KDC_TCP_SEND(context, &conn->addr);
--        nwritten = SOCKET_WRITEV(conn->fd, out->sgp, out->sg_count, tmp);
--        if (nwritten < 0) {
--            TRACE_SENDTO_KDC_TCP_ERROR_SEND(context, &conn->addr,
--                                            SOCKET_ERRNO);
--            goto kill_conn;
-+    if (e) {
-+        TRACE_SENDTO_KDC_TCP_ERROR_CONNECT(context, &conn->addr, e);
-+        kill_conn(context, conn, selstate);
-+        return FALSE;
-+    }
-+
-+    conn->state = WRITING;
-+
-+    /* Record this connection's timeout for service_fds. */
-+    if (get_curtime_ms(&conn->endtime) == 0)
-+        conn->endtime += 10000;
-+
-+    return service_tcp_write(context, realm, conn, selstate);
-+}
-+
-+/* Sets conn->state to READING when done. */
-+static krb5_boolean
-+service_tcp_write(krb5_context context, const krb5_data *realm,
-+                  struct conn_state *conn, struct select_state *selstate)
-+{
-+    ssize_t nwritten;
-+    SOCKET_WRITEV_TEMP tmp;
-+
-+    TRACE_SENDTO_KDC_TCP_SEND(context, &conn->addr);
-+    nwritten = SOCKET_WRITEV(conn->fd, conn->out.sgp, conn->out.sg_count, tmp);
-+    if (nwritten < 0) {
-+        TRACE_SENDTO_KDC_TCP_ERROR_SEND(context, &conn->addr, SOCKET_ERRNO);
-+        kill_conn(context, conn, selstate);
-+        return FALSE;
-+    }
-+    while (nwritten) {
-+        sg_buf *sgp = conn->out.sgp;
-+        if ((size_t)nwritten < SG_LEN(sgp)) {
-+            SG_ADVANCE(sgp, (size_t)nwritten);
-+            nwritten = 0;
-+        } else {
-+            nwritten -= SG_LEN(sgp);
-+            conn->out.sgp++;
-+            conn->out.sg_count--;
-         }
--        while (nwritten) {
--            sg_buf *sgp = out->sgp;
--            if ((size_t) nwritten < SG_LEN(sgp)) {
--                SG_ADVANCE(sgp, (size_t) nwritten);
--                nwritten = 0;
--            } else {
--                nwritten -= SG_LEN(sgp);
--                out->sgp++;
--                out->sg_count--;
--            }
-+    }
-+    if (conn->out.sg_count == 0) {
-+        /* Done writing, switch to reading. */
-+        cm_read(selstate, conn->fd);
-+        conn->state = READING;
-+    }
-+    return FALSE;
-+}
-+
-+/* Return true on usable data. */
-+static krb5_boolean
-+service_tcp_read(krb5_context context, const krb5_data *realm,
-+                 struct conn_state *conn, struct select_state *selstate)
-+{
-+    ssize_t nread;
-+    int e = 0;
-+    struct incoming_message *in = &conn->in;
-+
-+    if (in->bufsizebytes_read == 4) {
-+        /* Reading data.  */
-+        nread = SOCKET_READ(conn->fd, &in->buf[in->pos], in->n_left);
-+        if (nread <= 0) {
-+            e = nread ? SOCKET_ERRNO : ECONNRESET;
-+            TRACE_SENDTO_KDC_TCP_ERROR_RECV(context, &conn->addr, e);
-+            kill_conn(context, conn, selstate);
-+            return FALSE;
-         }
--        if (out->sg_count == 0) {
--            /* Done writing, switch to reading. */
--            cm_read(selstate, conn->fd);
--            conn->state = READING;
--            in->bufsizebytes_read = 0;
--            in->bufsize = 0;
--            in->pos = 0;
--            in->buf = NULL;
--            in->n_left = 0;
-+        in->n_left -= nread;
-+        in->pos += nread;
-+        if (in->n_left <= 0)
-+            return TRUE;
-+    } else {
-+        /* Reading length.  */
-+        nread = SOCKET_READ(conn->fd, in->bufsizebytes + in->bufsizebytes_read,
-+                            4 - in->bufsizebytes_read);
-+        if (nread <= 0) {
-+            e = nread ? SOCKET_ERRNO : ECONNRESET;
-+            TRACE_SENDTO_KDC_TCP_ERROR_RECV_LEN(context, &conn->addr, e);
-+            kill_conn(context, conn, selstate);
-+            return FALSE;
-         }
--        return 0;
--
--    case READING:
-+        in->bufsizebytes_read += nread;
-         if (in->bufsizebytes_read == 4) {
--            /* Reading data.  */
--            nread = SOCKET_READ(conn->fd, &in->buf[in->pos], in->n_left);
--            if (nread <= 0) {
--                e = nread ? SOCKET_ERRNO : ECONNRESET;
--                TRACE_SENDTO_KDC_TCP_ERROR_RECV(context, &conn->addr, e);
--                goto kill_conn;
--            }
--            in->n_left -= nread;
--            in->pos += nread;
--            if (in->n_left <= 0)
--                return 1;
--        } else {
--            /* Reading length.  */
--            nread = SOCKET_READ(conn->fd,
--                                in->bufsizebytes + in->bufsizebytes_read,
--                                4 - in->bufsizebytes_read);
--            if (nread <= 0) {
--                e = nread ? SOCKET_ERRNO : ECONNRESET;
--                TRACE_SENDTO_KDC_TCP_ERROR_RECV_LEN(context, &conn->addr, e);
--                goto kill_conn;
-+            unsigned long len = load_32_be(in->bufsizebytes);
-+            /* Arbitrary 1M cap.  */
-+            if (len > 1 * 1024 * 1024) {
-+                kill_conn(context, conn, selstate);
-+                return FALSE;
-             }
--            in->bufsizebytes_read += nread;
--            if (in->bufsizebytes_read == 4) {
--                unsigned long len = load_32_be(in->bufsizebytes);
--                /* Arbitrary 1M cap.  */
--                if (len > 1 * 1024 * 1024)
--                    goto kill_conn;
--                in->bufsize = in->n_left = len;
--                in->pos = 0;
--                in->buf = malloc(len);
--                if (in->buf == NULL)
--                    goto kill_conn;
-+            in->bufsize = in->n_left = len;
-+            in->pos = 0;
-+            in->buf = malloc(len);
-+            if (in->buf == NULL) {
-+                kill_conn(context, conn, selstate);
-+                return FALSE;
-             }
-         }
--        break;
--
--    default:
--        abort();
-     }
--    return 0;
--
--kill_conn:
--    TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr);
--    kill_conn(conn, selstate);
--    return 0;
-+    return FALSE;
- }
- 
--/* Process events on a UDP socket.  Return 1 if we get a reply. */
--static int
--service_udp_fd(krb5_context context, struct conn_state *conn,
--               struct select_state *selstate, int ssflags)
-+/* Process events on a UDP socket.  Return true if we get a reply. */
-+static krb5_boolean
-+service_udp_read(krb5_context context, const krb5_data *realm,
-+                 struct conn_state *conn, struct select_state *selstate)
- {
-     int nread;
- 
--    if (!(ssflags & (SSF_READ|SSF_EXCEPTION)))
--        abort();
--    if (conn->state != READING)
--        abort();
--
-     nread = recv(conn->fd, conn->in.buf, conn->in.bufsize, 0);
-     if (nread < 0) {
-         TRACE_SENDTO_KDC_UDP_ERROR_RECV(context, &conn->addr, SOCKET_ERRNO);
--        kill_conn(conn, selstate);
--        return 0;
-+        kill_conn(context, conn, selstate);
-+        return FALSE;
-     }
-     conn->in.pos = nread;
--    return 1;
-+    return TRUE;
- }
- 
- /* Return the maximum of endtime and the endtime fields of all currently active
-@@ -965,7 +1001,7 @@ get_endtime(time_ms endtime, struct conn_state *conns)
- static krb5_boolean
- service_fds(krb5_context context, struct select_state *selstate,
-             time_ms interval, struct conn_state *conns,
--            struct select_state *seltemp,
-+            struct select_state *seltemp, const krb5_data *realm,
-             int (*msg_handler)(krb5_context, const krb5_data *, void *),
-             void *msg_handler_data, struct conn_state **winner_out)
- {
-@@ -977,7 +1013,7 @@ service_fds(krb5_context context, struct select_state *selstate,
- 
-     e = get_curtime_ms(&endtime);
-     if (e)
--        return 1;
-+        return TRUE;
-     endtime += interval;
- 
-     e = 0;
-@@ -991,7 +1027,7 @@ service_fds(krb5_context context, struct select_state *selstate,
- 
-         if (selret == 0)
-             /* Timeout, return to caller.  */
--            return 0;
-+            return FALSE;
- 
-         /* Got something on a socket, process it.  */
-         for (state = conns; state != NULL; state = state->next) {
-@@ -1003,7 +1039,7 @@ service_fds(krb5_context context, struct select_state *selstate,
-             if (!ssflags)
-                 continue;
- 
--            if (state->service(context, state, selstate, ssflags)) {
-+            if (service_dispatch(context, realm, state, selstate, ssflags)) {
-                 int stop = 1;
- 
-                 if (msg_handler != NULL) {
-@@ -1014,14 +1050,14 @@ service_fds(krb5_context context, struct select_state *selstate,
- 
-                 if (stop) {
-                     *winner_out = state;
--                    return 1;
-+                    return TRUE;
-                 }
-             }
-         }
-     }
-     if (e != 0)
--        return 1;
--    return 0;
-+        return TRUE;
-+    return FALSE;
- }
- 
- /*
-@@ -1052,7 +1088,8 @@ service_fds(krb5_context context, struct select_state *selstate,
- 
- krb5_error_code
- k5_sendto(krb5_context context, const krb5_data *message,
--          const struct serverlist *servers, k5_transport_strategy strategy,
-+          const krb5_data *realm, const struct serverlist *servers,
-+          k5_transport_strategy strategy,
-           struct sendto_callback_info* callback_info, krb5_data *reply,
-           struct sockaddr *remoteaddr, socklen_t *remoteaddrlen,
-           int *server_used,
-@@ -1098,7 +1135,7 @@ k5_sendto(krb5_context context, const krb5_data *message,
-             if (maybe_send(context, state, message, sel_state, callback_info))
-                 continue;
-             done = service_fds(context, sel_state, 1000, conns, seltemp,
--                               msg_handler, msg_handler_data, &winner);
-+                               realm, msg_handler, msg_handler_data, &winner);
-         }
-     }
- 
-@@ -1110,13 +1147,13 @@ k5_sendto(krb5_context context, const krb5_data *message,
-         if (maybe_send(context, state, message, sel_state, callback_info))
-             continue;
-         done = service_fds(context, sel_state, 1000, conns, seltemp,
--                           msg_handler, msg_handler_data, &winner);
-+                           realm, msg_handler, msg_handler_data, &winner);
-     }
- 
-     /* Wait for two seconds at the end of the first pass. */
-     if (!done) {
-         done = service_fds(context, sel_state, 2000, conns, seltemp,
--                           msg_handler, msg_handler_data, &winner);
-+                           realm, msg_handler, msg_handler_data, &winner);
-     }
- 
-     /* Make remaining passes over all of the connections. */
-@@ -1126,14 +1163,14 @@ k5_sendto(krb5_context context, const krb5_data *message,
-             if (maybe_send(context, state, message, sel_state, callback_info))
-                 continue;
-             done = service_fds(context, sel_state, 1000, conns, seltemp,
--                               msg_handler, msg_handler_data, &winner);
-+                               realm, msg_handler, msg_handler_data, &winner);
-             if (sel_state->nfds == 0)
-                 break;
-         }
-         /* Wait for the delay backoff at the end of this pass. */
-         if (!done) {
-             done = service_fds(context, sel_state, delay, conns, seltemp,
--                               msg_handler, msg_handler_data, &winner);
-+                               realm, msg_handler, msg_handler_data, &winner);
-         }
-         if (sel_state->nfds == 0)
-             break;
--- 
-2.1.0
-
diff --git a/SOURCES/0006-Use-more-randomness-for-ksu-secondary-cache-names.patch b/SOURCES/0006-Use-more-randomness-for-ksu-secondary-cache-names.patch
deleted file mode 100644
index da8a32a..0000000
--- a/SOURCES/0006-Use-more-randomness-for-ksu-secondary-cache-names.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-From 69c8e20b18577781e17c5959e23514134dfb5755 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@redhat.com>
-Date: Thu, 24 Jul 2014 16:43:21 -0400
-Subject: [PATCH 6/7] Use more randomness for ksu secondary cache names
-
-When generating a suffix to append to a ccache name that will hold the
-credentials for a ksu-invoked process, instead of using integers
-counting up from 1, use the result of base64-encoding six randomly-
-generated octets.  Tweak the output alphabet just a bit to avoid using
-'+' or '/' in the generated names, the latter of which could really
-confuse things.
----
- src/clients/ksu/ccache.c | 27 +++++++++++++++++++++++----
- src/clients/ksu/ksu.h    |  2 +-
- src/clients/ksu/main.c   | 16 ++++++++++++----
- 3 files changed, 36 insertions(+), 9 deletions(-)
-
-diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
-index 0f9e042..a0736f2 100644
---- a/src/clients/ksu/ccache.c
-+++ b/src/clients/ksu/ccache.c
-@@ -27,6 +27,7 @@
-  */
- 
- #include "ksu.h"
-+#include "k5-base64.h"
- #include "adm_proto.h"
- #include <sys/types.h>
- #include <sys/stat.h>
-@@ -504,10 +505,28 @@ show_credential(context, cred, cc)
-     free(sname);
- }
- 
--int gen_sym(){
--    static int i = 0;
--    i ++;
--    return i;
-+/* Create a random string suitable for a filename extension. */
-+krb5_error_code
-+gen_sym(krb5_context context, char **sym_out)
-+{
-+    krb5_error_code retval;
-+    char bytes[6], *p, *sym;
-+    krb5_data data = make_data(bytes, sizeof(bytes));
-+
-+    *sym_out = NULL;
-+    retval = krb5_c_random_make_octets(context, &data);
-+    if (retval)
-+        return retval;
-+    sym = k5_base64_encode(data.data, data.length);
-+    if (sym == NULL)
-+        return ENOMEM;
-+    /* Tweak the output alphabet just a bit. */
-+    while ((p = strchr(sym, '/')) != NULL)
-+        *p = '_';
-+    while ((p = strchr(sym, '+')) != NULL)
-+        *p = '-';
-+    *sym_out = sym;
-+    return 0;
- }
- 
- krb5_error_code krb5_ccache_overwrite(context, ccs, cct, primary_principal)
-diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h
-index fbbf217..5ba5ceb 100644
---- a/src/clients/ksu/ksu.h
-+++ b/src/clients/ksu/ksu.h
-@@ -130,7 +130,7 @@ extern krb5_error_code krb5_get_login_princ
- extern void show_credential
- (krb5_context, krb5_creds *, krb5_ccache);
- 
--extern int gen_sym (void);
-+krb5_error_code gen_sym(krb5_context context, char **sym);
- 
- extern krb5_error_code krb5_ccache_overwrite
- (krb5_context, krb5_ccache, krb5_ccache, krb5_principal);
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index 41a3bf8..47fa820 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -856,7 +856,7 @@ resolve_target_cache(krb5_context context, krb5_principal princ,
-     krb5_error_code retval;
-     krb5_boolean switchable, reused = FALSE;
-     krb5_ccache ccache = NULL;
--    char *sep, *ccname = NULL, *target;
-+    char *sep, *ccname = NULL, *sym = NULL, *target;
- 
-     *ccache_out = NULL;
-     *ccache_reused = FALSE;
-@@ -876,12 +876,20 @@ resolve_target_cache(krb5_context context, krb5_principal princ,
-          * the name of a cache that doesn't exist yet. */
-         do {
-             free(ccname);
--            if (asprintf(&ccname, "%s.%d", target, gen_sym()) < 0) {
-+            retval = gen_sym(context, &sym);
-+            if (retval) {
-+                com_err(prog_name, retval,
-+                        _("while generating part of the target ccache name"));
-+                return retval;
-+            }
-+            if (asprintf(&ccname, "%s.%s", target, sym) < 0) {
-                 retval = ENOMEM;
--                com_err(prog_name, ENOMEM,
--                        _("while allocating memory for target ccache name"));
-+                free(sym);
-+                com_err(prog_name, retval, _("while allocating memory for the "
-+                                             "target ccache name"));
-                 goto cleanup;
-             }
-+            free(sym);
-         } while (ks_ccache_name_is_initialized(context, ccname));
-         retval = krb5_cc_resolve(context, ccname, &ccache);
-     } else {
--- 
-2.0.4
-
diff --git a/SOURCES/0007-HTTPS-transport-Microsoft-KKDCPP-implementation.patch b/SOURCES/0007-HTTPS-transport-Microsoft-KKDCPP-implementation.patch
deleted file mode 100644
index cd21dac..0000000
--- a/SOURCES/0007-HTTPS-transport-Microsoft-KKDCPP-implementation.patch
+++ /dev/null
@@ -1,858 +0,0 @@
-From d950809ff49e3e7603594186d77135a09ab6b1b2 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Thu, 24 Apr 2014 16:30:56 -0400
-Subject: [PATCH 07/13] HTTPS transport (Microsoft KKDCPP implementation)
-
-Add an 'HTTPS' transport type which connects to an [MS-KKDCP] proxy
-server using HTTPS to communicate with a KDC.  The KDC's name should
-take the form of an HTTPS URL (e.g. "https://proxybox/KdcProxy").
-
-An HTTPS connection's encryption layer can be reading and writing when
-the application layer is expecting to write and read, so the HTTPS
-callbacks have to handle being called multiple times.
-
-[nalin@redhat.com: use cleanup labels, make sure we always send the
- realm name, keep a copy of the URI on-hand, move most of the
- conditionally-compiled sections into their own conditionally-built
- functions, break out HTTPS request formatting into a helper function,
- handle the MS-KKDCP length bytes, update comments to mention specific
- versions of the MS-KKDCP spec, differentiate TCP and HTTP trace
- messages, trace unparseable responses]
-
-ticket: 7929
----
- src/include/k5-trace.h         |  13 ++
- src/lib/krb5/os/locate_kdc.c   |  63 ++++++-
- src/lib/krb5/os/os-proto.h     |   2 +
- src/lib/krb5/os/sendto_kdc.c   | 417 ++++++++++++++++++++++++++++++++++++++---
- src/lib/krb5/os/t_locate_kdc.c |   2 +
- src/lib/krb5/os/trace.c        |   2 +
- 6 files changed, 471 insertions(+), 28 deletions(-)
-
-diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
-index dfd34f6..f0d79f1 100644
---- a/src/include/k5-trace.h
-+++ b/src/include/k5-trace.h
-@@ -312,6 +312,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
-     TRACE(c, "AP-REQ ticket: {princ} -> {princ}, session key {keyblock}", \
-           client, server, keyblock)
- 
-+#define TRACE_SENDTO_KDC_ERROR_SET_MESSAGE(c, raddr, err)               \
-+    TRACE(c, "Error preparing message to send to {raddr}: {errno}",     \
-+          raddr, err)
- #define TRACE_SENDTO_KDC(c, len, rlm, master, tcp)                     \
-     TRACE(c, "Sending request ({int} bytes) to {data}{str}{str}", len,  \
-           rlm, (master) ? " (master)" : "", (tcp) ? " (tcp only)" : "")
-@@ -321,6 +324,16 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
-     TRACE(c, "Resolving hostname {str}", hostname)
- #define TRACE_SENDTO_KDC_RESPONSE(c, len, raddr)                        \
-     TRACE(c, "Received answer ({int} bytes) from {raddr}", len, raddr)
-+#define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr)                  \
-+    TRACE(c, "HTTPS error connecting to {raddr}", raddr)
-+#define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr, err)                \
-+    TRACE(c, "HTTPS error receiving from {raddr}: {errno}", raddr, err)
-+#define TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(c, raddr)                     \
-+    TRACE(c, "HTTPS error sending to {raddr}", raddr)
-+#define TRACE_SENDTO_KDC_HTTPS_SEND(c, raddr)                           \
-+    TRACE(c, "Sending HTTPS request to {raddr}", raddr)
-+#define TRACE_SENDTO_KDC_HTTPS_ERROR(c, errs)                           \
-+    TRACE(c, "HTTPS error: {str}", errs)
- #define TRACE_SENDTO_KDC_TCP_CONNECT(c, raddr)                  \
-     TRACE(c, "Initiating TCP connection to {raddr}", raddr)
- #define TRACE_SENDTO_KDC_TCP_DISCONNECT(c, raddr)               \
-diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
-index 4c8aead..1136809 100644
---- a/src/lib/krb5/os/locate_kdc.c
-+++ b/src/lib/krb5/os/locate_kdc.c
-@@ -91,8 +91,10 @@ k5_free_serverlist (struct serverlist *list)
- {
-     size_t i;
- 
--    for (i = 0; i < list->nservers; i++)
-+    for (i = 0; i < list->nservers; i++) {
-         free(list->servers[i].hostname);
-+        free(list->servers[i].uri_path);
-+    }
-     free(list->servers);
-     list->servers = NULL;
-     list->nservers = 0;
-@@ -140,6 +142,7 @@ add_addr_to_list(struct serverlist *list, k5_transport transport, int family,
-     entry->transport = transport;
-     entry->family = family;
-     entry->hostname = NULL;
-+    entry->uri_path = NULL;
-     entry->addrlen = addrlen;
-     memcpy(&entry->addr, addr, addrlen);
-     list->nservers++;
-@@ -149,7 +152,7 @@ add_addr_to_list(struct serverlist *list, k5_transport transport, int family,
- /* Add a hostname entry to list. */
- static int
- add_host_to_list(struct serverlist *list, const char *hostname, int port,
--                 k5_transport transport, int family)
-+                 k5_transport transport, int family, char *uri_path)
- {
-     struct server_entry *entry;
- 
-@@ -160,11 +163,46 @@ add_host_to_list(struct serverlist *list, const char *hostname, int port,
-     entry->family = family;
-     entry->hostname = strdup(hostname);
-     if (entry->hostname == NULL)
--        return ENOMEM;
-+        goto oom;
-+    if (uri_path != NULL) {
-+        entry->uri_path = strdup(uri_path);
-+        if (entry->uri_path == NULL)
-+            goto oom;
-+    }
-     entry->port = port;
-     list->nservers++;
-     return 0;
-+oom:
-+    free(entry->hostname);
-+    entry->hostname = NULL;
-+    return ENOMEM;
-+}
-+
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+static void
-+parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host,
-+                   char **uri_path)
-+{
-+    char *cp;
-+
-+    if (strncmp(host_or_uri, "https://", 8) == 0) {
-+        *transport = HTTPS;
-+        *host = host_or_uri + 8;
-+
-+        cp = strchr(*host, '/');
-+        if (cp != NULL) {
-+            *cp = '\0';
-+            *uri_path = cp + 1;
-+        }
-+    }
-+}
-+#else
-+static void
-+parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host,
-+                   char **uri)
-+{
- }
-+#endif
- 
- /* Return true if server is identical to an entry in list. */
- static krb5_boolean
-@@ -222,9 +260,14 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm,
- 
-     for (i=0; hostlist[i]; i++) {
-         int p1, p2;
-+        k5_transport this_transport = transport;
-+        char *uri_path = NULL;
- 
-         host = hostlist[i];
-         Tprintf ("entry %d is '%s'\n", i, host);
-+
-+        parse_uri_if_https(host, &this_transport, &host, &uri_path);
-+
-         /* Find port number, and strip off any excess characters. */
-         if (*host == '[' && (cp = strchr(host, ']')))
-             cp = cp + 1;
-@@ -244,6 +287,9 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm,
-                 return EINVAL;
-             p1 = htons (l);
-             p2 = 0;
-+        } else if (this_transport == HTTPS) {
-+            p1 = htons(443);
-+            p2 = 0;
-         } else {
-             p1 = udpport;
-             p2 = sec_udpport;
-@@ -255,12 +301,15 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm,
-             *cp = '\0';
-         }
- 
--        code = add_host_to_list(serverlist, host, p1, transport, AF_UNSPEC);
-+        code = add_host_to_list(serverlist, host, p1, this_transport,
-+                                AF_UNSPEC, uri_path);
-         /* Second port is for IPv4 UDP only, and should possibly go away as
-          * it was originally a krb4 compatibility measure. */
-         if (code == 0 && p2 != 0 &&
--            (transport == TCP_OR_UDP || transport == UDP))
--            code = add_host_to_list(serverlist, host, p2, UDP, AF_INET);
-+            (this_transport == TCP_OR_UDP || this_transport == UDP)) {
-+            code = add_host_to_list(serverlist, host, p2, UDP, AF_INET,
-+                                    uri_path);
-+        }
-         if (code)
-             goto cleanup;
-     }
-@@ -313,7 +362,7 @@ locate_srv_dns_1(const krb5_data *realm, const char *service,
-     for (entry = head; entry != NULL; entry = entry->next) {
-         transport = (strcmp(protocol, "_tcp") == 0) ? TCP : UDP;
-         code = add_host_to_list(serverlist, entry->host, htons(entry->port),
--                                transport, AF_UNSPEC);
-+                                transport, AF_UNSPEC, NULL);
-         if (code)
-             goto cleanup;
-     }
-diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
-index e60ccd0..34bf028 100644
---- a/src/lib/krb5/os/os-proto.h
-+++ b/src/lib/krb5/os/os-proto.h
-@@ -42,6 +42,7 @@ typedef enum {
-     TCP_OR_UDP = 0,
-     TCP,
-     UDP,
-+    HTTPS,
- } k5_transport;
- 
- typedef enum {
-@@ -55,6 +56,7 @@ struct server_entry {
-     char *hostname;             /* NULL -> use addrlen/addr instead */
-     int port;                   /* Used only if hostname set */
-     k5_transport transport;     /* May be 0 for UDP/TCP if hostname set */
-+    char *uri_path;             /* Used only if transport is HTTPS */
-     int family;                 /* May be 0 (aka AF_UNSPEC) if hostname set */
-     size_t addrlen;
-     struct sockaddr_storage addr;
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index 28f1c4d..a4727c4 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -23,6 +23,32 @@
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  */
-+/*
-+ * MS-KKDCP implementation Copyright 2013,2014 Red Hat, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ *    1. Redistributions of source code must retain the above copyright
-+ *       notice, this list of conditions and the following disclaimer.
-+ *
-+ *    2. Redistributions in binary form must reproduce the above copyright
-+ *       notice, this list of conditions and the following disclaimer in
-+ *       the documentation and/or other materials provided with the
-+ *       distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
- 
- /* Send packet to KDC for realm; wait for response, retransmitting
-  * as necessary. */
-@@ -49,6 +75,7 @@
- #endif
- 
- #ifdef PROXY_TLS_IMPL_OPENSSL
-+#include <openssl/err.h>
- #include <openssl/ssl.h>
- #endif
- 
-@@ -116,6 +143,13 @@ struct conn_state {
-     struct conn_state *next;
-     time_ms endtime;
-     krb5_boolean defer;
-+    struct {
-+        const char *uri_path;
-+        char *https_request;
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+        SSL *ssl;
-+#endif
-+    } http;
- };
- 
- void
-@@ -140,6 +174,22 @@ get_curtime_ms(time_ms *time_out)
-     return 0;
- }
- 
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+static void
-+free_http_ssl_data(struct conn_state *state)
-+{
-+    SSL_free(state->http.ssl);
-+    state->http.ssl = NULL;
-+    free(state->http.https_request);
-+    state->http.https_request = NULL;
-+}
-+#else
-+static void
-+free_http_ssl_data(struct conn_state *state)
-+{
-+}
-+#endif
-+
- #ifdef USE_POLL
- 
- /* Find a pollfd in selstate by fd, or abort if we can't find it. */
-@@ -321,6 +371,7 @@ socktype_for_transport(k5_transport transport)
-     case UDP:
-         return SOCK_DGRAM;
-     case TCP:
-+    case HTTPS:
-         return SOCK_STREAM;
-     default:
-         return 0;
-@@ -468,33 +519,113 @@ static fd_handler_fn service_tcp_connect;
- static fd_handler_fn service_tcp_write;
- static fd_handler_fn service_tcp_read;
- static fd_handler_fn service_udp_read;
-+static fd_handler_fn service_https_write;
-+static fd_handler_fn service_https_read;
-+
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+static krb5_error_code
-+make_proxy_request(struct conn_state *state, const krb5_data *realm,
-+                   const krb5_data *message, char **req_out, size_t *len_out)
-+{
-+    krb5_kkdcp_message pm;
-+    krb5_data *encoded_pm = NULL;
-+    struct k5buf buf;
-+    const char *uri_path;
-+    krb5_error_code ret;
-+
-+    *req_out = NULL;
-+    *len_out = 0;
-+
-+    /*
-+     * Stuff the message length in at the front of the kerb_message field
-+     * before encoding.  The proxied messages are actually the payload we'd
-+     * be sending and receiving if we were using plain TCP.
-+     */
-+    memset(&pm, 0, sizeof(pm));
-+    ret = alloc_data(&pm.kerb_message, message->length + 4);
-+    if (ret != 0)
-+        goto cleanup;
-+    store_32_be(message->length, pm.kerb_message.data);
-+    memcpy(pm.kerb_message.data + 4, message->data, message->length);
-+    pm.target_domain = *realm;
-+    ret = encode_krb5_kkdcp_message(&pm, &encoded_pm);
-+    if (ret != 0)
-+        goto cleanup;
-+
-+    /* Build the request to transmit: the headers + the proxy message. */
-+    k5_buf_init_dynamic(&buf);
-+    uri_path = (state->http.uri_path != NULL) ? state->http.uri_path : "";
-+    k5_buf_add_fmt(&buf, "POST /%s HTTP/1.0\r\n", uri_path);
-+    k5_buf_add(&buf, "Cache-Control: no-cache\r\n");
-+    k5_buf_add(&buf, "Pragma: no-cache\r\n");
-+    k5_buf_add(&buf, "User-Agent: kerberos/1.0\r\n");
-+    k5_buf_add(&buf, "Content-type: application/kerberos\r\n");
-+    k5_buf_add_fmt(&buf, "Content-Length: %d\r\n\r\n", encoded_pm->length);
-+    k5_buf_add_len(&buf, encoded_pm->data, encoded_pm->length);
-+    if (k5_buf_data(&buf) == NULL) {
-+        ret = ENOMEM;
-+        goto cleanup;
-+    }
-+
-+    *req_out = k5_buf_data(&buf);
-+    *len_out = k5_buf_len(&buf);
-+
-+cleanup:
-+    krb5_free_data_contents(NULL, &pm.kerb_message);
-+    krb5_free_data(NULL, encoded_pm);
-+    return ret;
-+}
-+#else
-+static krb5_error_code
-+make_proxy_request(struct conn_state *state, const krb5_data *realm,
-+                   const krb5_data *message, char **req_out, size_t *len_out)
-+{
-+    abort();
-+}
-+#endif
- 
- /* Set up the actual message we will send across the underlying transport to
-  * communicate the payload message, using one or both of state->out.sgbuf. */
--static void
--set_transport_message(struct conn_state *state, const krb5_data *message)
-+static krb5_error_code
-+set_transport_message(struct conn_state *state, const krb5_data *realm,
-+                      const krb5_data *message)
- {
-     struct outgoing_message *out = &state->out;
-+    char *req = NULL;
-+    size_t reqlen;
-+    krb5_error_code ret;
- 
-     if (message == NULL || message->length == 0)
--        return;
-+        return 0;
- 
-     if (state->addr.transport == TCP) {
-         store_32_be(message->length, out->msg_len_buf);
-         SG_SET(&out->sgbuf[0], out->msg_len_buf, 4);
-         SG_SET(&out->sgbuf[1], message->data, message->length);
-         out->sg_count = 2;
-+        return 0;
-+    } else if (state->addr.transport == HTTPS) {
-+        ret = make_proxy_request(state, realm, message, &req, &reqlen);
-+        if (ret != 0)
-+            return ret;
-+        SG_SET(&state->out.sgbuf[0], req, reqlen);
-+        SG_SET(&state->out.sgbuf[1], 0, 0);
-+        state->out.sg_count = 1;
-+        free(state->http.https_request);
-+        state->http.https_request = req;
-+        return 0;
-     } else {
-         SG_SET(&out->sgbuf[0], message->data, message->length);
-         SG_SET(&out->sgbuf[1], NULL, 0);
-         out->sg_count = 1;
-+        return 0;
-     }
- }
- 
- static krb5_error_code
- add_connection(struct conn_state **conns, k5_transport transport,
-                krb5_boolean defer, struct addrinfo *ai, size_t server_index,
--               char **udpbufp)
-+               const krb5_data *realm, const char *uri_path, char **udpbufp)
- {
-     struct conn_state *state, **tailptr;
- 
-@@ -515,6 +646,11 @@ add_connection(struct conn_state **conns, k5_transport transport,
-         state->service_connect = service_tcp_connect;
-         state->service_write = service_tcp_write;
-         state->service_read = service_tcp_read;
-+    } else if (transport == HTTPS) {
-+        state->service_connect = service_tcp_connect;
-+        state->service_write = service_https_write;
-+        state->service_read = service_https_read;
-+        state->http.uri_path = uri_path;
-     } else {
-         state->service_connect = NULL;
-         state->service_write = NULL;
-@@ -589,10 +725,10 @@ translate_ai_error (int err)
-  * connections.
-  */
- static krb5_error_code
--resolve_server(krb5_context context, const struct serverlist *servers,
--               size_t ind, k5_transport_strategy strategy,
--               const krb5_data *message, char **udpbufp,
--               struct conn_state **conns)
-+resolve_server(krb5_context context, const krb5_data *realm,
-+               const struct serverlist *servers, size_t ind,
-+               k5_transport_strategy strategy, const krb5_data *message,
-+               char **udpbufp, struct conn_state **conns)
- {
-     krb5_error_code retval;
-     struct server_entry *entry = &servers->servers[ind];
-@@ -615,7 +751,7 @@ resolve_server(krb5_context context, const struct serverlist *servers,
-         ai.ai_addr = (struct sockaddr *)&entry->addr;
-         defer = (entry->transport != transport);
-         return add_connection(conns, entry->transport, defer, &ai, ind,
--                              udpbufp);
-+                              realm, entry->uri_path, udpbufp);
-     }
- 
-     /* If the entry has a specified transport, use it. */
-@@ -639,8 +775,10 @@ resolve_server(krb5_context context, const struct serverlist *servers,
- 
-     /* Add each address with the specified or preferred transport. */
-     retval = 0;
--    for (a = addrs; a != 0 && retval == 0; a = a->ai_next)
--        retval = add_connection(conns, transport, FALSE, a, ind, udpbufp);
-+    for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
-+        retval = add_connection(conns, transport, FALSE, a, ind, realm,
-+                                entry->uri_path, udpbufp);
-+    }
- 
-     /* For TCP_OR_UDP entries, add each address again with the non-preferred
-      * transport, unless we are avoiding UDP.  Flag these as deferred. */
-@@ -648,7 +786,8 @@ resolve_server(krb5_context context, const struct serverlist *servers,
-         transport = (strategy == UDP_FIRST) ? TCP : UDP;
-         for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
-             a->ai_socktype = socktype_for_transport(transport);
--            retval = add_connection(conns, transport, TRUE, a, ind, udpbufp);
-+            retval = add_connection(conns, transport, TRUE, a, ind, realm,
-+                                    entry->uri_path, udpbufp);
-         }
-     }
-     freeaddrinfo(addrs);
-@@ -658,6 +797,7 @@ resolve_server(krb5_context context, const struct serverlist *servers,
- static int
- start_connection(krb5_context context, struct conn_state *state,
-                  const krb5_data *message, struct select_state *selstate,
-+                 const krb5_data *realm,
-                  struct sendto_callback_info *callback_info)
- {
-     int fd, e, type;
-@@ -718,7 +858,15 @@ start_connection(krb5_context context, struct conn_state *state,
- 
-         message = &state->callback_buffer;
-     }
--    set_transport_message(state, message);
-+
-+    e = set_transport_message(state, realm, message);
-+    if (e != 0) {
-+        TRACE_SENDTO_KDC_ERROR_SET_MESSAGE(context, &state->addr, e);
-+        (void) closesocket(state->fd);
-+        state->fd = INVALID_SOCKET;
-+        state->state = FAILED;
-+        return -4;
-+    }
- 
-     if (state->addr.transport == UDP) {
-         /* Send it now.  */
-@@ -733,7 +881,7 @@ start_connection(krb5_context context, struct conn_state *state,
-             (void) closesocket(state->fd);
-             state->fd = INVALID_SOCKET;
-             state->state = FAILED;
--            return -4;
-+            return -5;
-         } else {
-             state->state = READING;
-         }
-@@ -760,6 +908,7 @@ start_connection(krb5_context context, struct conn_state *state,
- static int
- maybe_send(krb5_context context, struct conn_state *conn,
-            const krb5_data *message, struct select_state *selstate,
-+           const krb5_data *realm,
-            struct sendto_callback_info *callback_info)
- {
-     sg_buf *sg;
-@@ -767,7 +916,7 @@ maybe_send(krb5_context context, struct conn_state *conn,
- 
-     if (conn->state == INITIALIZING) {
-         return start_connection(context, conn, message, selstate,
--                                callback_info);
-+                                realm, callback_info);
-     }
- 
-     /* Did we already shut down this channel?  */
-@@ -802,6 +951,8 @@ static void
- kill_conn(krb5_context context, struct conn_state *conn,
-           struct select_state *selstate)
- {
-+    free_http_ssl_data(conn);
-+
-     if (socktype_for_transport(conn->addr.transport) == SOCK_STREAM)
-         TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr);
-     cm_remove_fd(selstate, conn->fd);
-@@ -876,7 +1027,7 @@ service_tcp_connect(krb5_context context, const krb5_data *realm,
-     if (get_curtime_ms(&conn->endtime) == 0)
-         conn->endtime += 10000;
- 
--    return service_tcp_write(context, realm, conn, selstate);
-+    return conn->service_write(context, realm, conn, selstate);
- }
- 
- /* Sets conn->state to READING when done. */
-@@ -982,6 +1133,223 @@ service_udp_read(krb5_context context, const krb5_data *realm,
-     return TRUE;
- }
- 
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+/* Output any error strings that OpenSSL's accumulated as tracing messages. */
-+static void
-+flush_ssl_errors(krb5_context context)
-+{
-+    unsigned long err;
-+    char buf[128];
-+
-+    while ((err = ERR_get_error()) != 0) {
-+        ERR_error_string_n(err, buf, sizeof(buf));
-+        TRACE_SENDTO_KDC_HTTPS_ERROR(context, buf);
-+    }
-+}
-+
-+/*
-+ * Set up structures that we use to manage the SSL handling for this connection
-+ * and apply any non-default settings.  Kill the connection and return false if
-+ * anything goes wrong while we're doing that; return true otherwise.
-+ */
-+static krb5_boolean
-+setup_ssl(krb5_context context, const krb5_data *realm,
-+          struct conn_state *conn, struct select_state *selstate)
-+{
-+    long options;
-+    SSL_CTX *ctx = NULL;
-+    SSL *ssl = NULL;
-+
-+    /* Do general SSL library setup. */
-+    ctx = SSL_CTX_new(SSLv23_client_method());
-+    if (ctx == NULL)
-+        goto kill_conn;
-+    options = SSL_CTX_get_options(ctx);
-+    SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2);
-+
-+    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
-+    if (!SSL_CTX_set_default_verify_paths(ctx))
-+        goto kill_conn;
-+
-+    ssl = SSL_new(ctx);
-+    if (ssl == NULL)
-+        goto kill_conn;
-+
-+    /* Tell the SSL library about the socket. */
-+    if (!SSL_set_fd(ssl, conn->fd))
-+        goto kill_conn;
-+    SSL_set_connect_state(ssl);
-+
-+    SSL_CTX_free(ctx);
-+    conn->http.ssl = ssl;
-+
-+    return TRUE;
-+
-+kill_conn:
-+    TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(context, &conn->addr);
-+    flush_ssl_errors(context);
-+    SSL_free(ssl);
-+    SSL_CTX_free(ctx);
-+    kill_conn(context, conn, selstate);
-+    return FALSE;
-+}
-+
-+/* Set conn->state to READING when done; otherwise, call a cm_set_. */
-+static krb5_boolean
-+service_https_write(krb5_context context, const krb5_data *realm,
-+                    struct conn_state *conn, struct select_state *selstate)
-+{
-+    ssize_t nwritten;
-+    int e;
-+
-+    /* If this is our first time in here, set up the SSL context. */
-+    if (conn->http.ssl == NULL && !setup_ssl(context, realm, conn, selstate))
-+        return FALSE;
-+
-+    /* Try to transmit our request to the server. */
-+    nwritten = SSL_write(conn->http.ssl, SG_BUF(conn->out.sgp),
-+                         SG_LEN(conn->out.sgbuf));
-+    if (nwritten <= 0) {
-+        e = SSL_get_error(conn->http.ssl, nwritten);
-+        if (e == SSL_ERROR_WANT_READ) {
-+            cm_read(selstate, conn->fd);
-+            return FALSE;
-+        } else if (e == SSL_ERROR_WANT_WRITE) {
-+            cm_write(selstate, conn->fd);
-+            return FALSE;
-+        }
-+        TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(context, &conn->addr);
-+        flush_ssl_errors(context);
-+        kill_conn(context, conn, selstate);
-+        return FALSE;
-+    }
-+
-+    /* Done writing, switch to reading. */
-+    TRACE_SENDTO_KDC_HTTPS_SEND(context, &conn->addr);
-+    cm_read(selstate, conn->fd);
-+    conn->state = READING;
-+    return FALSE;
-+}
-+
-+/*
-+ * Return true on readable data, call a cm_read/write function and return
-+ * false if the SSL layer needs it, kill the connection otherwise.
-+ */
-+static krb5_boolean
-+https_read_bytes(krb5_context context, struct conn_state *conn,
-+                 struct select_state *selstate)
-+{
-+    size_t bufsize;
-+    ssize_t nread;
-+    krb5_boolean readbytes = FALSE;
-+    int e = 0;
-+    char *tmp;
-+    struct incoming_message *in = &conn->in;
-+
-+    for (;;) {
-+        if (in->buf == NULL || in->bufsize - in->pos < 1024) {
-+            bufsize = in->bufsize ? in->bufsize * 2 : 8192;
-+            if (bufsize > 1024 * 1024) {
-+                kill_conn(context, conn, selstate);
-+                return FALSE;
-+            }
-+            tmp = realloc(in->buf, bufsize);
-+            if (tmp == NULL) {
-+                kill_conn(context, conn, selstate);
-+                return FALSE;
-+            }
-+            in->buf = tmp;
-+            in->bufsize = bufsize;
-+        }
-+
-+        nread = SSL_read(conn->http.ssl, &in->buf[in->pos],
-+                         in->bufsize - in->pos - 1);
-+        if (nread <= 0)
-+            break;
-+        in->pos += nread;
-+        in->buf[in->pos] = '\0';
-+        readbytes = TRUE;
-+    }
-+
-+    e = SSL_get_error(conn->http.ssl, nread);
-+    if (e == SSL_ERROR_WANT_READ) {
-+        cm_read(selstate, conn->fd);
-+        return FALSE;
-+    } else if (e == SSL_ERROR_WANT_WRITE) {
-+        cm_write(selstate, conn->fd);
-+        return FALSE;
-+    } else if ((e == SSL_ERROR_ZERO_RETURN) ||
-+               (e == SSL_ERROR_SYSCALL && nread == 0 && readbytes)) {
-+        return TRUE;
-+    }
-+
-+    e = readbytes ? SOCKET_ERRNO : ECONNRESET;
-+    TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(context, &conn->addr, e);
-+    flush_ssl_errors(context);
-+    kill_conn(context, conn, selstate);
-+    return FALSE;
-+}
-+
-+/* Return true on readable, valid KKDCPP data. */
-+static krb5_boolean
-+service_https_read(krb5_context context, const krb5_data *realm,
-+                   struct conn_state *conn, struct select_state *selstate)
-+{
-+    krb5_kkdcp_message *pm = NULL;
-+    krb5_data buf;
-+    const char *rep;
-+    struct incoming_message *in = &conn->in;
-+
-+    /* Read data through the encryption layer. */
-+    if (!https_read_bytes(context, conn, selstate))
-+        return FALSE;
-+
-+    /* Find the beginning of the response body. */
-+    rep = strstr(in->buf, "\r\n\r\n");
-+    if (rep == NULL)
-+        goto kill_conn;
-+    rep += 4;
-+
-+    /* Decode the response. */
-+    buf = make_data((char *)rep, in->pos - (rep - in->buf));
-+    if (decode_krb5_kkdcp_message(&buf, &pm) != 0)
-+        goto kill_conn;
-+
-+    /* Check and discard the message length at the front of the kerb_message
-+     * field after decoding.  If it's wrong or missing, something broke. */
-+    if (pm->kerb_message.length < 4 ||
-+        load_32_be(pm->kerb_message.data) != pm->kerb_message.length - 4) {
-+        goto kill_conn;
-+    }
-+
-+    /* Replace all of the content that we read back with just the message. */
-+    memcpy(in->buf, pm->kerb_message.data + 4, pm->kerb_message.length - 4);
-+    in->pos = pm->kerb_message.length - 4;
-+    k5_free_kkdcp_message(context, pm);
-+
-+    return TRUE;
-+
-+kill_conn:
-+    TRACE_SENDTO_KDC_HTTPS_ERROR(context, in->buf);
-+    k5_free_kkdcp_message(context, pm);
-+    kill_conn(context, conn, selstate);
-+    return FALSE;
-+}
-+#else
-+static krb5_boolean
-+service_https_write(krb5_context context, const krb5_data *realm,
-+                    struct conn_state *conn, struct select_state *selstate)
-+{
-+    abort();
-+}
-+static krb5_boolean
-+service_https_read(krb5_context context, const krb5_data *realm,
-+                   struct conn_state *conn, struct select_state *selstate)
-+{
-+    abort();
-+}
-+#endif
-+
- /* Return the maximum of endtime and the endtime fields of all currently active
-  * TCP connections. */
- static time_ms
-@@ -1123,7 +1491,7 @@ k5_sendto(krb5_context context, const krb5_data *message,
-     for (s = 0; s < servers->nservers && !done; s++) {
-         /* Find the current tail pointer. */
-         for (tailptr = &conns; *tailptr != NULL; tailptr = &(*tailptr)->next);
--        retval = resolve_server(context, servers, s, strategy, message,
-+        retval = resolve_server(context, realm, servers, s, strategy, message,
-                                 &udpbuf, &conns);
-         if (retval)
-             goto cleanup;
-@@ -1132,7 +1500,8 @@ k5_sendto(krb5_context context, const krb5_data *message,
-              * non-preferred RFC 4120 transport. */
-             if (state->defer)
-                 continue;
--            if (maybe_send(context, state, message, sel_state, callback_info))
-+            if (maybe_send(context, state, message, sel_state, realm,
-+                           callback_info))
-                 continue;
-             done = service_fds(context, sel_state, 1000, conns, seltemp,
-                                realm, msg_handler, msg_handler_data, &winner);
-@@ -1144,7 +1513,8 @@ k5_sendto(krb5_context context, const krb5_data *message,
-     for (state = conns; state != NULL && !done; state = state->next) {
-         if (!state->defer)
-             continue;
--        if (maybe_send(context, state, message, sel_state, callback_info))
-+        if (maybe_send(context, state, message, sel_state, realm,
-+                       callback_info))
-             continue;
-         done = service_fds(context, sel_state, 1000, conns, seltemp,
-                            realm, msg_handler, msg_handler_data, &winner);
-@@ -1160,7 +1530,8 @@ k5_sendto(krb5_context context, const krb5_data *message,
-     delay = 4000;
-     for (pass = 1; pass < MAX_PASS && !done; pass++) {
-         for (state = conns; state != NULL && !done; state = state->next) {
--            if (maybe_send(context, state, message, sel_state, callback_info))
-+            if (maybe_send(context, state, message, sel_state, realm,
-+                           callback_info))
-                 continue;
-             done = service_fds(context, sel_state, 1000, conns, seltemp,
-                                realm, msg_handler, msg_handler_data, &winner);
-@@ -1194,8 +1565,12 @@ k5_sendto(krb5_context context, const krb5_data *message,
- cleanup:
-     for (state = conns; state != NULL; state = next) {
-         next = state->next;
--        if (state->fd != INVALID_SOCKET)
-+        if (state->fd != INVALID_SOCKET) {
-+            if (socktype_for_transport(state->addr.transport) == SOCK_STREAM)
-+                TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &state->addr);
-             closesocket(state->fd);
-+            free_http_ssl_data(state);
-+        }
-         if (state->state == READING && state->in.buf != udpbuf)
-             free(state->in.buf);
-         if (callback_info) {
-diff --git a/src/lib/krb5/os/t_locate_kdc.c b/src/lib/krb5/os/t_locate_kdc.c
-index 300aa71..dd609fd 100644
---- a/src/lib/krb5/os/t_locate_kdc.c
-+++ b/src/lib/krb5/os/t_locate_kdc.c
-@@ -39,6 +39,8 @@ ttypename (k5_transport ttype)
-         return "tcp";
-     case UDP:
-         return "udp";
-+    case HTTPS:
-+        return "https";
-     default:
-         snprintf(buf, sizeof(buf), "?%d", ttype);
-         return buf;
-diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
-index 8319a86..105a2cd 100644
---- a/src/lib/krb5/os/trace.c
-+++ b/src/lib/krb5/os/trace.c
-@@ -201,6 +201,8 @@ trace_format(krb5_context context, const char *fmt, va_list ap)
-                 k5_buf_add(&buf, "dgram");
-             else if (ra->transport == TCP)
-                 k5_buf_add(&buf, "stream");
-+            else if (ra->transport == HTTPS)
-+                k5_buf_add(&buf, "https");
-             else
-                 k5_buf_add_fmt(&buf, "transport%d", ra->transport);
- 
--- 
-2.1.0
-
diff --git a/SOURCES/0007-Make-krb5_cc_new_unique-create-DIR-directories.patch b/SOURCES/0007-Make-krb5_cc_new_unique-create-DIR-directories.patch
deleted file mode 100644
index c0b8778..0000000
--- a/SOURCES/0007-Make-krb5_cc_new_unique-create-DIR-directories.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-Context tweaked to apply to 1.12.1.
-
-From bca1191210eb582fe09e94486e2631d72b8a5ca5 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@redhat.com>
-Date: Fri, 8 Aug 2014 16:58:03 -0400
-Subject: [PATCH 7/7] Make krb5_cc_new_unique create DIR: directories
-
-When we use krb5_cc_new_unique to create a new cache in a directory
-cache collection, we will fail if the directory doesn't exist yet.
-
-Go ahead and preemptively create it, as we do during krb5_cc_resolve,
-before attempting to create a new file under it.
-
-ticket: 7988 (new)
-target_version: 1.13
-tags: pullup
----
- src/lib/krb5/ccache/cc_dir.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
-index d82f335..b00a6bb 100644
---- a/src/lib/krb5/ccache/cc_dir.c
-+++ b/src/lib/krb5/ccache/cc_dir.c
-@@ -401,6 +401,9 @@ dcc_gen_new(krb5_context context, krb5_ccache *cache_out)
-                                  "collection"));
-         return KRB5_DCC_CANNOT_CREATE;
-     }
-+    ret = verify_dir(context, dirname);
-+    if (ret)
-+        goto cleanup;
-     ret = k5_path_join(dirname, "tktXXXXXX", &template);
-     if (ret)
-         goto cleanup;
--- 
-2.0.4
-
diff --git a/SOURCES/0008-Load-custom-anchors-when-using-KKDCP.patch b/SOURCES/0008-Load-custom-anchors-when-using-KKDCP.patch
deleted file mode 100644
index 19fe964..0000000
--- a/SOURCES/0008-Load-custom-anchors-when-using-KKDCP.patch
+++ /dev/null
@@ -1,312 +0,0 @@
-From f220067c2969aab107bd1300ad1cb8d4855389a7 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Thu, 17 Apr 2014 17:17:13 -0400
-Subject: [PATCH 08/13] Load custom anchors when using KKDCP
-
-Add an http_anchors per-realm setting which we'll apply when using an
-HTTPS proxy, more or less mimicking the syntax of its similarly-named
-PKINIT counterpart.  We only check the [realms] section, though.
-
-ticket: 7929
----
- doc/admin/conf_files/krb5_conf.rst |  26 ++++++
- src/include/k5-int.h               |   1 +
- src/include/k5-trace.h             |   7 ++
- src/lib/krb5/os/sendto_kdc.c       | 169 ++++++++++++++++++++++++++++++++++++-
- 4 files changed, 201 insertions(+), 2 deletions(-)
-
-diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
-index 19ea9c9..c069327 100644
---- a/doc/admin/conf_files/krb5_conf.rst
-+++ b/doc/admin/conf_files/krb5_conf.rst
-@@ -428,6 +428,32 @@ following tags may be specified in the realm's subsection:
-     (for example, when converting ``rcmd.hostname`` to
-     ``host/hostname.domain``).
- 
-+**http_anchors**
-+    When KDCs and kpasswd servers are accessed through HTTPS proxies, this tag
-+    can be used to specify the location of the CA certificate which should be
-+    trusted to issue the certificate for a proxy server.  If left unspecified,
-+    the system-wide default set of CA certificates is used.
-+
-+    The syntax for values is similar to that of values for the
-+    **pkinit_anchors** tag:
-+
-+    **FILE:** *filename*
-+
-+    *filename* is assumed to be the name of an OpenSSL-style ca-bundle file.
-+
-+    **DIR:** *dirname*
-+
-+    *dirname* is assumed to be an directory which contains CA certificates.
-+    All files in the directory will be examined; if they contain certificates
-+    (in PEM format), they will be used.
-+
-+    **ENV:** *envvar*
-+
-+    *envvar* specifies the name of an environment variable which has been set
-+    to a value conforming to one of the previous values.  For example,
-+    ``ENV:X509_PROXY_CA``, where environment variable ``X509_PROXY_CA`` has
-+    been set to ``FILE:/tmp/my_proxy.pem``.
-+
- **kdc**
-     The name or address of a host running a KDC for that realm.  An
-     optional port number, separated from the hostname by a colon, may
-diff --git a/src/include/k5-int.h b/src/include/k5-int.h
-index 8f039ee..187d16d 100644
---- a/src/include/k5-int.h
-+++ b/src/include/k5-int.h
-@@ -212,6 +212,7 @@ typedef unsigned char   u_char;
- #define KRB5_CONF_EXTRA_ADDRESSES             "extra_addresses"
- #define KRB5_CONF_FORWARDABLE                 "forwardable"
- #define KRB5_CONF_HOST_BASED_SERVICES         "host_based_services"
-+#define KRB5_CONF_HTTP_ANCHORS                "http_anchors"
- #define KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME    "ignore_acceptor_hostname"
- #define KRB5_CONF_IPROP_ENABLE                "iprop_enable"
- #define KRB5_CONF_IPROP_MASTER_ULOGSIZE       "iprop_master_ulogsize"
-diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
-index f0d79f1..046bc95 100644
---- a/src/include/k5-trace.h
-+++ b/src/include/k5-trace.h
-@@ -324,6 +324,13 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
-     TRACE(c, "Resolving hostname {str}", hostname)
- #define TRACE_SENDTO_KDC_RESPONSE(c, len, raddr)                        \
-     TRACE(c, "Received answer ({int} bytes) from {raddr}", len, raddr)
-+#define TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(c)                 \
-+    TRACE(c, "HTTPS server certificate not received")
-+#define TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(c, depth,        \
-+                                                       namelen, name,   \
-+                                                       err, errs)       \
-+    TRACE(c, "HTTPS certificate error at {int} ({lenstr}): "            \
-+          "{int} ({str})", depth, namelen, name, err, errs)
- #define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr)                  \
-     TRACE(c, "HTTPS error connecting to {raddr}", raddr)
- #define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr, err)                \
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index a4727c4..4bd8698 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -77,6 +77,9 @@
- #ifdef PROXY_TLS_IMPL_OPENSSL
- #include <openssl/err.h>
- #include <openssl/ssl.h>
-+#include <openssl/x509.h>
-+#include <openssl/x509v3.h>
-+#include <dirent.h>
- #endif
- 
- #define MAX_PASS                    3
-@@ -152,6 +155,11 @@ struct conn_state {
-     } http;
- };
- 
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+/* Extra-data identifier, used to pass context into the verify callback. */
-+static int ssl_ex_context_id = -1;
-+#endif
-+
- void
- k5_sendto_kdc_initialize(void)
- {
-@@ -159,6 +167,8 @@ k5_sendto_kdc_initialize(void)
-     SSL_library_init();
-     SSL_load_error_strings();
-     OpenSSL_add_all_algorithms();
-+
-+    ssl_ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
- #endif
- }
- 
-@@ -1147,6 +1157,152 @@ flush_ssl_errors(krb5_context context)
-     }
- }
- 
-+static krb5_error_code
-+load_http_anchor_file(X509_STORE *store, const char *path)
-+{
-+    FILE *fp;
-+    STACK_OF(X509_INFO) *sk = NULL;
-+    X509_INFO *xi;
-+    int i;
-+
-+    fp = fopen(path, "r");
-+    if (fp == NULL)
-+        return errno;
-+    sk = PEM_X509_INFO_read(fp, NULL, NULL, NULL);
-+    fclose(fp);
-+    if (sk == NULL)
-+        return ENOENT;
-+    for (i = 0; i < sk_X509_INFO_num(sk); i++) {
-+        xi = sk_X509_INFO_value(sk, i);
-+        if (xi->x509 != NULL)
-+            X509_STORE_add_cert(store, xi->x509);
-+    }
-+    sk_X509_INFO_pop_free(sk, X509_INFO_free);
-+    return 0;
-+}
-+
-+static krb5_error_code
-+load_http_anchor_dir(X509_STORE *store, const char *path)
-+{
-+    DIR *d = NULL;
-+    struct dirent *dentry = NULL;
-+    char filename[1024];
-+    krb5_boolean found_any = FALSE;
-+
-+    d = opendir(path);
-+    if (d == NULL)
-+        return ENOENT;
-+    while ((dentry = readdir(d)) != NULL) {
-+        if (dentry->d_name[0] != '.') {
-+            snprintf(filename, sizeof(filename), "%s/%s",
-+                     path, dentry->d_name);
-+            if (load_http_anchor_file(store, filename) == 0)
-+                found_any = TRUE;
-+        }
-+    }
-+    closedir(d);
-+    return found_any ? 0 : ENOENT;
-+}
-+
-+static krb5_error_code
-+load_http_anchor(SSL_CTX *ctx, const char *location)
-+{
-+    X509_STORE *store;
-+    const char *envloc;
-+
-+    store = SSL_CTX_get_cert_store(ctx);
-+    if (strncmp(location, "FILE:", 5) == 0) {
-+        return load_http_anchor_file(store, location + 5);
-+    } else if (strncmp(location, "DIR:", 4) == 0) {
-+        return load_http_anchor_dir(store, location + 4);
-+    } else if (strncmp(location, "ENV:", 4) == 0) {
-+        envloc = getenv(location + 4);
-+        if (envloc == NULL)
-+            return ENOENT;
-+        return load_http_anchor(ctx, envloc);
-+    }
-+    return EINVAL;
-+}
-+
-+static krb5_error_code
-+load_http_verify_anchors(krb5_context context, const krb5_data *realm,
-+                         SSL_CTX *sctx)
-+{
-+    const char *anchors[4];
-+    char **values = NULL, *realmz;
-+    unsigned int i;
-+    krb5_error_code err;
-+
-+    realmz = k5memdup0(realm->data, realm->length, &err);
-+    if (realmz == NULL)
-+        goto cleanup;
-+
-+    /* Load the configured anchors. */
-+    anchors[0] = KRB5_CONF_REALMS;
-+    anchors[1] = realmz;
-+    anchors[2] = KRB5_CONF_HTTP_ANCHORS;
-+    anchors[3] = NULL;
-+    if (profile_get_values(context->profile, anchors, &values) == 0) {
-+        for (i = 0; values[i] != NULL; i++) {
-+            err = load_http_anchor(sctx, values[i]);
-+            if (err != 0)
-+                break;
-+        }
-+        profile_free_list(values);
-+    } else {
-+        /* Use the library defaults. */
-+        if (SSL_CTX_set_default_verify_paths(sctx) != 1)
-+            err = ENOENT;
-+    }
-+
-+cleanup:
-+    free(realmz);
-+    return err;
-+}
-+
-+static int
-+ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx)
-+{
-+    X509 *x;
-+    SSL *ssl;
-+    BIO *bio;
-+    krb5_context context;
-+    int err, depth;
-+    const char *cert = NULL, *errstr;
-+    size_t count;
-+
-+    ssl = X509_STORE_CTX_get_ex_data(store_ctx,
-+                                     SSL_get_ex_data_X509_STORE_CTX_idx());
-+    context = SSL_get_ex_data(ssl, ssl_ex_context_id);
-+    /* We do have the peer's cert, right? */
-+    x = X509_STORE_CTX_get_current_cert(store_ctx);
-+    if (x == NULL) {
-+        TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(context);
-+        return 0;
-+    }
-+    /* Figure out where we are. */
-+    depth = X509_STORE_CTX_get_error_depth(store_ctx);
-+    if (depth < 0)
-+        return 0;
-+    /* If there's an error at this level that we're not ignoring, fail. */
-+    err = X509_STORE_CTX_get_error(store_ctx);
-+    if (err != X509_V_OK) {
-+        bio = BIO_new(BIO_s_mem());
-+        if (bio != NULL) {
-+            X509_NAME_print_ex(bio, x->cert_info->subject, 0, 0);
-+            count = BIO_get_mem_data(bio, &cert);
-+            errstr = X509_verify_cert_error_string(err);
-+            TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(context, depth,
-+                                                           count, cert, err,
-+                                                           errstr);
-+            BIO_free(bio);
-+        }
-+        return 0;
-+    }
-+    /* All done. */
-+    return 1;
-+}
-+
- /*
-  * Set up structures that we use to manage the SSL handling for this connection
-  * and apply any non-default settings.  Kill the connection and return false if
-@@ -1156,10 +1312,14 @@ static krb5_boolean
- setup_ssl(krb5_context context, const krb5_data *realm,
-           struct conn_state *conn, struct select_state *selstate)
- {
-+    int e;
-     long options;
-     SSL_CTX *ctx = NULL;
-     SSL *ssl = NULL;
- 
-+    if (ssl_ex_context_id == -1)
-+        goto kill_conn;
-+
-     /* Do general SSL library setup. */
-     ctx = SSL_CTX_new(SSLv23_client_method());
-     if (ctx == NULL)
-@@ -1167,14 +1327,19 @@ setup_ssl(krb5_context context, const krb5_data *realm,
-     options = SSL_CTX_get_options(ctx);
-     SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2);
- 
--    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
--    if (!SSL_CTX_set_default_verify_paths(ctx))
-+    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ssl_verify_callback);
-+    X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), 0);
-+    e = load_http_verify_anchors(context, realm, ctx);
-+    if (e != 0)
-         goto kill_conn;
- 
-     ssl = SSL_new(ctx);
-     if (ssl == NULL)
-         goto kill_conn;
- 
-+    if (!SSL_set_ex_data(ssl, ssl_ex_context_id, context))
-+        goto kill_conn;
-+
-     /* Tell the SSL library about the socket. */
-     if (!SSL_set_fd(ssl, conn->fd))
-         goto kill_conn;
--- 
-2.1.0
-
diff --git a/SOURCES/0009-Check-names-in-the-server-s-cert-when-using-KKDCP.patch b/SOURCES/0009-Check-names-in-the-server-s-cert-when-using-KKDCP.patch
deleted file mode 100644
index 14e3354..0000000
--- a/SOURCES/0009-Check-names-in-the-server-s-cert-when-using-KKDCP.patch
+++ /dev/null
@@ -1,562 +0,0 @@
-From f7825e81b1ebf533c1dba9f84ae9ad36073a89cf Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Thu, 17 Apr 2014 17:19:03 -0400
-Subject: [PATCH 09/13] Check names in the server's cert when using KKDCP
-
-When we connect to a KDC using an HTTPS proxy, check that the naming
-information in the certificate matches the name or address which we
-extracted from the server URL in the configuration.
-
-ticket: 7929
----
- src/include/k5-trace.h       |   5 +
- src/lib/krb5/os/Makefile.in  |   3 +
- src/lib/krb5/os/checkhost.c  | 251 +++++++++++++++++++++++++++++++++++++++++++
- src/lib/krb5/os/checkhost.h  |  39 +++++++
- src/lib/krb5/os/deps         |  14 ++-
- src/lib/krb5/os/sendto_kdc.c |  53 +++++++--
- 6 files changed, 355 insertions(+), 10 deletions(-)
- create mode 100644 src/lib/krb5/os/checkhost.c
- create mode 100644 src/lib/krb5/os/checkhost.h
-
-diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
-index 046bc95..9e75b29 100644
---- a/src/include/k5-trace.h
-+++ b/src/include/k5-trace.h
-@@ -324,6 +324,11 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
-     TRACE(c, "Resolving hostname {str}", hostname)
- #define TRACE_SENDTO_KDC_RESPONSE(c, len, raddr)                        \
-     TRACE(c, "Received answer ({int} bytes) from {raddr}", len, raddr)
-+#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MISMATCH(c, hostname)        \
-+    TRACE(c, "HTTPS certificate name mismatch: server certificate is "  \
-+          "not for \"{str}\"", hostname)
-+#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MATCH(c, hostname)           \
-+    TRACE(c, "HTTPS certificate name matched \"{str}\"", hostname)
- #define TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(c)                 \
-     TRACE(c, "HTTPS server certificate not received")
- #define TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(c, depth,        \
-diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in
-index fb4001a..fa8a093 100644
---- a/src/lib/krb5/os/Makefile.in
-+++ b/src/lib/krb5/os/Makefile.in
-@@ -13,6 +13,7 @@ STLIBOBJS= \
- 	c_ustime.o	\
- 	ccdefname.o	\
- 	changepw.o	\
-+	checkhost.o	\
- 	dnsglue.o	\
- 	dnssrv.o	\
- 	expand_path.o	\
-@@ -59,6 +60,7 @@ OBJS= \
- 	$(OUTPRE)c_ustime.$(OBJEXT)	\
- 	$(OUTPRE)ccdefname.$(OBJEXT)	\
- 	$(OUTPRE)changepw.$(OBJEXT)	\
-+	$(OUTPRE)checkhost.$(OBJEXT)	\
- 	$(OUTPRE)dnsglue.$(OBJEXT)	\
- 	$(OUTPRE)dnssrv.$(OBJEXT)	\
- 	$(OUTPRE)expand_path.$(OBJEXT)	\
-@@ -105,6 +107,7 @@ SRCS= \
- 	$(srcdir)/c_ustime.c	\
- 	$(srcdir)/ccdefname.c	\
- 	$(srcdir)/changepw.c	\
-+	$(srcdir)/checkhost.c	\
- 	$(srcdir)/dnsglue.c	\
- 	$(srcdir)/dnssrv.c	\
- 	$(srcdir)/expand_path.c	\
-diff --git a/src/lib/krb5/os/checkhost.c b/src/lib/krb5/os/checkhost.c
-new file mode 100644
-index 0000000..a91615d
---- /dev/null
-+++ b/src/lib/krb5/os/checkhost.c
-@@ -0,0 +1,251 @@
-+/*
-+ * Copyright 2014 Red Hat, Inc.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ *    1. Redistributions of source code must retain the above copyright
-+ *       notice, this list of conditions and the following disclaimer.
-+ *
-+ *    2. Redistributions in binary form must reproduce the above copyright
-+ *       notice, this list of conditions and the following disclaimer in
-+ *       the documentation and/or other materials provided with the
-+ *       distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include "k5-int.h"
-+#include "k5-utf8.h"
-+
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+#include <openssl/ssl.h>
-+#include <openssl/x509.h>
-+#include <openssl/x509v3.h>
-+#include "checkhost.h"
-+
-+/* Return the passed-in character, lower-cased if it's an ASCII character. */
-+static inline char
-+ascii_tolower(char p)
-+{
-+    if (KRB5_UPPER(p))
-+        return p + ('a' - 'A');
-+    return p;
-+}
-+
-+/*
-+ * Check a single label.  If allow_wildcard is true, and the presented name
-+ * includes a wildcard, return true and note that we matched a wildcard.
-+ * Otherwise, for both the presented and expected values, do a case-insensitive
-+ * comparison of ASCII characters, and a case-sensitive comparison of
-+ * everything else.
-+ */
-+static krb5_boolean
-+label_match(const char *presented, size_t plen, const char *expected,
-+            size_t elen, krb5_boolean allow_wildcard, krb5_boolean *wildcard)
-+{
-+    unsigned int i;
-+
-+    if (allow_wildcard && plen == 1 && presented[0] == '*') {
-+        *wildcard = TRUE;
-+        return TRUE;
-+    }
-+
-+    if (plen != elen)
-+        return FALSE;
-+
-+    for (i = 0; i < elen; i++) {
-+        if (ascii_tolower(presented[i]) != ascii_tolower(expected[i]))
-+            return FALSE;
-+    }
-+    return TRUE;
-+}
-+
-+/* Break up the two names and check them, label by label. */
-+static krb5_boolean
-+domain_match(const char *presented, size_t plen, const char *expected)
-+{
-+    const char *p, *q, *r, *s;
-+    int n_label;
-+    krb5_boolean used_wildcard = FALSE;
-+
-+    n_label = 0;
-+    p = presented;
-+    r = expected;
-+    while (p < presented + plen && *r != '\0') {
-+        q = memchr(p, '.', plen - (p - presented));
-+        if (q == NULL)
-+            q = presented + plen;
-+        s = r + strcspn(r, ".");
-+        if (!label_match(p, q - p, r, s - r, n_label == 0, &used_wildcard))
-+            return FALSE;
-+        p = q < presented + plen ? q + 1 : q;
-+        r = *s ? s + 1 : s;
-+        n_label++;
-+    }
-+    if (used_wildcard && n_label <= 2)
-+        return FALSE;
-+    if (p == presented + plen && *r == '\0')
-+        return TRUE;
-+    return FALSE;
-+}
-+
-+/* Fetch the list of subjectAltNames from a certificate. */
-+static GENERAL_NAMES *
-+get_cert_sans(X509 *x)
-+{
-+    int ext;
-+    X509_EXTENSION *san_ext;
-+
-+    ext = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
-+    if (ext < 0)
-+        return NULL;
-+    san_ext = X509_get_ext(x, ext);
-+    if (san_ext == NULL)
-+        return NULL;
-+    return X509V3_EXT_d2i(san_ext);
-+}
-+
-+/* Fetch a CN value from the subjct name field, returning its length, or -1 if
-+ * there is no subject name or it contains no CN value. */
-+static ssize_t
-+get_cert_cn(X509 *x, char *buf, size_t bufsize)
-+{
-+    X509_NAME *name;
-+
-+    name = X509_get_subject_name(x);
-+    if (name == NULL)
-+        return -1;
-+    return X509_NAME_get_text_by_NID(name, NID_commonName, buf, bufsize);
-+}
-+
-+/*
-+ * Return true if the passed-in expected IP address matches any of the names we
-+ * can recover from the server certificate, false otherwise.
-+ */
-+krb5_boolean
-+k5_check_cert_address(X509 *x, const char *text)
-+{
-+    char buf[1024];
-+    GENERAL_NAMES *sans;
-+    GENERAL_NAME *san = NULL;
-+    ASN1_OCTET_STRING *ip;
-+    krb5_boolean found_ip_san = FALSE, matched = FALSE;
-+    int n_sans, i;
-+    size_t name_length;
-+    union {
-+        struct in_addr in;
-+        struct in6_addr in6;
-+    } name;
-+
-+    /* Parse the IP address into an octet string. */
-+    ip = M_ASN1_OCTET_STRING_new();
-+    if (ip == NULL)
-+        return FALSE;
-+
-+    if (inet_aton(text, &name.in) == 1)
-+        name_length = sizeof(name.in);
-+    else if (inet_pton(AF_INET6, text, &name.in6) == 1)
-+        name_length = sizeof(name.in6);
-+    else
-+        name_length = 0;
-+
-+    if (name_length == 0) {
-+        ASN1_OCTET_STRING_free(ip);
-+        return FALSE;
-+    }
-+    M_ASN1_OCTET_STRING_set(ip, &name, name_length);
-+
-+    /* Check for matches in ipaddress subjectAltName values. */
-+    sans = get_cert_sans(x);
-+    if (sans != NULL) {
-+        n_sans = sk_GENERAL_NAME_num(sans);
-+        for (i = 0; i < n_sans; i++) {
-+            san = sk_GENERAL_NAME_value(sans, i);
-+            if (san->type != GEN_IPADD)
-+                continue;
-+            found_ip_san = TRUE;
-+            matched = ASN1_OCTET_STRING_cmp(ip, san->d.iPAddress) == 0;
-+            if (matched)
-+                break;
-+        }
-+        sk_GENERAL_NAME_pop_free(sans, GENERAL_NAME_free);
-+    }
-+    ASN1_OCTET_STRING_free(ip);
-+
-+    if (matched)
-+        return TRUE;
-+    if (found_ip_san)
-+        return matched;
-+
-+    /* Check for a match against the CN value in the peer's subject name. */
-+    name_length = get_cert_cn(x, buf, sizeof(buf));
-+    if (name_length >= 0) {
-+        /* Do a string compare to check if it's an acceptable value. */
-+        return strlen(text) == name_length &&
-+               strncmp(text, buf, name_length) == 0;
-+    }
-+
-+    /* We didn't find a match. */
-+    return FALSE;
-+}
-+
-+/*
-+ * Return true if the passed-in expected name matches any of the names we can
-+ * recover from a server certificate, false otherwise.
-+ */
-+krb5_boolean
-+k5_check_cert_servername(X509 *x, const char *expected)
-+{
-+    char buf[1024];
-+    GENERAL_NAMES *sans;
-+    GENERAL_NAME *san = NULL;
-+    unsigned char *dnsname;
-+    krb5_boolean found_dns_san = FALSE, matched = FALSE;
-+    int name_length, n_sans, i;
-+
-+    /* Check for matches in dnsname subjectAltName values. */
-+    sans = get_cert_sans(x);
-+    if (sans != NULL) {
-+        n_sans = sk_GENERAL_NAME_num(sans);
-+        for (i = 0; i < n_sans; i++) {
-+            san = sk_GENERAL_NAME_value(sans, i);
-+            if (san->type != GEN_DNS)
-+                continue;
-+            found_dns_san = TRUE;
-+            dnsname = NULL;
-+            name_length = ASN1_STRING_to_UTF8(&dnsname, san->d.dNSName);
-+            if (dnsname == NULL)
-+                continue;
-+            matched = domain_match((char *)dnsname, name_length, expected);
-+            OPENSSL_free(dnsname);
-+            if (matched)
-+                break;
-+        }
-+        sk_GENERAL_NAME_pop_free(sans, GENERAL_NAME_free);
-+    }
-+
-+    if (matched)
-+        return TRUE;
-+    if (found_dns_san)
-+        return matched;
-+
-+    /* Check for a match against the CN value in the peer's subject name. */
-+    name_length = get_cert_cn(x, buf, sizeof(buf));
-+    if (name_length >= 0)
-+        return domain_match(buf, name_length, expected);
-+
-+    /* We didn't find a match. */
-+    return FALSE;
-+}
-+#endif
-diff --git a/src/lib/krb5/os/checkhost.h b/src/lib/krb5/os/checkhost.h
-new file mode 100644
-index 0000000..b9d751e
---- /dev/null
-+++ b/src/lib/krb5/os/checkhost.h
-@@ -0,0 +1,39 @@
-+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-+/*
-+ * Copyright 2014 Red Hat, Inc.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ *    1. Redistributions of source code must retain the above copyright
-+ *       notice, this list of conditions and the following disclaimer.
-+ *
-+ *    2. Redistributions in binary form must reproduce the above copyright
-+ *       notice, this list of conditions and the following disclaimer in
-+ *       the documentation and/or other materials provided with the
-+ *       distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * Certificate subjectAltName check prototypes.
-+ */
-+
-+#ifndef KRB5_LIBOS_CHECKHOST_PROTO__
-+#define KRB5_LIBOS_CHECKHOST_PROTO__
-+
-+krb5_boolean k5_check_cert_servername(X509 *x, const char *expected);
-+krb5_boolean k5_check_cert_address(X509 *x, const char *expected);
-+
-+#endif /* KRB5_LIBOS_CHECKHOST_PROTO__ */
-diff --git a/src/lib/krb5/os/deps b/src/lib/krb5/os/deps
-index 3dd6d46..d56ff30 100644
---- a/src/lib/krb5/os/deps
-+++ b/src/lib/krb5/os/deps
-@@ -49,6 +49,17 @@ changepw.so changepw.po $(OUTPRE)changepw.$(OBJEXT): \
-   $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \
-   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-   changepw.c os-proto.h
-+checkhost.so checkhost.po $(OUTPRE)checkhost.$(OBJEXT): \
-+  $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
-+  $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
-+  $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
-+  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
-+  $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
-+  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
-+  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \
-+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
-+  $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
-+  $(top_srcdir)/include/socket-utils.h checkhost.c checkhost.h
- dnsglue.so dnsglue.po $(OUTPRE)dnsglue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
-   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
-@@ -418,7 +429,8 @@ sendto_kdc.so sendto_kdc.po $(OUTPRE)sendto_kdc.$(OBJEXT): \
-   $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
-   $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
-   $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
--  $(top_srcdir)/include/socket-utils.h os-proto.h sendto_kdc.c
-+  $(top_srcdir)/include/socket-utils.h checkhost.h os-proto.h \
-+  sendto_kdc.c
- sn2princ.so sn2princ.po $(OUTPRE)sn2princ.$(OBJEXT): \
-   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
-   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index 4bd8698..f083c0f 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -80,6 +80,7 @@
- #include <openssl/x509.h>
- #include <openssl/x509v3.h>
- #include <dirent.h>
-+#include "checkhost.h"
- #endif
- 
- #define MAX_PASS                    3
-@@ -148,6 +149,7 @@ struct conn_state {
-     krb5_boolean defer;
-     struct {
-         const char *uri_path;
-+        const char *servername;
-         char *https_request;
- #ifdef PROXY_TLS_IMPL_OPENSSL
-         SSL *ssl;
-@@ -158,6 +160,7 @@ struct conn_state {
- #ifdef PROXY_TLS_IMPL_OPENSSL
- /* Extra-data identifier, used to pass context into the verify callback. */
- static int ssl_ex_context_id = -1;
-+static int ssl_ex_conn_id = -1;
- #endif
- 
- void
-@@ -169,6 +172,7 @@ k5_sendto_kdc_initialize(void)
-     OpenSSL_add_all_algorithms();
- 
-     ssl_ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
-+    ssl_ex_conn_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
- #endif
- }
- 
-@@ -635,7 +639,8 @@ set_transport_message(struct conn_state *state, const krb5_data *realm,
- static krb5_error_code
- add_connection(struct conn_state **conns, k5_transport transport,
-                krb5_boolean defer, struct addrinfo *ai, size_t server_index,
--               const krb5_data *realm, const char *uri_path, char **udpbufp)
-+               const krb5_data *realm, const char *hostname,
-+               const char *uri_path, char **udpbufp)
- {
-     struct conn_state *state, **tailptr;
- 
-@@ -661,6 +666,7 @@ add_connection(struct conn_state **conns, k5_transport transport,
-         state->service_write = service_https_write;
-         state->service_read = service_https_read;
-         state->http.uri_path = uri_path;
-+        state->http.servername = hostname;
-     } else {
-         state->service_connect = NULL;
-         state->service_write = NULL;
-@@ -760,8 +766,8 @@ resolve_server(krb5_context context, const krb5_data *realm,
-         ai.ai_addrlen = entry->addrlen;
-         ai.ai_addr = (struct sockaddr *)&entry->addr;
-         defer = (entry->transport != transport);
--        return add_connection(conns, entry->transport, defer, &ai, ind,
--                              realm, entry->uri_path, udpbufp);
-+        return add_connection(conns, entry->transport, defer, &ai, ind, realm,
-+                              NULL, entry->uri_path, udpbufp);
-     }
- 
-     /* If the entry has a specified transport, use it. */
-@@ -787,7 +793,7 @@ resolve_server(krb5_context context, const krb5_data *realm,
-     retval = 0;
-     for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
-         retval = add_connection(conns, transport, FALSE, a, ind, realm,
--                                entry->uri_path, udpbufp);
-+                                entry->hostname, entry->uri_path, udpbufp);
-     }
- 
-     /* For TCP_OR_UDP entries, add each address again with the non-preferred
-@@ -797,7 +803,7 @@ resolve_server(krb5_context context, const krb5_data *realm,
-         for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
-             a->ai_socktype = socktype_for_transport(transport);
-             retval = add_connection(conns, transport, TRUE, a, ind, realm,
--                                    entry->uri_path, udpbufp);
-+                                    entry->hostname, entry->uri_path, udpbufp);
-         }
-     }
-     freeaddrinfo(addrs);
-@@ -1260,6 +1266,20 @@ cleanup:
-     return err;
- }
- 
-+static krb5_boolean
-+ssl_check_name_or_ip(X509 *x, const char *expected_name)
-+{
-+    struct in_addr in;
-+    struct in6_addr in6;
-+
-+    if (inet_aton(expected_name, &in) != 0 ||
-+        inet_pton(AF_INET6, expected_name, &in6) != 0) {
-+        return k5_check_cert_address(x, expected_name);
-+    } else {
-+        return k5_check_cert_servername(x, expected_name);
-+    }
-+}
-+
- static int
- ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx)
- {
-@@ -1268,12 +1288,14 @@ ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx)
-     BIO *bio;
-     krb5_context context;
-     int err, depth;
--    const char *cert = NULL, *errstr;
-+    struct conn_state *conn = NULL;
-+    const char *cert = NULL, *errstr, *expected_name;
-     size_t count;
- 
-     ssl = X509_STORE_CTX_get_ex_data(store_ctx,
-                                      SSL_get_ex_data_X509_STORE_CTX_idx());
-     context = SSL_get_ex_data(ssl, ssl_ex_context_id);
-+    conn = SSL_get_ex_data(ssl, ssl_ex_conn_id);
-     /* We do have the peer's cert, right? */
-     x = X509_STORE_CTX_get_current_cert(store_ctx);
-     if (x == NULL) {
-@@ -1299,8 +1321,19 @@ ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx)
-         }
-         return 0;
-     }
--    /* All done. */
--    return 1;
-+    /* If we're not looking at the peer, we're done and everything's ok. */
-+    if (depth != 0)
-+        return 1;
-+    /* Check if the name we expect to find is in the certificate. */
-+    expected_name = conn->http.servername;
-+    if (ssl_check_name_or_ip(x, expected_name)) {
-+        TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MATCH(context, expected_name);
-+        return 1;
-+    } else {
-+        TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MISMATCH(context, expected_name);
-+    }
-+    /* The name didn't match. */
-+    return 0;
- }
- 
- /*
-@@ -1317,7 +1350,7 @@ setup_ssl(krb5_context context, const krb5_data *realm,
-     SSL_CTX *ctx = NULL;
-     SSL *ssl = NULL;
- 
--    if (ssl_ex_context_id == -1)
-+    if (ssl_ex_context_id == -1 || ssl_ex_conn_id == -1)
-         goto kill_conn;
- 
-     /* Do general SSL library setup. */
-@@ -1339,6 +1372,8 @@ setup_ssl(krb5_context context, const krb5_data *realm,
- 
-     if (!SSL_set_ex_data(ssl, ssl_ex_context_id, context))
-         goto kill_conn;
-+    if (!SSL_set_ex_data(ssl, ssl_ex_conn_id, conn))
-+        goto kill_conn;
- 
-     /* Tell the SSL library about the socket. */
-     if (!SSL_set_fd(ssl, conn->fd))
--- 
-2.1.0
-
diff --git a/SOURCES/0010-Add-some-longer-form-docs-for-HTTPS.patch b/SOURCES/0010-Add-some-longer-form-docs-for-HTTPS.patch
deleted file mode 100644
index 88f1327..0000000
--- a/SOURCES/0010-Add-some-longer-form-docs-for-HTTPS.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From b52acabf478e8d1aa19f7823aade81eed1553143 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Tue, 22 Apr 2014 16:31:14 -0400
-Subject: [PATCH 10/13] Add some longer-form docs for HTTPS
-
-Add some longer-form documentation for the new HTTPS support, walking a
-prospective administrator through generating a bare minimal signing
-setup, deploying a WSGI-based proxy server onto an Apache httpd server
-using mod_ssl and mod_wsgi, and configuring clients to use it.
-
-ticket: 7929
----
- doc/admin/https.rst | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
- doc/admin/index.rst |  1 +
- 2 files changed, 49 insertions(+)
- create mode 100644 doc/admin/https.rst
-
-diff --git a/doc/admin/https.rst b/doc/admin/https.rst
-new file mode 100644
-index 0000000..b4e68b2
---- /dev/null
-+++ b/doc/admin/https.rst
-@@ -0,0 +1,48 @@
-+.. _https:
-+
-+HTTPS proxy configuration
-+=========================
-+
-+In addition to being able to use UDP or TCP to communicate directly
-+with a KDC as is outlined in RFC4120, and with kpasswd services in a
-+similar fashion, the client libraries can attempt to use an HTTPS
-+proxy server to communicate with a KDC or kpasswd service, using the
-+protocol outlined in [MS-KKDCP].
-+
-+Communicating with a KDC through an HTTPS proxy allows clients to
-+contact servers when network firewalls might otherwise prevent them
-+from doing so.  The use of TLS also encrypts all traffic between the
-+clients and the KDC, preventing observers from conducting password
-+dictionary attacks or from observing the client and server principals
-+being authenticated, at additional computational cost to both clients
-+and servers.
-+
-+An HTTPS proxy server is provided as a feature in some versions of
-+Microsoft Windows Server, and a WSGI implementation named `kdcproxy`
-+is available in the python package index.
-+
-+
-+Configuring the clients
-+-----------------------
-+
-+To use an HTTPS proxy, a client host must trust the CA which issued
-+that proxy's SSL certificate.  If that CA's certificate is not in the
-+system-wide default set of trusted certificates, configure the
-+following relation in the client host's :ref:`krb5.conf(5)` file in
-+the appropriate :ref:`realms` subsection::
-+
-+    http_anchors = FILE:/etc/krb5/cacert.pem
-+
-+Adjust the pathname to match the path of the file which contains a
-+copy of the CA's certificate.  The `http_anchors` option is documented
-+more fully in :ref:`krb5.conf(5)`.
-+
-+Configure the client to access the KDC and kpasswd service by
-+specifying their locations in its :ref:`krb5.conf(5)` file in the form
-+of HTTPS URLs for the proxy server::
-+
-+    kdc = https://server.fqdn/KdcProxy
-+    kpasswd_server = https://server.fqdn/KdcProxy
-+
-+If the proxy and client are properly configured, client commands such
-+as ``kinit``, ``kvno``, and ``kpasswd`` should all function normally.
-diff --git a/doc/admin/index.rst b/doc/admin/index.rst
-index 3406843..3cd57f5 100644
---- a/doc/admin/index.rst
-+++ b/doc/admin/index.rst
-@@ -17,6 +17,7 @@ For administrators
-    otp.rst
-    princ_dns.rst
-    enctypes.rst
-+   https.rst
- 
- .. toctree::
-    :maxdepth: 1
--- 
-2.1.0
-
diff --git a/SOURCES/0011-Have-k5test.py-provide-runenv-to-python-tests.patch b/SOURCES/0011-Have-k5test.py-provide-runenv-to-python-tests.patch
deleted file mode 100644
index 218e629..0000000
--- a/SOURCES/0011-Have-k5test.py-provide-runenv-to-python-tests.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From f78f8b1a46534db3a4547323ba952c1fa1b41fe9 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Fri, 30 May 2014 17:13:31 -0400
-Subject: [PATCH 11/13] Have k5test.py provide 'runenv' to python tests
-
-Expose the formerly-internal _runenv module as k5test.runenv, so that
-settings we store in the top-level runenv.py will be available to them.
-
-ticket: 7929
----
- src/util/k5test.py | 15 ++++++++++-----
- 1 file changed, 10 insertions(+), 5 deletions(-)
-
-diff --git a/src/util/k5test.py b/src/util/k5test.py
-index a2bfbee..8cb477d 100644
---- a/src/util/k5test.py
-+++ b/src/util/k5test.py
-@@ -177,6 +177,12 @@ Scripts may use the following functions and variables:
- 
- * args: Positional arguments left over after flags are processed.
- 
-+* runenv: The contents of $srctop/runenv.py, containing a dictionary
-+  'env' which specifies additional variables to be added to the realm
-+  environment, and a variable 'proxy_tls_impl', which indicates which
-+  SSL implementation (if any) is being used by libkrb5's support for
-+  contacting KDCs and kpasswd servers over HTTPS.
-+
- * verbose: Whether the script is running verbosely.
- 
- * testpass: The command-line test pass argument.  The script does not
-@@ -526,9 +532,9 @@ def _match_cmdnum(cmdnum, ind):
- # Return an environment suitable for running programs in the build
- # tree.  It is safe to modify the result.
- def _build_env():
--    global buildtop, _runenv
-+    global buildtop, runenv
-     env = os.environ.copy()
--    for (k, v) in _runenv.iteritems():
-+    for (k, v) in runenv.env.iteritems():
-         if v.find('./') == 0:
-             env[k] = os.path.join(buildtop, v)
-         else:
-@@ -544,8 +550,7 @@ def _import_runenv():
-     runenv_py = os.path.join(buildtop, 'runenv.py')
-     if not os.path.exists(runenv_py):
-         fail('You must run "make runenv.py" in %s first.' % buildtop)
--    module = imp.load_source('runenv', runenv_py)
--    return module.env
-+    return imp.load_source('runenv', runenv_py)
- 
- 
- # Merge the nested dictionaries cfg1 and cfg2 into a new dictionary.
-@@ -1174,7 +1179,7 @@ _cmd_index = 1
- buildtop = _find_buildtop()
- srctop = _find_srctop()
- plugins = os.path.join(buildtop, 'plugins')
--_runenv = _import_runenv()
-+runenv = _import_runenv()
- hostname = _get_hostname()
- null_input = open(os.devnull, 'r')
- 
--- 
-2.1.0
-
diff --git a/SOURCES/0012-Add-a-simple-KDC-proxy-test-server.patch b/SOURCES/0012-Add-a-simple-KDC-proxy-test-server.patch
deleted file mode 100644
index 48aa032..0000000
--- a/SOURCES/0012-Add-a-simple-KDC-proxy-test-server.patch
+++ /dev/null
@@ -1,526 +0,0 @@
-From 142255ba9af4ce1016a8eadf147e599ee490f1f7 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Fri, 7 Feb 2014 18:03:29 -0500
-Subject: [PATCH 12/13] Add a simple KDC proxy test server
-
-This proxy server uses python-paste to run the kdcproxy from
-https://pypi.python.org/pypi/kdcproxy.  It should be used along
-with the proxy.pem certificate in ../tests/dejagnu/proxy-certs.
-
-ticket: 7929
----
- src/tests/dejagnu/proxy-certs/ca.pem             |  28 +++++
- src/tests/dejagnu/proxy-certs/make-certs.sh      | 124 +++++++++++++++++++++++
- src/tests/dejagnu/proxy-certs/proxy-badsig.pem   |  56 ++++++++++
- src/tests/dejagnu/proxy-certs/proxy-ideal.pem    |  56 ++++++++++
- src/tests/dejagnu/proxy-certs/proxy-no-match.pem |  54 ++++++++++
- src/tests/dejagnu/proxy-certs/proxy-san.pem      |  56 ++++++++++
- src/tests/dejagnu/proxy-certs/proxy-subject.pem  |  54 ++++++++++
- src/util/paste-kdcproxy.py                       |  18 ++++
- 8 files changed, 446 insertions(+)
- create mode 100644 src/tests/dejagnu/proxy-certs/ca.pem
- create mode 100755 src/tests/dejagnu/proxy-certs/make-certs.sh
- create mode 100644 src/tests/dejagnu/proxy-certs/proxy-badsig.pem
- create mode 100644 src/tests/dejagnu/proxy-certs/proxy-ideal.pem
- create mode 100644 src/tests/dejagnu/proxy-certs/proxy-no-match.pem
- create mode 100644 src/tests/dejagnu/proxy-certs/proxy-san.pem
- create mode 100644 src/tests/dejagnu/proxy-certs/proxy-subject.pem
- create mode 100755 src/util/paste-kdcproxy.py
-
-diff --git a/src/tests/dejagnu/proxy-certs/ca.pem b/src/tests/dejagnu/proxy-certs/ca.pem
-new file mode 100644
-index 0000000..e0f8dc7
---- /dev/null
-+++ b/src/tests/dejagnu/proxy-certs/ca.pem
-@@ -0,0 +1,28 @@
-+-----BEGIN CERTIFICATE-----
-+MIIEuzCCA6OgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
-+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG
-+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww
-+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x
-+NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaMIGZMQswCQYDVQQGEwJVUzEWMBQG
-+A1UECBMNTWFzc2FjaHVzZXR0czESMBAGA1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQK
-+EwNNSVQxIjAgBgNVBAsTGUluc2VjdXJlIEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNV
-+BAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlMIIBIjANBgkq
-+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6
-+zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJ
-+IkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtq
-+fpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1Yd
-+pmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObS
-+g13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABo4IB
-+CjCCAQYwHQYDVR0OBBYEFHO5+DSYzq8rvQhUldyvn0y4AqlHMIHGBgNVHSMEgb4w
-+gbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGfpIGcMIGZMQswCQYDVQQGEwJVUzEW
-+MBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAGA1UEBxMJQ2FtYnJpZGdlMQwwCgYD
-+VQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJlIEtlcmJlcm9zIHRlc3QgQ0ExLDAq
-+BgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlggEBMAsG
-+A1UdDwQEAwIB/jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAM
-+Mf4ptC6WoQBH3GoTfgBL0WlIeYeSFmLO7IaSjpK0FV6F/yF7iPFSXcpmu23m6USY
-+LRSxnAvxFTi+h1S5Za9O2Pjq88R9nHmesg4v8HJqOw4HpkDowYo2lumjIMfAutyR
-+MQUOujYJW1WyZ2PidN5M1exDeMgQN9nVjUCx/WKD9fnzOjOOR1Sc8Us2KpoyccIi
-+A+ABHubCvSO3cln0Sp7qjkssJScZtouzPu8FYiroTIR+1oSIKTpJiik1EptlsTea
-+L6fHTMHspFhZaiUJFHWTBAgn/dT+UkFntHdHGI6HWBThFVW05hKoarBA7N25W7FN
-+AHyfC0lKds4qFiBQkpdi
-+-----END CERTIFICATE-----
-diff --git a/src/tests/dejagnu/proxy-certs/make-certs.sh b/src/tests/dejagnu/proxy-certs/make-certs.sh
-new file mode 100755
-index 0000000..1191bf0
---- /dev/null
-+++ b/src/tests/dejagnu/proxy-certs/make-certs.sh
-@@ -0,0 +1,124 @@
-+#!/bin/sh -e
-+
-+PWD=`pwd`
-+NAMETYPE=1
-+KEYSIZE=2048
-+DAYS=4000
-+REALM=KRBTEST.COM
-+TLS_SERVER_EKU=1.3.6.1.5.5.7.3.1
-+PROXY_EKU_LIST=$TLS_SERVER_EKU
-+
-+cat > openssl.cnf << EOF
-+[req]
-+prompt = no
-+distinguished_name = \$ENV::SUBJECT
-+
-+[ca]
-+default_ca = test_ca
-+
-+[test_ca]
-+new_certs_dir = $PWD
-+serial = $PWD/ca.srl
-+database = $PWD/ca.db
-+certificate = $PWD/ca.pem
-+private_key = $PWD/privkey.pem
-+default_days = $DAYS
-+x509_extensions = exts_proxy
-+policy = proxyname
-+default_md = sha1
-+unique_subject = no
-+email_in_dn = no
-+
-+[signer]
-+CN = test CA certificate
-+C = US
-+ST = Massachusetts
-+L = Cambridge
-+O = MIT
-+OU = Insecure Kerberos test CA
-+CN = test suite CA; do not use otherwise
-+
-+[proxy]
-+C = US
-+ST = Massachusetts
-+O = KRBTEST.COM
-+CN = PROXYinSubject
-+
-+[localhost]
-+C = US
-+ST = Massachusetts
-+O = KRBTEST.COM
-+CN = localhost
-+
-+[proxyname]
-+C = supplied
-+ST = supplied
-+O = supplied
-+CN = supplied
-+
-+[exts_ca]
-+subjectKeyIdentifier = hash
-+authorityKeyIdentifier = keyid:always,issuer:always
-+keyUsage = nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign
-+basicConstraints = critical,CA:TRUE
-+
-+[exts_proxy]
-+subjectKeyIdentifier = hash
-+authorityKeyIdentifier = keyid:always,issuer:always
-+keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
-+basicConstraints = critical,CA:FALSE
-+subjectAltName = DNS:proxyŠubjectÄltÑame,DNS:proxySubjectAltName,IP:127.0.0.1,IP:::1,DNS:localhost
-+extendedKeyUsage = $PROXY_EKU_LIST
-+
-+[exts_proxy_no_san]
-+subjectKeyIdentifier = hash
-+authorityKeyIdentifier = keyid:always,issuer:always
-+keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
-+basicConstraints = critical,CA:FALSE
-+extendedKeyUsage = $PROXY_EKU_LIST
-+EOF
-+
-+# Generate a private key.
-+openssl genrsa $KEYSIZE -nodes > privkey.pem
-+
-+# Generate a "CA" certificate.
-+SUBJECT=signer openssl req -config openssl.cnf -new -x509 -extensions exts_ca \
-+    -set_serial 1 -days $DAYS -key privkey.pem -out ca.pem
-+
-+# Generate proxy certificate signing requests.
-+SUBJECT=proxy openssl req -config openssl.cnf -new -key privkey.pem \
-+	-out proxy.csr
-+SUBJECT=localhost openssl req -config openssl.cnf -new -key privkey.pem \
-+	-out localhost.csr
-+
-+# Issue the certificate with the right name in a subjectAltName.
-+echo 02 > ca.srl
-+cat /dev/null > ca.db
-+SUBJECT=proxy openssl ca  -config openssl.cnf -extensions exts_proxy \
-+    -batch -days $DAYS -notext -out tmp.pem -in proxy.csr
-+cat privkey.pem tmp.pem > proxy-san.pem
-+
-+# Issue a certificate that only has the name in the subject field
-+SUBJECT=proxy openssl ca  -config openssl.cnf -extensions exts_proxy_no_san \
-+    -batch -days $DAYS -notext -out tmp.pem -in localhost.csr
-+cat privkey.pem tmp.pem > proxy-subject.pem
-+
-+# Issue a certificate that doesn't include any matching name values.
-+SUBJECT=proxy openssl ca  -config openssl.cnf -extensions exts_proxy_no_san \
-+    -batch -days $DAYS -notext -out tmp.pem -in proxy.csr
-+cat privkey.pem tmp.pem > proxy-no-match.pem
-+
-+# Issue a certificate that contains all matching name values.
-+SUBJECT=proxy openssl ca  -config openssl.cnf -extensions exts_proxy \
-+    -batch -days $DAYS -notext -out tmp.pem -in localhost.csr
-+cat privkey.pem tmp.pem > proxy-ideal.pem
-+
-+# Corrupt the signature on the certificate.
-+SUBJECT=proxy openssl x509 -outform der -in proxy-ideal.pem -out bad.der
-+length=`od -Ad bad.der | tail -n 1 | awk '{print $1}'`
-+dd if=/dev/zero bs=1 of=bad.der count=16 seek=`expr $length - 16`
-+SUBJECT=proxy openssl x509 -inform der -in bad.der -out tmp.pem
-+cat privkey.pem tmp.pem > proxy-badsig.pem
-+
-+# Clean up.
-+rm -f openssl.cnf proxy.csr localhost.csr privkey.pem ca.db ca.db.old ca.srl ca.srl.old ca.db.attr ca.db.attr.old 02.pem 03.pem 04.pem 05.pem tmp.pem bad.der
-diff --git a/src/tests/dejagnu/proxy-certs/proxy-badsig.pem b/src/tests/dejagnu/proxy-certs/proxy-badsig.pem
-new file mode 100644
-index 0000000..2b31f7d
---- /dev/null
-+++ b/src/tests/dejagnu/proxy-certs/proxy-badsig.pem
-@@ -0,0 +1,56 @@
-+-----BEGIN RSA PRIVATE KEY-----
-+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU
-+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I
-+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ
-+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x
-+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP
-+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo
-+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM
-+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS
-+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR
-+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o
-+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt
-+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm
-+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL
-+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB
-+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn
-+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+
-+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3
-+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG
-+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6
-+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj
-+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9
-+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6
-+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK
-+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW
-+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w=
-+-----END RSA PRIVATE KEY-----
-+-----BEGIN CERTIFICATE-----
-+MIIE3TCCA8WgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
-+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG
-+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww
-+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x
-+NDA1MDIxOTA2MDlaFw0yNTA0MTQxOTA2MDlaME8xCzAJBgNVBAYTAlVTMRYwFAYD
-+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTESMBAGA1UE
-+AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zud
-+npN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5
-+MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMpp
-+mO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7F
-+YhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00W
-+VwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFr
-+WVR3QLTxnnmXsqnXvwIDAQABo4IBdzCCAXMwHQYDVR0OBBYEFHO5+DSYzq8rvQhU
-+ldyvn0y4AqlHMIHGBgNVHSMEgb4wgbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGf
-+pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAG
-+A1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJl
-+IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v
-+dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMFkG
-+A1UdEQRSMFCCFnByb3h5xaB1YmplY3TDhGx0w5FhbWWCE3Byb3h5U3ViamVjdEFs
-+dE5hbWWHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9zdDATBgNVHSUE
-+DDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOCAQEAfTctgFjQSaevBi64q7yh
-+GNsK3PqeNEALZz4pSXRbOwm0E4RpYIS7uqg1C4zJ5Zbd4V/dOX7q+T/iBS7gErzS
-+rj21jH3Ggc92TmXzcFxMDCxLV0hO8xFkqg3P4sslJESOHxvEMTTf5s893yUb8vJ/
-+DCvZXXRoRwPot9MFozkmcQcaTNunREWFvn4i4JXcMCSAfWTd+/VkpVsy69u3tj68
-+7G2/K5nalvZikutEC+DyfyBuvDAoxIYzCi3VtQxCalW28Q5hzWV21QsvKTP5QBsh
-+RaU2r0O58lZPPvrOrtWQBCudUgsnoraVLrjJshEQ4z/ZAAAAAAAAAAAAAAAAAAAA
-+AA==
-+-----END CERTIFICATE-----
-diff --git a/src/tests/dejagnu/proxy-certs/proxy-ideal.pem b/src/tests/dejagnu/proxy-certs/proxy-ideal.pem
-new file mode 100644
-index 0000000..4588f7d
---- /dev/null
-+++ b/src/tests/dejagnu/proxy-certs/proxy-ideal.pem
-@@ -0,0 +1,56 @@
-+-----BEGIN RSA PRIVATE KEY-----
-+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU
-+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I
-+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ
-+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x
-+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP
-+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo
-+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM
-+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS
-+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR
-+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o
-+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt
-+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm
-+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL
-+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB
-+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn
-+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+
-+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3
-+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG
-+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6
-+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj
-+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9
-+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6
-+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK
-+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW
-+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w=
-+-----END RSA PRIVATE KEY-----
-+-----BEGIN CERTIFICATE-----
-+MIIE3TCCA8WgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
-+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG
-+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww
-+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x
-+NDA1MDIxOTA2MDlaFw0yNTA0MTQxOTA2MDlaME8xCzAJBgNVBAYTAlVTMRYwFAYD
-+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTESMBAGA1UE
-+AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zud
-+npN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5
-+MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMpp
-+mO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7F
-+YhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00W
-+VwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFr
-+WVR3QLTxnnmXsqnXvwIDAQABo4IBdzCCAXMwHQYDVR0OBBYEFHO5+DSYzq8rvQhU
-+ldyvn0y4AqlHMIHGBgNVHSMEgb4wgbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGf
-+pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAG
-+A1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJl
-+IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v
-+dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMFkG
-+A1UdEQRSMFCCFnByb3h5xaB1YmplY3TDhGx0w5FhbWWCE3Byb3h5U3ViamVjdEFs
-+dE5hbWWHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9zdDATBgNVHSUE
-+DDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOCAQEAfTctgFjQSaevBi64q7yh
-+GNsK3PqeNEALZz4pSXRbOwm0E4RpYIS7uqg1C4zJ5Zbd4V/dOX7q+T/iBS7gErzS
-+rj21jH3Ggc92TmXzcFxMDCxLV0hO8xFkqg3P4sslJESOHxvEMTTf5s893yUb8vJ/
-+DCvZXXRoRwPot9MFozkmcQcaTNunREWFvn4i4JXcMCSAfWTd+/VkpVsy69u3tj68
-+7G2/K5nalvZikutEC+DyfyBuvDAoxIYzCi3VtQxCalW28Q5hzWV21QsvKTP5QBsh
-+RaU2r0O58lZPPvrOrtWQBCudUgsnoraVLrjJshEQ4z/ZA9fVtX2ndCSIoyWpWk01
-+gQ==
-+-----END CERTIFICATE-----
-diff --git a/src/tests/dejagnu/proxy-certs/proxy-no-match.pem b/src/tests/dejagnu/proxy-certs/proxy-no-match.pem
-new file mode 100644
-index 0000000..a97c1c7
---- /dev/null
-+++ b/src/tests/dejagnu/proxy-certs/proxy-no-match.pem
-@@ -0,0 +1,54 @@
-+-----BEGIN RSA PRIVATE KEY-----
-+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU
-+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I
-+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ
-+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x
-+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP
-+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo
-+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM
-+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS
-+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR
-+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o
-+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt
-+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm
-+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL
-+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB
-+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn
-+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+
-+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3
-+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG
-+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6
-+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj
-+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9
-+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6
-+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK
-+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW
-+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w=
-+-----END RSA PRIVATE KEY-----
-+-----BEGIN CERTIFICATE-----
-+MIIEhzCCA2+gAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
-+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG
-+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww
-+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x
-+NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaMFQxCzAJBgNVBAYTAlVTMRYwFAYD
-+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTEXMBUGA1UE
-+AxMOUFJPWFlpblN1YmplY3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-+AQDXO52ek3wU/uIufW+CTJNKf9FDFfHXK3rOKQdoytU+OSNc89SgIWlZLd54jhpA
-+WiP3cvkzBkOZLE5+UECovBXYAwBpytic08kiQe1tgp1Wy/D1vgg1NapX38M44M7t
-+SjDIymmY7fn+lRdosv4CMeMvDX8SFDdli2p+kAw6R/lOdLka2pkWWtiBkoTy9MLw
-+HEMozsViFZjPuSn+0bdLw79FOc/s136HVh2maUcEZ+7AhEgnPnE3DoohwLLdDQ02
-+gqeHTRZXAuZH7HXUEZKQyOJlmTAnkPRE5tKDXdAP+K2sahXaC0/ONCA099OuOwy/
-+I5YAAWtZVHdAtPGeeZeyqde/AgMBAAGjggEcMIIBGDAdBgNVHQ4EFgQUc7n4NJjO
-+ryu9CFSV3K+fTLgCqUcwgcYGA1UdIwSBvjCBu4AUc7n4NJjOryu9CFSV3K+fTLgC
-+qUehgZ+kgZwwgZkxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRz
-+MRIwEAYDVQQHEwlDYW1icmlkZ2UxDDAKBgNVBAoTA01JVDEiMCAGA1UECxMZSW5z
-+ZWN1cmUgS2VyYmVyb3MgdGVzdCBDQTEsMCoGA1UEAxQjdGVzdCBzdWl0ZSBDQTsg
-+ZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0PBAQDAgPoMAwGA1UdEwEB/wQC
-+MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEFBQADggEBAMsP++r4
-+vki0mBJg3POpp0i+H6zNMimoYLLtM5NvwXinfFuFQKbwLm8QWuHVifjfCYxMUm+l
-+iL5cS/bq+SUWGDmrlOhsuu4+aYaxgNiEyki5Rol6miSOHbfOhzX8yp0EBPpq08dg
-+SEdrTd/FIl4qgkkb1A4RJYZRErn/fbsyjJN66KIfSOXJuC8XMBf03Vw9f2rdrHJa
-+r5lVGvqa4wjO2MPq9vVK52VFrbU/zuyyCUtggyIOwGLGSY0Axtbci+IHToDBQes+
-+6W4WwSUCssWfIZXQDLjFw1oRHnN43fXmX5vsVLi7YvOFHOAa1BDnDtCTZit26xVA
-+Mdic66hR2jHP0TE=
-+-----END CERTIFICATE-----
-diff --git a/src/tests/dejagnu/proxy-certs/proxy-san.pem b/src/tests/dejagnu/proxy-certs/proxy-san.pem
-new file mode 100644
-index 0000000..ac8bbaa
---- /dev/null
-+++ b/src/tests/dejagnu/proxy-certs/proxy-san.pem
-@@ -0,0 +1,56 @@
-+-----BEGIN RSA PRIVATE KEY-----
-+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU
-+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I
-+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ
-+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x
-+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP
-+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo
-+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM
-+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS
-+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR
-+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o
-+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt
-+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm
-+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL
-+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB
-+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn
-+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+
-+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3
-+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG
-+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6
-+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj
-+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9
-+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6
-+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK
-+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW
-+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w=
-+-----END RSA PRIVATE KEY-----
-+-----BEGIN CERTIFICATE-----
-+MIIE4jCCA8qgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
-+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG
-+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww
-+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x
-+NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaMFQxCzAJBgNVBAYTAlVTMRYwFAYD
-+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTEXMBUGA1UE
-+AxMOUFJPWFlpblN1YmplY3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-+AQDXO52ek3wU/uIufW+CTJNKf9FDFfHXK3rOKQdoytU+OSNc89SgIWlZLd54jhpA
-+WiP3cvkzBkOZLE5+UECovBXYAwBpytic08kiQe1tgp1Wy/D1vgg1NapX38M44M7t
-+SjDIymmY7fn+lRdosv4CMeMvDX8SFDdli2p+kAw6R/lOdLka2pkWWtiBkoTy9MLw
-+HEMozsViFZjPuSn+0bdLw79FOc/s136HVh2maUcEZ+7AhEgnPnE3DoohwLLdDQ02
-+gqeHTRZXAuZH7HXUEZKQyOJlmTAnkPRE5tKDXdAP+K2sahXaC0/ONCA099OuOwy/
-+I5YAAWtZVHdAtPGeeZeyqde/AgMBAAGjggF3MIIBczAdBgNVHQ4EFgQUc7n4NJjO
-+ryu9CFSV3K+fTLgCqUcwgcYGA1UdIwSBvjCBu4AUc7n4NJjOryu9CFSV3K+fTLgC
-+qUehgZ+kgZwwgZkxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRz
-+MRIwEAYDVQQHEwlDYW1icmlkZ2UxDDAKBgNVBAoTA01JVDEiMCAGA1UECxMZSW5z
-+ZWN1cmUgS2VyYmVyb3MgdGVzdCBDQTEsMCoGA1UEAxQjdGVzdCBzdWl0ZSBDQTsg
-+ZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0PBAQDAgPoMAwGA1UdEwEB/wQC
-+MAAwWQYDVR0RBFIwUIIWcHJveHnFoHViamVjdMOEbHTDkWFtZYITcHJveHlTdWJq
-+ZWN0QWx0TmFtZYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAAYIJbG9jYWxob3N0MBMG
-+A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQAH6AWuyRLzMbKq
-+MUlyg9ZIar8p0Ms0/UEaa6Xm3/cfm6HSujtgcYlDN3M86Z3zWzWdTrOHsRr/YSG3
-+H3YDhJToKqxcjgho+1xdBPm0xuFsJcypRqGj/mIaJSoa+wC2AdY1EdE+URsh87XC
-+SHYNbxAVo8qBHMjtROm6AKb2YusYqHnkT+U6nc4Pn9UnIzmu4wfoSB+X1vtY24TP
-+AtXNYQEG4BkgSrcsgoL+z/+wtZLU8QFk6JRO7Bedq711Oh/taEasZHjRAmnqC5TB
-+Ab2fnwWuoVZHqz2qydeywXUKrZlctuRVdjE++wOt9xuMPKFGo0PKDw/SymCe61Q8
-+Nc/d2mhz
-+-----END CERTIFICATE-----
-diff --git a/src/tests/dejagnu/proxy-certs/proxy-subject.pem b/src/tests/dejagnu/proxy-certs/proxy-subject.pem
-new file mode 100644
-index 0000000..e17918f
---- /dev/null
-+++ b/src/tests/dejagnu/proxy-certs/proxy-subject.pem
-@@ -0,0 +1,54 @@
-+-----BEGIN RSA PRIVATE KEY-----
-+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU
-+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I
-+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ
-+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x
-+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP
-+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo
-+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM
-+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS
-+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR
-+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o
-+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt
-+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm
-+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL
-+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB
-+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn
-+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+
-+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3
-+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG
-+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6
-+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj
-+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9
-+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6
-+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK
-+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW
-+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w=
-+-----END RSA PRIVATE KEY-----
-+-----BEGIN CERTIFICATE-----
-+MIIEgjCCA2qgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
-+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG
-+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww
-+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x
-+NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaME8xCzAJBgNVBAYTAlVTMRYwFAYD
-+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTESMBAGA1UE
-+AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zud
-+npN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5
-+MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMpp
-+mO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7F
-+YhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00W
-+VwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFr
-+WVR3QLTxnnmXsqnXvwIDAQABo4IBHDCCARgwHQYDVR0OBBYEFHO5+DSYzq8rvQhU
-+ldyvn0y4AqlHMIHGBgNVHSMEgb4wgbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGf
-+pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAG
-+A1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJl
-+IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v
-+dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMBMG
-+A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQCzGPT+QOrl9mbJ
-+nsGlPlLUOF+PYz0a/9V/iznlofxwCXiRi2ryMpLFbjLeOvjLJ3UzyNKtmEeudTBM
-+yfR4i8tb9WA7Oh0BjK1+kD4688bAUXiIDhueKBjonmPvMd9kq3MDd4vDLkcZk6R4
-+4IcbdwhzSBmnJH8ha2J82XShPpRq5CZNR9+vTyFwGdGWdPDjTMiXoXAmpRemcEgO
-+iO4Gxvcrg/Z06Ys3eLze7QHNMAEwXhC4rUR34j5I2zgU7CEhff3AktLmnKVa8go8
-+4BJT/n3XGB+3gdAEihQmgCEZetHH+YxAR0Ppn3ty7fpAlOnbRJqpeu6TMN8x/lL8
-+c6JtDWRG
-+-----END CERTIFICATE-----
-diff --git a/src/util/paste-kdcproxy.py b/src/util/paste-kdcproxy.py
-new file mode 100755
-index 0000000..1e56b89
---- /dev/null
-+++ b/src/util/paste-kdcproxy.py
-@@ -0,0 +1,18 @@
-+#!/usr/bin/python
-+import kdcproxy
-+from paste import httpserver
-+import os
-+import sys
-+
-+if len(sys.argv) > 1:
-+    port = sys.argv[1]
-+else:
-+    port = 8443
-+if len(sys.argv) > 2:
-+    pem = sys.argv[2]
-+else:
-+    pem = '*'
-+server = httpserver.serve(kdcproxy.Application(), port=port, ssl_pem=pem,
-+                          start_loop=False)
-+os.write(sys.stdout.fileno(), 'proxy server ready\n')
-+server.serve_forever()
--- 
-2.1.0
-
diff --git a/SOURCES/0013-Add-tests-for-MS-KKDCP-client-support.patch b/SOURCES/0013-Add-tests-for-MS-KKDCP-client-support.patch
deleted file mode 100644
index fdb6eca..0000000
--- a/SOURCES/0013-Add-tests-for-MS-KKDCP-client-support.patch
+++ /dev/null
@@ -1,259 +0,0 @@
-Tweaked context for src/tests/Makefile.in because t_salt.py hadn't yet been
-added as a test in 1.12, and the rdreq and s2p helpers weren't there yet.
-
-From 3e2c7cc557048faac3400ae41b0228bd37a82a4c Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date: Fri, 7 Feb 2014 18:56:10 -0500
-Subject: [PATCH 13/13] Add tests for MS-KKDCP client support
-
-Exercise the MS-KKDCP client support using the test proxy server, for
-AS, TGS, and kpasswd requests while also checking the certificate
-verification and name checks.
-
-ticket: 7929
----
- src/tests/Makefile.in |   1 +
- src/tests/t_proxy.py  | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 220 insertions(+)
- create mode 100644 src/tests/t_proxy.py
-
-diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
-index 7347ed6..536f5cb 100644
---- a/src/tests/Makefile.in
-+++ b/src/tests/Makefile.in
-@@ -134,6 +134,7 @@ check-pytests:: t_init_creds t_localauth
- 	$(RUNPYTEST) $(srcdir)/jsonwalker.py -d $(srcdir)/au_dict.json \
- 			-i au.log
- 	$(RUNPYTEST) $(srcdir)/t_bogus_kdc_req.py $(PYTESTFLAGS)
-+	$(RUNPYTEST) $(srcdir)/t_proxy.py $(PYTESTFLAGS)
- 
- clean::
- 	$(RM) gcred hist hrealm kdbtest plugorder responder
-diff --git a/src/tests/t_proxy.py b/src/tests/t_proxy.py
-new file mode 100644
-index 0000000..e4e3d48
---- /dev/null
-+++ b/src/tests/t_proxy.py
-@@ -0,0 +1,219 @@
-+#!/usr/bin/python
-+from k5test import *
-+
-+# Skip this test if we're missing proxy functionality or parts of the proxy.
-+if runenv.proxy_tls_impl == 'no':
-+    success('Warning: not testing proxy support because feature ' +
-+            'was not enabled')
-+    exit(0)
-+try:
-+    from paste import httpserver
-+except:
-+    success('Warning: not testing proxy support because python ' +
-+            'paste.httpserver module not found')
-+    exit(0)
-+try:
-+    import kdcproxy
-+except:
-+    success('Warning: not testing proxy support because python ' +
-+            'kdcproxy module not found')
-+    exit(0)
-+
-+# Construct a krb5.conf fragment configuring the client to use a local proxy
-+# server.
-+proxysubjectpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
-+                               'proxy-subject.pem')
-+proxysanpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
-+                           'proxy-san.pem')
-+proxyidealpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
-+                             'proxy-ideal.pem')
-+proxywrongpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
-+                             'proxy-no-match.pem')
-+proxybadpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs',
-+                           'proxy-badsig.pem')
-+proxyca = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'ca.pem')
-+proxyurl = 'https://localhost:$port5/KdcProxy'
-+proxyurlupcase = 'https://LocalHost:$port5/KdcProxy'
-+proxyurl4 = 'https://127.0.0.1:$port5/KdcProxy'
-+proxyurl6 = 'https://[::1]:$port5/KdcProxy'
-+
-+unanchored_krb5_conf = {'realms': {'$realm': {
-+                        'kdc': proxyurl,
-+                        'kpasswd_server': proxyurl}}}
-+anchored_name_krb5_conf = {'realms': {'$realm': {
-+                           'kdc': proxyurl,
-+                           'kpasswd_server': proxyurl,
-+                           'http_anchors': 'FILE:%s' % proxyca}}}
-+anchored_upcasename_krb5_conf = {'realms': {'$realm': {
-+                                 'kdc': proxyurlupcase,
-+                                 'kpasswd_server': proxyurlupcase,
-+                                 'http_anchors': 'FILE:%s' % proxyca}}}
-+anchored_kadmin_krb5_conf = {'realms': {'$realm': {
-+                             'kdc': proxyurl,
-+                             'admin_server': proxyurl,
-+                             'http_anchors': 'FILE:%s' % proxyca}}}
-+anchored_ipv4_krb5_conf = {'realms': {'$realm': {
-+                           'kdc': proxyurl4,
-+                           'kpasswd_server': proxyurl4,
-+                           'http_anchors': 'FILE:%s' % proxyca}}}
-+kpasswd_input = (password('user') + '\n' + password('user') + '\n' +
-+                 password('user') + '\n')
-+
-+def start_proxy(realm, keycertpem):
-+    proxy_conf_path = os.path.join(realm.testdir, 'kdcproxy.conf')
-+    proxy_exec_path = os.path.join(srctop, 'util', 'paste-kdcproxy.py')
-+    conf = open(proxy_conf_path, 'w')
-+    conf.write('[%s]\n' % realm.realm)
-+    conf.write('kerberos = kerberos://localhost:%d\n' % realm.portbase)
-+    conf.write('kpasswd = kpasswd://localhost:%d\n' % (realm.portbase + 2))
-+    conf.close()
-+    realm.env['KDCPROXY_CONFIG'] = proxy_conf_path
-+    cmd = [proxy_exec_path, str(realm.server_port()), keycertpem]
-+    return realm.start_server(cmd, sentinel='proxy server ready')
-+
-+# Fail: untrusted issuer and hostname doesn't match.
-+output("running pass 1: issuer not trusted and hostname doesn't match\n")
-+realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False,
-+                create_host=False)
-+proxy = start_proxy(realm, proxywrongpem)
-+realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Fail: untrusted issuer, host name matches subject.
-+output("running pass 2: subject matches, issuer not trusted\n")
-+realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False,
-+                create_host=False)
-+proxy = start_proxy(realm, proxysubjectpem)
-+realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Fail: untrusted issuer, host name matches subjectAltName.
-+output("running pass 3: subjectAltName matches, issuer not trusted\n")
-+realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False,
-+                create_host=False)
-+proxy = start_proxy(realm, proxysanpem)
-+realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Fail: untrusted issuer, certificate signature is bad.
-+output("running pass 4: subject matches, issuer not trusted\n")
-+realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False,
-+                create_host=False)
-+proxy = start_proxy(realm, proxybadpem)
-+realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Fail: trusted issuer but hostname doesn't match.
-+output("running pass 5: issuer trusted but hostname doesn't match\n")
-+realm = K5Realm(krb5_conf=anchored_name_krb5_conf, get_creds=False,
-+                create_host=False)
-+proxy = start_proxy(realm, proxywrongpem)
-+realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Succeed: trusted issuer and host name matches subject.
-+output("running pass 6: issuer trusted, subject matches\n")
-+realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True,
-+                get_creds=False)
-+proxy = start_proxy(realm, proxysubjectpem)
-+realm.kinit(realm.user_princ, password=password('user'))
-+realm.run([kvno, realm.host_princ])
-+realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Succeed: trusted issuer and host name matches subjectAltName.
-+output("running pass 7: issuer trusted, subjectAltName matches\n")
-+realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True,
-+                get_creds=False)
-+proxy = start_proxy(realm, proxysanpem)
-+realm.kinit(realm.user_princ, password=password('user'))
-+realm.run([kvno, realm.host_princ])
-+realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Fail: certificate signature is bad.
-+output("running pass 8: issuer trusted and subjectAltName matches, sig bad\n")
-+realm = K5Realm(krb5_conf=anchored_name_krb5_conf,
-+                get_creds=False,
-+		                create_host=False)
-+proxy = start_proxy(realm, proxybadpem)
-+realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Fail: trusted issuer but IP doesn't match.
-+output("running pass 9: issuer trusted but no name matches IP\n")
-+realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False,
-+                create_host=False)
-+proxy = start_proxy(realm, proxywrongpem)
-+realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Fail: trusted issuer, but subject does not match.
-+output("running pass 10: issuer trusted, but subject does not match IP\n")
-+realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False,
-+                create_host=False)
-+proxy = start_proxy(realm, proxysubjectpem)
-+realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Succeed: trusted issuer and host name matches subjectAltName.
-+output("running pass 11: issuer trusted, subjectAltName matches IP\n")
-+realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, start_kadmind=True,
-+                get_creds=False)
-+proxy = start_proxy(realm, proxysanpem)
-+realm.kinit(realm.user_princ, password=password('user'))
-+realm.run([kvno, realm.host_princ])
-+realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Fail: certificate signature is bad.
-+output("running pass 12: issuer trusted, names don't match, signature bad\n")
-+realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False,
-+                create_host=False)
-+proxy = start_proxy(realm, proxybadpem)
-+realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Succeed: trusted issuer and host name matches subject, using kadmin
-+# configuration to find kpasswdd.
-+output("running pass 13: issuer trusted, subject matches\n")
-+realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True,
-+                get_creds=False, create_host=False)
-+proxy = start_proxy(realm, proxysubjectpem)
-+realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Succeed: trusted issuer and host name matches subjectAltName, using
-+# kadmin configuration to find kpasswdd.
-+output("running pass 14: issuer trusted, subjectAltName matches\n")
-+realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True,
-+                get_creds=False, create_host=False)
-+proxy = start_proxy(realm, proxysanpem)
-+realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+# Succeed: trusted issuer and host name matches subjectAltName (give or take
-+# case).
-+output("running pass 15: issuer trusted, subjectAltName case-insensitive\n")
-+realm = K5Realm(krb5_conf=anchored_upcasename_krb5_conf, start_kadmind=True,
-+                get_creds=False, create_host=False)
-+proxy = start_proxy(realm, proxysanpem)
-+realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
-+stop_daemon(proxy)
-+realm.stop()
-+
-+success('MS-KKDCP proxy')
--- 
-2.1.0
-
diff --git a/SOURCES/krb5-1.10-kprop-mktemp.patch b/SOURCES/krb5-1.10-kprop-mktemp.patch
deleted file mode 100644
index 62178df..0000000
--- a/SOURCES/krb5-1.10-kprop-mktemp.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-Use an in-memory ccache to silence a compiler warning, for RT#6414.
-
---- krb5/src/slave/kprop.c
-+++ krb5/src/slave/kprop.c
-@@ -202,9 +202,8 @@ void PRS(argc, argv)
- void get_tickets(context)
-     krb5_context context;
- {
--    char   buf[BUFSIZ], *def_realm;
-+    char buf[] = "MEMORY:_kproptkt", *def_realm;
-     krb5_error_code retval;
--    static char tkstring[] = "/tmp/kproptktXXXXXX";
-     krb5_keytab keytab = NULL;
- 
-     /*
-@@ -229,11 +228,8 @@ void get_tickets(context)
- #endif
- 
-     /*
--     * Initialize cache file which we're going to be using
-+     * Initialize an in-memory cache for temporary use
-      */
--    (void) mktemp(tkstring);
--    snprintf(buf, sizeof(buf), "FILE:%s", tkstring);
--
-     retval = krb5_cc_resolve(context, buf, &ccache);
-     if (retval) {
-         com_err(progname, retval, _("while opening credential cache %s"), buf);
diff --git a/SOURCES/krb5-1.11-dirsrv-accountlock.patch b/SOURCES/krb5-1.11-dirsrv-accountlock.patch
deleted file mode 100644
index 12d201d..0000000
--- a/SOURCES/krb5-1.11-dirsrv-accountlock.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-Treat 'nsAccountLock: true' the same as 'loginDisabled: true'.  Updated from
-original version filed as RT#5891.
-
-diff -up krb5-1.8/src/aclocal.m4.dirsrv-accountlock krb5-1.8/src/aclocal.m4
---- krb5-1.8/src/aclocal.m4.dirsrv-accountlock	2010-03-05 11:03:09.000000000 -0500
-+++ krb5-1.8/src/aclocal.m4	2010-03-05 11:03:10.000000000 -0500
-@@ -1656,6 +1656,15 @@ if test $with_ldap = yes; then
-   AC_MSG_NOTICE(enabling OpenLDAP database backend module support)
-   OPENLDAP_PLUGIN=yes
- fi
-+AC_ARG_WITH([dirsrv-account-locking],
-+[  --with-dirsrv-account-locking       compile 389/Red Hat/Fedora/Netscape Directory Server database backend module],
-+[case "$withval" in
-+    yes | no) ;;
-+    *)  AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;;
-+esac], with_dirsrv_account_locking=no)
-+if test $with_dirsrv_account_locking = yes; then
-+    AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.])
-+fi
- ])dnl
- dnl
- dnl If libkeyutils exists (on Linux) include it and use keyring ccache
-diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
---- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock	2009-11-24 18:52:25.000000000 -0500
-+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c	2010-03-05 11:03:10.000000000 -0500
-@@ -2101,6 +2101,22 @@ populate_krb5_db_entry(krb5_context cont
-         goto cleanup;
-     if ((st=krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data)) != 0)
-         goto cleanup;
-+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING
-+    {
-+        krb5_timestamp              expiretime=0;
-+        char                        *is_login_disabled=NULL;
-+
-+        /* LOGIN DISABLED */
-+        if ((st=krb5_ldap_get_string(ld, ent, "nsAccountLock", &is_login_disabled,
-+                    &attr_present)) != 0)
-+            goto cleanup;
-+        if (attr_present == TRUE) {
-+            if (strcasecmp(is_login_disabled, "TRUE")== 0)
-+                entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
-+            free (is_login_disabled);
-+        }
-+    }
-+#endif
- 
-     if ((st=krb5_read_tkt_policy (context, ldap_context, entry, tktpolname)) !=0)
-         goto cleanup;
-diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
---- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock	2009-11-24 18:52:25.000000000 -0500
-+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c	2010-03-05 11:03:10.000000000 -0500
-@@ -59,6 +59,9 @@ char     *principal_attributes[] = { "kr
-                                      "krbLastFailedAuth",
-                                      "krbLoginFailedCount",
-                                      "krbLastSuccessfulAuth",
-+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING
-+                                     "nsAccountLock",
-+#endif
-                                      "krbLastPwdChange",
-                                      "krbLastAdminUnlock",
-                                      "krbExtraData",
diff --git a/SOURCES/krb5-1.12-kpasswd-skip-address-check.patch b/SOURCES/krb5-1.12-kpasswd-skip-address-check.patch
deleted file mode 100644
index 9873b93..0000000
--- a/SOURCES/krb5-1.12-kpasswd-skip-address-check.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-commit b562400826409deceb0d52ffbe6570670ee9db55
-Author: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date:   Wed Oct 9 15:03:16 2013 -0400
-
-    Don't check kpasswd reply address
-    
-    Don't check the address of the kpasswd server when parsing the reply
-    we received from it.  If the server's address was modified by a proxy
-    or other network element, the user will be incorrectly warned that the
-    password change failed when it succeeded.  The check is unnecessary as
-    the kpasswd protocol is not subject to a reflection attack.
-    
-    [ghudson@mit.edu: edit commit message]
-    
-    ticket: 7886 (new)
-
-diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
-index 462910f..4d8abd9 100644
---- a/src/lib/krb5/os/changepw.c
-+++ b/src/lib/krb5/os/changepw.c
-@@ -214,7 +214,6 @@ change_set_password(krb5_context context,
-                     krb5_data *result_string)
- {
-     krb5_data                   chpw_rep;
--    krb5_address                remote_kaddr;
-     krb5_boolean                use_tcp = 0;
-     GETSOCKNAME_ARG3_TYPE       addrlen;
-     krb5_error_code             code = 0;
-@@ -272,26 +271,6 @@ change_set_password(krb5_context context,
-             break;
-         }
- 
--        if (remote_addr.ss_family == AF_INET) {
--            remote_kaddr.addrtype = ADDRTYPE_INET;
--            remote_kaddr.length = sizeof(ss2sin(&remote_addr)->sin_addr);
--            remote_kaddr.contents =
--                (krb5_octet *) &ss2sin(&remote_addr)->sin_addr;
--        } else if (remote_addr.ss_family == AF_INET6) {
--            remote_kaddr.addrtype = ADDRTYPE_INET6;
--            remote_kaddr.length = sizeof(ss2sin6(&remote_addr)->sin6_addr);
--            remote_kaddr.contents =
--                (krb5_octet *) &ss2sin6(&remote_addr)->sin6_addr;
--        } else {
--            break;
--        }
--
--        if ((code = krb5_auth_con_setaddrs(callback_ctx.context,
--                                           callback_ctx.auth_context,
--                                           NULL,
--                                           &remote_kaddr)))
--            break;
--
-         code = krb5int_rd_chpw_rep(callback_ctx.context,
-                                    callback_ctx.auth_context,
-                                    &chpw_rep, &local_result_code,
diff --git a/SOURCES/krb5-1.12-ksu-no-ccache.patch b/SOURCES/krb5-1.12-ksu-no-ccache.patch
deleted file mode 100644
index 67346b4..0000000
--- a/SOURCES/krb5-1.12-ksu-no-ccache.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-commit 26e202d26b47d62fbff4f153fc7f03cc300cc4ab
-Author: Nalin Dahyabhai <nalin@redhat.com>
-Date:   Mon Sep 8 13:34:05 2014 -0400
-
-    Fix ksu crash in cases where it obtains the TGT
-    
-    In order to allow ksu to use any locally-present service key for
-    verifying creds, the previous change to ksu switched from using a
-    retrieved or obtained TGT to fetch creds for the local "host" service,
-    and then passing those creds to krb5_verify_init_creds(), to passing the
-    retrieved TGT directly to krb5_verify_init_creds().  It did not take
-    care to retrieve the TGT from the temporary ccache if it had obtained
-    them, and in those cases it would attempt to verify NULL creds.
-
-diff --git a/src/clients/ksu/krb_auth_su.c b/src/clients/ksu/krb_auth_su.c
-index dd0a127..bd37c9c 100644
---- a/src/clients/ksu/krb_auth_su.c
-+++ b/src/clients/ksu/krb_auth_su.c
-@@ -122,6 +122,17 @@ krb5_boolean krb5_auth_check(context, client_pname, hostname, options,
-             return FALSE;
-         }
- 
-+        retval = krb5_cc_retrieve_cred(context, cc,
-+                                       KRB5_TC_MATCH_SRV_NAMEONLY |
-+                                       KRB5_TC_SUPPORTED_KTYPES,
-+                                       &tgtq, &tgt);
-+
-+        if (! retval) retval = krb5_check_exp(context, tgt.times);
-+
-+        if (retval){
-+            com_err(prog_name, retval, _("while getting initial credentials"));
-+            return (FALSE) ;
-+        }
- #else
-         plain_dump_principal (context, client);
-         fprintf(stderr,
diff --git a/SOURCES/krb5-1.12-ksu-untyped-default-ccache-name.patch b/SOURCES/krb5-1.12-ksu-untyped-default-ccache-name.patch
deleted file mode 100644
index 4e1f835..0000000
--- a/SOURCES/krb5-1.12-ksu-untyped-default-ccache-name.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-commit bda574576a5a2d0613fecf12d820e0adcbedf95c
-Author: Nalin Dahyabhai <nalin@redhat.com>
-Date:   Mon Sep 8 13:15:40 2014 -0400
-
-    In ksu, handle typeless default_ccache_name values
-    
-    When a configured or compiled-in default ccache name doesn't contain a
-    cache type and ':' as a prefix, add one to the writeable value that we
-    construct when we go to look it up.  This lets the rest of the
-    application always assume that it'll be there.
-    
-    [ghudson@mit.edu: minor style changes]
-    
-    ticket: 8007 (new)
-    target_version: 1.13
-    tags: pullup
-
-diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
-index 47fa820..622c36a 100644
---- a/src/clients/ksu/main.c
-+++ b/src/clients/ksu/main.c
-@@ -819,7 +819,7 @@ get_configured_defccname(krb5_context context, char **target_out)
- {
-     krb5_error_code retval;
-     const char *defname;
--    char *target;
-+    char *target = NULL;
- 
-     *target_out = NULL;
- 
-@@ -838,7 +838,14 @@ get_configured_defccname(krb5_context context, char **target_out)
-     }
- 
-     defname = krb5_cc_default_name(context);
--    target = (defname == NULL) ? NULL : strdup(defname);
-+    if (defname != NULL) {
-+        if (strchr(defname, ':') != NULL) {
-+            target = strdup(defname);
-+        } else {
-+            if (asprintf(&target, "FILE:%s", defname) < 0)
-+                target = NULL;
-+        }
-+    }
-     if (target == NULL) {
-         com_err(prog_name, ENOMEM, _("while determining target ccache name"));
-         return ENOMEM;
diff --git a/SOURCES/krb5-1.12-nodelete-plugins.patch b/SOURCES/krb5-1.12-nodelete-plugins.patch
deleted file mode 100644
index 88fb8c6..0000000
--- a/SOURCES/krb5-1.12-nodelete-plugins.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-commit 0f46175d632ae03ab7d4cfba5e62534d31e128e0
-Author: Greg Hudson <ghudson@mit.edu>
-Date:   Wed Jun 25 11:41:54 2014 -0400
-
-    Load plugins with RTLD_NODELETE if possible
-    
-    On platforms which support RTLD_NODELETE, use it to load plugin
-    modules.  While using this flag makes plugins stay in the process map
-    after libkrb5/libgssapi_krb5 are unloaded, it solves several problems:
-    
-    1. It prevents plugin modules which link against OpenSSL (PKINIT and
-    k5tls) from repeatedly initializing instances of libssl or libcrypto,
-    leaking heap memory each time.  This is only an issue because we
-    cannot safely uninitialize OpenSSL.
-    
-    2. It prevents finalization ordering issues from causing a process
-    crash when unloading libgssapi_krb5 (issue #7135).
-    
-    3. It makes memory leak tracing with valgrind easier.
-    
-    ticket: 7947 (new)
-
-diff --git a/src/util/support/plugins.c b/src/util/support/plugins.c
-index a04dfc3..ca4b128 100644
---- a/src/util/support/plugins.c
-+++ b/src/util/support/plugins.c
-@@ -45,6 +45,20 @@
- 
- #include "k5-platform.h"
- 
-+#if USE_DLOPEN
-+#ifdef RTLD_GROUP
-+#define GROUP RTLD_GROUP
-+#else
-+#define GROUP 0
-+#endif
-+#ifdef RTLD_NODELETE
-+#define NODELETE RTLD_NODELETE
-+#else
-+#define NODELETE 0
-+#endif
-+#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL | GROUP | NODELETE)
-+#endif
-+
- #if USE_DLOPEN && USE_CFBUNDLE
- #include <CoreFoundation/CoreFoundation.h>
- 
-@@ -257,11 +271,6 @@ krb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct
-         }
- #endif /* USE_CFBUNDLE */
- 
--#ifdef RTLD_GROUP
--#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL | RTLD_GROUP)
--#else
--#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL)
--#endif
-         if (!err) {
-             handle = dlopen(filepath, PLUGIN_DLOPEN_FLAGS);
-             if (handle == NULL) {
diff --git a/SOURCES/krb5-1.12-pwdch-fast.patch b/SOURCES/krb5-1.12-pwdch-fast.patch
deleted file mode 100644
index 3b7d4bb..0000000
--- a/SOURCES/krb5-1.12-pwdch-fast.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-From 230858394d2dded001ef3d2029daa6c468aca097 Mon Sep 17 00:00:00 2001
-From: Greg Hudson <ghudson@mit.edu>
-Date: Fri, 28 Feb 2014 14:49:35 -0500
-Subject: [PATCH] Use preauth options when changing password
-
-If we try to change the password in rb5_get_init_creds_password, we
-must use all application-specified gic options which affect
-preauthentication when getting the kadmin/changepw ticket.  Create a
-helper function make_chpw_options which copies the application's
-options, unsets the options we don't want, and sets options
-appropriate for a temporary ticket.
-
-ticket: 7868
-
-npmccallum:
-  * include tests from 06817686bfdef99523f300464bcbb0c8b037a27d
----
- src/lib/krb5/krb/gic_pwd.c | 63 +++++++++++++++++++++++++++++++++++++---------
- src/tests/Makefile.in      |  1 +
- src/tests/t_changepw.py    | 37 +++++++++++++++++++++++++++
- 3 files changed, 89 insertions(+), 12 deletions(-)
- create mode 100644 src/tests/t_changepw.py
-
-diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
-index a97823f6b51b7393755e82f36612c30b64096754..6aec7c3a71f99d2194b09374b296327174e6d4b8 100644
---- a/src/lib/krb5/krb/gic_pwd.c
-+++ b/src/lib/krb5/krb/gic_pwd.c
-@@ -242,6 +242,54 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
-     (*prompter)(context, data, 0, banner, 0, 0);
- }
- 
-+/*
-+ * Create a temporary options structure for getting a kadmin/changepw ticket,
-+ * based on the appplication-specified options.  Propagate all application
-+ * options which affect preauthentication, but not options which affect the
-+ * resulting ticket or how it is stored.  Set lifetime and flags appropriate
-+ * for a ticket which we will use immediately and then discard.
-+ *
-+ * storage1 and storage2 will be used to hold the temporary options.  The
-+ * caller must not free the result, as it will contain aliases into the
-+ * application options.
-+ */
-+static krb5_get_init_creds_opt *
-+make_chpw_options(krb5_get_init_creds_opt *in, krb5_gic_opt_ext *storage1,
-+                  gic_opt_private *storage2)
-+{
-+    krb5_gic_opt_ext *in_ext;
-+    krb5_get_init_creds_opt *opt;
-+
-+    /* Copy the application's options to storage. */
-+    if (in == NULL) {
-+        storage1->flags = 0;
-+    } else if (gic_opt_is_extended(in)) {
-+        in_ext = (krb5_gic_opt_ext *)in;
-+        *storage1 = *in_ext;
-+        *storage2 = *in_ext->opt_private;
-+        storage1->opt_private = storage2;
-+    } else {
-+        *(krb5_get_init_creds_opt *)storage1 = *in;
-+    }
-+
-+    /* Get a non-forwardable, non-proxiable, short-lifetime ticket. */
-+    opt = (krb5_get_init_creds_opt *)storage1;
-+    krb5_get_init_creds_opt_set_tkt_life(opt, 5 * 60);
-+    krb5_get_init_creds_opt_set_renew_life(opt, 0);
-+    krb5_get_init_creds_opt_set_forwardable(opt, 0);
-+    krb5_get_init_creds_opt_set_proxiable(opt, 0);
-+
-+    /* Unset options which should only apply to the actual ticket. */
-+    opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST;
-+    opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ANONYMOUS;
-+
-+    /* The output ccache should only be used for the actual ticket. */
-+    if (gic_opt_is_extended(opt))
-+        storage2->out_ccache = NULL;
-+
-+    return opt;
-+}
-+
- krb5_error_code KRB5_CALLCONV
- krb5_get_init_creds_password(krb5_context context,
-                              krb5_creds *creds,
-@@ -259,6 +307,8 @@ krb5_get_init_creds_password(krb5_context context,
-     int tries;
-     krb5_creds chpw_creds;
-     krb5_get_init_creds_opt *chpw_opts = NULL;
-+    krb5_gic_opt_ext storage1;
-+    gic_opt_private storage2;
-     struct gak_password gakpw;
-     krb5_data pw0, pw1;
-     char banner[1024], pw0array[1024], pw1array[1024];
-@@ -345,16 +395,7 @@ krb5_get_init_creds_password(krb5_context context,
-     /* ok, we have an expired password.  Give the user a few chances
-        to change it */
- 
--    /* use a minimal set of options */
--
--    ret = krb5_get_init_creds_opt_alloc(context, &chpw_opts);
--    if (ret)
--        goto cleanup;
--    krb5_get_init_creds_opt_set_tkt_life(chpw_opts, 5*60);
--    krb5_get_init_creds_opt_set_renew_life(chpw_opts, 0);
--    krb5_get_init_creds_opt_set_forwardable(chpw_opts, 0);
--    krb5_get_init_creds_opt_set_proxiable(chpw_opts, 0);
--
-+    chpw_opts = make_chpw_options(options, &storage1, &storage2);
-     ret = k5_get_init_creds(context, &chpw_creds, client, prompter, data,
-                             start_time, "kadmin/changepw", chpw_opts,
-                             krb5_get_as_key_password, &gakpw, &use_master,
-@@ -471,8 +512,6 @@ cleanup:
-         warn_pw_expiry(context, options, prompter, data, in_tkt_service,
-                        as_reply);
- 
--    if (chpw_opts)
--        krb5_get_init_creds_opt_free(context, chpw_opts);
-     zapfree(gakpw.storage.data, gakpw.storage.length);
-     memset(pw0array, 0, sizeof(pw0array));
-     memset(pw1array, 0, sizeof(pw1array));
-diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
-index 62523895d53da24844141a6ada6cab23e77dd9e6..55f1d6419f8d924a6f9a2971d36f1eac6d293d32 100644
---- a/src/tests/Makefile.in
-+++ b/src/tests/Makefile.in
-@@ -94,6 +94,7 @@ check-pytests:: t_init_creds t_localauth
- 	$(RUNPYTEST) $(srcdir)/t_iprop.py $(PYTESTFLAGS)
- 	$(RUNPYTEST) $(srcdir)/t_kprop.py $(PYTESTFLAGS)
- 	$(RUNPYTEST) $(srcdir)/t_policy.py $(PYTESTFLAGS)
-+	$(RUNPYTEST) $(srcdir)/t_changepw.py $(PYTESTFLAGS)
- 	$(RUNPYTEST) $(srcdir)/t_pkinit.py $(PYTESTFLAGS)
- 	$(RUNPYTEST) $(srcdir)/t_otp.py $(PYTESTFLAGS)
- 	$(RUNPYTEST) $(srcdir)/t_localauth.py $(PYTESTFLAGS)
-diff --git a/src/tests/t_changepw.py b/src/tests/t_changepw.py
-new file mode 100644
-index 0000000000000000000000000000000000000000..0b9832668e618b3db8d88cf388ec918898bb4df3
---- /dev/null
-+++ b/src/tests/t_changepw.py
-@@ -0,0 +1,37 @@
-+#!/usr/bin/python
-+from k5test import *
-+
-+# This file is intended to cover any password-changing mechanism.  For
-+# now it only contains a regression test for #7868.
-+
-+realm = K5Realm(create_host=False, get_creds=False, start_kadmind=True)
-+
-+# Mark a principal as expired and change its password through kinit.
-+realm.run_kadminl('modprinc -pwexpire "1 day ago" user')
-+pwinput = password('user') + '\nabcd\nabcd\n'
-+realm.run([kinit, realm.user_princ], input=pwinput)
-+
-+# Do the same thing with FAST, with tracing turned on.
-+realm.run_kadminl('modprinc -pwexpire "1 day ago" user')
-+pwinput = 'abcd\nefgh\nefgh\n'
-+tracefile = os.path.join(realm.testdir, 'trace')
-+realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-T', realm.ccache,
-+           realm.user_princ], input=pwinput)
-+
-+# Read the trace and check that FAST was used when getting the
-+# kadmin/changepw ticket.
-+f = open(tracefile, 'r')
-+trace = f.read()
-+f.close()
-+getting_changepw = fast_used_for_changepw = False
-+for line in trace.splitlines():
-+    if 'Getting initial credentials for user@' in line:
-+        getting_changepw_ticket = False
-+    if 'Setting initial creds service to kadmin/changepw' in line:
-+        getting_changepw_ticket = True
-+    if getting_changepw_ticket and 'Using FAST' in line:
-+        fast_used_for_changepw = True
-+if not fast_used_for_changepw:
-+    fail('FAST was not used to get kadmin/changepw ticket')
-+
-+success('Password change tests')
--- 
-1.8.5.3
-
diff --git a/SOURCES/krb5-1.12-selinux-label.patch b/SOURCES/krb5-1.12-selinux-label.patch
deleted file mode 100644
index 395f5f7..0000000
--- a/SOURCES/krb5-1.12-selinux-label.patch
+++ /dev/null
@@ -1,979 +0,0 @@
-SELinux bases access to files on the domain of the requesting process,
-the operation being performed, and the context applied to the file.
-
-In many cases, applications needn't be SELinux aware to work properly,
-because SELinux can apply a default label to a file based on the label
-of the directory in which it's created.
-
-In the case of files such as /etc/krb5.keytab, however, this isn't
-sufficient, as /etc/krb5.keytab will almost always need to be given a
-label which differs from that of /etc/issue or /etc/resolv.conf.  The
-the kdb stash file needs a different label than the database for which
-it's holding a master key, even though both typically live in the same
-directory.
-
-To give the file the correct label, we can either force a "restorecon"
-call to fix a file's label after it's created, or create the file with
-the right label, as we attempt to do here.  We lean on THREEPARAMOPEN
-and define a similar macro named WRITABLEFOPEN with which we replace
-several uses of fopen().
-
-The file creation context that we're manipulating here is a process-wide
-attribute.  While for the most part, applications which need to label
-files when they're created have tended to be single-threaded, there's
-not much we can do to avoid interfering with an application that
-manipulates the creation context directly.  Right now we're mediating
-access using a library-local mutex, but that can only work for consumers
-that are part of this package -- an unsuspecting application will still
-stomp all over us.
-
-The selabel APIs for looking up the context should be thread-safe (per
-Red Hat #273081), so switching to using them instead of matchpathcon(),
-which we used earlier, is some improvement.
-
---- krb5/src/aclocal.m4
-+++ krb5/src/aclocal.m4
-@@ -103,6 +103,7 @@ AC_SUBST_FILE(libnodeps_frag)
- dnl
- KRB5_AC_PRAGMA_WEAK_REF
- WITH_LDAP
-+KRB5_WITH_SELINUX
- KRB5_LIB_PARAMS
- KRB5_AC_INITFINI
- KRB5_AC_ENABLE_THREADS
-@@ -1791,3 +1792,51 @@ AC_SUBST(manlocalstatedir)
- AC_SUBST(PAM_MAN)
- AC_SUBST(NON_PAM_MAN)
- ])dnl
-+dnl
-+dnl Use libselinux to set file contexts on newly-created files.
-+dnl 
-+AC_DEFUN(KRB5_WITH_SELINUX,[
-+AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])],
-+           withselinux="$withval",withselinux=auto)
-+old_LIBS="$LIBS"
-+if test "$withselinux" != no ; then
-+       AC_MSG_RESULT([checking for libselinux...])
-+       SELINUX_LIBS=
-+       AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h)
-+       if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then
-+               if test "$withselinux" = auto ; then
-+                       AC_MSG_RESULT([Unable to locate selinux/selinux.h.])
-+                       withselinux=no
-+               else
-+                       AC_MSG_ERROR([Unable to locate selinux/selinux.h.])
-+               fi
-+       fi
-+
-+       LIBS=
-+       unset ac_cv_func_setfscreatecon
-+       AC_CHECK_FUNCS(setfscreatecon selabel_open)
-+       if test "x$ac_cv_func_setfscreatecon" = xno ; then
-+               AC_CHECK_LIB(selinux,setfscreatecon)
-+               unset ac_cv_func_setfscreatecon
-+               AC_CHECK_FUNCS(setfscreatecon selabel_open)
-+               if test "x$ac_cv_func_setfscreatecon" = xyes ; then
-+                       SELINUX_LIBS="$LIBS"
-+               else
-+                       if test "$withselinux" = auto ; then
-+                               AC_MSG_RESULT([Unable to locate libselinux.])
-+                               withselinux=no
-+                       else
-+                               AC_MSG_ERROR([Unable to locate libselinux.])
-+                       fi
-+               fi
-+       fi
-+       if test "$withselinux" != no ; then
-+               AC_MSG_NOTICE([building with SELinux labeling support])
-+               AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.])
-+               SELINUX_LIBS="$LIBS"
-+		EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon"
-+       fi
-+fi
-+LIBS="$old_LIBS"
-+AC_SUBST(SELINUX_LIBS)
-+])dnl
---- krb5/src/config/pre.in
-+++ krb5/src/config/pre.in
-@@ -180,6 +180,7 @@ LD_UNRESOLVED_PREFIX = @LD_UNRESOLVED_PREFIX@
- KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include
- LDFLAGS = @LDFLAGS@
- LIBS = @LIBS@
-+SELINUX_LIBS=@SELINUX_LIBS@
- 
- INSTALL=@INSTALL@
- INSTALL_STRIP=
-@@ -379,7 +380,7 @@ SUPPORT_LIB			= -l$(SUPPORT_LIBNAME)
- # HESIOD_LIBS is -lhesiod...
- HESIOD_LIBS	= @HESIOD_LIBS@
- 
--KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB)
-+KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
- KDB5_LIBS	= $(KDB5_LIB) $(GSSRPC_LIBS)
- GSS_LIBS	= $(GSS_KRB5_LIB)
- # needs fixing if ever used on Mac OS X!
---- krb5/src/configure.in
-+++ krb5/src/configure.in
-@@ -1053,6 +1053,8 @@ fi
- 
- KRB5_WITH_PAM
- 
-+KRB5_WITH_SELINUX
-+
- # Make localedir work in autoconf 2.5x.
- if test "${localedir+set}" != set; then
-     localedir='$(datadir)/locale'
---- krb5/src/include/k5-int.h
-+++ krb5/src/include/k5-int.h
-@@ -133,6 +133,7 @@ typedef unsigned char   u_char;
- typedef UINT64_TYPE krb5_ui_8;
- typedef INT64_TYPE krb5_int64;
- 
-+#include "k5-label.h"
- 
- #define KRB5_KDB_MAX_LIFE       (60*60*24) /* one day */
- #define KRB5_KDB_MAX_RLIFE      (60*60*24*7) /* one week */
---- krb5/src/include/k5-label.h
-+++ krb5/src/include/k5-label.h
-@@ -0,0 +1,32 @@
-+#ifndef _KRB5_LABEL_H
-+#define _KRB5_LABEL_H
-+
-+#ifdef THREEPARAMOPEN
-+#undef THREEPARAMOPEN
-+#endif
-+#ifdef WRITABLEFOPEN
-+#undef WRITABLEFOPEN
-+#endif
-+
-+/* Wrapper functions which help us create files and directories with the right
-+ * context labels. */
-+#ifdef USE_SELINUX
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <stdio.h>
-+#include <unistd.h>
-+FILE *krb5int_labeled_fopen(const char *path, const char *mode);
-+int krb5int_labeled_creat(const char *path, mode_t mode);
-+int krb5int_labeled_open(const char *path, int flags, ...);
-+int krb5int_labeled_mkdir(const char *path, mode_t mode);
-+int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device);
-+#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z)
-+#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y)
-+void *krb5int_push_fscreatecon_for(const char *pathname);
-+void krb5int_pop_fscreatecon(void *previous);
-+#else
-+#define WRITABLEFOPEN(x,y) fopen(x,y)
-+#define THREEPARAMOPEN(x,y,z) open(x,y,z)
-+#endif
-+#endif
---- krb5/src/include/krb5/krb5.hin
-+++ krb5/src/include/krb5/krb5.hin
-@@ -87,6 +87,12 @@
- #define THREEPARAMOPEN(x,y,z) open(x,y,z)
- #endif
- 
-+#if KRB5_PRIVATE
-+#ifndef WRITABLEFOPEN
-+#define WRITABLEFOPEN(x,y) fopen(x,y)
-+#endif
-+#endif
-+
- #define KRB5_OLD_CRYPTO
- 
- #include <stdlib.h>
---- krb5/src/kadmin/dbutil/dump.c
-+++ krb5/src/kadmin/dbutil/dump.c
-@@ -376,12 +376,21 @@ create_ofile(char *ofile, char **tmpname
- {
-     int fd = -1;
-     FILE *f;
-+#ifdef USE_SELINUX
-+    void *selabel;
-+#endif
- 
-     *tmpname = NULL;
-     if (asprintf(tmpname, "%s-XXXXXX", ofile) < 0)
-         goto error;
- 
-+#ifdef USE_SELINUX
-+    selabel = krb5int_push_fscreatecon_for(ofile);
-+#endif
-     fd = mkstemp(*tmpname);
-+#ifdef USE_SELINUX
-+    krb5int_pop_fscreatecon(selabel);
-+#endif
-     if (fd == -1)
-         goto error;
- 
-@@ -514,7 +514,7 @@ prep_ok_file(krb5_context context, char
-         return 0;
-     }
- 
--    *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-+    *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-     if (*fd == -1) {
-         com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
-         exit_status++;
---- krb5/src/build-tools/krb5-config.in
-+++ krb5/src/build-tools/krb5-config.in
-@@ -38,6 +38,7 @@ RPATH_FLAG='@RPATH_FLAG@'
- DEFCCNAME='@DEFCCNAME@'
- DEFKTNAME='@DEFKTNAME@'
- DEFCKTNAME='@DEFCKTNAME@'
-+SELINUX_LIBS='@SELINUX_LIBS@'
- 
- LIBS='@LIBS@'
- GEN_LIB=@GEN_LIB@
-@@ -218,7 +219,7 @@
-     fi
- 
-     # If we ever support a flag to generate output suitable for static
--    # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB"
-+    # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB"
-     # here.
- 
-     echo $lib_flags
---- krb5/src/lib/kadm5/logger.c
-+++ krb5/src/lib/kadm5/logger.c
-@@ -425,7 +425,7 @@ krb5_klog_init(krb5_context kcontext, ch
-                      * Check for append/overwrite, then open the file.
-                      */
-                     if (cp[4] == ':' || cp[4] == '=') {
--                        f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w");
-+                        f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w");
-                         if (f) {
-                             set_cloexec_file(f);
-                             log_control.log_entries[i].lfu_filep = f;
-@@ -961,7 +961,7 @@ krb5_klog_reopen(krb5_context kcontext)
-              * In case the old logfile did not get moved out of the
-              * way, open for append to prevent squashing the old logs.
-              */
--            f = fopen(log_control.log_entries[lindex].lfu_fname, "a+");
-+            f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+");
-             if (f) {
-                 set_cloexec_file(f);
-                 log_control.log_entries[lindex].lfu_filep = f;
---- krb5/src/lib/krb5/keytab/kt_file.c
-+++ krb5/src/lib/krb5/keytab/kt_file.c
-@@ -1050,7 +1050,7 @@ krb5_ktfileint_open(krb5_context context
- 
-     KTCHECKLOCK(id);
-     errno = 0;
--    KTFILEP(id) = fopen(KTFILENAME(id),
-+    KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id),
-                         (mode == KRB5_LOCKMODE_EXCLUSIVE) ?
-                         fopen_mode_rbplus : fopen_mode_rb);
-     if (!KTFILEP(id)) {
-@@ -1058,7 +1058,7 @@ krb5_ktfileint_open(krb5_context context
-             /* try making it first time around */
-             k5_create_secure_file(context, KTFILENAME(id));
-             errno = 0;
--            KTFILEP(id) = fopen(KTFILENAME(id), fopen_mode_rbplus);
-+            KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), fopen_mode_rbplus);
-             if (!KTFILEP(id))
-                 goto report_errno;
-             writevno = 1;
---- krb5/src/plugins/kdb/db2/adb_openclose.c
-+++ krb5/src/plugins/kdb/db2/adb_openclose.c
-@@ -201,7 +201,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char 
-          * POSIX systems
-          */
-         lockp->lockinfo.filename = strdup(lockfilename);
--        if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) {
-+        if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) {
-             /*
-              * maybe someone took away write permission so we could only
-              * get shared locks?
---- krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c
-+++ krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c
-@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c	8.
- 
- #include "k5-platform.h"	/* mkstemp? */
- 
-+#include "k5-int.h"
- #include "db-int.h"
- #include "btree.h"
- 
-@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, 
- 			goto einval;
- 		}
- 
--		if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0)
-+		if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
- 			goto err;
- 
- 	} else {
---- krb5/src/plugins/kdb/db2/libdb2/hash/hash.c
-+++ krb5/src/plugins/kdb/db2/libdb2/hash/hash.c
-@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c	8.12 
- #include <assert.h>
- #endif
- 
-+#include "k5-int.h"
- #include "db-int.h"
- #include "hash.h"
- #include "page.h"
-@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info
- 		new_table = 1;
- 	}
- 	if (file) {
--		if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1)
-+		if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1)
- 			RETURN_ERROR(errno, error0);
- 		(void)fcntl(hashp->fp, F_SETFD, 1);
- 	}
---- krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
-+++ krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
-@@ -179,7 +179,7 @@ done:
- 
-     /* set password in the file */
-     old_mode = umask(0177);
--    pfile = fopen(file_name, "a+");
-+    pfile = WRITABLEFOPEN(file_name, "a+");
-     if (pfile == NULL) {
-         com_err(me, errno, _("Failed to open file %s: %s"), file_name,
-                 strerror (errno));
-@@ -220,6 +220,9 @@ done:
-          * Delete the existing entry and add the new entry
-          */
-         FILE *newfile;
-+#ifdef USE_SELINUX
-+        void *selabel;
-+#endif
- 
-         mode_t omask;
- 
-@@ -231,7 +234,13 @@ done:
-         }
- 
-         omask = umask(077);
-+#ifdef USE_SELINUX
-+        selabel = krb5int_push_fscreatecon_for(file_name);
-+#endif
-         newfile = fopen(tmp_file, "w");
-+#ifdef USE_SELINUX
-+        krb5int_pop_fscreatecon(selabel);
-+#endif
-         umask (omask);
-         if (newfile == NULL) {
-             com_err(me, errno, _("Error creating file %s"), tmp_file);
---- krb5/src/slave/kpropd.c
-+++ krb5/src/slave/kpropd.c
-@@ -437,6 +437,9 @@ void doit(fd)
-     krb5_enctype etype;
-     int database_fd;
-     char host[INET6_ADDRSTRLEN+1];
-+#ifdef USE_SELINUX
-+    void *selabel;
-+#endif
- 
-     signal_wrapper(SIGALRM, alarm_handler);
-     alarm(params.iprop_resync_timeout);
-@@ -515,9 +518,15 @@ void doit(fd)
-         free(name);
-         exit(1);
-     }
-+#ifdef USE_SELINUX
-+    selabel = krb5int_push_fscreatecon_for(file);
-+#endif
-     omask = umask(077);
-     lock_fd = open(temp_file_name, O_RDWR|O_CREAT, 0600);
-     (void) umask(omask);
-+#ifdef USE_SELINUX
-+    krb5int_pop_fscreatecon(selabel);
-+#endif
-     retval = krb5_lock_file(kpropd_context, lock_fd,
-                             KRB5_LOCKMODE_EXCLUSIVE|KRB5_LOCKMODE_DONTBLOCK);
-     if (retval) {
---- krb5/src/util/profile/prof_file.c
-+++ krb5/src/util/profile/prof_file.c
-@@ -30,6 +30,7 @@
- #endif
- 
- #include "k5-platform.h"
-+#include "k5-label.h"
- 
- struct global_shared_profile_data {
-     /* This is the head of the global list of shared trees */
-@@ -418,7 +419,7 @@ static errcode_t write_data_to_file(prf_
- 
-     errno = 0;
- 
--    f = fopen(new_file, "w");
-+    f = WRITABLEFOPEN(new_file, "w");
-     if (!f) {
-         retval = errno;
-         if (retval == 0)
---- krb5/src/util/support/Makefile.in
-+++ krb5/src/util/support/Makefile.in
-@@ -54,6 +54,7 @@ IPC_SYMS= \
- 
- STLIBOBJS= \
- 	threads.o \
-+	selinux.o \
- 	init-addrinfo.o \
- 	plugins.o \
- 	errors.o \
-@@ -108,7 +109,7 @@ SRCS=\
- 
- SHLIB_EXPDEPS =
- # Add -lm if dumping thread stats, for sqrt.
--SHLIB_EXPLIBS= $(LIBS) $(DL_LIB)
-+SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
- 
- DEPLIBS=
- 
---- krb5/src/util/support/selinux.c
-+++ krb5/src/util/support/selinux.c
-@@ -0,0 +1,381 @@
-+/*
-+ * Copyright 2007,2008,2009,2011,2012,2013 Red Hat, Inc.  All Rights Reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ *  Redistributions of source code must retain the above copyright notice, this
-+ *  list of conditions and the following disclaimer.
-+ *
-+ *  Redistributions in binary form must reproduce the above copyright notice,
-+ *  this list of conditions and the following disclaimer in the documentation
-+ *  and/or other materials provided with the distribution.
-+ *
-+ *  Neither the name of Red Hat, Inc. nor the names of its contributors may be
-+ *  used to endorse or promote products derived from this software without
-+ *  specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ * 
-+ * File-opening wrappers for creating correctly-labeled files.  So far, we can
-+ * assume that this is Linux-specific, so we make many simplifying assumptions.
-+ */
-+
-+#include "../../include/autoconf.h"
-+
-+#ifdef USE_SELINUX
-+
-+#include <k5-label.h>
-+#include <k5-platform.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <limits.h>
-+#include <pthread.h>
-+#include <stdarg.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <selinux/selinux.h>
-+#include <selinux/context.h>
-+#ifdef HAVE_SELINUX_LABEL_H
-+#include <selinux/label.h>
-+#endif
-+
-+/* #define DEBUG 1 */
-+
-+/* Mutex used to serialize use of the process-global file creation context. */
-+k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
-+
-+/* Make sure we finish initializing that mutex before attempting to use it. */
-+k5_once_t labeled_once = K5_ONCE_INIT;
-+static void
-+label_mutex_init(void)
-+{
-+	k5_mutex_finish_init(&labeled_mutex);
-+}
-+
-+#ifdef HAVE_SELINUX_LABEL_H
-+static struct selabel_handle *selabel_ctx;
-+static time_t selabel_last_changed;
-+
-+MAKE_FINI_FUNCTION(cleanup_fscreatecon);
-+
-+static void
-+cleanup_fscreatecon(void)
-+{
-+	if (selabel_ctx != NULL) {
-+		selabel_close(selabel_ctx);
-+		selabel_ctx = NULL;
-+	}
-+}
-+#endif
-+
-+static security_context_t
-+push_fscreatecon(const char *pathname, mode_t mode)
-+{
-+	security_context_t previous, configuredsc, currentsc, derivedsc;
-+	context_t current, derived;
-+	const char *fullpath, *currentuser;
-+
-+	previous = NULL;
-+	if (is_selinux_enabled()) {
-+		if (getfscreatecon(&previous) == 0) {
-+			char *genpath;
-+			genpath = NULL;
-+			if (pathname[0] != '/') {
-+				char *wd;
-+				size_t len;
-+				len = 0;
-+				wd = getcwd(NULL, len);
-+				if (wd == NULL) {
-+					if (previous != NULL) {
-+						freecon(previous);
-+					}
-+					return NULL;
-+				}
-+				len = strlen(wd) + 1 + strlen(pathname) + 1;
-+				genpath = malloc(len);
-+				if (genpath == NULL) {
-+					free(wd);
-+					if (previous != NULL) {
-+						freecon(previous);
-+					}
-+					return NULL;
-+				}
-+				sprintf(genpath, "%s/%s", wd, pathname);
-+				free(wd);
-+				fullpath = genpath;
-+			} else {
-+				fullpath = pathname;
-+			}
-+#ifdef DEBUG
-+			if (isatty(fileno(stderr))) {
-+				fprintf(stderr, "Looking up context for "
-+					"\"%s\"(%05o).\n", fullpath, mode);
-+			}
-+#endif
-+			configuredsc = NULL;
-+#ifdef HAVE_SELINUX_LABEL_H
-+			if ((selabel_ctx != NULL) ||
-+			    (selabel_last_changed == 0)) {
-+				const char *cpath;
-+				struct stat st;
-+				int i = -1;
-+				cpath = selinux_file_context_path();
-+				if ((cpath == NULL) ||
-+				    ((i = stat(cpath, &st)) != 0) ||
-+				    (st.st_mtime != selabel_last_changed)) {
-+					if (selabel_ctx != NULL) {
-+						selabel_close(selabel_ctx);
-+						selabel_ctx = NULL;
-+					}
-+					selabel_last_changed = i ?
-+							       time(NULL) :
-+							       st.st_mtime;
-+				}
-+			}
-+			if (selabel_ctx == NULL) {
-+				selabel_ctx = selabel_open(SELABEL_CTX_FILE,
-+							   NULL, 0);
-+			}
-+			if (selabel_ctx != NULL) {
-+				if (selabel_lookup(selabel_ctx, &configuredsc,
-+						   fullpath, mode) != 0) {
-+					free(genpath);
-+					if (previous != NULL) {
-+						freecon(previous);
-+					}
-+					return NULL;
-+				}
-+			}
-+#else
-+			if (matchpathcon(fullpath, mode, &configuredsc) != 0) {
-+				free(genpath);
-+				if (previous != NULL) {
-+					freecon(previous);
-+				}
-+				return NULL;
-+			}
-+#endif
-+			free(genpath);
-+			if (configuredsc == NULL) {
-+				if (previous != NULL) {
-+					freecon(previous);
-+				}
-+				return NULL;
-+			}
-+			currentsc = NULL;
-+			getcon(&currentsc);
-+			if (currentsc != NULL) {
-+				derived = context_new(configuredsc);
-+				if (derived != NULL) {
-+					current = context_new(currentsc);
-+					if (current != NULL) {
-+						currentuser = context_user_get(current);
-+						if (currentuser != NULL) {
-+							if (context_user_set(derived,
-+									     currentuser) == 0) {
-+								derivedsc = context_str(derived);
-+								if (derivedsc != NULL) {
-+									freecon(configuredsc);
-+									configuredsc = strdup(derivedsc);
-+								}
-+							}
-+						}
-+						context_free(current);
-+					}
-+					context_free(derived);
-+				}
-+				freecon(currentsc);
-+			}
-+#ifdef DEBUG
-+			if (isatty(fileno(stderr))) {
-+				fprintf(stderr, "Setting file creation context "
-+					"to \"%s\".\n", configuredsc);
-+			}
-+#endif
-+			if (setfscreatecon(configuredsc) != 0) {
-+				freecon(configuredsc);
-+				if (previous != NULL) {
-+					freecon(previous);
-+				}
-+				return NULL;
-+			}
-+			freecon(configuredsc);
-+#ifdef DEBUG
-+		} else {
-+			if (isatty(fileno(stderr))) {
-+				fprintf(stderr, "Unable to determine "
-+					"current context.\n");
-+			}
-+#endif
-+		}
-+	}
-+	return previous;
-+}
-+
-+static void
-+pop_fscreatecon(security_context_t previous)
-+{
-+	if (is_selinux_enabled()) {
-+#ifdef DEBUG
-+		if (isatty(fileno(stderr))) {
-+			if (previous != NULL) {
-+				fprintf(stderr, "Resetting file creation "
-+					"context to \"%s\".\n", previous);
-+			} else {
-+				fprintf(stderr, "Resetting file creation "
-+					"context to default.\n");
-+			}
-+		}
-+#endif
-+		setfscreatecon(previous);
-+		if (previous != NULL) {
-+			freecon(previous);
-+		}
-+	}
-+}
-+
-+void *
-+krb5int_push_fscreatecon_for(const char *pathname)
-+{
-+	struct stat st;
-+	void *retval;
-+	k5_once(&labeled_once, label_mutex_init);
-+	k5_mutex_lock(&labeled_mutex);
-+	if (stat(pathname, &st) != 0) {
-+		st.st_mode = S_IRUSR | S_IWUSR;
-+	}
-+	retval = push_fscreatecon(pathname, st.st_mode);
-+	return retval ? retval : (void *) -1;
-+}
-+
-+void
-+krb5int_pop_fscreatecon(void *con)
-+{
-+	if (con != NULL) {
-+		pop_fscreatecon((con == (void *) -1) ? NULL : con);
-+		k5_mutex_unlock(&labeled_mutex);
-+	}
-+}
-+
-+FILE *
-+krb5int_labeled_fopen(const char *path, const char *mode)
-+{
-+	FILE *fp;
-+	int errno_save;
-+	security_context_t ctx;
-+
-+	if ((strcmp(mode, "r") == 0) ||
-+	    (strcmp(mode, "rb") == 0)) {
-+		return fopen(path, mode);
-+	}
-+
-+	k5_once(&labeled_once, label_mutex_init);
-+	k5_mutex_lock(&labeled_mutex);
-+	ctx = push_fscreatecon(path, 0);
-+	fp = fopen(path, mode);
-+	errno_save = errno;
-+	pop_fscreatecon(ctx);
-+	k5_mutex_unlock(&labeled_mutex);
-+	errno = errno_save;
-+	return fp;
-+}
-+
-+int
-+krb5int_labeled_creat(const char *path, mode_t mode)
-+{
-+	int fd;
-+	int errno_save;
-+	security_context_t ctx;
-+
-+	k5_once(&labeled_once, label_mutex_init);
-+	k5_mutex_lock(&labeled_mutex);
-+	ctx = push_fscreatecon(path, 0);
-+	fd = creat(path, mode);
-+	errno_save = errno;
-+	pop_fscreatecon(ctx);
-+	k5_mutex_unlock(&labeled_mutex);
-+	errno = errno_save;
-+	return fd;
-+}
-+
-+int
-+krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev)
-+{
-+	int ret;
-+	int errno_save;
-+	security_context_t ctx;
-+
-+	k5_once(&labeled_once, label_mutex_init);
-+	k5_mutex_lock(&labeled_mutex);
-+	ctx = push_fscreatecon(path, mode);
-+	ret = mknod(path, mode, dev);
-+	errno_save = errno;
-+	pop_fscreatecon(ctx);
-+	k5_mutex_unlock(&labeled_mutex);
-+	errno = errno_save;
-+	return ret;
-+}
-+
-+int
-+krb5int_labeled_mkdir(const char *path, mode_t mode)
-+{
-+	int ret;
-+	int errno_save;
-+	security_context_t ctx;
-+
-+	k5_once(&labeled_once, label_mutex_init);
-+	k5_mutex_lock(&labeled_mutex);
-+	ctx = push_fscreatecon(path, S_IFDIR);
-+	ret = mkdir(path, mode);
-+	errno_save = errno;
-+	pop_fscreatecon(ctx);
-+	k5_mutex_unlock(&labeled_mutex);
-+	errno = errno_save;
-+	return ret;
-+}
-+
-+int
-+krb5int_labeled_open(const char *path, int flags, ...)
-+{
-+	int fd;
-+	int errno_save;
-+	security_context_t ctx;
-+	mode_t mode;
-+	va_list ap;
-+
-+	if ((flags & O_CREAT) == 0) {
-+		return open(path, flags);
-+	}
-+
-+	k5_once(&labeled_once, label_mutex_init);
-+	k5_mutex_lock(&labeled_mutex);
-+	ctx = push_fscreatecon(path, 0);
-+
-+	va_start(ap, flags);
-+	mode = va_arg(ap, mode_t);
-+	fd = open(path, flags, mode);
-+	va_end(ap);
-+
-+	errno_save = errno;
-+	pop_fscreatecon(ctx);
-+	k5_mutex_unlock(&labeled_mutex);
-+	errno = errno_save;
-+	return fd;
-+}
-+
-+#endif
---- krb5/src/lib/krb5/rcache/rc_dfl.c
-+++ krb5/src/lib/krb5/rcache/rc_dfl.c
-@@ -813,6 +813,9 @@ krb5_rc_dfl_expunge_locked(krb5_context 
-     krb5_error_code retval = 0;
-     krb5_rcache tmp;
-     krb5_deltat lifespan = t->lifespan;  /* save original lifespan */
-+#ifdef USE_SELINUX
-+    void *selabel;
-+#endif
- 
-     if (! t->recovering) {
-         name = t->name;
-@@ -834,7 +837,17 @@ krb5_rc_dfl_expunge_locked(krb5_context 
-     retval = krb5_rc_resolve(context, tmp, 0);
-     if (retval)
-         goto cleanup;
-+#ifdef USE_SELINUX
-+    if (t->d.fn != NULL)
-+        selabel = krb5int_push_fscreatecon_for(t->d.fn);
-+    else
-+        selabel = NULL;
-+#endif
-     retval = krb5_rc_initialize(context, tmp, lifespan);
-+#ifdef USE_SELINUX
-+    if (selabel != NULL)
-+        krb5int_pop_fscreatecon(selabel);
-+#endif
-     if (retval)
-         goto cleanup;
-     for (q = t->a; q; q = q->na) {
---- krb5/src/lib/krb5/ccache/cc_dir.c
-+++ krb5/src/lib/krb5/ccache/cc_dir.c
-@@ -185,10 +185,19 @@ write_primary_file(const char *primary_p
-     char *newpath = NULL;
-     FILE *fp = NULL;
-     int fd = -1, status;
-+#ifdef USE_SELINUX
-+    void *selabel;
-+#endif
- 
-     if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0)
-         return ENOMEM;
-+#ifdef USE_SELINUX
-+    selabel = krb5int_push_fscreatecon_for(primary_path);
-+#endif
-     fd = mkstemp(newpath);
-+#ifdef USE_SELINUX
-+    krb5int_pop_fscreatecon(selabel);
-+#endif
-     if (fd < 0)
-         goto cleanup;
- #ifdef HAVE_CHMOD
-@@ -223,10 +232,23 @@
- verify_dir(krb5_context context, const char *dirname)
- {
-     struct stat st;
-+    int status;
-+#ifdef USE_SELINUX
-+    void *selabel;
-+#endif
- 
-     if (stat(dirname, &st) < 0) {
--        if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0)
--            return 0;
-+        if (errno == ENOENT) {
-+#ifdef USE_SELINUX
-+            selabel = krb5int_push_fscreatecon_for(dirname);
-+#endif
-+            status = mkdir(dirname, S_IRWXU);
-+#ifdef USE_SELINUX
-+            krb5int_pop_fscreatecon(selabel);
-+#endif
-+            if (status == 0)
-+                return 0;
-+        }
-         krb5_set_error_message(context, KRB5_FCC_NOFILE,
-                                _("Credential cache directory %s does not "
-                                  "exist"), dirname);
---- krb5/src/lib/krb5/os/trace.c
-+++ krb5/src/lib/krb5/os/trace.c
-@@ -401,7 +401,7 @@ krb5_set_trace_filename(krb5_context con
-     fd = malloc(sizeof(*fd));
-     if (fd == NULL)
-         return ENOMEM;
--    *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600);
-+    *fd = THREEPARAMOPEN(filename, O_WRONLY|O_CREAT|O_APPEND, 0600);
-     if (*fd == -1) {
-         free(fd);
-         return errno;
---- krb5/src/plugins/kdb/db2/kdb_db2.c
-+++ krb5/src/plugins/kdb/db2/kdb_db2.c
-@@ -683,8 +683,8 @@
-     if (retval)
-         return retval;
- 
--    dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC,
--                           0600);
-+    dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name,
-+                                     O_CREAT | O_RDWR | O_TRUNC, 0600);
-     if (dbc->db_lf_file < 0) {
-         retval = errno;
-         goto cleanup;
---- krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c
-+++ krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c
-@@ -51,6 +51,7 @@
- #include <stdio.h>
- #include <unistd.h>
- 
-+#include "k5-int.h"
- #include "db-int.h"
- #include "recno.h"
- 
-@@ -68,7 +69,8 @@
- 	int rfd = -1, sverrno;
- 
- 	/* Open the user's file -- if this fails, we're done. */
--	if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0)
-+	if (fname != NULL &&
-+            (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
- 		return (NULL);
- 
- 	if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
---- krb5/src/kdc/main.c
-+++ krb5/src/kdc/main.c
-@@ -905,7 +905,7 @@ write_pid_file(const char *path)
-     FILE *file;
-     unsigned long pid;
- 
--    file = fopen(path, "w");
-+    file = WRITABLEFOPEN(path, "w");
-     if (file == NULL)
-         return errno;
-     pid = (unsigned long) getpid();
---- krb5/src/lib/kdb/kdb_log.c
-+++ krb5/src/lib/kdb/kdb_log.c
-@@ -566,7 +566,7 @@ ulog_map(krb5_context context, const cha
-         if (caller == FKPROPLOG)
-             return errno;
- 
--        ulogfd = open(logname, O_RDWR | O_CREAT, 0600);
-+        ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600);
-         if (ulogfd == -1)
-             return errno;
- 
---- krb5/src/util/gss-kernel-lib/Makefile.in
-+++ krb5/src/util/gss-kernel-lib/Makefile.in
-@@ -60,6 +60,7 @@ HEADERS= \
- 	gssapi_err_generic.h \
- 	k5-int.h \
- 	k5-int-pkinit.h \
-+	k5-label.h \
- 	k5-thread.h \
- 	k5-platform.h \
- 	k5-buf.h \
-@@ -166,10 +167,12 @@ gssapi_generic.h: $(GSS_GENERIC)/gssapi_
- 	$(CP) $(GSS_GENERIC)/gssapi_generic.h $@
- gssapi_err_generic.h: $(GSS_GENERIC_BUILD)/gssapi_err_generic.h
- 	$(CP) $(GSS_GENERIC_BUILD)/gssapi_err_generic.h $@
--k5-int.h: $(INCLUDE)/k5-int.h
-+k5-int.h: $(INCLUDE)/k5-int.h k5-label.h
- 	$(CP) $(INCLUDE)/k5-int.h $@
- k5-int-pkinit.h: $(INCLUDE)/k5-int-pkinit.h
- 	$(CP) $(INCLUDE)/k5-int-pkinit.h $@
-+k5-label.h: $(INCLUDE)/k5-label.h
-+	$(CP) $(INCLUDE)/k5-label.h $@
- k5-thread.h: $(INCLUDE)/k5-thread.h
- 	$(CP) $(INCLUDE)/k5-thread.h $@
- k5-platform.h: $(INCLUDE)/k5-platform.h
diff --git a/SOURCES/krb5-1.12-system-exts.patch b/SOURCES/krb5-1.12-system-exts.patch
deleted file mode 100644
index b90fb1b..0000000
--- a/SOURCES/krb5-1.12-system-exts.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-On a glibc system, EAI_NODATA isn't defined unless _GNU_SOURCE is.  The
-recommended thing is to use AC_USE_SYSTEM_EXTENSIONS to get all extensions
-defined, but that would require fixups in varous other places, so we go for the
-smaller change here.
-
---- krb5-1.11/src/lib/krb5/os/hostrealm.c
-+++ krb5-1.11/src/lib/krb5/os/hostrealm.c
-@@ -30,6 +30,9 @@
-  * OF THE POSSIBILITY OF SUCH DAMAGE.
-  */
- 
-+/* We need to have EAI_NODATA and friends declared. */
-+#define _GNU_SOURCE
-+
- #include "k5-int.h"
- #include "os-proto.h"
- #include "fake-addrinfo.h"
---- krb5-1.11/src/lib/krb5/os/sendto_kdc.c
-+++ krb5-1.11/src/lib/krb5/os/sendto_kdc.c
-@@ -27,6 +27,9 @@
- /* Send packet to KDC for realm; wait for response, retransmitting
-  * as necessary. */
- 
-+/* We need to have EAI_NODATA and friends declared. */
-+#define _GNU_SOURCE
-+
- #include "fake-addrinfo.h"
- #include "k5-tls.h"
- #include "k5-int.h"
---- krb5-1.11/src/util/support/fake-addrinfo.c
-+++ krb5-1.11/src/util/support/fake-addrinfo.c
-@@ -101,6 +101,9 @@
-  *   these functions, and throw all this away.  Pleeease?  :-)
-  */
- 
-+/* We need to have EAI_NODATA and friends declared. */
-+#define _GNU_SOURCE
-+
- #include "port-sockets.h"
- #include "socket-utils.h"
- #include "k5-platform.h"
---- krb5-1.12/src/lib/krad/client.c
-+++ krb5-1.12/src/lib/krad/client.c
-@@ -27,6 +27,9 @@
-  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-  */
- 
-+/* We need to have EAI_NODATA and friends declared. */
-+#define _GNU_SOURCE
-+
- #include <k5-queue.h>
- #include "internal.h"
- 
diff --git a/SOURCES/krb5-1.12.2.tar.gz.asc b/SOURCES/krb5-1.12.2.tar.gz.asc
deleted file mode 100644
index fc16e6f..0000000
--- a/SOURCES/krb5-1.12.2.tar.gz.asc
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1
-
-iQEVAwUAU+lJVhUCTNN0nXiJAQIpkgf9HczaywhoXEZYbVORXAxDGrb8ADlAnFdY
-htRjqJ8xTmj0yMtPF1NJk4ian/u9ksc7qZ9JQg7F64gy/7098RlCfsTMT/b3qp0r
-0cmNiTMYq19igxHy9qWm0JonudDQhUulmIMi/58nBXc7IblhaVtlDnQNbA8qpg9W
-RLdn0qyeksVWAIxJ1KKsZTbZ4+U1OOPE2npZ7nHeLeYmz7rKqorQQM+NNxu+/dtB
-eo0fmeeX7bXPE2Xe/kYw7HSfIhRMHy1oH0fi9AAZnREA00/xgPq+JqhC3hIloqlk
-NDTJk2+cKZnyuDh+nyuS7wGsExqJCWjFSE5mrJiJ6N0YS0hsLn+7aA==
-=O612
------END PGP SIGNATURE-----
diff --git a/SOURCES/krb5-1.12ish-kpasswd_tcp.patch b/SOURCES/krb5-1.12ish-kpasswd_tcp.patch
deleted file mode 100644
index 4fdfca4..0000000
--- a/SOURCES/krb5-1.12ish-kpasswd_tcp.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-Fall back to TCP on kdc-unresolvable/unreachable errors.  We still have
-to wait for UDP to fail, so this might not be ideal.  RT #5868.
-
---- krb5/src/lib/krb5/os/changepw.c
-+++ krb5/src/lib/krb5/os/changepw.c
-@@ -270,10 +270,22 @@ change_set_password(krb5_context context
-                          &sl, strategy, &callback_info, &chpw_rep,
-                          ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL);
-         if (code) {
--            /*
--             * Here we may want to switch to TCP on some errors.
--             * right?
--             */
-+            /* if we're not using a stream socket, and it's an error which
-+             * might reasonably be specific to a datagram "connection", try
-+             * again with a stream socket */
-+            if (!no_udp) {
-+                switch (code) {
-+                case KRB5_KDC_UNREACH:
-+                case KRB5_REALM_CANT_RESOLVE:
-+                case KRB5KRB_ERR_RESPONSE_TOO_BIG:
-+                    /* should we do this for more result codes than these? */
-+                    k5_free_serverlist (&sl);
-+                    no_udp = 1;
-+                    continue;
-+                default:
-+                    break;
-+                }
-+            }
-             break;
-         }
- 
diff --git a/SOURCES/krb5-1.12ish-tls-plugins.patch b/SOURCES/krb5-1.12ish-tls-plugins.patch
deleted file mode 100644
index 9004f74..0000000
--- a/SOURCES/krb5-1.12ish-tls-plugins.patch
+++ /dev/null
@@ -1,1680 +0,0 @@
-Adapt to headers being included in a different order in sendto_kdc.c.
-Drop portions which drop checkhost.c and checkhost.h.
-
-commit 472349d2a47fbc7db82e46ba46411b95c312fc1f
-Author: Greg Hudson <ghudson@mit.edu>
-Date:   Sun Jun 22 10:42:14 2014 -0400
-
-    Move KKDCP OpenSSL code to an internal plugin
-    
-    Create an internal pluggable interface "tls" with one in-tree dynamic
-    plugin module named "k5tls".  Move all of the OpenSSL calls to the
-    plugin module, and make the libkrb5 code load and invoke the plugin.
-    This way we do not load or initialize libssl unless an HTTP proxy is
-    used.
-    
-    ticket: 7929
-
-diff --git a/src/Makefile.in b/src/Makefile.in
-index 5e2cf4e..92bb60a 100644
---- a/src/Makefile.in
-+++ b/src/Makefile.in
-@@ -20,6 +20,7 @@ SUBDIRS=util include lib \
- 	@ldap_plugin_dir@ \
- 	plugins/preauth/otp \
- 	plugins/preauth/pkinit \
-+	plugins/tls/k5tls \
- 	kdc kadmin slave clients appl tests \
- 	config-files build-tools man doc @po@
- WINSUBDIRS=include util lib ccapi windows clients appl
-@@ -62,7 +63,7 @@ INSTALLMKDIRS = $(KRB5ROOT) $(KRB5MANROOT) $(KRB5OTHERMKDIRS) \
- 		$(KRB5_LIBDIR) $(KRB5_INCDIR) \
- 		$(KRB5_DB_MODULE_DIR) $(KRB5_PA_MODULE_DIR) \
- 		$(KRB5_AD_MODULE_DIR) \
--		$(KRB5_LIBKRB5_MODULE_DIR) \
-+		$(KRB5_LIBKRB5_MODULE_DIR) $(KRB5_TLS_MODULE_DIR) \
- 		@localstatedir@ @localstatedir@/krb5kdc \
- 		$(KRB5_INCSUBDIRS) $(datadir) $(EXAMPLEDIR) \
- 		$(PKGCONFIG_DIR)
-diff --git a/src/config/pre.in b/src/config/pre.in
-index e1d7e4b..fd8ee56 100644
---- a/src/config/pre.in
-+++ b/src/config/pre.in
-@@ -213,6 +213,7 @@ KRB5_DB_MODULE_DIR = $(MODULE_DIR)/kdb
- KRB5_PA_MODULE_DIR = $(MODULE_DIR)/preauth
- KRB5_AD_MODULE_DIR = $(MODULE_DIR)/authdata
- KRB5_LIBKRB5_MODULE_DIR = $(MODULE_DIR)/libkrb5
-+KRB5_TLS_MODULE_DIR = $(MODULE_DIR)/tls
- KRB5_LOCALEDIR = @localedir@
- GSS_MODULE_DIR = @libdir@/gss
- KRB5_INCSUBDIRS = \
-diff --git a/src/configure.in b/src/configure.in
-index 8aa513e..43509ab 100644
---- a/src/configure.in
-+++ b/src/configure.in
-@@ -308,6 +308,11 @@ no)
-   ;;
- esac
- 
-+if test "$PROXY_TLS_IMPL" = no; then
-+   AC_DEFINE(PROXY_TLS_IMPL_NONE,1,
-+             [Define if no HTTP TLS implementation is selected])
-+fi
-+
- AC_SUBST(PROXY_TLS_IMPL)
- AC_SUBST(PROXY_TLS_IMPL_CFLAGS)
- AC_SUBST(PROXY_TLS_IMPL_LIBS)
-@@ -1386,6 +1391,7 @@ dnl	ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test
- 	plugins/authdata/greet
- 	plugins/authdata/greet_client
- 	plugins/authdata/greet_server
-+	plugins/tls/k5tls
- 
- 	clients clients/klist clients/kinit clients/kvno
- 	clients/kdestroy clients/kpasswd clients/ksu clients/kswitch
-diff --git a/src/include/k5-int.h b/src/include/k5-int.h
-index 9f14ee0..38846eb 100644
---- a/src/include/k5-int.h
-+++ b/src/include/k5-int.h
-@@ -1083,7 +1083,8 @@ struct plugin_interface {
- #define PLUGIN_INTERFACE_LOCALAUTH   5
- #define PLUGIN_INTERFACE_HOSTREALM   6
- #define PLUGIN_INTERFACE_AUDIT       7
--#define PLUGIN_NUM_INTERFACES        8
-+#define PLUGIN_INTERFACE_TLS         8
-+#define PLUGIN_NUM_INTERFACES        9
- 
- /* Retrieve the plugin module of type interface_id and name modname,
-  * storing the result into module. */
-@@ -1126,6 +1127,7 @@ typedef struct krb5_preauth_context_st krb5_preauth_context;
- struct ccselect_module_handle;
- struct localauth_module_handle;
- struct hostrealm_module_handle;
-+struct k5_tls_vtable_st;
- struct _krb5_context {
-     krb5_magic      magic;
-     krb5_enctype    *in_tkt_etypes;
-@@ -1169,6 +1171,9 @@ struct _krb5_context {
-     /* hostrealm module stuff */
-     struct hostrealm_module_handle **hostrealm_handles;
- 
-+    /* TLS module vtable (if loaded) */
-+    struct k5_tls_vtable_st *tls;
-+
-     /* error detail info */
-     struct errinfo err;
- 
-diff --git a/src/include/k5-tls.h b/src/include/k5-tls.h
-new file mode 100644
-index 0000000..0661c05
---- /dev/null
-+++ b/src/include/k5-tls.h
-@@ -0,0 +1,104 @@
-+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-+/* include/k5-tls.h - internal pluggable interface for TLS */
-+/*
-+ * Copyright (C) 2014 by the Massachusetts Institute of Technology.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ *   notice, this list of conditions and the following disclaimer.
-+ *
-+ * * Redistributions in binary form must reproduce the above copyright
-+ *   notice, this list of conditions and the following disclaimer in
-+ *   the documentation and/or other materials provided with the
-+ *   distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/*
-+ * This internal pluggable interface allows libkrb5 to load an in-tree module
-+ * providing TLS support at runtime.  It is currently tailored for the needs of
-+ * the OpenSSL module as used for HTTP proxy support.  As an internal
-+ * interface, it can be changed to fit different implementations and consumers
-+ * without regard for backward compatibility.
-+ */
-+
-+#ifndef K5_TLS_H
-+#define K5_TLS_H
-+
-+#include "k5-int.h"
-+
-+/* An abstract type for localauth module data. */
-+typedef struct k5_tls_handle_st *k5_tls_handle;
-+
-+typedef enum {
-+    DATA_READ, DONE, WANT_READ, WANT_WRITE, ERROR_TLS
-+} k5_tls_status;
-+
-+/*
-+ * Create a handle for fd, where the server certificate must match servername
-+ * and be trusted according to anchors.  anchors is a null-terminated list
-+ * using the DIR:/FILE:/ENV: syntax borrowed from PKINIT.  If anchors is null,
-+ * use the system default trust anchors.
-+ */
-+typedef krb5_error_code
-+(*k5_tls_setup_fn)(krb5_context context, SOCKET fd, const char *servername,
-+                   char **anchors, k5_tls_handle *handle_out);
-+
-+/*
-+ * Write len bytes of data using TLS.  Return DONE if writing is complete,
-+ * WANT_READ or WANT_WRITE if the underlying socket must be readable or
-+ * writable to continue, and ERROR_TLS if the TLS channel or underlying socket
-+ * experienced an error.  After WANT_READ or WANT_WRITE, the operation will be
-+ * retried with the same arguments even if some data has already been written.
-+ * (OpenSSL makes this contract easy to fulfill.  For other implementations we
-+ * might want to change it.)
-+ */
-+typedef k5_tls_status
-+(*k5_tls_write_fn)(krb5_context context, k5_tls_handle handle,
-+                   const void *data, size_t len);
-+
-+/*
-+ * Read up to data_size bytes of data using TLS.  Return DATA_READ and set
-+ * *len_out if any data is read.  Return DONE if there is no more data to be
-+ * read on the connection, WANT_READ or WANT_WRITE if the underlying socket
-+ * must be readable or writable to continue, and ERROR_TLS if the TLS channel
-+ * or underlying socket experienced an error.
-+ *
-+ * After DATA_READ, there may still be pending buffered data to read.  The
-+ * caller must call this method again with additional buffer space before
-+ * selecting for reading on the underlying socket.
-+ */
-+typedef k5_tls_status
-+(*k5_tls_read_fn)(krb5_context context, k5_tls_handle handle, void *data,
-+                  size_t data_size, size_t *len_out);
-+
-+/* Release a handle.  Do not pass a null pointer. */
-+typedef void
-+(*k5_tls_free_handle_fn)(krb5_context context, k5_tls_handle handle);
-+
-+/* All functions are mandatory unless they are all null, in which case the
-+ * caller should assume that TLS is unsupported. */
-+typedef struct k5_tls_vtable_st {
-+    k5_tls_setup_fn setup;
-+    k5_tls_write_fn write;
-+    k5_tls_read_fn read;
-+    k5_tls_free_handle_fn free_handle;
-+} *k5_tls_vtable;
-+
-+#endif /* K5_TLS_H */
-diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
-index 9e75b29..a0aa85a 100644
---- a/src/include/k5-trace.h
-+++ b/src/include/k5-trace.h
-@@ -324,23 +324,11 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
-     TRACE(c, "Resolving hostname {str}", hostname)
- #define TRACE_SENDTO_KDC_RESPONSE(c, len, raddr)                        \
-     TRACE(c, "Received answer ({int} bytes) from {raddr}", len, raddr)
--#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MISMATCH(c, hostname)        \
--    TRACE(c, "HTTPS certificate name mismatch: server certificate is "  \
--          "not for \"{str}\"", hostname)
--#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MATCH(c, hostname)           \
--    TRACE(c, "HTTPS certificate name matched \"{str}\"", hostname)
--#define TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(c)                 \
--    TRACE(c, "HTTPS server certificate not received")
--#define TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(c, depth,        \
--                                                       namelen, name,   \
--                                                       err, errs)       \
--    TRACE(c, "HTTPS certificate error at {int} ({lenstr}): "            \
--          "{int} ({str})", depth, namelen, name, err, errs)
--#define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr)                  \
-+#define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr)          \
-     TRACE(c, "HTTPS error connecting to {raddr}", raddr)
--#define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr, err)                \
--    TRACE(c, "HTTPS error receiving from {raddr}: {errno}", raddr, err)
--#define TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(c, raddr)                     \
-+#define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr)             \
-+    TRACE(c, "HTTPS error receiving from {raddr}", raddr)
-+#define TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(c, raddr)     \
-     TRACE(c, "HTTPS error sending to {raddr}", raddr)
- #define TRACE_SENDTO_KDC_HTTPS_SEND(c, raddr)                           \
-     TRACE(c, "Sending HTTPS request to {raddr}", raddr)
-@@ -383,6 +371,19 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
-     TRACE(c, "TGS reply didn't decode with subkey; trying session key " \
-           "({keyblock)}", keyblock)
- 
-+#define TRACE_TLS_ERROR(c, errs)                \
-+    TRACE(c, "TLS error: {str}", errs)
-+#define TRACE_TLS_NO_REMOTE_CERTIFICATE(c)              \
-+    TRACE(c, "TLS server certificate not received")
-+#define TRACE_TLS_CERT_ERROR(c, depth, namelen, name, err, errs)        \
-+    TRACE(c, "TLS certificate error at {int} ({lenstr}): {int} ({str})", \
-+          depth, namelen, name, err, errs)
-+#define TRACE_TLS_SERVER_NAME_MISMATCH(c, hostname)                     \
-+    TRACE(c, "TLS certificate name mismatch: server certificate is "    \
-+          "not for \"{str}\"", hostname)
-+#define TRACE_TLS_SERVER_NAME_MATCH(c, hostname)                        \
-+    TRACE(c, "TLS certificate name matched \"{str}\"", hostname)
-+
- #define TRACE_TKT_CREDS(c, creds, cache)                            \
-     TRACE(c, "Getting credentials {creds} using ccache {ccache}",   \
-           creds, cache)
-diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in
-index 472c008..d9cddc1 100644
---- a/src/lib/krb5/Makefile.in
-+++ b/src/lib/krb5/Makefile.in
-@@ -56,8 +56,7 @@ RELDIR=krb5
- SHLIB_EXPDEPS = \
- 	$(TOPLIBD)/libk5crypto$(SHLIBEXT) \
- 	$(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB)
--SHLIB_EXPLIBS=-lk5crypto -lcom_err $(PROXY_TLS_IMPL_LIBS) $(SUPPORT_LIB) \
--	@GEN_LIB@ $(LIBS)
-+SHLIB_EXPLIBS=-lk5crypto -lcom_err $(SUPPORT_LIB) @GEN_LIB@ $(LIBS)
- 
- all-unix:: all-liblinks
- 
-diff --git a/src/lib/krb5/krb/copy_ctx.c b/src/lib/krb5/krb/copy_ctx.c
-index 4237023..322c288 100644
---- a/src/lib/krb5/krb/copy_ctx.c
-+++ b/src/lib/krb5/krb/copy_ctx.c
-@@ -81,6 +81,7 @@ krb5_copy_context(krb5_context ctx, krb5_context *nctx_out)
-     nctx->ccselect_handles = NULL;
-     nctx->localauth_handles = NULL;
-     nctx->hostrealm_handles = NULL;
-+    nctx->tls = NULL;
-     nctx->kdblog_context = NULL;
-     nctx->trace_callback = NULL;
-     nctx->trace_callback_data = NULL;
-diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
-index 6801bb1..6548f36 100644
---- a/src/lib/krb5/krb/init_ctx.c
-+++ b/src/lib/krb5/krb/init_ctx.c
-@@ -319,6 +319,7 @@ krb5_free_context(krb5_context ctx)
-     k5_localauth_free_context(ctx);
-     k5_plugin_free_context(ctx);
-     free(ctx->plugin_base_dir);
-+    free(ctx->tls);
- 
-     ctx->magic = 0;
-     free(ctx);
-diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c
-index 8b62c7b..7375f51 100644
---- a/src/lib/krb5/krb/plugin.c
-+++ b/src/lib/krb5/krb/plugin.c
-@@ -55,7 +55,8 @@ const char *interface_names[] = {
-     "ccselect",
-     "localauth",
-     "hostrealm",
--    "audit"
-+    "audit",
-+    "tls"
- };
- 
- /* Return the context's interface structure for id, or NULL if invalid. */
-diff --git a/src/lib/krb5/krb5_libinit.c b/src/lib/krb5/krb5_libinit.c
-index b72bc58..eb40124 100644
---- a/src/lib/krb5/krb5_libinit.c
-+++ b/src/lib/krb5/krb5_libinit.c
-@@ -55,8 +55,6 @@ int krb5int_lib_init(void)
-     if (err)
-         return err;
- 
--    k5_sendto_kdc_initialize();
--
-     return 0;
- }
- 
-diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in
-index fa8a093..ea68990 100644
---- a/src/lib/krb5/os/Makefile.in
-+++ b/src/lib/krb5/os/Makefile.in
-@@ -2,7 +2,7 @@ mydir=lib$(S)krb5$(S)os
- BUILDTOP=$(REL)..$(S)..$(S)..
- DEFINES=-DLIBDIR=\"$(KRB5_LIBDIR)\" -DBINDIR=\"$(CLIENT_BINDIR)\" \
- 	-DSBINDIR=\"$(ADMIN_BINDIR)\"
--LOCALINCLUDES= $(PROXY_TLS_IMPL_CFLAGS) -I$(top_srcdir)/util/profile
-+LOCALINCLUDES= -I$(top_srcdir)/util/profile
- 
- ##DOS##BUILDTOP = ..\..\..
- ##DOS##PREFIXDIR=os
-@@ -13,7 +13,6 @@ STLIBOBJS= \
- 	c_ustime.o	\
- 	ccdefname.o	\
- 	changepw.o	\
--	checkhost.o	\
- 	dnsglue.o	\
- 	dnssrv.o	\
- 	expand_path.o	\
-diff --git a/src/lib/krb5/os/deps b/src/lib/krb5/os/deps
-index d56ff30..211354c 100644
---- a/src/lib/krb5/os/deps
-+++ b/src/lib/krb5/os/deps
-@@ -49,17 +49,6 @@ changepw.so changepw.po $(OUTPRE)changepw.$(OBJEXT): \
-   $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \
-   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-   changepw.c os-proto.h
--checkhost.so checkhost.po $(OUTPRE)checkhost.$(OBJEXT): \
--  $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
--  $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
--  $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
--  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
--  $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
--  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
--  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \
--  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
--  $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
--  $(top_srcdir)/include/socket-utils.h checkhost.c checkhost.h
- dnsglue.so dnsglue.po $(OUTPRE)dnsglue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-   $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
-   $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
-@@ -429,7 +418,7 @@ sendto_kdc.so sendto_kdc.po $(OUTPRE)sendto_kdc.$(OBJEXT): \
-   $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
-   $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \
-   $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
--  $(top_srcdir)/include/socket-utils.h checkhost.h os-proto.h \
-+  $(top_srcdir)/include/socket-utils.h os-proto.h \
-   sendto_kdc.c
- sn2princ.so sn2princ.po $(OUTPRE)sn2princ.$(OBJEXT): \
-   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
-diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c
-index 1f2039c..160a2d0 100644
---- a/src/lib/krb5/os/locate_kdc.c
-+++ b/src/lib/krb5/os/locate_kdc.c
-@@ -177,7 +177,6 @@ oom:
-     return ENOMEM;
- }
- 
--#ifdef PROXY_TLS_IMPL_OPENSSL
- static void
- parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host,
-                    char **uri_path)
-@@ -195,13 +194,6 @@ parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host,
-         }
-     }
- }
--#else
--static void
--parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host,
--                   char **uri)
--{
--}
--#endif
- 
- /* Return true if server is identical to an entry in list. */
- static krb5_boolean
-diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
-index 34bf028..69ee376 100644
---- a/src/lib/krb5/os/os-proto.h
-+++ b/src/lib/krb5/os/os-proto.h
-@@ -187,6 +187,5 @@ krb5_error_code localauth_k5login_initvt(krb5_context context, int maj_ver,
-                                          krb5_plugin_vtable vtable);
- krb5_error_code localauth_an2ln_initvt(krb5_context context, int maj_ver,
-                                        int min_ver, krb5_plugin_vtable vtable);
--void k5_sendto_kdc_initialize(void);
- 
- #endif /* KRB5_LIBOS_INT_PROTO__ */
-diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
-index a572831..2242240 100644
---- a/src/lib/krb5/os/sendto_kdc.c
-+++ b/src/lib/krb5/os/sendto_kdc.c
-@@ -54,6 +54,7 @@
-  * as necessary. */
- 
- #include "fake-addrinfo.h"
-+#include "k5-tls.h"
- #include "k5-int.h"
- 
- #include "os-proto.h"
-@@ -74,15 +75,6 @@
- #endif
- #endif
- 
--#ifdef PROXY_TLS_IMPL_OPENSSL
--#include <openssl/err.h>
--#include <openssl/ssl.h>
--#include <openssl/x509.h>
--#include <openssl/x509v3.h>
--#include <dirent.h>
--#include "checkhost.h"
--#endif
--
- #define MAX_PASS                    3
- #define DEFAULT_UDP_PREF_LIMIT   1465
- #define HARD_UDP_LIMIT          32700 /* could probably do 64K-epsilon ? */
-@@ -147,29 +139,30 @@ struct conn_state {
-         const char *uri_path;
-         const char *servername;
-         char *https_request;
--#ifdef PROXY_TLS_IMPL_OPENSSL
--        SSL *ssl;
--#endif
-+        k5_tls_handle tls;
-     } http;
- };
- 
--#ifdef PROXY_TLS_IMPL_OPENSSL
--/* Extra-data identifier, used to pass context into the verify callback. */
--static int ssl_ex_context_id = -1;
--static int ssl_ex_conn_id = -1;
--#endif
--
--void
--k5_sendto_kdc_initialize(void)
-+/* Set up context->tls.  On allocation failure, return ENOMEM.  On plugin load
-+ * failure, set context->tls to point to a nulled vtable and return 0. */
-+static krb5_error_code
-+init_tls_vtable(krb5_context context)
- {
--#ifdef PROXY_TLS_IMPL_OPENSSL
--    SSL_library_init();
--    SSL_load_error_strings();
--    OpenSSL_add_all_algorithms();
-+    krb5_plugin_initvt_fn initfn;
- 
--    ssl_ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
--    ssl_ex_conn_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
--#endif
-+    if (context->tls != NULL)
-+        return 0;
-+
-+    context->tls = calloc(1, sizeof(*context->tls));
-+    if (context->tls == NULL)
-+        return ENOMEM;
-+
-+    /* Attempt to load the module; just let it stay nulled out on failure. */
-+    k5_plugin_register_dyn(context, PLUGIN_INTERFACE_TLS, "k5tls", "tls");
-+    if (k5_plugin_load(context, PLUGIN_INTERFACE_TLS, "k5tls", &initfn) == 0)
-+        (*initfn)(context, 0, 0, (krb5_plugin_vtable)context->tls);
-+
-+    return 0;
- }
- 
- /* Get current time in milliseconds. */
-@@ -184,21 +177,15 @@ get_curtime_ms(time_ms *time_out)
-     return 0;
- }
- 
--#ifdef PROXY_TLS_IMPL_OPENSSL
- static void
--free_http_ssl_data(struct conn_state *state)
-+free_http_tls_data(krb5_context context, struct conn_state *state)
- {
--    SSL_free(state->http.ssl);
--    state->http.ssl = NULL;
-+    if (state->http.tls != NULL)
-+        context->tls->free_handle(context, state->http.tls);
-+    state->http.tls = NULL;
-     free(state->http.https_request);
-     state->http.https_request = NULL;
- }
--#else
--static void
--free_http_ssl_data(struct conn_state *state)
--{
--}
--#endif
- 
- #ifdef USE_POLL
- 
-@@ -532,7 +519,6 @@ static fd_handler_fn service_udp_read;
- static fd_handler_fn service_https_write;
- static fd_handler_fn service_https_read;
- 
--#ifdef PROXY_TLS_IMPL_OPENSSL
- static krb5_error_code
- make_proxy_request(struct conn_state *state, const krb5_data *realm,
-                    const krb5_data *message, char **req_out, size_t *len_out)
-@@ -585,14 +571,6 @@ cleanup:
-     krb5_free_data(NULL, encoded_pm);
-     return ret;
- }
--#else
--static krb5_error_code
--make_proxy_request(struct conn_state *state, const krb5_data *realm,
--                   const krb5_data *message, char **req_out, size_t *len_out)
--{
--    abort();
--}
--#endif
- 
- /* Set up the actual message we will send across the underlying transport to
-  * communicate the payload message, using one or both of state->out.sgbuf. */
-@@ -963,7 +941,7 @@ static void
- kill_conn(krb5_context context, struct conn_state *conn,
-           struct select_state *selstate)
- {
--    free_http_ssl_data(conn);
-+    free_http_tls_data(context, conn);
- 
-     if (socktype_for_transport(conn->addr.transport) == SOCK_STREAM)
-         TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr);
-@@ -1145,249 +1123,44 @@ service_udp_read(krb5_context context, const krb5_data *realm,
-     return TRUE;
- }
- 
--#ifdef PROXY_TLS_IMPL_OPENSSL
--/* Output any error strings that OpenSSL's accumulated as tracing messages. */
--static void
--flush_ssl_errors(krb5_context context)
--{
--    unsigned long err;
--    char buf[128];
--
--    while ((err = ERR_get_error()) != 0) {
--        ERR_error_string_n(err, buf, sizeof(buf));
--        TRACE_SENDTO_KDC_HTTPS_ERROR(context, buf);
--    }
--}
--
--static krb5_error_code
--load_http_anchor_file(X509_STORE *store, const char *path)
--{
--    FILE *fp;
--    STACK_OF(X509_INFO) *sk = NULL;
--    X509_INFO *xi;
--    int i;
--
--    fp = fopen(path, "r");
--    if (fp == NULL)
--        return errno;
--    sk = PEM_X509_INFO_read(fp, NULL, NULL, NULL);
--    fclose(fp);
--    if (sk == NULL)
--        return ENOENT;
--    for (i = 0; i < sk_X509_INFO_num(sk); i++) {
--        xi = sk_X509_INFO_value(sk, i);
--        if (xi->x509 != NULL)
--            X509_STORE_add_cert(store, xi->x509);
--    }
--    sk_X509_INFO_pop_free(sk, X509_INFO_free);
--    return 0;
--}
--
--static krb5_error_code
--load_http_anchor_dir(X509_STORE *store, const char *path)
--{
--    DIR *d = NULL;
--    struct dirent *dentry = NULL;
--    char filename[1024];
--    krb5_boolean found_any = FALSE;
--
--    d = opendir(path);
--    if (d == NULL)
--        return ENOENT;
--    while ((dentry = readdir(d)) != NULL) {
--        if (dentry->d_name[0] != '.') {
--            snprintf(filename, sizeof(filename), "%s/%s",
--                     path, dentry->d_name);
--            if (load_http_anchor_file(store, filename) == 0)
--                found_any = TRUE;
--        }
--    }
--    closedir(d);
--    return found_any ? 0 : ENOENT;
--}
--
--static krb5_error_code
--load_http_anchor(SSL_CTX *ctx, const char *location)
-+/* Set up conn->http.tls.  Return true on success. */
-+static krb5_boolean
-+setup_tls(krb5_context context, const krb5_data *realm,
-+          struct conn_state *conn, struct select_state *selstate)
- {
--    X509_STORE *store;
--    const char *envloc;
--
--    store = SSL_CTX_get_cert_store(ctx);
--    if (strncmp(location, "FILE:", 5) == 0) {
--        return load_http_anchor_file(store, location + 5);
--    } else if (strncmp(location, "DIR:", 4) == 0) {
--        return load_http_anchor_dir(store, location + 4);
--    } else if (strncmp(location, "ENV:", 4) == 0) {
--        envloc = getenv(location + 4);
--        if (envloc == NULL)
--            return ENOENT;
--        return load_http_anchor(ctx, envloc);
--    }
--    return EINVAL;
--}
-+    krb5_error_code ret;
-+    krb5_boolean ok = FALSE;
-+    char **anchors = NULL, *realmstr = NULL;
-+    const char *names[4];
- 
--static krb5_error_code
--load_http_verify_anchors(krb5_context context, const krb5_data *realm,
--                         SSL_CTX *sctx)
--{
--    const char *anchors[4];
--    char **values = NULL, *realmz;
--    unsigned int i;
--    krb5_error_code err;
-+    if (init_tls_vtable(context) != 0 || context->tls->setup == NULL)
-+        return FALSE;
- 
--    realmz = k5memdup0(realm->data, realm->length, &err);
--    if (realmz == NULL)
-+    realmstr = k5memdup0(realm->data, realm->length, &ret);
-+    if (realmstr == NULL)
-         goto cleanup;
- 
-     /* Load the configured anchors. */
--    anchors[0] = KRB5_CONF_REALMS;
--    anchors[1] = realmz;
--    anchors[2] = KRB5_CONF_HTTP_ANCHORS;
--    anchors[3] = NULL;
--    if (profile_get_values(context->profile, anchors, &values) == 0) {
--        for (i = 0; values[i] != NULL; i++) {
--            err = load_http_anchor(sctx, values[i]);
--            if (err != 0)
--                break;
--        }
--        profile_free_list(values);
--    } else {
--        /* Use the library defaults. */
--        if (SSL_CTX_set_default_verify_paths(sctx) != 1)
--            err = ENOENT;
--    }
--
--cleanup:
--    free(realmz);
--    return err;
--}
--
--static krb5_boolean
--ssl_check_name_or_ip(X509 *x, const char *expected_name)
--{
--    struct in_addr in;
--    struct in6_addr in6;
--
--    if (inet_aton(expected_name, &in) != 0 ||
--        inet_pton(AF_INET6, expected_name, &in6) != 0) {
--        return k5_check_cert_address(x, expected_name);
--    } else {
--        return k5_check_cert_servername(x, expected_name);
--    }
--}
-+    names[0] = KRB5_CONF_REALMS;
-+    names[1] = realmstr;
-+    names[2] = KRB5_CONF_HTTP_ANCHORS;
-+    names[3] = NULL;
-+    ret = profile_get_values(context->profile, names, &anchors);
-+    if (ret != 0 && ret != PROF_NO_RELATION)
-+        goto cleanup;
- 
--static int
--ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx)
--{
--    X509 *x;
--    SSL *ssl;
--    BIO *bio;
--    krb5_context context;
--    int err, depth;
--    struct conn_state *conn = NULL;
--    const char *cert = NULL, *errstr, *expected_name;
--    size_t count;
--
--    ssl = X509_STORE_CTX_get_ex_data(store_ctx,
--                                     SSL_get_ex_data_X509_STORE_CTX_idx());
--    context = SSL_get_ex_data(ssl, ssl_ex_context_id);
--    conn = SSL_get_ex_data(ssl, ssl_ex_conn_id);
--    /* We do have the peer's cert, right? */
--    x = X509_STORE_CTX_get_current_cert(store_ctx);
--    if (x == NULL) {
--        TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(context);
--        return 0;
--    }
--    /* Figure out where we are. */
--    depth = X509_STORE_CTX_get_error_depth(store_ctx);
--    if (depth < 0)
--        return 0;
--    /* If there's an error at this level that we're not ignoring, fail. */
--    err = X509_STORE_CTX_get_error(store_ctx);
--    if (err != X509_V_OK) {
--        bio = BIO_new(BIO_s_mem());
--        if (bio != NULL) {
--            X509_NAME_print_ex(bio, x->cert_info->subject, 0, 0);
--            count = BIO_get_mem_data(bio, &cert);
--            errstr = X509_verify_cert_error_string(err);
--            TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(context, depth,
--                                                           count, cert, err,
--                                                           errstr);
--            BIO_free(bio);
--        }
--        return 0;
--    }
--    /* If we're not looking at the peer, we're done and everything's ok. */
--    if (depth != 0)
--        return 1;
--    /* Check if the name we expect to find is in the certificate. */
--    expected_name = conn->http.servername;
--    if (ssl_check_name_or_ip(x, expected_name)) {
--        TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MATCH(context, expected_name);
--        return 1;
--    } else {
--        TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MISMATCH(context, expected_name);
-+    if (context->tls->setup(context, conn->fd, conn->http.servername, anchors,
-+                            &conn->http.tls) != 0) {
-+        TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(context, &conn->addr);
-+        goto cleanup;
-     }
--    /* The name didn't match. */
--    return 0;
--}
- 
--/*
-- * Set up structures that we use to manage the SSL handling for this connection
-- * and apply any non-default settings.  Kill the connection and return false if
-- * anything goes wrong while we're doing that; return true otherwise.
-- */
--static krb5_boolean
--setup_ssl(krb5_context context, const krb5_data *realm,
--          struct conn_state *conn, struct select_state *selstate)
--{
--    int e;
--    long options;
--    SSL_CTX *ctx = NULL;
--    SSL *ssl = NULL;
-+    ok = TRUE;
- 
--    if (ssl_ex_context_id == -1 || ssl_ex_conn_id == -1)
--        goto kill_conn;
--
--    /* Do general SSL library setup. */
--    ctx = SSL_CTX_new(SSLv23_client_method());
--    if (ctx == NULL)
--        goto kill_conn;
--    options = SSL_CTX_get_options(ctx);
--    SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2);
--
--    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ssl_verify_callback);
--    X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), 0);
--    e = load_http_verify_anchors(context, realm, ctx);
--    if (e != 0)
--        goto kill_conn;
--
--    ssl = SSL_new(ctx);
--    if (ssl == NULL)
--        goto kill_conn;
--
--    if (!SSL_set_ex_data(ssl, ssl_ex_context_id, context))
--        goto kill_conn;
--    if (!SSL_set_ex_data(ssl, ssl_ex_conn_id, conn))
--        goto kill_conn;
--
--    /* Tell the SSL library about the socket. */
--    if (!SSL_set_fd(ssl, conn->fd))
--        goto kill_conn;
--    SSL_set_connect_state(ssl);
--
--    SSL_CTX_free(ctx);
--    conn->http.ssl = ssl;
--
--    return TRUE;
--
--kill_conn:
--    TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(context, &conn->addr);
--    flush_ssl_errors(context);
--    SSL_free(ssl);
--    SSL_CTX_free(ctx);
--    kill_conn(context, conn, selstate);
--    return FALSE;
-+cleanup:
-+    free(realmstr);
-+    profile_free_list(anchors);
-+    return ok;
- }
- 
- /* Set conn->state to READING when done; otherwise, call a cm_set_. */
-@@ -1395,50 +1168,41 @@ static krb5_boolean
- service_https_write(krb5_context context, const krb5_data *realm,
-                     struct conn_state *conn, struct select_state *selstate)
- {
--    ssize_t nwritten;
--    int e;
-+    k5_tls_status st;
- 
-     /* If this is our first time in here, set up the SSL context. */
--    if (conn->http.ssl == NULL && !setup_ssl(context, realm, conn, selstate))
-+    if (conn->http.tls == NULL && !setup_tls(context, realm, conn, selstate)) {
-+        kill_conn(context, conn, selstate);
-         return FALSE;
-+    }
- 
-     /* Try to transmit our request to the server. */
--    nwritten = SSL_write(conn->http.ssl, SG_BUF(conn->out.sgp),
--                         SG_LEN(conn->out.sgbuf));
--    if (nwritten <= 0) {
--        e = SSL_get_error(conn->http.ssl, nwritten);
--        if (e == SSL_ERROR_WANT_READ) {
--            cm_read(selstate, conn->fd);
--            return FALSE;
--        } else if (e == SSL_ERROR_WANT_WRITE) {
--            cm_write(selstate, conn->fd);
--            return FALSE;
--        }
-+    st = context->tls->write(context, conn->http.tls, SG_BUF(conn->out.sgp),
-+                             SG_LEN(conn->out.sgbuf));
-+    if (st == DONE) {
-+        TRACE_SENDTO_KDC_HTTPS_SEND(context, &conn->addr);
-+        cm_read(selstate, conn->fd);
-+        conn->state = READING;
-+    } else if (st == WANT_READ) {
-+        cm_read(selstate, conn->fd);
-+    } else if (st == WANT_WRITE) {
-+        cm_write(selstate, conn->fd);
-+    } else if (st == ERROR_TLS) {
-         TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(context, &conn->addr);
--        flush_ssl_errors(context);
-         kill_conn(context, conn, selstate);
--        return FALSE;
-     }
- 
--    /* Done writing, switch to reading. */
--    TRACE_SENDTO_KDC_HTTPS_SEND(context, &conn->addr);
--    cm_read(selstate, conn->fd);
--    conn->state = READING;
-     return FALSE;
- }
- 
--/*
-- * Return true on readable data, call a cm_read/write function and return
-- * false if the SSL layer needs it, kill the connection otherwise.
-- */
-+/* Return true on finished data.  Call a cm_read/write function and return
-+ * false if the TLS layer needs it.  Kill the connection on error. */
- static krb5_boolean
- https_read_bytes(krb5_context context, struct conn_state *conn,
-                  struct select_state *selstate)
- {
--    size_t bufsize;
--    ssize_t nread;
--    krb5_boolean readbytes = FALSE;
--    int e = 0;
-+    size_t bufsize, nread;
-+    k5_tls_status st;
-     char *tmp;
-     struct incoming_message *in = &conn->in;
- 
-@@ -1458,31 +1222,26 @@ https_read_bytes(krb5_context context, struct conn_state *conn,
-             in->bufsize = bufsize;
-         }
- 
--        nread = SSL_read(conn->http.ssl, &in->buf[in->pos],
--                         in->bufsize - in->pos - 1);
--        if (nread <= 0)
-+        st = context->tls->read(context, conn->http.tls, &in->buf[in->pos],
-+                                in->bufsize - in->pos - 1, &nread);
-+        if (st != DATA_READ)
-             break;
-+
-         in->pos += nread;
-         in->buf[in->pos] = '\0';
--        readbytes = TRUE;
-     }
- 
--    e = SSL_get_error(conn->http.ssl, nread);
--    if (e == SSL_ERROR_WANT_READ) {
-+    if (st == DONE)
-+        return TRUE;
-+
-+    if (st == WANT_READ) {
-         cm_read(selstate, conn->fd);
--        return FALSE;
--    } else if (e == SSL_ERROR_WANT_WRITE) {
-+    } else if (st == WANT_WRITE) {
-         cm_write(selstate, conn->fd);
--        return FALSE;
--    } else if ((e == SSL_ERROR_ZERO_RETURN) ||
--               (e == SSL_ERROR_SYSCALL && nread == 0 && readbytes)) {
--        return TRUE;
-+    } else if (st == ERROR_TLS) {
-+        TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(context, &conn->addr);
-+        kill_conn(context, conn, selstate);
-     }
--
--    e = readbytes ? SOCKET_ERRNO : ECONNRESET;
--    TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(context, &conn->addr, e);
--    flush_ssl_errors(context);
--    kill_conn(context, conn, selstate);
-     return FALSE;
- }
- 
-@@ -1531,20 +1290,6 @@ kill_conn:
-     kill_conn(context, conn, selstate);
-     return FALSE;
- }
--#else
--static krb5_boolean
--service_https_write(krb5_context context, const krb5_data *realm,
--                    struct conn_state *conn, struct select_state *selstate)
--{
--    abort();
--}
--static krb5_boolean
--service_https_read(krb5_context context, const krb5_data *realm,
--                   struct conn_state *conn, struct select_state *selstate)
--{
--    abort();
--}
--#endif
- 
- /* Return the maximum of endtime and the endtime fields of all currently active
-  * TCP connections. */
-@@ -1765,7 +1510,7 @@ cleanup:
-             if (socktype_for_transport(state->addr.transport) == SOCK_STREAM)
-                 TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &state->addr);
-             closesocket(state->fd);
--            free_http_ssl_data(state);
-+            free_http_tls_data(context, state);
-         }
-         if (state->state == READING && state->in.buf != udpbuf)
-             free(state->in.buf);
-diff --git a/src/plugins/tls/k5tls/Makefile.in b/src/plugins/tls/k5tls/Makefile.in
-new file mode 100644
-index 0000000..4d58df0
---- /dev/null
-+++ b/src/plugins/tls/k5tls/Makefile.in
-@@ -0,0 +1,22 @@
-+mydir=plugins$(S)tls$(S)k5tls
-+BUILDTOP=$(REL)..$(S)..$(S)..
-+MODULE_INSTALL_DIR = $(KRB5_TLS_MODULE_DIR)
-+LOCALINCLUDES= $(PROXY_TLS_IMPL_CFLAGS)
-+
-+LIBBASE=k5tls
-+LIBMAJOR=0
-+LIBMINOR=0
-+RELDIR=../plugins/tls/k5tls
-+SHLIB_EXPDEPS= $(KRB5_DEPLIB) $(SUPPORT_DEPLIB)
-+SHLIB_EXPLIBS= $(KRB5_LIB) $(SUPPORT_LIB) $(PROXY_TLS_IMPL_LIBS)
-+
-+STLIBOBJS=openssl.o notls.o
-+
-+SRCS=$(srcdir)/openssl.c $(srcdir)/notls.c
-+
-+all-unix:: all-liblinks
-+install-unix:: install-libs
-+clean-unix:: clean-libs clean-libobjs
-+
-+@libnover_frag@
-+@libobj_frag@
-diff --git a/src/plugins/tls/k5tls/deps b/src/plugins/tls/k5tls/deps
-new file mode 100644
-index 0000000..a6088a7
---- /dev/null
-+++ b/src/plugins/tls/k5tls/deps
-@@ -0,0 +1,25 @@
-+#
-+# Generated makefile dependencies follow.
-+#
-+openssl.so openssl.po $(OUTPRE)openssl.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
-+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
-+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
-+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
-+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
-+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-tls.h \
-+  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \
-+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
-+  $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
-+  $(top_srcdir)/include/socket-utils.h openssl.c
-+notls.so notls.po $(OUTPRE)notls.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-+  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
-+  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
-+  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
-+  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
-+  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
-+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-tls.h \
-+  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \
-+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
-+  $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
-+  $(top_srcdir)/include/socket-utils.h notls.c
-diff --git a/src/plugins/tls/k5tls/k5tls.exports b/src/plugins/tls/k5tls/k5tls.exports
-new file mode 100644
-index 0000000..d67d928
---- /dev/null
-+++ b/src/plugins/tls/k5tls/k5tls.exports
-@@ -0,0 +1 @@
-+tls_k5tls_initvt
-diff --git a/src/plugins/tls/k5tls/notls.c b/src/plugins/tls/k5tls/notls.c
-new file mode 100644
-index 0000000..7be0a4a
---- /dev/null
-+++ b/src/plugins/tls/k5tls/notls.c
-@@ -0,0 +1,53 @@
-+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-+/* plus/tls/k5tls/none.c - Stub TLS module implementation */
-+/*
-+ * Copyright (C) 2014 by the Massachusetts Institute of Technology.
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * * Redistributions of source code must retain the above copyright
-+ *   notice, this list of conditions and the following disclaimer.
-+ *
-+ * * Redistributions in binary form must reproduce the above copyright
-+ *   notice, this list of conditions and the following disclaimer in
-+ *   the documentation and/or other materials provided with the
-+ *   distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* This dummy module is used if no TLS implemented is selected. */
-+
-+#include "k5-int.h"
-+#include "k5-utf8.h"
-+#include "k5-tls.h"
-+
-+#ifdef PROXY_TLS_IMPL_NONE
-+
-+krb5_error_code
-+tls_k5tls_initvt(krb5_context context, int maj_ver, int min_ver,
-+                 krb5_plugin_vtable vtable);
-+
-+krb5_error_code
-+tls_k5tls_initvt(krb5_context context, int maj_ver, int min_ver,
-+                 krb5_plugin_vtable vtable)
-+{
-+    /* Leave all vtable functions nulled. */
-+    return 0;
-+}
-+
-+#endif /* PROXY_TLS_IMPL_NONE */
-diff --git a/src/plugins/tls/k5tls/openssl.c b/src/plugins/tls/k5tls/openssl.c
-new file mode 100644
-index 0000000..0691a34
---- /dev/null
-+++ b/src/plugins/tls/k5tls/openssl.c
-@@ -0,0 +1,570 @@
-+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-+/* plugins/tls/k5tls/openssl.c - OpenSSL TLS module implementation */
-+/*
-+ * Copyright 2013,2014 Red Hat, Inc.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ *    1. Redistributions of source code must retain the above copyright
-+ *       notice, this list of conditions and the following disclaimer.
-+ *
-+ *    2. Redistributions in binary form must reproduce the above copyright
-+ *       notice, this list of conditions and the following disclaimer in
-+ *       the documentation and/or other materials provided with the
-+ *       distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+#include "k5-int.h"
-+#include "k5-utf8.h"
-+#include "k5-tls.h"
-+
-+#ifdef PROXY_TLS_IMPL_OPENSSL
-+#include <openssl/err.h>
-+#include <openssl/ssl.h>
-+#include <openssl/x509.h>
-+#include <openssl/x509v3.h>
-+#include <dirent.h>
-+
-+struct k5_tls_handle_st {
-+    SSL *ssl;
-+    char *servername;
-+};
-+
-+static int ex_context_id = -1;
-+static int ex_handle_id = -1;
-+
-+MAKE_INIT_FUNCTION(init_openssl);
-+
-+int
-+init_openssl()
-+{
-+    SSL_library_init();
-+    SSL_load_error_strings();
-+    OpenSSL_add_all_algorithms();
-+    ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
-+    ex_handle_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
-+    return 0;
-+}
-+
-+static void
-+flush_errors(krb5_context context)
-+{
-+    unsigned long err;
-+    char buf[128];
-+
-+    while ((err = ERR_get_error()) != 0) {
-+        ERR_error_string_n(err, buf, sizeof(buf));
-+        TRACE_TLS_ERROR(context, buf);
-+    }
-+}
-+
-+/* Return the passed-in character, lower-cased if it's an ASCII character. */
-+static inline char
-+ascii_tolower(char p)
-+{
-+    if (KRB5_UPPER(p))
-+        return p + ('a' - 'A');
-+    return p;
-+}
-+
-+/*
-+ * Check a single label.  If allow_wildcard is true, and the presented name
-+ * includes a wildcard, return true and note that we matched a wildcard.
-+ * Otherwise, for both the presented and expected values, do a case-insensitive
-+ * comparison of ASCII characters, and a case-sensitive comparison of
-+ * everything else.
-+ */
-+static krb5_boolean
-+label_match(const char *presented, size_t plen, const char *expected,
-+            size_t elen, krb5_boolean allow_wildcard, krb5_boolean *wildcard)
-+{
-+    unsigned int i;
-+
-+    if (allow_wildcard && plen == 1 && presented[0] == '*') {
-+        *wildcard = TRUE;
-+        return TRUE;
-+    }
-+
-+    if (plen != elen)
-+        return FALSE;
-+
-+    for (i = 0; i < elen; i++) {
-+        if (ascii_tolower(presented[i]) != ascii_tolower(expected[i]))
-+            return FALSE;
-+    }
-+    return TRUE;
-+}
-+
-+/* Break up the two names and check them, label by label. */
-+static krb5_boolean
-+domain_match(const char *presented, size_t plen, const char *expected)
-+{
-+    const char *p, *q, *r, *s;
-+    int n_label;
-+    krb5_boolean used_wildcard = FALSE;
-+
-+    n_label = 0;
-+    p = presented;
-+    r = expected;
-+    while (p < presented + plen && *r != '\0') {
-+        q = memchr(p, '.', plen - (p - presented));
-+        if (q == NULL)
-+            q = presented + plen;
-+        s = r + strcspn(r, ".");
-+        if (!label_match(p, q - p, r, s - r, n_label == 0, &used_wildcard))
-+            return FALSE;
-+        p = q < presented + plen ? q + 1 : q;
-+        r = *s ? s + 1 : s;
-+        n_label++;
-+    }
-+    if (used_wildcard && n_label <= 2)
-+        return FALSE;
-+    if (p == presented + plen && *r == '\0')
-+        return TRUE;
-+    return FALSE;
-+}
-+
-+/* Fetch the list of subjectAltNames from a certificate. */
-+static GENERAL_NAMES *
-+get_cert_sans(X509 *x)
-+{
-+    int ext;
-+    X509_EXTENSION *san_ext;
-+
-+    ext = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
-+    if (ext < 0)
-+        return NULL;
-+    san_ext = X509_get_ext(x, ext);
-+    if (san_ext == NULL)
-+        return NULL;
-+    return X509V3_EXT_d2i(san_ext);
-+}
-+
-+/* Fetch a CN value from the subjct name field, returning its length, or -1 if
-+ * there is no subject name or it contains no CN value. */
-+static int
-+get_cert_cn(X509 *x, char *buf, size_t bufsize)
-+{
-+    X509_NAME *name;
-+
-+    name = X509_get_subject_name(x);
-+    if (name == NULL)
-+        return -1;
-+    return X509_NAME_get_text_by_NID(name, NID_commonName, buf, bufsize);
-+}
-+
-+/* Return true if text matches any of the addresses we can recover from x. */
-+static krb5_boolean
-+check_cert_address(X509 *x, const char *text)
-+{
-+    char buf[1024];
-+    GENERAL_NAMES *sans;
-+    GENERAL_NAME *san = NULL;
-+    ASN1_OCTET_STRING *ip;
-+    krb5_boolean found_ip_san = FALSE, matched = FALSE;
-+    int n_sans, i;
-+    int name_length;
-+    struct in_addr sin;
-+    struct in6_addr sin6;
-+
-+    /* Parse the IP address into an octet string. */
-+    ip = M_ASN1_OCTET_STRING_new();
-+    if (ip == NULL)
-+        return FALSE;
-+    if (inet_pton(AF_INET, text, &sin)) {
-+        M_ASN1_OCTET_STRING_set(ip, &sin, sizeof(sin));
-+    } else if (inet_pton(AF_INET6, text, &sin6)) {
-+        M_ASN1_OCTET_STRING_set(ip, &sin6, sizeof(sin6));
-+    } else {
-+        ASN1_OCTET_STRING_free(ip);
-+        return FALSE;
-+    }
-+
-+    /* Check for matches in ipaddress subjectAltName values. */
-+    sans = get_cert_sans(x);
-+    if (sans != NULL) {
-+        n_sans = sk_GENERAL_NAME_num(sans);
-+        for (i = 0; i < n_sans; i++) {
-+            san = sk_GENERAL_NAME_value(sans, i);
-+            if (san->type != GEN_IPADD)
-+                continue;
-+            found_ip_san = TRUE;
-+            matched = (ASN1_OCTET_STRING_cmp(ip, san->d.iPAddress) == 0);
-+            if (matched)
-+                break;
-+        }
-+        sk_GENERAL_NAME_pop_free(sans, GENERAL_NAME_free);
-+    }
-+    ASN1_OCTET_STRING_free(ip);
-+
-+    if (found_ip_san)
-+        return matched;
-+
-+    /* Check for a match against the CN value in the peer's subject name. */
-+    name_length = get_cert_cn(x, buf, sizeof(buf));
-+    if (name_length >= 0) {
-+        /* Do a string compare to check if it's an acceptable value. */
-+        return strlen(text) == (size_t)name_length &&
-+               strncmp(text, buf, name_length) == 0;
-+    }
-+
-+    /* We didn't find a match. */
-+    return FALSE;
-+}
-+
-+/* Return true if expected matches any of the names we can recover from x. */
-+static krb5_boolean
-+check_cert_servername(X509 *x, const char *expected)
-+{
-+    char buf[1024];
-+    GENERAL_NAMES *sans;
-+    GENERAL_NAME *san = NULL;
-+    unsigned char *dnsname;
-+    krb5_boolean found_dns_san = FALSE, matched = FALSE;
-+    int name_length, n_sans, i;
-+
-+    /* Check for matches in dnsname subjectAltName values. */
-+    sans = get_cert_sans(x);
-+    if (sans != NULL) {
-+        n_sans = sk_GENERAL_NAME_num(sans);
-+        for (i = 0; i < n_sans; i++) {
-+            san = sk_GENERAL_NAME_value(sans, i);
-+            if (san->type != GEN_DNS)
-+                continue;
-+            found_dns_san = TRUE;
-+            dnsname = NULL;
-+            name_length = ASN1_STRING_to_UTF8(&dnsname, san->d.dNSName);
-+            if (dnsname == NULL)
-+                continue;
-+            matched = domain_match((char *)dnsname, name_length, expected);
-+            OPENSSL_free(dnsname);
-+            if (matched)
-+                break;
-+        }
-+        sk_GENERAL_NAME_pop_free(sans, GENERAL_NAME_free);
-+    }
-+
-+    if (matched)
-+        return TRUE;
-+    if (found_dns_san)
-+        return matched;
-+
-+    /* Check for a match against the CN value in the peer's subject name. */
-+    name_length = get_cert_cn(x, buf, sizeof(buf));
-+    if (name_length >= 0)
-+        return domain_match(buf, name_length, expected);
-+
-+    /* We didn't find a match. */
-+    return FALSE;
-+}
-+
-+static krb5_boolean
-+check_cert_name_or_ip(X509 *x, const char *expected_name)
-+{
-+    struct in_addr in;
-+    struct in6_addr in6;
-+
-+    if (inet_pton(AF_INET, expected_name, &in) != 0 ||
-+        inet_pton(AF_INET6, expected_name, &in6) != 0) {
-+        return check_cert_address(x, expected_name);
-+    } else {
-+        return check_cert_servername(x, expected_name);
-+    }
-+}
-+
-+static int
-+verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx)
-+{
-+    X509 *x;
-+    SSL *ssl;
-+    BIO *bio;
-+    krb5_context context;
-+    int err, depth;
-+    k5_tls_handle handle;
-+    const char *cert = NULL, *errstr, *expected_name;
-+    size_t count;
-+
-+    ssl = X509_STORE_CTX_get_ex_data(store_ctx,
-+                                     SSL_get_ex_data_X509_STORE_CTX_idx());
-+    context = SSL_get_ex_data(ssl, ex_context_id);
-+    handle = SSL_get_ex_data(ssl, ex_handle_id);
-+    assert(context != NULL && handle != NULL);
-+    /* We do have the peer's cert, right? */
-+    x = X509_STORE_CTX_get_current_cert(store_ctx);
-+    if (x == NULL) {
-+        TRACE_TLS_NO_REMOTE_CERTIFICATE(context);
-+        return 0;
-+    }
-+    /* Figure out where we are. */
-+    depth = X509_STORE_CTX_get_error_depth(store_ctx);
-+    if (depth < 0)
-+        return 0;
-+    /* If there's an error at this level that we're not ignoring, fail. */
-+    err = X509_STORE_CTX_get_error(store_ctx);
-+    if (err != X509_V_OK) {
-+        bio = BIO_new(BIO_s_mem());
-+        if (bio != NULL) {
-+            X509_NAME_print_ex(bio, x->cert_info->subject, 0, 0);
-+            count = BIO_get_mem_data(bio, &cert);
-+            errstr = X509_verify_cert_error_string(err);
-+            TRACE_TLS_CERT_ERROR(context, depth, count, cert, err, errstr);
-+            BIO_free(bio);
-+        }
-+        return 0;
-+    }
-+    /* If we're not looking at the peer, we're done and everything's ok. */
-+    if (depth != 0)
-+        return 1;
-+    /* Check if the name we expect to find is in the certificate. */
-+    expected_name = handle->servername;
-+    if (check_cert_name_or_ip(x, expected_name)) {
-+        TRACE_TLS_SERVER_NAME_MATCH(context, expected_name);
-+        return 1;
-+    } else {
-+        TRACE_TLS_SERVER_NAME_MISMATCH(context, expected_name);
-+    }
-+    /* The name didn't match. */
-+    return 0;
-+}
-+
-+static krb5_error_code
-+load_anchor_file(X509_STORE *store, const char *path)
-+{
-+    FILE *fp;
-+    STACK_OF(X509_INFO) *sk = NULL;
-+    X509_INFO *xi;
-+    int i;
-+
-+    fp = fopen(path, "r");
-+    if (fp == NULL)
-+        return errno;
-+    sk = PEM_X509_INFO_read(fp, NULL, NULL, NULL);
-+    fclose(fp);
-+    if (sk == NULL)
-+        return ENOENT;
-+    for (i = 0; i < sk_X509_INFO_num(sk); i++) {
-+        xi = sk_X509_INFO_value(sk, i);
-+        if (xi->x509 != NULL)
-+            X509_STORE_add_cert(store, xi->x509);
-+    }
-+    sk_X509_INFO_pop_free(sk, X509_INFO_free);
-+    return 0;
-+}
-+
-+static krb5_error_code
-+load_anchor_dir(X509_STORE *store, const char *path)
-+{
-+    DIR *d = NULL;
-+    struct dirent *dentry = NULL;
-+    char filename[1024];
-+    krb5_boolean found_any = FALSE;
-+
-+    d = opendir(path);
-+    if (d == NULL)
-+        return ENOENT;
-+    while ((dentry = readdir(d)) != NULL) {
-+        if (dentry->d_name[0] != '.') {
-+            snprintf(filename, sizeof(filename), "%s/%s",
-+                     path, dentry->d_name);
-+            if (load_anchor_file(store, filename) == 0)
-+                found_any = TRUE;
-+        }
-+    }
-+    closedir(d);
-+    return found_any ? 0 : ENOENT;
-+}
-+
-+static krb5_error_code
-+load_anchor(SSL_CTX *ctx, const char *location)
-+{
-+    X509_STORE *store;
-+    const char *envloc;
-+
-+    store = SSL_CTX_get_cert_store(ctx);
-+    if (strncmp(location, "FILE:", 5) == 0) {
-+        return load_anchor_file(store, location + 5);
-+    } else if (strncmp(location, "DIR:", 4) == 0) {
-+        return load_anchor_dir(store, location + 4);
-+    } else if (strncmp(location, "ENV:", 4) == 0) {
-+        envloc = getenv(location + 4);
-+        if (envloc == NULL)
-+            return ENOENT;
-+        return load_anchor(ctx, envloc);
-+    }
-+    return EINVAL;
-+}
-+
-+static krb5_error_code
-+load_anchors(krb5_context context, char **anchors, SSL_CTX *sctx)
-+{
-+    unsigned int i;
-+    krb5_error_code ret;
-+
-+    if (anchors != NULL) {
-+        for (i = 0; anchors[i] != NULL; i++) {
-+            ret = load_anchor(sctx, anchors[i]);
-+            if (ret)
-+                return ret;
-+        }
-+    } else {
-+        /* Use the library defaults. */
-+        if (SSL_CTX_set_default_verify_paths(sctx) != 1)
-+            return ENOENT;
-+    }
-+
-+    return 0;
-+}
-+
-+static krb5_error_code
-+setup(krb5_context context, SOCKET fd, const char *servername,
-+      char **anchors, k5_tls_handle *handle_out)
-+{
-+    int e;
-+    long options;
-+    SSL_CTX *ctx = NULL;
-+    SSL *ssl = NULL;
-+    k5_tls_handle handle = NULL;
-+
-+    *handle_out = NULL;
-+
-+    (void)CALL_INIT_FUNCTION(init_openssl);
-+    if (ex_context_id == -1 || ex_handle_id == -1)
-+        return KRB5_PLUGIN_OP_NOTSUPP;
-+
-+    /* Do general SSL library setup. */
-+    ctx = SSL_CTX_new(SSLv23_client_method());
-+    if (ctx == NULL)
-+        goto error;
-+    options = SSL_CTX_get_options(ctx);
-+    SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2);
-+
-+    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
-+    X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), 0);
-+    e = load_anchors(context, anchors, ctx);
-+    if (e != 0)
-+        goto error;
-+
-+    ssl = SSL_new(ctx);
-+    if (ssl == NULL)
-+        goto error;
-+
-+    if (!SSL_set_fd(ssl, fd))
-+        goto error;
-+    SSL_set_connect_state(ssl);
-+
-+    /* Create a handle and allow verify_callback to access it. */
-+    handle = malloc(sizeof(*handle));
-+    if (handle == NULL || !SSL_set_ex_data(ssl, ex_handle_id, handle))
-+        goto error;
-+
-+    handle->ssl = ssl;
-+    handle->servername = strdup(servername);
-+    if (handle->servername == NULL)
-+        goto error;
-+    *handle_out = handle;
-+    SSL_CTX_free(ctx);
-+    return 0;
-+
-+error:
-+    flush_errors(context);
-+    free(handle);
-+    SSL_free(ssl);
-+    SSL_CTX_free(ctx);
-+    return KRB5_PLUGIN_OP_NOTSUPP;
-+}
-+
-+static k5_tls_status
-+write_tls(krb5_context context, k5_tls_handle handle, const void *data,
-+          size_t len)
-+{
-+    int nwritten, e;
-+
-+    /* Try to transmit our request; allow verify_callback to access context. */
-+    if (!SSL_set_ex_data(handle->ssl, ex_context_id, context))
-+        return ERROR_TLS;
-+    nwritten = SSL_write(handle->ssl, data, len);
-+    (void)SSL_set_ex_data(handle->ssl, ex_context_id, NULL);
-+    if (nwritten > 0)
-+        return DONE;
-+
-+    e = SSL_get_error(handle->ssl, nwritten);
-+    if (e == SSL_ERROR_WANT_READ)
-+        return WANT_READ;
-+    else if (e == SSL_ERROR_WANT_WRITE)
-+        return WANT_WRITE;
-+    flush_errors(context);
-+    return ERROR_TLS;
-+}
-+
-+static k5_tls_status
-+read_tls(krb5_context context, k5_tls_handle handle, void *data,
-+         size_t data_size, size_t *len_out)
-+{
-+    ssize_t nread;
-+    int e;
-+
-+    *len_out = 0;
-+
-+    /* Try to read response data; allow verify_callback to access context. */
-+    if (!SSL_set_ex_data(handle->ssl, ex_context_id, context))
-+        return ERROR_TLS;
-+    nread = SSL_read(handle->ssl, data, data_size);
-+    (void)SSL_set_ex_data(handle->ssl, ex_context_id, NULL);
-+    if (nread > 0) {
-+        *len_out = nread;
-+        return DATA_READ;
-+    }
-+
-+    e = SSL_get_error(handle->ssl, nread);
-+    if (e == SSL_ERROR_WANT_READ)
-+        return WANT_READ;
-+    else if (e == SSL_ERROR_WANT_WRITE)
-+        return WANT_WRITE;
-+
-+    if (e == SSL_ERROR_ZERO_RETURN || (e == SSL_ERROR_SYSCALL && nread == 0))
-+        return DONE;
-+
-+    flush_errors(context);
-+    return ERROR_TLS;
-+}
-+
-+static void
-+free_handle(krb5_context context, k5_tls_handle handle)
-+{
-+    SSL_free(handle->ssl);
-+    free(handle->servername);
-+    free(handle);
-+}
-+
-+krb5_error_code
-+tls_k5tls_initvt(krb5_context context, int maj_ver, int min_ver,
-+                 krb5_plugin_vtable vtable);
-+
-+krb5_error_code
-+tls_k5tls_initvt(krb5_context context, int maj_ver, int min_ver,
-+                 krb5_plugin_vtable vtable)
-+{
-+    k5_tls_vtable vt;
-+
-+    vt = (k5_tls_vtable)vtable;
-+    vt->setup = setup;
-+    vt->write = write_tls;
-+    vt->read = read_tls;
-+    vt->free_handle = free_handle;
-+    return 0;
-+}
-+
-+#endif /* PROXY_TLS_IMPL_OPENSSL */
diff --git a/SOURCES/krb5-1.13-dirsrv-accountlock.patch b/SOURCES/krb5-1.13-dirsrv-accountlock.patch
new file mode 100644
index 0000000..0a6661c
--- /dev/null
+++ b/SOURCES/krb5-1.13-dirsrv-accountlock.patch
@@ -0,0 +1,63 @@
+Treat 'nsAccountLock: true' the same as 'loginDisabled: true'.  Updated from
+original version filed as RT#5891.
+
+diff -up krb5-1.8/src/aclocal.m4.dirsrv-accountlock krb5-1.8/src/aclocal.m4
+--- krb5-1.8/src/aclocal.m4.dirsrv-accountlock	2010-03-05 11:03:09.000000000 -0500
++++ krb5-1.8/src/aclocal.m4	2010-03-05 11:03:10.000000000 -0500
+@@ -1656,6 +1656,15 @@ if test $with_ldap = yes; then
+   AC_MSG_NOTICE(enabling OpenLDAP database backend module support)
+   OPENLDAP_PLUGIN=yes
+ fi
++AC_ARG_WITH([dirsrv-account-locking],
++[  --with-dirsrv-account-locking       compile 389/Red Hat/Fedora/Netscape Directory Server database backend module],
++[case "$withval" in
++    yes | no) ;;
++    *)  AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;;
++esac], with_dirsrv_account_locking=no)
++if test $with_dirsrv_account_locking = yes; then
++    AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.])
++fi
+ ])dnl
+ dnl
+ dnl If libkeyutils exists (on Linux) include it and use keyring ccache
+diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
+--- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock	2009-11-24 18:52:25.000000000 -0500
++++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c	2010-03-05 11:03:10.000000000 -0500
+@@ -1546,6 +1546,23 @@ populate_krb5_db_entry(krb5_context cont
+     ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data);
+     if (ret)
+         goto cleanup;
++#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING
++    {
++        krb5_timestamp              expiretime=0;
++        char                        *is_login_disabled=NULL;
++
++        /* LOGIN DISABLED */
++        ret = krb5_ldap_get_string(ld, ent, "nsAccountLock", &is_login_disabled,
++                                   &attr_present);
++        if (ret)
++            goto cleanup;
++        if (attr_present == TRUE) {
++            if (strcasecmp(is_login_disabled, "TRUE")== 0)
++                entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
++            free (is_login_disabled);
++        }
++    }
++#endif
+ 
+     ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname);
+     if (ret)
+         goto cleanup;
+diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+--- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock	2009-11-24 18:52:25.000000000 -0500
++++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c	2010-03-05 11:03:10.000000000 -0500
+@@ -59,6 +59,9 @@ char     *principal_attributes[] = { "kr
+                                      "krbLastFailedAuth",
+                                      "krbLoginFailedCount",
+                                      "krbLastSuccessfulAuth",
++#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING
++                                     "nsAccountLock",
++#endif
+                                      "krbLastPwdChange",
+                                      "krbLastAdminUnlock",
+                                      "krbExtraData",
diff --git a/SOURCES/krb5-1.13-selinux-label.patch b/SOURCES/krb5-1.13-selinux-label.patch
new file mode 100644
index 0000000..1cd86c0
--- /dev/null
+++ b/SOURCES/krb5-1.13-selinux-label.patch
@@ -0,0 +1,979 @@
+SELinux bases access to files on the domain of the requesting process,
+the operation being performed, and the context applied to the file.
+
+In many cases, applications needn't be SELinux aware to work properly,
+because SELinux can apply a default label to a file based on the label
+of the directory in which it's created.
+
+In the case of files such as /etc/krb5.keytab, however, this isn't
+sufficient, as /etc/krb5.keytab will almost always need to be given a
+label which differs from that of /etc/issue or /etc/resolv.conf.  The
+the kdb stash file needs a different label than the database for which
+it's holding a master key, even though both typically live in the same
+directory.
+
+To give the file the correct label, we can either force a "restorecon"
+call to fix a file's label after it's created, or create the file with
+the right label, as we attempt to do here.  We lean on THREEPARAMOPEN
+and define a similar macro named WRITABLEFOPEN with which we replace
+several uses of fopen().
+
+The file creation context that we're manipulating here is a process-wide
+attribute.  While for the most part, applications which need to label
+files when they're created have tended to be single-threaded, there's
+not much we can do to avoid interfering with an application that
+manipulates the creation context directly.  Right now we're mediating
+access using a library-local mutex, but that can only work for consumers
+that are part of this package -- an unsuspecting application will still
+stomp all over us.
+
+The selabel APIs for looking up the context should be thread-safe (per
+Red Hat #273081), so switching to using them instead of matchpathcon(),
+which we used earlier, is some improvement.
+
+--- krb5/src/aclocal.m4
++++ krb5/src/aclocal.m4
+@@ -103,6 +103,7 @@ AC_SUBST_FILE(libnodeps_frag)
+ dnl
+ KRB5_AC_PRAGMA_WEAK_REF
+ WITH_LDAP
++KRB5_WITH_SELINUX
+ KRB5_LIB_PARAMS
+ KRB5_AC_INITFINI
+ KRB5_AC_ENABLE_THREADS
+@@ -1791,3 +1792,51 @@ AC_SUBST(manlocalstatedir)
+ AC_SUBST(PAM_MAN)
+ AC_SUBST(NON_PAM_MAN)
+ ])dnl
++dnl
++dnl Use libselinux to set file contexts on newly-created files.
++dnl 
++AC_DEFUN(KRB5_WITH_SELINUX,[
++AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])],
++           withselinux="$withval",withselinux=auto)
++old_LIBS="$LIBS"
++if test "$withselinux" != no ; then
++       AC_MSG_RESULT([checking for libselinux...])
++       SELINUX_LIBS=
++       AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h)
++       if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then
++               if test "$withselinux" = auto ; then
++                       AC_MSG_RESULT([Unable to locate selinux/selinux.h.])
++                       withselinux=no
++               else
++                       AC_MSG_ERROR([Unable to locate selinux/selinux.h.])
++               fi
++       fi
++
++       LIBS=
++       unset ac_cv_func_setfscreatecon
++       AC_CHECK_FUNCS(setfscreatecon selabel_open)
++       if test "x$ac_cv_func_setfscreatecon" = xno ; then
++               AC_CHECK_LIB(selinux,setfscreatecon)
++               unset ac_cv_func_setfscreatecon
++               AC_CHECK_FUNCS(setfscreatecon selabel_open)
++               if test "x$ac_cv_func_setfscreatecon" = xyes ; then
++                       SELINUX_LIBS="$LIBS"
++               else
++                       if test "$withselinux" = auto ; then
++                               AC_MSG_RESULT([Unable to locate libselinux.])
++                               withselinux=no
++                       else
++                               AC_MSG_ERROR([Unable to locate libselinux.])
++                       fi
++               fi
++       fi
++       if test "$withselinux" != no ; then
++               AC_MSG_NOTICE([building with SELinux labeling support])
++               AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.])
++               SELINUX_LIBS="$LIBS"
++		EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon"
++       fi
++fi
++LIBS="$old_LIBS"
++AC_SUBST(SELINUX_LIBS)
++])dnl
+--- krb5/src/config/pre.in
++++ krb5/src/config/pre.in
+@@ -180,6 +180,7 @@ LD_UNRESOLVED_PREFIX = @LD_UNRESOLVED_PREFIX@
+ KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include
+ LDFLAGS = @LDFLAGS@
+ LIBS = @LIBS@
++SELINUX_LIBS=@SELINUX_LIBS@
+ 
+ INSTALL=@INSTALL@
+ INSTALL_STRIP=
+@@ -379,7 +380,7 @@ SUPPORT_LIB			= -l$(SUPPORT_LIBNAME)
+ # HESIOD_LIBS is -lhesiod...
+ HESIOD_LIBS	= @HESIOD_LIBS@
+ 
+-KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB)
++KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
+ KDB5_LIBS	= $(KDB5_LIB) $(GSSRPC_LIBS)
+ GSS_LIBS	= $(GSS_KRB5_LIB)
+ # needs fixing if ever used on Mac OS X!
+--- krb5/src/configure.in
++++ krb5/src/configure.in
+@@ -1053,6 +1053,8 @@ fi
+ 
+ KRB5_WITH_PAM
+ 
++KRB5_WITH_SELINUX
++
+ # Make localedir work in autoconf 2.5x.
+ if test "${localedir+set}" != set; then
+     localedir='$(datadir)/locale'
+--- krb5/src/include/k5-int.h
++++ krb5/src/include/k5-int.h
+@@ -129,6 +129,7 @@ typedef unsigned char   u_char;
+ 
+ 
+ #include "k5-platform.h"
++#include "k5-label.h"
+ 
+ #define KRB5_KDB_MAX_LIFE       (60*60*24) /* one day */
+ #define KRB5_KDB_MAX_RLIFE      (60*60*24*7) /* one week */
+--- krb5/src/include/k5-label.h
++++ krb5/src/include/k5-label.h
+@@ -0,0 +1,32 @@
++#ifndef _KRB5_LABEL_H
++#define _KRB5_LABEL_H
++
++#ifdef THREEPARAMOPEN
++#undef THREEPARAMOPEN
++#endif
++#ifdef WRITABLEFOPEN
++#undef WRITABLEFOPEN
++#endif
++
++/* Wrapper functions which help us create files and directories with the right
++ * context labels. */
++#ifdef USE_SELINUX
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <stdio.h>
++#include <unistd.h>
++FILE *krb5int_labeled_fopen(const char *path, const char *mode);
++int krb5int_labeled_creat(const char *path, mode_t mode);
++int krb5int_labeled_open(const char *path, int flags, ...);
++int krb5int_labeled_mkdir(const char *path, mode_t mode);
++int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device);
++#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z)
++#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y)
++void *krb5int_push_fscreatecon_for(const char *pathname);
++void krb5int_pop_fscreatecon(void *previous);
++#else
++#define WRITABLEFOPEN(x,y) fopen(x,y)
++#define THREEPARAMOPEN(x,y,z) open(x,y,z)
++#endif
++#endif
+--- krb5/src/include/krb5/krb5.hin
++++ krb5/src/include/krb5/krb5.hin
+@@ -87,6 +87,12 @@
+ #define THREEPARAMOPEN(x,y,z) open(x,y,z)
+ #endif
+ 
++#if KRB5_PRIVATE
++#ifndef WRITABLEFOPEN
++#define WRITABLEFOPEN(x,y) fopen(x,y)
++#endif
++#endif
++
+ #define KRB5_OLD_CRYPTO
+ 
+ #include <stdlib.h>
+--- krb5/src/kadmin/dbutil/dump.c
++++ krb5/src/kadmin/dbutil/dump.c
+@@ -376,12 +376,21 @@ create_ofile(char *ofile, char **tmpname
+ {
+     int fd = -1;
+     FILE *f;
++#ifdef USE_SELINUX
++    void *selabel;
++#endif
+ 
+     *tmpname = NULL;
+     if (asprintf(tmpname, "%s-XXXXXX", ofile) < 0)
+         goto error;
+ 
++#ifdef USE_SELINUX
++    selabel = krb5int_push_fscreatecon_for(ofile);
++#endif
+     fd = mkstemp(*tmpname);
++#ifdef USE_SELINUX
++    krb5int_pop_fscreatecon(selabel);
++#endif
+     if (fd == -1)
+         goto error;
+ 
+@@ -514,7 +514,7 @@ prep_ok_file(krb5_context context, char
+         return 0;
+     }
+ 
+-    *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
++    *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+     if (*fd == -1) {
+         com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
+         exit_status++;
+--- krb5/src/build-tools/krb5-config.in
++++ krb5/src/build-tools/krb5-config.in
+@@ -38,6 +38,7 @@ RPATH_FLAG='@RPATH_FLAG@'
+ DEFCCNAME='@DEFCCNAME@'
+ DEFKTNAME='@DEFKTNAME@'
+ DEFCKTNAME='@DEFCKTNAME@'
++SELINUX_LIBS='@SELINUX_LIBS@'
+ 
+ LIBS='@LIBS@'
+ GEN_LIB=@GEN_LIB@
+@@ -218,7 +219,7 @@
+     fi
+ 
+     # If we ever support a flag to generate output suitable for static
+-    # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB"
++    # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB"
+     # here.
+ 
+     echo $lib_flags
+--- krb5/src/lib/kadm5/logger.c
++++ krb5/src/lib/kadm5/logger.c
+@@ -425,7 +425,7 @@ krb5_klog_init(krb5_context kcontext, ch
+                      * Check for append/overwrite, then open the file.
+                      */
+                     if (cp[4] == ':' || cp[4] == '=') {
+-                        f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w");
++                        f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w");
+                         if (f) {
+                             set_cloexec_file(f);
+                             log_control.log_entries[i].lfu_filep = f;
+@@ -961,7 +961,7 @@ krb5_klog_reopen(krb5_context kcontext)
+              * In case the old logfile did not get moved out of the
+              * way, open for append to prevent squashing the old logs.
+              */
+-            f = fopen(log_control.log_entries[lindex].lfu_fname, "a+");
++            f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+");
+             if (f) {
+                 set_cloexec_file(f);
+                 log_control.log_entries[lindex].lfu_filep = f;
+--- krb5/src/lib/krb5/keytab/kt_file.c
++++ krb5/src/lib/krb5/keytab/kt_file.c
+@@ -1050,7 +1050,7 @@ krb5_ktfileint_open(krb5_context context
+ 
+     KTCHECKLOCK(id);
+     errno = 0;
+-    KTFILEP(id) = fopen(KTFILENAME(id),
++    KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id),
+                         (mode == KRB5_LOCKMODE_EXCLUSIVE) ?
+                         fopen_mode_rbplus : fopen_mode_rb);
+     if (!KTFILEP(id)) {
+@@ -1058,7 +1058,7 @@ krb5_ktfileint_open(krb5_context context
+             /* try making it first time around */
+             k5_create_secure_file(context, KTFILENAME(id));
+             errno = 0;
+-            KTFILEP(id) = fopen(KTFILENAME(id), fopen_mode_rbplus);
++            KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), fopen_mode_rbplus);
+             if (!KTFILEP(id))
+                 goto report_errno;
+             writevno = 1;
+--- krb5/src/plugins/kdb/db2/adb_openclose.c
++++ krb5/src/plugins/kdb/db2/adb_openclose.c
+@@ -201,7 +201,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char 
+          * POSIX systems
+          */
+         lockp->lockinfo.filename = strdup(lockfilename);
+-        if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) {
++        if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) {
+             /*
+              * maybe someone took away write permission so we could only
+              * get shared locks?
+--- krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c
++++ krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c
+@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c	8.
+ #include <string.h>
+ #include <unistd.h>
+ 
++#include "k5-int.h"
+ #include "db-int.h"
+ #include "btree.h"
+ 
+@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, 
+ 			goto einval;
+ 		}
+ 
+-		if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0)
++		if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
+ 			goto err;
+ 
+ 	} else {
+--- krb5/src/plugins/kdb/db2/libdb2/hash/hash.c
++++ krb5/src/plugins/kdb/db2/libdb2/hash/hash.c
+@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c	8.12 
+ #include <assert.h>
+ #endif
+ 
++#include "k5-int.h"
+ #include "db-int.h"
+ #include "hash.h"
+ #include "page.h"
+@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info
+ 		new_table = 1;
+ 	}
+ 	if (file) {
+-		if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1)
++		if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1)
+ 			RETURN_ERROR(errno, error0);
+ 		(void)fcntl(hashp->fp, F_SETFD, 1);
+ 	}
+--- krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
++++ krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
+@@ -179,7 +179,7 @@ done:
+ 
+     /* set password in the file */
+     old_mode = umask(0177);
+-    pfile = fopen(file_name, "a+");
++    pfile = WRITABLEFOPEN(file_name, "a+");
+     if (pfile == NULL) {
+         com_err(me, errno, _("Failed to open file %s: %s"), file_name,
+                 strerror (errno));
+@@ -220,6 +220,9 @@ done:
+          * Delete the existing entry and add the new entry
+          */
+         FILE *newfile;
++#ifdef USE_SELINUX
++        void *selabel;
++#endif
+ 
+         mode_t omask;
+ 
+@@ -231,7 +234,13 @@ done:
+         }
+ 
+         omask = umask(077);
++#ifdef USE_SELINUX
++        selabel = krb5int_push_fscreatecon_for(file_name);
++#endif
+         newfile = fopen(tmp_file, "w");
++#ifdef USE_SELINUX
++        krb5int_pop_fscreatecon(selabel);
++#endif
+         umask (omask);
+         if (newfile == NULL) {
+             com_err(me, errno, _("Error creating file %s"), tmp_file);
+--- krb5/src/slave/kpropd.c
++++ krb5/src/slave/kpropd.c
+@@ -437,6 +437,9 @@ void doit(fd)
+     krb5_enctype etype;
+     int database_fd;
+     char host[INET6_ADDRSTRLEN + 1];
++#ifdef USE_SELINUX
++    void *selabel;
++#endif
+ 
+     signal_wrapper(SIGALRM, alarm_handler);
+     alarm(params.iprop_resync_timeout);
+@@ -515,9 +518,15 @@ void doit(fd)
+         free(name);
+         exit(1);
+     }
++#ifdef USE_SELINUX
++    selabel = krb5int_push_fscreatecon_for(file);
++#endif
+     omask = umask(077);
+     lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600);
+     (void)umask(omask);
++#ifdef USE_SELINUX
++    krb5int_pop_fscreatecon(selabel);
++#endif
+     retval = krb5_lock_file(kpropd_context, lock_fd,
+                             KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK);
+     if (retval) {
+--- krb5/src/util/profile/prof_file.c
++++ krb5/src/util/profile/prof_file.c
+@@ -30,6 +30,7 @@
+ #endif
+ 
+ #include "k5-platform.h"
++#include "k5-label.h"
+ 
+ struct global_shared_profile_data {
+     /* This is the head of the global list of shared trees */
+@@ -418,7 +419,7 @@ static errcode_t write_data_to_file(prf_
+ 
+     errno = 0;
+ 
+-    f = fopen(new_file, "w");
++    f = WRITABLEFOPEN(new_file, "w");
+     if (!f) {
+         retval = errno;
+         if (retval == 0)
+--- krb5/src/util/support/Makefile.in
++++ krb5/src/util/support/Makefile.in
+@@ -54,6 +54,7 @@ IPC_SYMS= \
+ 
+ STLIBOBJS= \
+ 	threads.o \
++	selinux.o \
+ 	init-addrinfo.o \
+ 	plugins.o \
+ 	errors.o \
+@@ -108,7 +109,7 @@ SRCS=\
+ 
+ SHLIB_EXPDEPS =
+ # Add -lm if dumping thread stats, for sqrt.
+-SHLIB_EXPLIBS= $(LIBS) $(DL_LIB)
++SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
+ 
+ DEPLIBS=
+ 
+--- krb5/src/util/support/selinux.c
++++ krb5/src/util/support/selinux.c
+@@ -0,0 +1,381 @@
++/*
++ * Copyright 2007,2008,2009,2011,2012,2013 Red Hat, Inc.  All Rights Reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ *
++ *  Redistributions of source code must retain the above copyright notice, this
++ *  list of conditions and the following disclaimer.
++ *
++ *  Redistributions in binary form must reproduce the above copyright notice,
++ *  this list of conditions and the following disclaimer in the documentation
++ *  and/or other materials provided with the distribution.
++ *
++ *  Neither the name of Red Hat, Inc. nor the names of its contributors may be
++ *  used to endorse or promote products derived from this software without
++ *  specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ * 
++ * File-opening wrappers for creating correctly-labeled files.  So far, we can
++ * assume that this is Linux-specific, so we make many simplifying assumptions.
++ */
++
++#include "../../include/autoconf.h"
++
++#ifdef USE_SELINUX
++
++#include <k5-label.h>
++#include <k5-platform.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <limits.h>
++#include <pthread.h>
++#include <stdarg.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <selinux/selinux.h>
++#include <selinux/context.h>
++#ifdef HAVE_SELINUX_LABEL_H
++#include <selinux/label.h>
++#endif
++
++/* #define DEBUG 1 */
++
++/* Mutex used to serialize use of the process-global file creation context. */
++k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
++
++/* Make sure we finish initializing that mutex before attempting to use it. */
++k5_once_t labeled_once = K5_ONCE_INIT;
++static void
++label_mutex_init(void)
++{
++	k5_mutex_finish_init(&labeled_mutex);
++}
++
++#ifdef HAVE_SELINUX_LABEL_H
++static struct selabel_handle *selabel_ctx;
++static time_t selabel_last_changed;
++
++MAKE_FINI_FUNCTION(cleanup_fscreatecon);
++
++static void
++cleanup_fscreatecon(void)
++{
++	if (selabel_ctx != NULL) {
++		selabel_close(selabel_ctx);
++		selabel_ctx = NULL;
++	}
++}
++#endif
++
++static security_context_t
++push_fscreatecon(const char *pathname, mode_t mode)
++{
++	security_context_t previous, configuredsc, currentsc, derivedsc;
++	context_t current, derived;
++	const char *fullpath, *currentuser;
++
++	previous = NULL;
++	if (is_selinux_enabled()) {
++		if (getfscreatecon(&previous) == 0) {
++			char *genpath;
++			genpath = NULL;
++			if (pathname[0] != '/') {
++				char *wd;
++				size_t len;
++				len = 0;
++				wd = getcwd(NULL, len);
++				if (wd == NULL) {
++					if (previous != NULL) {
++						freecon(previous);
++					}
++					return NULL;
++				}
++				len = strlen(wd) + 1 + strlen(pathname) + 1;
++				genpath = malloc(len);
++				if (genpath == NULL) {
++					free(wd);
++					if (previous != NULL) {
++						freecon(previous);
++					}
++					return NULL;
++				}
++				sprintf(genpath, "%s/%s", wd, pathname);
++				free(wd);
++				fullpath = genpath;
++			} else {
++				fullpath = pathname;
++			}
++#ifdef DEBUG
++			if (isatty(fileno(stderr))) {
++				fprintf(stderr, "Looking up context for "
++					"\"%s\"(%05o).\n", fullpath, mode);
++			}
++#endif
++			configuredsc = NULL;
++#ifdef HAVE_SELINUX_LABEL_H
++			if ((selabel_ctx != NULL) ||
++			    (selabel_last_changed == 0)) {
++				const char *cpath;
++				struct stat st;
++				int i = -1;
++				cpath = selinux_file_context_path();
++				if ((cpath == NULL) ||
++				    ((i = stat(cpath, &st)) != 0) ||
++				    (st.st_mtime != selabel_last_changed)) {
++					if (selabel_ctx != NULL) {
++						selabel_close(selabel_ctx);
++						selabel_ctx = NULL;
++					}
++					selabel_last_changed = i ?
++							       time(NULL) :
++							       st.st_mtime;
++				}
++			}
++			if (selabel_ctx == NULL) {
++				selabel_ctx = selabel_open(SELABEL_CTX_FILE,
++							   NULL, 0);
++			}
++			if (selabel_ctx != NULL) {
++				if (selabel_lookup(selabel_ctx, &configuredsc,
++						   fullpath, mode) != 0) {
++					free(genpath);
++					if (previous != NULL) {
++						freecon(previous);
++					}
++					return NULL;
++				}
++			}
++#else
++			if (matchpathcon(fullpath, mode, &configuredsc) != 0) {
++				free(genpath);
++				if (previous != NULL) {
++					freecon(previous);
++				}
++				return NULL;
++			}
++#endif
++			free(genpath);
++			if (configuredsc == NULL) {
++				if (previous != NULL) {
++					freecon(previous);
++				}
++				return NULL;
++			}
++			currentsc = NULL;
++			getcon(&currentsc);
++			if (currentsc != NULL) {
++				derived = context_new(configuredsc);
++				if (derived != NULL) {
++					current = context_new(currentsc);
++					if (current != NULL) {
++						currentuser = context_user_get(current);
++						if (currentuser != NULL) {
++							if (context_user_set(derived,
++									     currentuser) == 0) {
++								derivedsc = context_str(derived);
++								if (derivedsc != NULL) {
++									freecon(configuredsc);
++									configuredsc = strdup(derivedsc);
++								}
++							}
++						}
++						context_free(current);
++					}
++					context_free(derived);
++				}
++				freecon(currentsc);
++			}
++#ifdef DEBUG
++			if (isatty(fileno(stderr))) {
++				fprintf(stderr, "Setting file creation context "
++					"to \"%s\".\n", configuredsc);
++			}
++#endif
++			if (setfscreatecon(configuredsc) != 0) {
++				freecon(configuredsc);
++				if (previous != NULL) {
++					freecon(previous);
++				}
++				return NULL;
++			}
++			freecon(configuredsc);
++#ifdef DEBUG
++		} else {
++			if (isatty(fileno(stderr))) {
++				fprintf(stderr, "Unable to determine "
++					"current context.\n");
++			}
++#endif
++		}
++	}
++	return previous;
++}
++
++static void
++pop_fscreatecon(security_context_t previous)
++{
++	if (is_selinux_enabled()) {
++#ifdef DEBUG
++		if (isatty(fileno(stderr))) {
++			if (previous != NULL) {
++				fprintf(stderr, "Resetting file creation "
++					"context to \"%s\".\n", previous);
++			} else {
++				fprintf(stderr, "Resetting file creation "
++					"context to default.\n");
++			}
++		}
++#endif
++		setfscreatecon(previous);
++		if (previous != NULL) {
++			freecon(previous);
++		}
++	}
++}
++
++void *
++krb5int_push_fscreatecon_for(const char *pathname)
++{
++	struct stat st;
++	void *retval;
++	k5_once(&labeled_once, label_mutex_init);
++	k5_mutex_lock(&labeled_mutex);
++	if (stat(pathname, &st) != 0) {
++		st.st_mode = S_IRUSR | S_IWUSR;
++	}
++	retval = push_fscreatecon(pathname, st.st_mode);
++	return retval ? retval : (void *) -1;
++}
++
++void
++krb5int_pop_fscreatecon(void *con)
++{
++	if (con != NULL) {
++		pop_fscreatecon((con == (void *) -1) ? NULL : con);
++		k5_mutex_unlock(&labeled_mutex);
++	}
++}
++
++FILE *
++krb5int_labeled_fopen(const char *path, const char *mode)
++{
++	FILE *fp;
++	int errno_save;
++	security_context_t ctx;
++
++	if ((strcmp(mode, "r") == 0) ||
++	    (strcmp(mode, "rb") == 0)) {
++		return fopen(path, mode);
++	}
++
++	k5_once(&labeled_once, label_mutex_init);
++	k5_mutex_lock(&labeled_mutex);
++	ctx = push_fscreatecon(path, 0);
++	fp = fopen(path, mode);
++	errno_save = errno;
++	pop_fscreatecon(ctx);
++	k5_mutex_unlock(&labeled_mutex);
++	errno = errno_save;
++	return fp;
++}
++
++int
++krb5int_labeled_creat(const char *path, mode_t mode)
++{
++	int fd;
++	int errno_save;
++	security_context_t ctx;
++
++	k5_once(&labeled_once, label_mutex_init);
++	k5_mutex_lock(&labeled_mutex);
++	ctx = push_fscreatecon(path, 0);
++	fd = creat(path, mode);
++	errno_save = errno;
++	pop_fscreatecon(ctx);
++	k5_mutex_unlock(&labeled_mutex);
++	errno = errno_save;
++	return fd;
++}
++
++int
++krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev)
++{
++	int ret;
++	int errno_save;
++	security_context_t ctx;
++
++	k5_once(&labeled_once, label_mutex_init);
++	k5_mutex_lock(&labeled_mutex);
++	ctx = push_fscreatecon(path, mode);
++	ret = mknod(path, mode, dev);
++	errno_save = errno;
++	pop_fscreatecon(ctx);
++	k5_mutex_unlock(&labeled_mutex);
++	errno = errno_save;
++	return ret;
++}
++
++int
++krb5int_labeled_mkdir(const char *path, mode_t mode)
++{
++	int ret;
++	int errno_save;
++	security_context_t ctx;
++
++	k5_once(&labeled_once, label_mutex_init);
++	k5_mutex_lock(&labeled_mutex);
++	ctx = push_fscreatecon(path, S_IFDIR);
++	ret = mkdir(path, mode);
++	errno_save = errno;
++	pop_fscreatecon(ctx);
++	k5_mutex_unlock(&labeled_mutex);
++	errno = errno_save;
++	return ret;
++}
++
++int
++krb5int_labeled_open(const char *path, int flags, ...)
++{
++	int fd;
++	int errno_save;
++	security_context_t ctx;
++	mode_t mode;
++	va_list ap;
++
++	if ((flags & O_CREAT) == 0) {
++		return open(path, flags);
++	}
++
++	k5_once(&labeled_once, label_mutex_init);
++	k5_mutex_lock(&labeled_mutex);
++	ctx = push_fscreatecon(path, 0);
++
++	va_start(ap, flags);
++	mode = va_arg(ap, mode_t);
++	fd = open(path, flags, mode);
++	va_end(ap);
++
++	errno_save = errno;
++	pop_fscreatecon(ctx);
++	k5_mutex_unlock(&labeled_mutex);
++	errno = errno_save;
++	return fd;
++}
++
++#endif
+--- krb5/src/lib/krb5/rcache/rc_dfl.c
++++ krb5/src/lib/krb5/rcache/rc_dfl.c
+@@ -813,6 +813,9 @@ krb5_rc_dfl_expunge_locked(krb5_context 
+     krb5_error_code retval = 0;
+     krb5_rcache tmp;
+     krb5_deltat lifespan = t->lifespan;  /* save original lifespan */
++#ifdef USE_SELINUX
++    void *selabel;
++#endif
+ 
+     if (! t->recovering) {
+         name = t->name;
+@@ -834,7 +837,17 @@ krb5_rc_dfl_expunge_locked(krb5_context 
+     retval = krb5_rc_resolve(context, tmp, 0);
+     if (retval)
+         goto cleanup;
++#ifdef USE_SELINUX
++    if (t->d.fn != NULL)
++        selabel = krb5int_push_fscreatecon_for(t->d.fn);
++    else
++        selabel = NULL;
++#endif
+     retval = krb5_rc_initialize(context, tmp, lifespan);
++#ifdef USE_SELINUX
++    if (selabel != NULL)
++        krb5int_pop_fscreatecon(selabel);
++#endif
+     if (retval)
+         goto cleanup;
+     for (q = t->a; q; q = q->na) {
+--- krb5/src/lib/krb5/ccache/cc_dir.c
++++ krb5/src/lib/krb5/ccache/cc_dir.c
+@@ -185,10 +185,19 @@ write_primary_file(const char *primary_p
+     char *newpath = NULL;
+     FILE *fp = NULL;
+     int fd = -1, status;
++#ifdef USE_SELINUX
++    void *selabel;
++#endif
+ 
+     if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0)
+         return ENOMEM;
++#ifdef USE_SELINUX
++    selabel = krb5int_push_fscreatecon_for(primary_path);
++#endif
+     fd = mkstemp(newpath);
++#ifdef USE_SELINUX
++    krb5int_pop_fscreatecon(selabel);
++#endif
+     if (fd < 0)
+         goto cleanup;
+ #ifdef HAVE_CHMOD
+@@ -223,10 +232,23 @@
+ verify_dir(krb5_context context, const char *dirname)
+ {
+     struct stat st;
++    int status;
++#ifdef USE_SELINUX
++    void *selabel;
++#endif
+ 
+     if (stat(dirname, &st) < 0) {
+-        if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0)
+-            return 0;
++        if (errno == ENOENT) {
++#ifdef USE_SELINUX
++            selabel = krb5int_push_fscreatecon_for(dirname);
++#endif
++            status = mkdir(dirname, S_IRWXU);
++#ifdef USE_SELINUX
++            krb5int_pop_fscreatecon(selabel);
++#endif
++            if (status == 0)
++                return 0;
++        }
+         k5_setmsg(context, KRB5_FCC_NOFILE,
+                   _("Credential cache directory %s does not exist"),
+                   dirname);
+--- krb5/src/lib/krb5/os/trace.c
++++ krb5/src/lib/krb5/os/trace.c
+@@ -401,7 +401,7 @@ krb5_set_trace_filename(krb5_context con
+     fd = malloc(sizeof(*fd));
+     if (fd == NULL)
+         return ENOMEM;
+-    *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600);
++    *fd = THREEPARAMOPEN(filename, O_WRONLY|O_CREAT|O_APPEND, 0600);
+     if (*fd == -1) {
+         free(fd);
+         return errno;
+--- krb5/src/plugins/kdb/db2/kdb_db2.c
++++ krb5/src/plugins/kdb/db2/kdb_db2.c
+@@ -683,8 +683,8 @@
+     if (retval)
+         return retval;
+ 
+-    dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC,
+-                           0600);
++    dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name,
++                                     O_CREAT | O_RDWR | O_TRUNC, 0600);
+     if (dbc->db_lf_file < 0) {
+         retval = errno;
+         goto cleanup;
+--- krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c
++++ krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c
+@@ -51,6 +51,7 @@
+ #include <stdio.h>
+ #include <unistd.h>
+ 
++#include "k5-int.h"
+ #include "db-int.h"
+ #include "recno.h"
+ 
+@@ -68,7 +69,8 @@
+ 	int rfd = -1, sverrno;
+ 
+ 	/* Open the user's file -- if this fails, we're done. */
+-	if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0)
++	if (fname != NULL &&
++            (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
+ 		return (NULL);
+ 
+ 	if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
+--- krb5/src/kdc/main.c
++++ krb5/src/kdc/main.c
+@@ -905,7 +905,7 @@ write_pid_file(const char *path)
+     FILE *file;
+     unsigned long pid;
+ 
+-    file = fopen(path, "w");
++    file = WRITABLEFOPEN(path, "w");
+     if (file == NULL)
+         return errno;
+     pid = (unsigned long) getpid();
+--- krb5/src/lib/kdb/kdb_log.c
++++ krb5/src/lib/kdb/kdb_log.c
+@@ -456,7 +456,7 @@ ulog_map(krb5_context context, const cha
+     int ulogfd = -1;
+ 
+     if (stat(logname, &st) == -1) {
+-        ulogfd = open(logname, O_RDWR | O_CREAT, 0600);
++        ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600);
+         if (ulogfd == -1)
+             return errno;
+ 
+--- krb5/src/util/gss-kernel-lib/Makefile.in
++++ krb5/src/util/gss-kernel-lib/Makefile.in
+@@ -60,6 +60,7 @@ HEADERS= \
+ 	gssapi_err_generic.h \
+ 	k5-int.h \
+ 	k5-int-pkinit.h \
++	k5-label.h \
+ 	k5-thread.h \
+ 	k5-platform.h \
+ 	k5-buf.h \
+@@ -166,10 +167,12 @@ gssapi_generic.h: $(GSS_GENERIC)/gssapi_
+ 	$(CP) $(GSS_GENERIC)/gssapi_generic.h $@
+ gssapi_err_generic.h: $(GSS_GENERIC_BUILD)/gssapi_err_generic.h
+ 	$(CP) $(GSS_GENERIC_BUILD)/gssapi_err_generic.h $@
+-k5-int.h: $(INCLUDE)/k5-int.h
++k5-int.h: $(INCLUDE)/k5-int.h k5-label.h
+ 	$(CP) $(INCLUDE)/k5-int.h $@
+ k5-int-pkinit.h: $(INCLUDE)/k5-int-pkinit.h
+ 	$(CP) $(INCLUDE)/k5-int-pkinit.h $@
++k5-label.h: $(INCLUDE)/k5-label.h
++	$(CP) $(INCLUDE)/k5-label.h $@
+ k5-thread.h: $(INCLUDE)/k5-thread.h
+ 	$(CP) $(INCLUDE)/k5-thread.h $@
+ k5-platform.h: $(INCLUDE)/k5-platform.h
diff --git a/SOURCES/krb5-1.13.2.tar.gz.asc b/SOURCES/krb5-1.13.2.tar.gz.asc
new file mode 100644
index 0000000..969169d
--- /dev/null
+++ b/SOURCES/krb5-1.13.2.tar.gz.asc
@@ -0,0 +1,14 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1
+
+iQGcBAABAgAGBQJVTUldAAoJEKMvF/0AVcMF9IoMAIEawAFZ1pRw91oRN6c3eAxy
+RYBuJWsEa73JtqKCRtz7LA3qgacnJ8FGTpXaGHB3zErO55+Bclo1KZsUoNDtT27O
+bxjsptPBjp15zTZhavlIpAjANFmo6QpghUHpLNcLxH8pXgmQDztHnPaenStxF8Bv
+P2oFKh31uY3gYzOKnYi/r14XKSTNpFiDiGty53KY61efAO4H7xRFMhBgN2Vv1pBm
+FvekjCWRypN7ai2z+94cuVNIlu8eipDnU4oBb865fRKlflxCdpBmHLr1K5AgwSEb
+OAvDUPAEV9GwBP94M0yAoPwGf5ZHPvdORXbHfX00lzX2SgV+9DH4BqJOnytOeuaT
+PA1Z+7izF+Xja4iHMcYlyJ7a/sGWachlZrw2ifELlYUf4vtcPY5e6gH0hSMUoA7t
+Ww18ryv5fPHT1l+/o2P03hzZSFllOXjVsComsfw6Ws7qzbFuigpiVYdBg1XKMi9L
+kjA7j43FTHvVKjtrEubiW+YHxowQHu5DIeQWVqsBJg==
+=KdUH
+-----END PGP SIGNATURE-----
diff --git a/SOURCES/krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch b/SOURCES/krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch
new file mode 100644
index 0000000..fc3101f
--- /dev/null
+++ b/SOURCES/krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch
@@ -0,0 +1,32 @@
+From 0e65104d521d29664c129c1cf5e918bf54ac055e Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Tue, 19 May 2015 10:38:51 -0400
+Subject: [PATCH] Fix bindresvport_sa port byte swap bug
+
+The sa_setport() helper handles conversion to network byte order, so
+bindresvport_sa() should not itself call htons() on the port argument.
+
+(This bug was introduced in commit
+0d04b60d159ab83b943e43802b1449a3b074bc83 when adding
+bindresvport_sa().  It was my fault, not Andreas Schneider's.)
+
+ticket: 8197 (new)
+target_version: 1.13.3
+tags: pullup
+---
+ src/lib/rpc/bindresvport.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/lib/rpc/bindresvport.c b/src/lib/rpc/bindresvport.c
+index ccc4d73..a421dd8 100644
+--- a/src/lib/rpc/bindresvport.c
++++ b/src/lib/rpc/bindresvport.c
+@@ -76,7 +76,7 @@ bindresvport_sa(int sd, struct sockaddr *sa)
+ 	res = -1;
+ 	errno = EADDRINUSE;
+ 	for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) {
+-		sa_setport(sa, htons(port++));
++		sa_setport(sa, port++);
+ 		if (port > ENDPORT) {
+ 			port = STARTPORT;
+ 		}
diff --git a/SOURCES/krb5-1.13.3-client_referrals.patch b/SOURCES/krb5-1.13.3-client_referrals.patch
new file mode 100644
index 0000000..6b94e1b
--- /dev/null
+++ b/SOURCES/krb5-1.13.3-client_referrals.patch
@@ -0,0 +1,31 @@
+From 4065b979071b6e34b440f1db24d66d8691792bee Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Thu, 3 Sep 2015 18:24:26 +0300
+Subject: [PATCH] client referral: return correct client principal in case of a
+ wrong realm
+
+prepare_error_as_req() gets protocol error code but compares it with
+table code and misses to add proper client principal as returned by the
+DAL driver.
+
+Use proper error code constant.
+---
+ src/kdc/do_as_req.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
+index 3a3ce8b..5440949 100644
+--- a/src/kdc/do_as_req.c
++++ b/src/kdc/do_as_req.c
+@@ -862,7 +862,7 @@ prepare_error_as(struct kdc_request_state *rstate, krb5_kdc_req *request,
+         return retval;
+     errpkt.error = error;
+     errpkt.server = request->server;
+-    errpkt.client = (error == KRB5KDC_ERR_WRONG_REALM) ? canon_client :
++    errpkt.client = (error == KDC_ERR_WRONG_REALM) ? canon_client :
+         request->client;
+     errpkt.text = string2data((char *)status);
+ 
+-- 
+2.4.3
+
diff --git a/SOURCES/krb5-1.13.3-client_referrals_test.patch b/SOURCES/krb5-1.13.3-client_referrals_test.patch
new file mode 100644
index 0000000..449646e
--- /dev/null
+++ b/SOURCES/krb5-1.13.3-client_referrals_test.patch
@@ -0,0 +1,604 @@
+diff --git a/src/plugins/kdb/test/Makefile.in b/src/plugins/kdb/test/Makefile.in
+new file mode 100644
+index 0000000..f9578a3
+--- /dev/null
++++ b/src/plugins/kdb/test/Makefile.in
+@@ -0,0 +1,21 @@
++mydir=plugins$(S)kdb$(S)test
++BUILDTOP=$(REL)..$(S)..$(S)..
++
++LIBBASE=test
++LIBMAJOR=0
++LIBMINOR=0
++RELDIR=../plugins/kdb/test
++SHLIB_EXPDEPS=$(KADMSRV_DEPLIB) $(KRB5_BASE_DEPLIBS)
++SHLIB_EXPLIBS=$(KADMSRV_LIBS) $(KRB5_BASE_LIBS)
++LOCALINCLUDES=-I../../../lib/kdb -I$(srcdir)/../../../lib/kdb
++
++SRCS = $(srcdir)/kdb_test.c
++
++STLIBOBJS = kdb_test.o
++
++all-unix:: all-liblinks
++install-unix::
++clean-unix:: clean-liblinks clean-libs clean-libobjs
++
++@libnover_frag@
++@libobj_frag@
+diff --git a/src/plugins/kdb/test/deps b/src/plugins/kdb/test/deps
+new file mode 100644
+index 0000000..e69de29
+diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c
+new file mode 100644
+index 0000000..a0e4970
+--- /dev/null
++++ b/src/plugins/kdb/test/kdb_test.c
+@@ -0,0 +1,561 @@
++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
++/* plugins/kdb/test/kdb_test.c - Test KDB module */
++/*
++ * Copyright (C) 2015 by the Massachusetts Institute of Technology.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * * Redistributions of source code must retain the above copyright
++ *   notice, this list of conditions and the following disclaimer.
++ *
++ * * Redistributions in binary form must reproduce the above copyright
++ *   notice, this list of conditions and the following disclaimer in
++ *   the documentation and/or other materials provided with the
++ *   distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/*
++ * This is a read-only KDB module intended to help test KDC behavior which
++ * cannot be exercised with the DB2 module.  Responses are read from the
++ * dbmodules subsection according to this example:
++ *
++ *     [dbmodules]
++ *         test = {
++ *             alias = {
++ *                 aliasname = canonname
++ *                 # For cross-realm aliases, only the realm part will
++ *                 # matter to the client.
++ *                 aliasname = @FOREIGN_REALM
++ *                 enterprise@PRINC = @FOREIGN_REALM
++ *             }
++ *             princs = {
++ *                 krbtgt/KRBTEST.COM = {
++ *                     flags = +preauth +ok-to-auth-as-delegate
++ *                     maxlife = 1d
++ *                     maxrenewlife = 7d
++ *                     expiration = 14d # relative to current time
++ *                     pwexpiration = 1h
++ *                     # Initial number is kvno; defaults to 1.
++ *                     keys = 3 aes256-cts aes128-cts:normal
++ *                     keys = 2 rc4-hmac
++ *                 }
++ *             }
++ *             delegation = {
++ *                 intermediate_service = target_service
++ *             }
++ *         }
++ *
++ * Key values are generated using a hash of the kvno, enctype, salt type, and
++ * principal name.  This module does not use master key encryption, so it
++ * serves as a partial test of the DAL's ability to avoid that.
++ */
++
++#include "k5-int.h"
++#include "kdb5.h"
++#include "adm_proto.h"
++#include <ctype.h>
++
++typedef struct {
++    void *profile;
++    char *section;
++    const char *names[6];
++} *testhandle;
++
++static void *
++ealloc(size_t sz)
++{
++    void *p = calloc(sz, 1);
++
++    if (p == NULL)
++        abort();
++    return p;
++}
++
++static char *
++estrdup(const char *s)
++{
++    char *copy = strdup(s);
++
++    if (copy == NULL)
++        abort();
++    return copy;
++}
++
++static void
++check(krb5_error_code code)
++{
++    if (code != 0)
++        abort();
++}
++
++/* Set up for a profile query using h->names.  Look up s1 -> s2 -> s3 (some of
++ * which may be NULL) within this database's dbmodules section. */
++static void
++set_names(testhandle h, const char *s1, const char *s2, const char *s3)
++{
++    h->names[0] = KDB_MODULE_SECTION;
++    h->names[1] = h->section;
++    h->names[2] = s1;
++    h->names[3] = s2;
++    h->names[4] = s3;
++    h->names[5] = NULL;
++}
++
++/* Look up a string within this database's dbmodules section. */
++static char *
++get_string(testhandle h, const char *s1, const char *s2, const char *s3)
++{
++    krb5_error_code ret;
++    char **values, *val;
++
++    set_names(h, s1, s2, s3);
++    ret = profile_get_values(h->profile, h->names, &values);
++    if (ret == PROF_NO_RELATION)
++        return NULL;
++    if (ret)
++        abort();
++    val = estrdup(values[0]);
++    profile_free_list(values);
++    return val;
++}
++
++/* Look up a duration within this database's dbmodules section. */
++static krb5_deltat
++get_duration(testhandle h, const char *s1, const char *s2, const char *s3)
++{
++    char *strval = get_string(h, s1, s2, s3);
++    krb5_deltat val;
++
++    if (strval == NULL)
++        return 0;
++    check(krb5_string_to_deltat(strval, &val));
++    free(strval);
++    return val;
++}
++
++/* Look up an absolute time within this database's dbmodules section.  The time
++ * is expressed in the profile as an interval relative to the current time. */
++static krb5_timestamp
++get_time(testhandle h, const char *s1, const char *s2, const char *s3)
++{
++    char *strval = get_string(h, s1, s2, s3);
++    krb5_deltat val;
++
++    if (strval == NULL)
++        return 0;
++    check(krb5_string_to_deltat(strval, &val));
++    free(strval);
++    return val + time(NULL);
++}
++
++/* Initialize kb_out with a key of type etype, using a hash of kvno, etype,
++ * salttype, and princstr for the key bytes. */
++static void
++make_keyblock(krb5_kvno kvno, krb5_enctype etype, int32_t salttype,
++              const char *princstr, krb5_keyblock *kb_out)
++{
++    size_t keybytes, keylength, pos, n;
++    char *hashstr;
++    krb5_data d, rndin;
++    krb5_checksum cksum;
++
++    check(krb5_c_keylengths(NULL, etype, &keybytes, &keylength));
++    alloc_data(&rndin, keybytes);
++
++    /* Hash the kvno, enctype, salt type, and principal name together. */
++    if (asprintf(&hashstr, "%d %d %d %s", (int)kvno, (int)etype,
++                 (int)salttype, princstr) < 0)
++        abort();
++    d = string2data(hashstr);
++    check(krb5_c_make_checksum(NULL, CKSUMTYPE_NIST_SHA, NULL, 0, &d, &cksum));
++
++    /* Make the appropriate number of input bytes from the hash result. */
++    for (pos = 0; pos < keybytes; pos += n) {
++        n = (cksum.length < keybytes - pos) ? cksum.length : keybytes - pos;
++        memcpy(rndin.data + pos, cksum.contents, n);
++    }
++
++    kb_out->enctype = etype;
++    kb_out->length = keylength;
++    kb_out->contents = ealloc(keylength);
++    check(krb5_c_random_to_key(NULL, etype, &rndin, kb_out));
++    free(cksum.contents);
++    free(rndin.data);
++    free(hashstr);
++}
++
++/* Return key data for the given key/salt tuple strings, using hashes of the
++ * enctypes, salts, and princstr for the key contents. */
++static void
++make_keys(char **strings, const char *princstr, krb5_db_entry *ent)
++{
++    krb5_key_data *key_data, *kd;
++    krb5_keyblock kb;
++    int32_t *ks_list_sizes, nstrings, nkeys, i, j;
++    krb5_key_salt_tuple **ks_lists, *ks;
++    krb5_kvno *kvnos;
++    char *s;
++
++    for (nstrings = 0; strings[nstrings] != NULL; nstrings++);
++    ks_lists = ealloc(nstrings * sizeof(*ks_lists));
++    ks_list_sizes = ealloc(nstrings * sizeof(*ks_list_sizes));
++    kvnos = ealloc(nstrings * sizeof(*kvnos));
++
++    /* Convert each string into a key/salt tuple list and count the total
++     * number of key data structures needed. */
++    nkeys = 0;
++    for (i = 0; i < nstrings; i++) {
++        s = strings[i];
++        /* Read a leading kvno if present; otherwise assume kvno 1. */
++        if (isdigit(*s)) {
++            kvnos[i] = strtol(s, &s, 10);
++            while (isspace(*s))
++                s++;
++        } else {
++            kvnos[i] = 1;
++        }
++        check(krb5_string_to_keysalts(s, NULL, NULL, FALSE, &ks_lists[i],
++                                      &ks_list_sizes[i]));
++        nkeys += ks_list_sizes[i];
++    }
++
++    /* Turn each key/salt tuple into a key data entry. */
++    kd = key_data = ealloc(nkeys * sizeof(*kd));
++    for (i = 0; i < nstrings; i++) {
++        ks = ks_lists[i];
++        for (j = 0; j < ks_list_sizes[i]; j++) {
++            make_keyblock(kvnos[i], ks[j].ks_enctype, ks[j].ks_salttype,
++                          princstr, &kb);
++            kd->key_data_ver = 2;
++            kd->key_data_kvno = kvnos[i];
++            kd->key_data_type[0] = ks[j].ks_enctype;
++            kd->key_data_length[0] = kb.length;
++            kd->key_data_contents[0] = kb.contents;
++            kd->key_data_type[1] = ks[j].ks_salttype;
++            kd++;
++        }
++    }
++
++    for (i = 0; i < nstrings; i++)
++        free(ks_lists[i]);
++    free(ks_lists);
++    free(ks_list_sizes);
++    free(kvnos);
++    ent->key_data = key_data;
++    ent->n_key_data = nkeys;
++}
++
++static krb5_error_code
++test_init()
++{
++    return 0;
++}
++
++static krb5_error_code
++test_cleanup()
++{
++    return 0;
++}
++
++static krb5_error_code
++test_open(krb5_context context, char *conf_section, char **db_args, int mode)
++{
++    testhandle h;
++
++    h = ealloc(sizeof(*h));
++    h->profile = context->profile;
++    h->section = estrdup(conf_section);
++    context->dal_handle->db_context = h;
++    return 0;
++}
++
++static krb5_error_code
++test_close(krb5_context context)
++{
++    testhandle h = context->dal_handle->db_context;
++
++    free(h->section);
++    free(h);
++    return 0;
++}
++
++static krb5_error_code
++test_get_principal(krb5_context context, krb5_const_principal search_for,
++                   unsigned int flags, krb5_db_entry **entry)
++{
++    krb5_error_code ret;
++    krb5_principal princ = NULL;
++    krb5_principal_data empty_princ = { KV5M_PRINCIPAL };
++    testhandle h = context->dal_handle->db_context;
++    char *search_name = NULL, *canon = NULL, *flagstr, **names, **key_strings;
++    const char *ename;
++    krb5_db_entry *ent;
++
++    *entry = NULL;
++
++    check(krb5_unparse_name_flags(context, search_for,
++                                  KRB5_PRINCIPAL_UNPARSE_NO_REALM,
++                                  &search_name));
++    canon = get_string(h, "alias", search_name, NULL);
++    if (canon != NULL) {
++        if (!(flags & KRB5_KDB_FLAG_ALIAS_OK)) {
++            ret = KRB5_KDB_NOENTRY;
++            goto cleanup;
++        }
++        check(krb5_parse_name(context, canon, &princ));
++        if (!krb5_realm_compare(context, search_for, princ)) {
++            if (flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) {
++                /* Return a client referral by creating an entry with only the
++                 * principal set. */
++                *entry = ealloc(sizeof(**entry));
++                (*entry)->princ = princ;
++                princ = NULL;
++                ret = 0;
++                goto cleanup;
++            } else {
++                /* We could look up a cross-realm TGS entry, but we don't need
++                 * that behavior yet. */
++                ret = KRB5_KDB_NOENTRY;
++                goto cleanup;
++            }
++        }
++        ename = canon;
++    } else {
++        check(krb5_copy_principal(context, search_for, &princ));
++        ename = search_name;
++    }
++
++    /* Check that the entry exists. */
++    set_names(h, "princs", ename, NULL);
++    ret = profile_get_relation_names(h->profile, h->names, &names);
++    if (ret == PROF_NO_RELATION) {
++        ret = KRB5_KDB_NOENTRY;
++        goto cleanup;
++    }
++    profile_free_list(names);
++
++    /* No error exits after this point. */
++
++    ent = ealloc(sizeof(*ent));
++    ent->princ = princ;
++    princ = NULL;
++
++    flagstr = get_string(h, "princs", ename, "flags");
++    if (flagstr != NULL) {
++        check(krb5_flagspec_to_mask(flagstr, &ent->attributes,
++                                    &ent->attributes));
++    }
++    free(flagstr);
++
++    ent->max_life = get_duration(h, "princs", ename, "maxlife");
++    ent->max_renewable_life = get_duration(h, "princs", ename, "maxrenewlife");
++    ent->expiration = get_time(h, "princs", ename, "expiration");
++    ent->pw_expiration = get_time(h, "princs", ename, "pwexpiration");
++
++    /* Leave last_success, last_failed, fail_auth_count zeroed. */
++    /* Leave tl_data and e_data empty. */
++
++    set_names(h, "princs", ename, "keys");
++    ret = profile_get_values(h->profile, h->names, &key_strings);
++    if (ret != PROF_NO_RELATION) {
++        make_keys(key_strings, ename, ent);
++        profile_free_list(key_strings);
++    }
++
++    /* We must include mod-princ data or kadm5_get_principal() won't work and
++     * we can't extract keys with kadmin.local. */
++    check(krb5_dbe_update_mod_princ_data(context, ent, 0, &empty_princ));
++
++    *entry = ent;
++
++cleanup:
++    krb5_free_unparsed_name(context, search_name);
++    krb5_free_principal(context, princ);
++    free(canon);
++    return ret;
++}
++
++static void
++test_free_principal(krb5_context context, krb5_db_entry *entry)
++{
++    krb5_tl_data *tl, *next;
++    int i, j;
++
++    if (entry == NULL)
++        return;
++    free(entry->e_data);
++    krb5_free_principal(context, entry->princ);
++    for (tl = entry->tl_data; tl != NULL; tl = next) {
++        next = tl->tl_data_next;
++        free(tl->tl_data_contents);
++        free(tl);
++    }
++    for (i = 0; i < entry->n_key_data; i++) {
++        for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
++            if (entry->key_data[i].key_data_length[j]) {
++                zapfree(entry->key_data[i].key_data_contents[j],
++                        entry->key_data[i].key_data_length[j]);
++            }
++            entry->key_data[i].key_data_contents[j] = NULL;
++            entry->key_data[i].key_data_length[j] = 0;
++            entry->key_data[i].key_data_type[j] = 0;
++        }
++    }
++    free(entry->key_data);
++    free(entry);
++}
++
++static void *
++test_alloc(krb5_context context, void *ptr, size_t size)
++{
++    return realloc(ptr, size);
++}
++
++static void
++test_free(krb5_context context, void *ptr)
++{
++    free(ptr);
++}
++
++static krb5_error_code
++test_fetch_master_key(krb5_context context, krb5_principal mname,
++                      krb5_keyblock *key_out, krb5_kvno *kvno_out,
++                      char *db_args)
++{
++    memset(key_out, 0, sizeof(*key_out));
++    *kvno_out = 0;
++    return 0;
++}
++
++static krb5_error_code
++test_fetch_master_key_list(krb5_context context, krb5_principal mname,
++                           const krb5_keyblock *key,
++                           krb5_keylist_node **mkeys_out)
++{
++    /* krb5_dbe_get_mkvno() returns an error if we produce NULL, so return an
++     * empty node to make kadm5_get_principal() work. */
++    *mkeys_out = ealloc(sizeof(**mkeys_out));
++    return 0;
++}
++
++static krb5_error_code
++test_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
++                      const krb5_key_data *kd, krb5_keyblock *key_out,
++                      krb5_keysalt *salt_out)
++{
++    key_out->magic = KV5M_KEYBLOCK;
++    key_out->enctype = kd->key_data_type[0];
++    key_out->length = kd->key_data_length[0];
++    key_out->contents = ealloc(key_out->length);
++    memcpy(key_out->contents, kd->key_data_contents[0], key_out->length);
++    if (salt_out != NULL) {
++        salt_out->type = (kd->key_data_ver > 1) ? kd->key_data_type[1] :
++            KRB5_KDB_SALTTYPE_NORMAL;
++        salt_out->data = empty_data();
++    }
++    return 0;
++}
++
++static krb5_error_code
++test_encrypt_key_data(krb5_context context, const krb5_keyblock *mkey,
++                      const krb5_keyblock *key, const krb5_keysalt *salt,
++                      int kvno, krb5_key_data *kd_out)
++{
++    memset(kd_out, 0, sizeof(*kd_out));
++    kd_out->key_data_ver = 2;
++    kd_out->key_data_kvno = kvno;
++    kd_out->key_data_type[0] = key->enctype;
++    kd_out->key_data_length[0] = key->length;
++    kd_out->key_data_contents[0] = ealloc(key->length);
++    memcpy(kd_out->key_data_contents[0], key->contents, key->length);
++    kd_out->key_data_type[1] = (salt != NULL) ? salt->type :
++        KRB5_KDB_SALTTYPE_NORMAL;
++    return 0;
++}
++
++static krb5_error_code
++test_check_allowed_to_delegate(krb5_context context,
++                               krb5_const_principal client,
++                               const krb5_db_entry *server,
++                               krb5_const_principal proxy)
++{
++    krb5_error_code ret;
++    testhandle h = context->dal_handle->db_context;
++    char *sprinc, *tprinc, **values, **v;
++    krb5_boolean found = FALSE;
++
++    check(krb5_unparse_name_flags(context, server->princ,
++                                  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &sprinc));
++    check(krb5_unparse_name_flags(context, proxy,
++                                  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &tprinc));
++    set_names(h, "delegation", sprinc, NULL);
++    ret = profile_get_values(h->profile, h->names, &values);
++    if (ret == PROF_NO_RELATION)
++        return KRB5KDC_ERR_POLICY;
++    for (v = values; *v != NULL; v++) {
++        if (strcmp(*v, tprinc) == 0) {
++            found = TRUE;
++            break;
++        }
++    }
++    profile_free_list(values);
++    return found ? 0 : KRB5KDC_ERR_POLICY;
++}
++
++kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_test, kdb_function_table) = {
++    KRB5_KDB_DAL_MAJOR_VERSION,             /* major version number */
++    0,                                      /* minor version number 0 */
++    test_init,
++    test_cleanup,
++    test_open,
++    test_close,
++    NULL, /* create */
++    NULL, /* destroy */
++    NULL, /* get_age */
++    NULL, /* lock */
++    NULL, /* unlock */
++    test_get_principal,
++    test_free_principal,
++    NULL, /* put_principal */
++    NULL, /* delete_principal */
++    NULL, /* iterate */
++    NULL, /* create_policy */
++    NULL, /* get_policy */
++    NULL, /* put_policy */
++    NULL, /* iter_policy */
++    NULL, /* delete_policy */
++    NULL, /* free_policy */
++    test_alloc,
++    test_free,
++    test_fetch_master_key,
++    test_fetch_master_key_list,
++    NULL, /* store_master_key_list */
++    NULL, /* dbe_search_enctype */
++    NULL, /* change_pwd */
++    NULL, /* promote_db */
++    test_decrypt_key_data,
++    test_encrypt_key_data,
++    NULL, /* sign_authdata */
++    NULL, /* check_transited_realms */
++    NULL, /* check_policy_as */
++    NULL, /* check_policy_tgs */
++    NULL, /* audit_as_req */
++    NULL, /* refresh_config */
++    test_check_allowed_to_delegate
++};
+diff --git a/src/plugins/kdb/test/test.exports b/src/plugins/kdb/test/test.exports
+new file mode 100644
+index 0000000..f2b7c11
+--- /dev/null
++++ b/src/plugins/kdb/test/test.exports
+@@ -0,0 +1 @@
++kdb_function_table
diff --git a/SOURCES/krb5-1.13_kinit_C_loop_krb5bug243.patch b/SOURCES/krb5-1.13_kinit_C_loop_krb5bug243.patch
deleted file mode 100644
index f9aa870..0000000
--- a/SOURCES/krb5-1.13_kinit_C_loop_krb5bug243.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From d5755694b620570defeecee772def90a2733c6cc Mon Sep 17 00:00:00 2001
-From: Simo Sorce <simo@redhat.com>
-Date: Tue, 20 Jan 2015 13:48:34 -0500
-Subject: [PATCH 1/2] Do not loop on principal unknown errors
-
-If the canonicalize flag is set, the MIT KDC always return the client
-principal when KRB5_KDC_ERR_C_PRICIPAL_UNKNOWN is returned.
-
-Check that this is really a referral by testing that the returned
-client realm differs from the requested one.
-
-[ghudson@mit.edu: simplified and narrowed is_referral() contract.
-Note that a WRONG_REALM response with e-data or FAST error padata
-could now be passed through k5_preauth_tryagain() if it has an empty
-crealm or a crealm equal to the requested client realm.  Such a
-response is unexpected in practice and there is nothing dangerous
-about handling it this way.]
-
-ticket: 8060
-target_version: 1.13.1
-tags: pullup
----
- src/lib/krb5/krb/get_in_tkt.c | 40 +++++++++++++---------------------------
- 1 file changed, 13 insertions(+), 27 deletions(-)
-
-diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
-index 2c2b654..f9bc027 100644
---- a/src/lib/krb5/krb/get_in_tkt.c
-+++ b/src/lib/krb5/krb/get_in_tkt.c
-@@ -1379,33 +1379,23 @@ note_req_timestamp(krb5_context context, krb5_init_creds_context ctx,
-         AUTH_OFFSET : UNAUTH_OFFSET;
- }
- 
--/* Determine whether the client realm in a KRB-ERROR is empty. */
--static krb5_boolean
--is_empty_crealm(krb5_error *err)
--{
--
--    return (err->client == NULL || err->client->realm.length == 0);
--}
--
- /*
-- * Determine whether a KRB-ERROR is a referral to another realm.
-+ * Determine whether err is a client referral to another realm, given the
-+ * previously requested client principal name.
-  *
-- * RFC 6806 Section 7 requires that KDCs return the referral realm in
-- * an error type WRONG_REALM, but Microsoft Windows Server 2003 (and
-- * possibly others) return the realm in a PRINCIPAL_UNKNOWN message.
-- * Detect this case by looking for a non-empty client.realm field in
-- * such responses.
-+ * RFC 6806 Section 7 requires that KDCs return the referral realm in an error
-+ * type WRONG_REALM, but Microsoft Windows Server 2003 (and possibly others)
-+ * return the realm in a PRINCIPAL_UNKNOWN message.
-  */
- static krb5_boolean
--is_referral(krb5_init_creds_context ctx)
-+is_referral(krb5_context context, krb5_error *err, krb5_principal client)
- {
--    krb5_error *err = ctx->err_reply;
--
--    if (err->error == KDC_ERR_WRONG_REALM)
--        return TRUE;
--    if (err->error != KDC_ERR_C_PRINCIPAL_UNKNOWN)
-+    if (err->error != KDC_ERR_WRONG_REALM &&
-+        err->error != KDC_ERR_C_PRINCIPAL_UNKNOWN)
-+        return FALSE;
-+    if (err->client == NULL)
-         return FALSE;
--    return !is_empty_crealm(err);
-+    return !krb5_realm_compare(context, err->client, client);
- }
- 
- static krb5_error_code
-@@ -1467,12 +1457,8 @@ init_creds_step_reply(krb5_context context,
-                                              ctx->preauth_to_use);
-             ctx->preauth_required = TRUE;
- 
--        } else if (canon_flag && is_referral(ctx)) {
--            if (is_empty_crealm(ctx->err_reply)) {
--                /* Only WRONG_REALM referral types can reach this. */
--                code = KRB5KDC_ERR_WRONG_REALM;
--                goto cleanup;
--            }
-+        } else if (canon_flag && is_referral(context, ctx->err_reply,
-+                                             ctx->request->client)) {
-             TRACE_INIT_CREDS_REFERRAL(context, &ctx->err_reply->client->realm);
-             /* Rewrite request.client with realm from error reply */
-             krb5_free_data_contents(context, &ctx->request->client->realm);
-
-From c0778ab2252ece4c3510788d9b72f7f5e3bb05dd Mon Sep 17 00:00:00 2001
-From: Greg Hudson <ghudson@mit.edu>
-Date: Fri, 23 Jan 2015 12:52:31 -0500
-Subject: [PATCH 2/2] Add test for kinit -C WRONG_REALM response
-
-ticket: 8060
----
- src/tests/t_general.py | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/src/tests/t_general.py b/src/tests/t_general.py
-index 98e77a2..5349b05 100755
---- a/src/tests/t_general.py
-+++ b/src/tests/t_general.py
-@@ -33,6 +33,13 @@
- 
- realm = K5Realm(create_host=False)
- 
-+# Test that WRONG_REALM responses aren't treated as referrals unless
-+# they contain a crealm field pointing to a different realm.
-+# (Regression test for #8060.)
-+out = realm.run([kinit, '-C', 'notfoundprinc'], expected_code=1)
-+if 'not found in Kerberos database' not in out:
-+    fail('Expected error message not seen in kinit -C output')
-+
- # Spot-check KRB5_TRACE output
- tracefile = os.path.join(realm.testdir, 'trace')
- realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, realm.user_princ],
diff --git a/SOURCES/krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch b/SOURCES/krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch
new file mode 100644
index 0000000..7757885
--- /dev/null
+++ b/SOURCES/krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch
@@ -0,0 +1,142 @@
+From 95c3cab051aa1b8b4f7eb309bf135e8f51665baa Mon Sep 17 00:00:00 2001
+From: Nathaniel McCallum <npmccallum@redhat.com>
+Date: Sun, 25 Jan 2015 16:53:49 -0500
+Subject: [PATCH] Support KDC_ERR_MORE_PREAUTH_DATA_REQUIRED
+
+Add support for multi-hop preauth mechs.
+
+In the KDC, allow kdcpreauth modules to return
+KDC_ERR_MORE_PREAUTH_DATA_REQUIRED as defined in RFC 6113.
+
+In libkrb5, treat this code like KDC_ERR_PREAUTH_REQUIRED.  clpreauth
+modules can use the modreq parameter to distinguish between the first
+and subsequent KDC messages.  We assume that the error padata will
+include an element of the preauth mech's type, or at least of a type
+recognized by the clpreauth module.
+
+Also reset the list of previously attempted preauth types for both
+kinds of errors.  That list is really only appropriate for retrying
+after a failed preauth attempt, which we don't currently do.  Add an
+intermediate variable for the reply code to avoid a long conditional
+expression.
+
+[ghudson@mit.edu: adjust get_in_tkt.c logic to avoid needing a helper
+function; clarify commit message]
+
+ticket: 8063 (new)
+---
+ doc/plugindev/clpreauth.rst           |  6 +++---
+ src/include/k5-int.h                  |  1 +
+ src/kdc/kdc_preauth.c                 |  2 ++
+ src/lib/krb5/error_tables/krb5_err.et |  2 +-
+ src/lib/krb5/krb/get_in_tkt.c         | 13 ++++++++-----
+ 5 files changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/doc/plugindev/clpreauth.rst b/doc/plugindev/clpreauth.rst
+index c3e7298..38aa52e 100644
+--- a/doc/plugindev/clpreauth.rst
++++ b/doc/plugindev/clpreauth.rst
+@@ -21,9 +21,9 @@ A clpreauth module is generally responsible for:
+   just returns ``PA_REAL``, indicating that it implements a normal
+   preauthentication type.
+ 
+-* Examining the padata information included in the preauth_required
+-  error and producing padata values for the next AS request.  This is
+-  done with the **process** method.
++* Examining the padata information included in a PREAUTH_REQUIRED or
++  MORE_PREAUTH_DATA_REQUIRED error and producing padata values for the
++  next AS request.  This is done with the **process** method.
+ 
+ * Examining the padata information included in a successful ticket
+   reply, possibly verifying the KDC identity and computing a reply
+diff --git a/src/include/k5-int.h b/src/include/k5-int.h
+index a1ea25a..4868e7d 100644
+--- a/src/include/k5-int.h
++++ b/src/include/k5-int.h
+@@ -391,6 +391,7 @@ typedef unsigned char   u_char;
+                                                       not find a KDC */
+ #define KRB_AP_ERR_IAKERB_KDC_NO_RESPONSE       86 /* The KDC did not respond
+                                                       to the IAKERB proxy */
++#define KDC_ERR_MORE_PREAUTH_DATA_REQUIRED      91 /* RFC 6113 */
+ #define KRB_ERR_MAX 127 /* err table base max offset for protocol err codes */
+ 
+ /*
+diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
+index 50cc252..dd83844 100644
+--- a/src/kdc/kdc_preauth.c
++++ b/src/kdc/kdc_preauth.c
+@@ -1000,6 +1000,8 @@ finish_check_padata(struct padata_state *state, krb5_error_code code)
+     case KRB5KDC_ERR_DISCARD:
+         /* pkinit alg-agility */
+     case KRB5KDC_ERR_NO_ACCEPTABLE_KDF:
++        /* rfc 6113 */
++    case KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED:
+         (*oldrespond)(oldarg, code);
+         return;
+     default:
+diff --git a/src/lib/krb5/error_tables/krb5_err.et b/src/lib/krb5/error_tables/krb5_err.et
+index 5c6f10b..7ba7c1e 100644
+--- a/src/lib/krb5/error_tables/krb5_err.et
++++ b/src/lib/krb5/error_tables/krb5_err.et
+@@ -132,7 +132,7 @@ error_code KRB5PLACEHOLD_87,	"KRB5 error code 87"
+ error_code KRB5PLACEHOLD_88,	"KRB5 error code 88"
+ error_code KRB5PLACEHOLD_89,	"KRB5 error code 89"
+ error_code KRB5PLACEHOLD_90,	"KRB5 error code 90"
+-error_code KRB5PLACEHOLD_91,	"KRB5 error code 91"
++error_code KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED,	"More preauthentication data is required"
+ error_code KRB5PLACEHOLD_92,	"KRB5 error code 92"
+ error_code KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION, "An unsupported critical FAST option was requested"
+ error_code KRB5PLACEHOLD_94,	"KRB5 error code 94"
+diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
+index f9bc027..fa8afcc 100644
+--- a/src/lib/krb5/krb/get_in_tkt.c
++++ b/src/lib/krb5/krb/get_in_tkt.c
+@@ -1239,7 +1239,8 @@ init_creds_step_request(krb5_context context,
+     clear_cc_config_out_data(context, ctx);
+ 
+     if (ctx->err_reply == NULL) {
+-        /* either our first attempt, or retrying after PREAUTH_NEEDED */
++        /* Either our first attempt, or retrying after KDC_ERR_PREAUTH_REQUIRED
++         * or KDC_ERR_MORE_PREAUTH_DATA_REQUIRED. */
+         code = k5_preauth(context, ctx, ctx->preauth_to_use,
+                           ctx->preauth_required, &ctx->request->padata,
+                           &ctx->selected_preauth_type);
+@@ -1408,6 +1409,7 @@ init_creds_step_reply(krb5_context context,
+     krb5_preauthtype kdc_pa_type;
+     krb5_boolean retry = FALSE;
+     int canon_flag = 0;
++    uint32_t reply_code;
+     krb5_keyblock *strengthen_key = NULL;
+     krb5_keyblock encrypting_key;
+     krb5_boolean fast_avail;
+@@ -1431,6 +1433,7 @@ init_creds_step_reply(krb5_context context,
+                                           &retry);
+         if (code != 0)
+             goto cleanup;
++        reply_code = ctx->err_reply->error;
+         if (negotiation_requests_restart(context, ctx, ctx->err_padata)) {
+             ctx->have_restarted = 1;
+             k5_preauth_request_context_fini(context);
+@@ -1441,9 +1444,10 @@ init_creds_step_reply(krb5_context context,
+             ctx->err_reply = NULL;
+             krb5_free_pa_data(context, ctx->err_padata);
+             ctx->err_padata = NULL;
+-        } else if (ctx->err_reply->error == KDC_ERR_PREAUTH_REQUIRED &&
+-                   retry) {
++        } else if ((reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED ||
++                    reply_code == KDC_ERR_PREAUTH_REQUIRED) && retry) {
+             /* reset the list of preauth types to try */
++            k5_reset_preauth_types_tried(context);
+             krb5_free_pa_data(context, ctx->preauth_to_use);
+             ctx->preauth_to_use = ctx->err_padata;
+             ctx->err_padata = NULL;
+@@ -1480,8 +1484,7 @@ init_creds_step_reply(krb5_context context,
+                 code = 0;
+             } else {
+                 /* error + no hints = give up */
+-                code = (krb5_error_code)ctx->err_reply->error +
+-                    ERROR_TABLE_BASE_krb5;
++                code = (krb5_error_code)reply_code + ERROR_TABLE_BASE_krb5;
+             }
+         }
+ 
diff --git a/SOURCES/krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch b/SOURCES/krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch
new file mode 100644
index 0000000..2aa2b93
--- /dev/null
+++ b/SOURCES/krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch
@@ -0,0 +1,22 @@
+# Fix for RH Bug #1250154 ("[s390x, ppc64, ppc64le]: kadmind does not
+# accept ACL if kadm5.acl does not end with EOL")
+# The code "accidently" works on x86/AMD64 because declaring a variable
+# |char| results in an |unsigned char| by default while most other platforms
+# (e.g. { s390x, ppc64, ppc64le, ...} ) default to |signed char|.
+# Lesson learned: Use lint(1) for development by default (saying that 
+# because Sun Studio lint(1) has found 38 more of these issues in
+# krb1.13.2... ;-( )
+# Written by Roland Mainz <rmainz@redhat.com>
+--- a/src/lib/kadm5/srv/server_acl.c
++++ b/src/lib/kadm5/srv/server_acl.c
+@@ -115,7 +115,7 @@
+             int byte;
+             byte = fgetc(fp);
+             acl_buf[i] = byte;
+-            if (byte == (char)EOF) {
++            if (byte == EOF) {
+                 if (i > 0 && acl_buf[i-1] == '\\')
+                     i--;
+                 break;          /* it gets nulled-out below */
+
+
diff --git a/SOURCES/krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch b/SOURCES/krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch
new file mode 100644
index 0000000..72ee35b
--- /dev/null
+++ b/SOURCES/krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch
@@ -0,0 +1,205 @@
+# Note: This file contains TWO patches, first the fix for the original
+# issue and then the valgrind fixes (modifed from the upstream commit
+# to match krb5 1.13.2)
+#######################################################################
+#### Patch1:
+From 50f426ac17a81ff5b7c212c24645b9874ea911f0 Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Mon, 17 Aug 2015 13:21:42 -0400
+Subject: [PATCH] Resolve krb5 GSS creds if time_rec is requested
+
+The code normally tries to defer credential acquisition to a later
+time.  However, if the application requests the lifetime, the code
+needs to resolve the credential and return the actual expiration time.
+Returning 0 would cause the application to think credentials are
+expired.
+
+In the mechglue, pass through null time_rec pointers to the mech so
+that the mech knows whether it was requested.  In SPNEGO, pass through
+time_rec to the mech when acquiring creds, via a new parameter to
+get_available_mechs().
+
+[ghudson@mit.edu: minor style changes; edit and expand commit message]
+
+ticket: 8235 (new)
+---
+# Comments:
+# - Added to fix RedHat bug #1252454 ('testsuite complains "Lifetime has
+#   increased by 32436 sec while 0 sec passed!", while rhel5-libkrb5 passes')
+# - Original upstream URL https://github.com/krb5/krb5/commit/50f426ac17a81ff5b7c212c24645b9874ea911f0
+---
+ src/lib/gssapi/krb5/acquire_cred.c       |  9 ++++++++-
+ src/lib/gssapi/mechglue/g_acquire_cred.c | 14 +++++++++-----
+ src/lib/gssapi/spnego/spnego_mech.c      | 15 ++++++++-------
+ 3 files changed, 25 insertions(+), 13 deletions(-)
+
+diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
+index 5bcfec9..6e83fb9 100644
+--- a/src/lib/gssapi/krb5/acquire_cred.c
++++ b/src/lib/gssapi/krb5/acquire_cred.c
+@@ -825,8 +825,15 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
+         if (code != 0)
+             goto krb_error_out;
+ 
+-        if (time_rec)
++        if (time_rec) {
++            /* Resolve cred now to determine the expiration time. */
++            ret = kg_cred_resolve(minor_status, context, (gss_cred_id_t)cred,
++                                  GSS_C_NO_NAME);
++            if (GSS_ERROR(ret))
++                goto error_out;
+             *time_rec = (cred->expire > now) ? (cred->expire - now) : 0;
++            k5_mutex_unlock(&cred->lock);
++        }
+     }
+ 
+     *minor_status = 0;
+diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c
+index ff250de..d29856c 100644
+--- a/src/lib/gssapi/mechglue/g_acquire_cred.c
++++ b/src/lib/gssapi/mechglue/g_acquire_cred.c
+@@ -190,8 +190,9 @@ OM_uint32 *			time_rec;
+ 	major = gss_add_cred_from(&tmpMinor, (gss_cred_id_t)creds,
+ 				  desired_name, &mechs->elements[i],
+ 				  cred_usage, time_req, time_req,
+-				  cred_store, NULL, NULL, &initTimeOut,
+-				  &acceptTimeOut);
++				  cred_store, NULL, NULL,
++				  time_rec ? &initTimeOut : NULL,
++				  time_rec ? &acceptTimeOut : NULL);
+ 	if (major == GSS_S_COMPLETE) {
+ 	    /* update the credential's time */
+ 	    if (cred_usage == GSS_C_ACCEPT) {
+@@ -356,7 +357,7 @@ gss_add_cred_from(minor_status, input_cred_handle,
+     OM_uint32		*acceptor_time_rec;
+ {
+     OM_uint32		status, temp_minor_status;
+-    OM_uint32		time_req, time_rec;
++    OM_uint32		time_req, time_rec = 0, *time_recp = NULL;
+     gss_union_name_t	union_name;
+     gss_union_cred_t	new_union_cred, union_cred;
+     gss_name_t		internal_name = GSS_C_NO_NAME;
+@@ -447,15 +448,18 @@ gss_add_cred_from(minor_status, input_cred_handle,
+     if (status != GSS_S_COMPLETE)
+ 	goto errout;
+ 
++    if (initiator_time_rec != NULL || acceptor_time_rec != NULL)
++	time_recp = &time_rec;
++
+     if (mech->gss_acquire_cred_from) {
+ 	status = mech->gss_acquire_cred_from(minor_status, internal_name,
+ 					     time_req, target_mechs,
+ 					     cred_usage, cred_store, &cred,
+-					     NULL, &time_rec);
++					     NULL, time_recp);
+     } else if (cred_store == GSS_C_NO_CRED_STORE) {
+ 	status = mech->gss_acquire_cred(minor_status, internal_name, time_req,
+ 					target_mechs, cred_usage, &cred, NULL,
+-					&time_rec);
++					time_recp);
+     } else {
+ 	return GSS_S_UNAVAILABLE;
+     }
+diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
+index 8ade245..f3d5f09 100644
+--- a/src/lib/gssapi/spnego/spnego_mech.c
++++ b/src/lib/gssapi/spnego/spnego_mech.c
+@@ -96,7 +96,8 @@ static gss_OID_set get_mech_set(OM_uint32 *, unsigned char **, unsigned int);
+ static OM_uint32 get_req_flags(unsigned char **, OM_uint32, OM_uint32 *);
+ static OM_uint32 get_available_mechs(OM_uint32 *, gss_name_t, gss_cred_usage_t,
+ 				     gss_const_key_value_set_t,
+-				     gss_cred_id_t *, gss_OID_set *);
++				     gss_cred_id_t *, gss_OID_set *,
++				     OM_uint32 *);
+ static OM_uint32 get_negotiable_mechs(OM_uint32 *, spnego_gss_cred_id_t,
+ 				      gss_cred_usage_t, gss_OID_set *);
+ static void release_spnego_ctx(spnego_gss_ctx_id_t *);
+@@ -399,7 +400,7 @@ spnego_gss_acquire_cred_from(OM_uint32 *minor_status,
+ 	 */
+ 	status = get_available_mechs(minor_status, desired_name,
+ 				     cred_usage, cred_store, &mcred,
+-				     &amechs);
++				     &amechs, time_rec);
+ 
+ 	if (actual_mechs && amechs != GSS_C_NULL_OID_SET) {
+ 		(void) gssint_copy_oid_set(&tmpmin, amechs, actual_mechs);
+@@ -2009,7 +2010,7 @@ spnego_gss_inquire_cred(
+ 			GSS_C_BOTH,
+ 			GSS_C_NO_CRED_STORE,
+ 			&creds,
+-			mechanisms);
++			mechanisms, NULL);
+ 		if (status != GSS_S_COMPLETE) {
+ 			dsyslog("Leaving inquire_cred\n");
+ 			return (status);
+@@ -2637,7 +2638,7 @@ spnego_gss_acquire_cred_with_password(OM_uint32 *minor_status,
+ 
+ 	status = get_available_mechs(minor_status, desired_name,
+ 				     cred_usage, GSS_C_NO_CRED_STORE,
+-				     NULL, &amechs);
++				     NULL, &amechs, NULL);
+ 	if (status != GSS_S_COMPLETE)
+ 	    goto cleanup;
+ 
+@@ -3006,7 +3007,7 @@ static OM_uint32
+ get_available_mechs(OM_uint32 *minor_status,
+ 	gss_name_t name, gss_cred_usage_t usage,
+ 	gss_const_key_value_set_t cred_store,
+-	gss_cred_id_t *creds, gss_OID_set *rmechs)
++	gss_cred_id_t *creds, gss_OID_set *rmechs, OM_uint32 *time_rec)
+ {
+ 	unsigned int	i;
+ 	int		found = 0;
+@@ -3060,7 +3061,7 @@ get_available_mechs(OM_uint32 *minor_status,
+ 						     GSS_C_INDEFINITE,
+ 						     *rmechs, usage,
+ 						     cred_store, creds,
+-						     &goodmechs, NULL);
++						     &goodmechs, time_rec);
+ 
+ 		/*
+ 		 * Drop the old list in favor of the new
+@@ -3110,7 +3111,7 @@ get_negotiable_mechs(OM_uint32 *minor_status, spnego_gss_cred_id_t spcred,
+ 		credptr = (usage == GSS_C_INITIATE) ? &creds : NULL;
+ 		ret = get_available_mechs(minor_status, GSS_C_NO_NAME, usage,
+ 					  GSS_C_NO_CRED_STORE, credptr,
+-					  rmechs);
++					  rmechs, NULL);
+ 		gss_release_cred(&tmpmin, &creds);
+ 		return (ret);
+ 	}
+#######################################################################
+#### Patch2:
+From 042e9fc95a662acb54dc9168749c6725f17ae34a Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Fri, 21 Aug 2015 12:16:07 -0400
+Subject: [PATCH] Keep valgrind happy after time_rec change
+
+In gss_acquire_cred_from(), initialize initTimeOut and acceptTimeOut
+so valgrind does not complain.  All these values are ignored if
+time_rec is NULL, so not having those variables initialized is
+harmless, but it is annoying to get noise in the valgrind output.
+
+[ghudson@mit.edu: clarify commit message]
+
+ticket: 8235
+---
+# Comments:
+# - modifed by Roland Mainz <rmainz@redhat.com> to match krb5 1.13.2
+---
+ src/lib/gssapi/mechglue/g_acquire_cred.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c
+index d29856c..9bd500b 100644
+--- a/src/lib/gssapi/mechglue/g_acquire_cred.c
++++ b/src/lib/gssapi/mechglue/g_acquire_cred.c
+@@ -133,7 +133,7 @@ OM_uint32 *			time_rec;
+ {
+     OM_uint32 major = GSS_S_FAILURE, tmpMinor;
+     OM_uint32 first_major = GSS_S_COMPLETE, first_minor = 0;
+-    OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE;
++    OM_uint32 initTimeOut = 0, acceptTimeOut = 0, outTime = GSS_C_INDEFINITE;
+     gss_OID_set mechs = GSS_C_NO_OID_SET;
+     unsigned int i;
+     gss_union_cred_t creds = NULL;
diff --git a/SOURCES/krb5-1.3.4-send-pr-tempfile.patch b/SOURCES/krb5-1.3.4-send-pr-tempfile.patch
deleted file mode 100644
index a9ffa31..0000000
--- a/SOURCES/krb5-1.3.4-send-pr-tempfile.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-Use mktemp to create our temporary files instead of basing them on our PID.
-Only portable if you assume the presence of a mktemp helper.
-diff -ur krb5-1.3.4/src/util/send-pr/send-pr.sh krb5-1.3.4/src/util/send-pr/send-pr.sh
---- krb5-1.3.4/src/util/send-pr/send-pr.sh	1997-03-20 01:13:56.000000000 +0100
-+++ krb5-1.3.4/src/util/send-pr/send-pr.sh	2004-09-20 11:28:56.000000000 +0200
-@@ -96,9 +96,9 @@
-   fi
- fi
- 
--TEMP=$TMPDIR/p$$
--BAD=$TMPDIR/pbad$$
--REF=$TMPDIR/pf$$
-+TEMP=`mktemp "$TMPDIR"/p.XXXXXX` || exit 1
-+BAD=`mktemp "$TMPDIR"/pbad.XXXXXX` || exit 1
-+REF=`mktemp "$TMPDIR"/pf.XXXXXX` || exit 1
- 
- # find a user name
- if [ "$LOGNAME" = "" ]; then
-@@ -122,9 +122,10 @@
- else
-   # Must use temp file due to incompatibilities in quoting behavior
-   # and to protect shell metacharacters in the expansion of $LOGNAME
--  $PASSWD | grep "^$LOGNAME:" | awk -F: '{print $5}' | sed -e 's/,.*//' > $TEMP
--  ORIGINATOR="`cat $TEMP`"
--  rm -f $TEMP
-+  TEMP2=`mktemp "$TMPDIR"/plogname.XXXXXX` || exit 1
-+  $PASSWD | grep "^$LOGNAME:" | awk -F: '{print $5}' | sed -e 's/,.*//' > $TEMP2
-+  ORIGINATOR="`cat $TEMP2`"
-+  rm -f $TEMP2
- fi
- 
- if [ -n "$ORGANIZATION" ]; then
-@@ -280,7 +281,7 @@
- # Catch some signals. ($xs kludge needed by Sun /bin/sh)
- xs=0
- trap 'rm -f $REF $TEMP; exit $xs' 0
--trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15
-+trap 'echo "$COMMAND: Aborting ..."; rm -f "$REF" "$BAD" "$TEMP"; xs=1; exit' 1 2 3 13 15
- 
- # If they told us to use a specific file, then do so.
- if [ -n "$IN_FILE" ]; then
diff --git a/SOURCES/krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch b/SOURCES/krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch
deleted file mode 100644
index e96c360..0000000
--- a/SOURCES/krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From d1f707024f1d0af6e54a18885322d70fa15ec4d3 Mon Sep 17 00:00:00 2001
-From: Greg Hudson <ghudson@mit.edu>
-Date: Fri, 5 Dec 2014 14:01:39 -0500
-Subject: [PATCH] Fix LDAP misused policy name crash [CVE-2014-5353]
-
-In krb5_ldap_get_password_policy_from_dn, if LDAP_SEARCH returns
-successfully with no results, return KRB5_KDB_NOENTRY instead of
-returning success with a zeroed-out policy object.  This fixes a null
-dereference when an admin attempts to use an LDAP ticket policy name
-as a password policy name.
-
-CVE-2014-5353:
-
-In MIT krb5, when kadmind is configured to use LDAP for the KDC
-database, an authenticated remote attacker can cause a NULL dereference
-by attempting to use a named ticket policy object as a password policy
-for a principal.  The attacker needs to be authenticated as a user who
-has the elevated privilege for setting password policy by adding or
-modifying principals.
-
-Queries to LDAP scoped to the krbPwdPolicy object class will correctly
-not return entries of other classes, such as ticket policy objects, but
-may return success with no returned elements if an object with the
-requested DN exists in a different object class.  In this case, the
-routine to retrieve a password policy returned success with a password
-policy object that consisted entirely of zeroed memory.  In particular,
-accesses to the policy name will dereference a NULL pointer.  KDC
-operation does not access the policy name field, but most kadmin
-operations involving the principal with incorrect password policy
-will trigger the crash.
-
-Thanks to Patrik Kis for reporting this problem.
-
-CVSSv2 Vector: AV:N/AC:M/Au:S/C:N/I:N/A:C/E:H/RL:OF/RC:C
-
-[kaduk@mit.edu: CVE description and CVSS score]
-
-ticket: 8051 (new)
-target_version: 1.13.1
-tags: pullup
----
- src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
-index 522773e..6779f51 100644
---- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
-+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
-@@ -314,10 +314,11 @@ krb5_ldap_get_password_policy_from_dn(krb5_context context, char *pol_name,
-     LDAP_SEARCH(pol_dn, LDAP_SCOPE_BASE, "(objectclass=krbPwdPolicy)", password_policy_attributes);
- 
-     ent=ldap_first_entry(ld, result);
--    if (ent != NULL) {
--        if ((st = populate_policy(context, ld, ent, pol_name, *policy)) != 0)
--            goto cleanup;
-+    if (ent == NULL) {
-+        st = KRB5_KDB_NOENTRY;
-+        goto cleanup;
-     }
-+    st = populate_policy(context, ld, ent, pol_name, *policy);
- 
- cleanup:
-     ldap_msgfree(result);
diff --git a/SOURCES/krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch b/SOURCES/krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch
deleted file mode 100644
index 01aef2c..0000000
--- a/SOURCES/krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 04038bf3633c4b909b5ded3072dc88c8c419bf16 Mon Sep 17 00:00:00 2001
-From: Ben Kaduk <kaduk@mit.edu>
-Date: Wed, 19 Nov 2014 12:04:46 -0500
-Subject: [PATCH] Support keyless principals in LDAP [CVE-2014-5354]
-
-Operations like "kadmin -q 'addprinc -nokey foo'" or
-"kadmin -q 'purgekeys -all foo'" result in principal entries with
-no keys present, so krb5_encode_krbsecretkey() would just return
-NULL, which then got unconditionally dereferenced in
-krb5_add_ber_mem_ldap_mod().
-
-Apply some fixes to krb5_encode_krbsecretkey() to handle zero-key
-principals better, correct the test for an allocation failure, and
-slightly restructure the cleanup handler to be shorter and more
-appropriate for the usage.  Once it no longer short-circuits when
-n_key_data is zero, it will produce an array of length two with both
-entries NULL, which is treated as an empty list by the LDAP library,
-the correct behavior for a keyless principal.
-
-However, attributes with empty values are only handled by the LDAP
-library for Modify operations, not Add operations (which only get
-a sequence of Attribute, with no operation field).  Therefore, only
-add an empty krbprincipalkey to the modlist when we will be performing a
-Modify, and not when we will be performing an Add, which is conditional
-on the (misspelled) create_standalone_prinicipal boolean.
-
-CVE-2014-5354:
-
-In MIT krb5, when kadmind is configured to use LDAP for the KDC
-database, an authenticated remote attacker can cause a NULL
-dereference by inserting into the database a principal entry which
-contains no long-term keys.
-
-In order for the LDAP KDC backend to translate a principal entry
-from the database abstraction layer into the form expected by the
-LDAP schema, the principal's keys are encoded into a
-NULL-terminated array of length-value entries to be stored in the
-LDAP database.  However, the subroutine which produced this array
-did not correctly handle the case where no keys were present,
-returning NULL instead of an empty array, and the array was
-unconditionally dereferenced while adding to the list of LDAP
-operations to perform.
-
-Versions of MIT krb5 prior to 1.12 did not expose a way for
-principal entries to have no long-term key material, and
-therefore are not vulnerable.
-
-    CVSSv2 Vector: AV:N/AC:M/Au:S/C:N/I:N/A:P/E:H/RL:OF/RC:C
-
-ticket: 8041 (new)
-tags: pullup
-target_version: 1.13.1
-subject: kadmind with ldap backend crashes when putting keyless entries
----
- src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c | 25 +++++++++++++++-------
- 1 file changed, 17 insertions(+), 8 deletions(-)
-
-diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
-index 3e560d9..10b5982 100644
---- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
-+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
-@@ -406,14 +406,14 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int n_key_data,
-     int num_versions = 1;
-     int i, j, last;
-     krb5_error_code err = 0;
--    krb5_key_data *key_data;
-+    krb5_key_data *key_data = NULL;
- 
--    if (n_key_data <= 0)
-+    if (n_key_data < 0)
-         return NULL;
- 
-     /* Make a shallow copy of the key data so we can alter it. */
-     key_data = k5calloc(n_key_data, sizeof(*key_data), &err);
--    if (key_data_in == NULL)
-+    if (key_data == NULL)
-         goto cleanup;
-     memcpy(key_data, key_data_in, n_key_data * sizeof(*key_data));
- 
-@@ -467,9 +467,8 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int n_key_data,
-     free(key_data);
-     if (err != 0) {
-         if (ret != NULL) {
--            for (i = 0; i <= num_versions; i++)
--                if (ret[i] != NULL)
--                    free (ret[i]);
-+            for (i = 0; ret[i] != NULL; i++)
-+                free (ret[i]);
-             free (ret);
-             ret = NULL;
-         }
-@@ -1036,9 +1035,19 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry,
-         bersecretkey = krb5_encode_krbsecretkey (entry->key_data,
-                                                  entry->n_key_data, mkvno);
- 
--        if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey",
--                                          LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, bersecretkey)) != 0)
-+        if (bersecretkey == NULL) {
-+            st = ENOMEM;
-             goto cleanup;
-+        }
-+        /* An empty list of bervals is only accepted for modify operations,
-+         * not add operations. */
-+        if (bersecretkey[0] != NULL || !create_standalone_prinicipal) {
-+            st = krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey",
-+                                           LDAP_MOD_REPLACE | LDAP_MOD_BVALUES,
-+                                           bersecretkey);
-+            if (st != 0)
-+                goto cleanup;
-+        }
- 
-         if (!(entry->mask & KADM5_PRINCIPAL)) {
-             memset(strval, 0, sizeof(strval));
diff --git a/SOURCES/krb5-ksu_not_working_with_default_principal.patch b/SOURCES/krb5-ksu_not_working_with_default_principal.patch
deleted file mode 100644
index 01ecdac..0000000
--- a/SOURCES/krb5-ksu_not_working_with_default_principal.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 3a32e1e6e644c6092f48cf6b6f2d0b8635b3dd52 Mon Sep 17 00:00:00 2001
-From: Nalin Dahyabhai <nalin@redhat.com>
-Date: Wed, 30 Jul 2014 17:12:31 -0400
-Subject: [PATCH] In ksu, without the -e flag, also check .k5users
-
-When ksu was explicitly told to spawn a shell, a line in .k5users which
-listed "*" as the allowed command would cause the principal named on the
-line to be considered as a candidate for authentication.
-
-When ksu was not passed a command to run, which implicitly meant that
-the invoking user wanted to run the target user's login shell, knowledge
-that the principal was a valid candidate was ignored, which could cause
-a less optimal choice of the default target principal.
-
-This doesn't impact the authorization checks which we perform later.
-
-ticket: 7983 (new)
----
- src/clients/ksu/heuristic.c | 19 ++++++-------------
- 1 file changed, 6 insertions(+), 13 deletions(-)
-
-diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c
-index c7e691c..99b54e5 100644
---- a/src/clients/ksu/heuristic.c
-+++ b/src/clients/ksu/heuristic.c
-@@ -264,20 +264,13 @@ get_authorized_princ_names(luser, cmd, princ_list)
- 
-     close_time(k5users_flag,users_fp, k5login_flag, login_fp);
- 
--    if (cmd) {
--        retval = list_union(k5login_list, k5users_filt_list, &combined_list);
--        if (retval){
--            close_time(k5users_flag,users_fp, k5login_flag,login_fp);
--            return retval;
--        }
--        *princ_list = combined_list;
--        return 0;
--    } else {
--        if (k5users_filt_list != NULL)
--            free(k5users_filt_list);
--        *princ_list = k5login_list;
--        return 0;
-+    retval = list_union(k5login_list, k5users_filt_list, &combined_list);
-+    if (retval){
-+        close_time(k5users_flag,users_fp, k5login_flag,login_fp);
-+        return retval;
-     }
-+    *princ_list = combined_list;
-+    return 0;
- }
- 
- static void close_time(k5users_flag, users_fp, k5login_flag, login_fp)
diff --git a/SOURCES/krb5-master-compatible-keys.patch b/SOURCES/krb5-master-compatible-keys.patch
deleted file mode 100644
index 7c36e05..0000000
--- a/SOURCES/krb5-master-compatible-keys.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-commit 4f99c75eb6b1a53d78b26648e39309261e37755c
-Author: Nalin Dahyabhai <nalin@dahyabhai.net>
-Date:   Tue Mar 18 16:39:47 2014 -0400
-
-    Try compatible keys in rd_req_dec "any" path
-    
-    When we go to decrypt a ticket using a keytab, we have two code paths.
-    
-    In the first (traditional) one, we try to read an entry that exactly
-    matches the principal name, enctype, and kvno from the ticket, and then
-    attempt to decrypt the ticket using the entry's key.  The keytab
-    routines helpfully return an entry so long as it's of a key type that's
-    compatible with the ticket being decrypted, fixing up the enctype in the
-    entry structure while doing so, allowing us to decrypt a DES-CBC-CRC
-    ticket with a DES-CBC-MD5 key.
-    
-    In the second code path, we try the key of every entry which loosely
-    matches the principal name from the ticket and which exactly matches its
-    enctype, meaning that the ticket/keytab pair above won't work if the
-    principal name is one which suggests we shouldn't be matching entries
-    exactly.
-    
-    This change modifies the "any" path to also try to decrypt the ticket
-    with compatible keys.
-    
-    [ghudson@mit.edu: avoid stuffing too much logic in one conditional]
-    
-    ticket: 7883 (new)
-
-diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c
-index 4b952f5..fbd088d 100644
---- a/src/lib/krb5/krb/rd_req_dec.c
-+++ b/src/lib/krb5/krb/rd_req_dec.c
-@@ -167,6 +167,8 @@ decrypt_ticket(krb5_context context, const krb5_ap_req *req,
-     krb5_error_code ret;
-     krb5_keytab_entry ent;
-     krb5_kt_cursor cursor;
-+    krb5_boolean similar;
-+    krb5_enctype req_etype = req->ticket->enc_part.enctype;
- 
- #ifdef LEAN_CLIENT
-     return KRB5KRB_AP_WRONG_PRINC;
-@@ -189,8 +191,12 @@ decrypt_ticket(krb5_context context, const krb5_ap_req *req,
-         goto cleanup;
- 
-     while ((ret = krb5_kt_next_entry(context, keytab, &ent, &cursor)) == 0) {
--        if (ent.key.enctype == req->ticket->enc_part.enctype &&
-+        ret = krb5_c_enctype_compare(context, ent.key.enctype, req_etype,
-+                                     &similar);
-+        if (ret == 0 && similar &&
-             krb5_sname_match(context, server, ent.principal)) {
-+            /* Coerce inexact matches to the request enctype. */
-+            ent.key.enctype = req_etype;
-             ret = try_one_entry(context, req, &ent, keyblock_out);
-             if (ret == 0) {
-                 TRACE_RD_REQ_DECRYPT_ANY(context, ent.principal, &ent.key);
diff --git a/SOURCES/krb5-master-mechd.patch b/SOURCES/krb5-master-mechd.patch
deleted file mode 100644
index 965a436..0000000
--- a/SOURCES/krb5-master-mechd.patch
+++ /dev/null
@@ -1,275 +0,0 @@
-commit 123c14fd8862ee8f11f6084d25958cb380655f35
-Author: Günther Deschner <gdeschner@redhat.com>
-Date:   Wed Mar 5 16:21:55 2014 +0100
-
-    Remove dead code from the mechglue initialization
-    
-    The stat check in gss_indicate_mechs had no consequent and would have
-    been redundant with logic in updateMechList if it did.
-    
-    [ghudson@mit.edu: elaborated commit message; removed unused
-    g_mechSetTime and now-irrelevant comment]
-
-diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
-index 48a825e..c6904e0 100644
---- a/src/lib/gssapi/mechglue/g_initialize.c
-+++ b/src/lib/gssapi/mechglue/g_initialize.c
-@@ -91,7 +91,6 @@ static gss_mech_info g_mechListTail = NULL;
- static k5_mutex_t g_mechListLock = K5_MUTEX_PARTIAL_INITIALIZER;
- static time_t g_confFileModTime = (time_t)0;
- 
--static time_t g_mechSetTime = (time_t)0;
- static gss_OID_set_desc g_mechSet = { 0, NULL };
- static k5_mutex_t g_mechSetLock = K5_MUTEX_PARTIAL_INITIALIZER;
- 
-@@ -213,8 +212,6 @@ gss_indicate_mechs(minorStatus, mechSet_out)
- OM_uint32 *minorStatus;
- gss_OID_set *mechSet_out;
- {
--	char *fileName;
--	struct stat fileInfo;
- 	OM_uint32 status;
- 
- 	/* Initialize outputs. */
-@@ -233,16 +230,6 @@ gss_OID_set *mechSet_out;
- 	if (*minorStatus != 0)
- 		return (GSS_S_FAILURE);
- 
--	fileName = MECH_CONF;
--
--	/*
--	 * If we have already computed the mechanisms supported and if it
--	 * is still valid; make a copy and return to caller,
--	 * otherwise build it first.
--	 */
--	if ((stat(fileName, &fileInfo) == 0 &&
--		fileInfo.st_mtime > g_mechSetTime)) {
--	} /* if g_mechSet is out of date or not initialized */
- 	if (build_mechSet())
- 		return GSS_S_FAILURE;
- 
-@@ -289,20 +276,6 @@ build_mechSet(void)
- 	 */
- 	k5_mutex_lock(&g_mechListLock);
- 
--#if 0
--	/*
--	 * this checks for the case when we need to re-construct the
--	 * g_mechSet structure, but the mechanism list is upto date
--	 * (because it has been read by someone calling
--	 * gssint_get_mechanism)
--	 */
--	if (fileInfo.st_mtime > g_confFileModTime)
--	{
--		g_confFileModTime = fileInfo.st_mtime;
--		loadConfigFile(fileName);
--	}
--#endif
--
- 	updateMechList();
- 
- 	/*
-
-commit 05cbef80d53f49d30a5d0563501226dc173734d4
-Author: Günther Deschner <gdeschner@redhat.com>
-Date:   Wed Mar 5 15:25:43 2014 +0100
-
-    Load mechglue config files from /etc/gss/mech.d
-    
-    In addition to loading /etc/gss/mech, glob for *.conf files in
-    /etc/gss/mech.d.  Load only config files which have changed since the
-    highest mtime we saw in the previous scan.  Scan at most once per
-    second to avoid excessive numbers of filesystem syscalls for busy
-    GSSAPI applications.
-    
-    [ghudson@mit.edu: rewrote commit message; style changes; added
-    once-per-second throttle on glob/stat calls]
-    
-    ticket: 7882 (new)
-
-diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
-index c6904e0..f0acf1a 100644
---- a/src/lib/gssapi/mechglue/g_initialize.c
-+++ b/src/lib/gssapi/mechglue/g_initialize.c
-@@ -41,6 +41,7 @@
- #include <string.h>
- #include <ctype.h>
- #include <errno.h>
-+#include <glob.h>
- 
- #define	M_DEFAULT	"default"
- 
-@@ -58,6 +59,7 @@
- #ifndef MECH_CONF
- #define	MECH_CONF "/etc/gss/mech"
- #endif
-+#define MECH_CONF_PATTERN MECH_CONF ".d/*.conf"
- 
- /* Local functions */
- static void addConfigEntry(const char *oidStr, const char *oid,
-@@ -90,6 +92,7 @@ static gss_mech_info g_mechList = NULL;
- static gss_mech_info g_mechListTail = NULL;
- static k5_mutex_t g_mechListLock = K5_MUTEX_PARTIAL_INITIALIZER;
- static time_t g_confFileModTime = (time_t)0;
-+static time_t g_confLastCall = (time_t)0;
- 
- static gss_OID_set_desc g_mechSet = { 0, NULL };
- static k5_mutex_t g_mechSetLock = K5_MUTEX_PARTIAL_INITIALIZER;
-@@ -383,6 +386,56 @@ const gss_OID oid;
- 	return (modOptions);
- } /* gssint_get_modOptions */
- 
-+/* Return the mtime of filename or its eventual symlink target (if it is a
-+ * symlink), whichever is larger.  Return (time_t)-1 if lstat or stat fails. */
-+static time_t
-+check_link_mtime(const char *filename, time_t *mtime_out)
-+{
-+	struct stat st1, st2;
-+
-+	if (lstat(filename, &st1) != 0)
-+		return (time_t)-1;
-+	if (!S_ISLNK(st1.st_mode))
-+		return st1.st_mtime;
-+	if (stat(filename, &st2) != 0)
-+		return (time_t)-1;
-+	return (st1.st_mtime > st2.st_mtime) ? st1.st_mtime : st2.st_mtime;
-+}
-+
-+/* Try to load any config files which have changed since the last call.  Config
-+ * files are MECH_CONF and any files matching MECH_CONF_PATTERN. */
-+static void
-+loadConfigFiles()
-+{
-+	glob_t globbuf;
-+	time_t highest_mtime = 0, mtime, now;
-+	char **pathptr;
-+
-+	/* Don't glob and stat more than once per second. */
-+	if (time(&now) == (time_t)-1 || now == g_confLastCall)
-+		return;
-+	g_confLastCall = now;
-+
-+	globbuf.gl_offs = 1;
-+	if (glob(MECH_CONF_PATTERN, GLOB_DOOFFS, NULL, &globbuf) != 0)
-+		return;
-+	globbuf.gl_pathv[0] = MECH_CONF;
-+
-+	for (pathptr = globbuf.gl_pathv; *pathptr != NULL; pathptr++) {
-+		mtime = check_link_mtime(*pathptr, &mtime);
-+		if (mtime == (time_t)-1)
-+			continue;
-+		if (mtime > highest_mtime)
-+			highest_mtime = mtime;
-+		if (mtime > g_confFileModTime)
-+			loadConfigFile(*pathptr);
-+	}
-+	g_confFileModTime = highest_mtime;
-+
-+	globbuf.gl_pathv[0] = NULL;
-+	globfree(&globbuf);
-+}
-+
- /*
-  * determines if the mechList needs to be updated from file
-  * and performs the update.
-@@ -401,17 +454,7 @@ updateMechList(void)
- 	loadConfigFromRegistry(HKEY_CURRENT_USER, MECH_KEY);
- 	loadConfigFromRegistry(HKEY_LOCAL_MACHINE, MECH_KEY);
- #else /* _WIN32 */
--	char *fileName;
--	struct stat fileInfo;
--
--	fileName = MECH_CONF;
--
--	/* check if mechList needs updating */
--	if (stat(fileName, &fileInfo) != 0 ||
--	    g_confFileModTime >= fileInfo.st_mtime)
--		return;
--	g_confFileModTime = fileInfo.st_mtime;
--	loadConfigFile(fileName);
-+	loadConfigFiles();
- #endif /* !_WIN32 */
- 
- 	/* Load any unloaded interposer mechanisms immediately, to make sure we
-
-commit ac98187641f6943ae571606c0b6a97f236f9b60c
-Author: Greg Hudson <ghudson@mit.edu>
-Date:   Wed May 28 23:51:49 2014 -0400
-
-    Read /etc/gss/mech if no mech.d/*.conf found
-    
-    Always read /etc/gss/mech, even if globbing /etc/gss/mech.d/*.conf
-    doesn't work.  Doing this using GLOB_DOOFFS proved error-prone, so use
-    a simpler approach: factor out the per-pathname handling into a helper
-    function load_if_changed, call it with MECH_CONF before the glob, then
-    pass each glob result through the helper.
-    
-    ticket: 7925
-
-diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
-index f0acf1a..8bce14c 100644
---- a/src/lib/gssapi/mechglue/g_initialize.c
-+++ b/src/lib/gssapi/mechglue/g_initialize.c
-@@ -402,38 +402,45 @@ check_link_mtime(const char *filename, time_t *mtime_out)
- 	return (st1.st_mtime > st2.st_mtime) ? st1.st_mtime : st2.st_mtime;
- }
- 
-+/* Load pathname if it is newer than last.  Update *highest to the maximum of
-+ * its current value and pathname's mod time. */
-+static void
-+load_if_changed(const char *pathname, time_t last, time_t *highest)
-+{
-+	time_t mtime;
-+
-+	mtime = check_link_mtime(pathname, &mtime);
-+	if (mtime == (time_t)-1)
-+		return;
-+	if (mtime > *highest)
-+		*highest = mtime;
-+	if (mtime > last)
-+		loadConfigFile(pathname);
-+}
-+
- /* Try to load any config files which have changed since the last call.  Config
-  * files are MECH_CONF and any files matching MECH_CONF_PATTERN. */
- static void
- loadConfigFiles()
- {
- 	glob_t globbuf;
--	time_t highest_mtime = 0, mtime, now;
--	char **pathptr;
-+	time_t highest = 0, now;
-+	char **path;
- 
- 	/* Don't glob and stat more than once per second. */
- 	if (time(&now) == (time_t)-1 || now == g_confLastCall)
- 		return;
- 	g_confLastCall = now;
- 
--	globbuf.gl_offs = 1;
--	if (glob(MECH_CONF_PATTERN, GLOB_DOOFFS, NULL, &globbuf) != 0)
--		return;
--	globbuf.gl_pathv[0] = MECH_CONF;
-+	load_if_changed(MECH_CONF, g_confFileModTime, &highest);
- 
--	for (pathptr = globbuf.gl_pathv; *pathptr != NULL; pathptr++) {
--		mtime = check_link_mtime(*pathptr, &mtime);
--		if (mtime == (time_t)-1)
--			continue;
--		if (mtime > highest_mtime)
--			highest_mtime = mtime;
--		if (mtime > g_confFileModTime)
--			loadConfigFile(*pathptr);
-+	if (glob(MECH_CONF_PATTERN, 0, NULL, &globbuf) == 0) {
-+		for (path = globbuf.gl_pathv; *path != NULL; path++)
-+			load_if_changed(*path, g_confFileModTime, &highest);
-+		globfree(&globbuf);
- 	}
--	g_confFileModTime = highest_mtime;
- 
--	globbuf.gl_pathv[0] = NULL;
--	globfree(&globbuf);
-+	g_confFileModTime = highest;
- }
- 
- /*
diff --git a/SOURCES/krb5-master-move-otp-sockets.patch b/SOURCES/krb5-master-move-otp-sockets.patch
deleted file mode 100644
index 8d86930..0000000
--- a/SOURCES/krb5-master-move-otp-sockets.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-Adjusted to apply to 1.12.2.
-
-commit 1e4bdcfed2c7bda94d5c135cc32a5993ca032501
-Author: Nathaniel McCallum <npmccallum@redhat.com>
-Date:   Wed Feb 5 10:59:46 2014 -0500
-
-    Move OTP sockets to KDC_RUN_DIR
-    
-    Some system configurations expect Unix-domain sockets to live under
-    /run or /var/run, and not other parts of /var where persistent
-    application state lives.  Define a new directory KDC_RUN_DIR using
-    $runstatedir (new in autoconf 2.70, so fall back to $localstatedir/run
-    if it's not set) and use that for the default socket path.
-    
-    [ghudson@mit.edu: commit message, otp.rst formatting fix]
-    
-    ticket: 7859 (new)
-
-diff --git a/doc/admin/otp.rst b/doc/admin/otp.rst
-index 0abd5ff..f12c36d 100644
---- a/doc/admin/otp.rst
-+++ b/doc/admin/otp.rst
-@@ -23,7 +23,7 @@ the following format::
- 
-     [otp]
-         <name> = {
--            server = <host:port or filename> (default: $KDCDIR/<name>.socket)
-+            server = <host:port or filename> (default: see below)
-             secret = <filename>
-             timeout = <integer> (default: 5 [seconds])
-             retries = <integer> (default: 3)
-@@ -33,7 +33,8 @@ the following format::
- If the server field begins with '/', it will be interpreted as a UNIX
- socket.  Otherwise, it is assumed to be in the format host:port.  When
- a UNIX domain socket is specified, the secret field is optional and an
--empty secret is used by default.
-+empty secret is used by default.  If the server field is not
-+specified, it defaults to |kdcrundir|\ ``/<name>.socket``.
- 
- When forwarding the request over RADIUS, by default the principal is
- used in the User-Name attribute of the RADIUS packet.  The strip_realm
-diff --git a/doc/conf.py b/doc/conf.py
-index f015fc8..bc8b2bd 100644
---- a/doc/conf.py
-+++ b/doc/conf.py
-@@ -231,6 +231,7 @@ if 'mansubs' in tags:
-     sbindir = '``@SBINDIR@``'
-     libdir = '``@LIBDIR@``'
-     localstatedir = '``@LOCALSTATEDIR@``'
-+    runstatedir = '``@RUNSTATEDIR@``'
-     sysconfdir = '``@SYSCONFDIR@``'
-     ccache = '``@CCNAME@``'
-     keytab = '``@KTNAME@``'
-@@ -243,6 +244,7 @@ else:
-     sbindir = ':ref:`SBINDIR <paths>`'
-     libdir = ':ref:`LIBDIR <paths>`'
-     localstatedir = ':ref:`LOCALSTATEDIR <paths>`'
-+    runstatedir = ':ref:`RUNSTATEDIR <paths>`'
-     sysconfdir = ':ref:`SYSCONFDIR <paths>`'
-     ccache = ':ref:`DEFCCNAME <paths>`'
-     keytab = ':ref:`DEFKTNAME <paths>`'
-@@ -262,6 +264,7 @@ else:
-     rst_epilog += '.. |sbindir| replace:: %s\n' % sbindir
-     rst_epilog += '.. |libdir| replace:: %s\n' % libdir
-     rst_epilog += '.. |kdcdir| replace:: %s\\ ``/krb5kdc``\n' % localstatedir
-+    rst_epilog += '.. |kdcrundir| replace:: %s\\ ``/krb5kdc``\n' % runstatedir
-     rst_epilog += '.. |sysconfdir| replace:: %s\n' % sysconfdir
-     rst_epilog += '.. |ccache| replace:: %s\n' % ccache
-     rst_epilog += '.. |keytab| replace:: %s\n' % keytab
-diff --git a/doc/mitK5defaults.rst b/doc/mitK5defaults.rst
-index 89b8f4c..838dabb 100644
---- a/doc/mitK5defaults.rst
-+++ b/doc/mitK5defaults.rst
-@@ -17,6 +17,7 @@ KDC config file :ref:`kdc.conf(5)`          |kdcdir|\ ``/kdc.conf``        **KRB
- KDC database path (DB2)                     |kdcdir|\ ``/principal``
- Master key :ref:`stash_definition`          |kdcdir|\ ``/.k5.``\ *realm*
- Admin server ACL file :ref:`kadm5.acl(5)`   |kdcdir|\ ``/kadm5.acl``
-+OTP socket directory                        |kdcrundir|
- Plugin base directory                       |libdir|\ ``/krb5/plugins``
- :ref:`rcache_definition` directory          ``/var/tmp``                   **KRB5RCACHEDIR**
- Master key default enctype                  |defmkey|
-@@ -64,6 +65,7 @@ Description                 Symbolic name  Custom build path            Typical
- User programs               BINDIR         ``/usr/local/bin``           ``/usr/bin``
- Libraries and plugins       LIBDIR         ``/usr/local/lib``           ``/usr/lib``
- Parent of KDC state dir     LOCALSTATEDIR  ``/usr/local/var``           ``/var``
-+Parent of KDC runtime dir   RUNSTATEDIR    ``/usr/local/var/run``       ``/run``
- Administrative programs     SBINDIR        ``/usr/local/sbin``          ``/usr/sbin``
- Alternate krb5.conf dir     SYSCONFDIR     ``/usr/local/etc``           ``/etc``
- Default ccache name         DEFCCNAME      ``FILE:/tmp/krb5cc_%{uid}``  ``FILE:/tmp/krb5cc_%{uid}``
-diff --git a/src/Makefile.in b/src/Makefile.in
-index a8bc990..1725093 100644
---- a/src/Makefile.in
-+++ b/src/Makefile.in
-@@ -64,6 +64,7 @@ INSTALLMKDIRS = $(KRB5ROOT) $(KRB5MANROOT) $(KRB5OTHERMKDIRS) \
- 		$(KRB5_AD_MODULE_DIR) \
- 		$(KRB5_LIBKRB5_MODULE_DIR) $(KRB5_TLS_MODULE_DIR) \
- 		@localstatedir@ @localstatedir@/krb5kdc \
-+		@runstatedir@ @runstatedir@/krb5kdc \
- 		$(KRB5_INCSUBDIRS) $(datadir) $(EXAMPLEDIR) \
- 		$(PKGCONFIG_DIR)
- 
-diff --git a/src/configure.in b/src/configure.in
-index 2145d54..c2eaf78 100644
---- a/src/configure.in
-+++ b/src/configure.in
-@@ -9,6 +9,12 @@
- fi
- AC_SUBST(SYSCONFCONF)
- 
-+# If $runstatedir isn't set by autoconf (<2.70), set it manually.
-+if test x"$runstatedir" == x; then
-+  runstatedir=$localstatedir/run
-+fi
-+AC_SUBST(runstatedir)
-+
- CONFIG_RULES
- KRB5_VERSION=K5_VERSION
- AC_SUBST(KRB5_VERSION)
-diff --git a/src/doc/Makefile.in b/src/doc/Makefile.in
-index a6bb7c5..b07e16a 100644
---- a/src/doc/Makefile.in
-+++ b/src/doc/Makefile.in
-@@ -7,6 +7,7 @@ DOXYGEN=doxygen
- 
- docsrc=$(top_srcdir)/../doc
- localstatedir=@localstatedir@
-+runstatedir=@runstatedir@
- sysconfdir=@sysconfdir@
- DEFCCNAME=@DEFCCNAME@
- DEFKTNAME=@DEFKTNAME@
-@@ -113,6 +114,7 @@ paths.py:
- 	echo 'sbindir = "``$(SERVER_BINDIR)``"' >> $@
- 	echo 'libdir = "``$(KRB5_LIBDIR)``"' >> $@
- 	echo 'localstatedir = "``$(localstatedir)``"' >> $@
-+	echo 'runstatedir = "``$(runstatedir)``"' >> $@
- 	echo 'sysconfdir = "``$(sysconfdir)``"' >> $@
- 	echo 'ccache = "``$(DEFCCNAME)``"' >> $@
- 	echo 'keytab = "``$(DEFKTNAME)``"' >> $@
-diff --git a/src/include/Makefile.in b/src/include/Makefile.in
-index e13042a..f83ff4e 100644
---- a/src/include/Makefile.in
-+++ b/src/include/Makefile.in
-@@ -53,6 +53,7 @@ autoconf.stamp: $(srcdir)/autoconf.h.in $(BUILDTOP)/config.status
- 
- SYSCONFDIR = @sysconfdir@
- LOCALSTATEDIR = @localstatedir@
-+RUNSTATEDIR = @runstatedir@
- BINDIR = @bindir@
- SBINDIR = @sbindir@
- LIBDIR  = @libdir@
-@@ -66,6 +67,7 @@ PROCESS_REPLACE = -e "s+@KRB5RCTMPDIR+$(KRB5RCTMPDIR)+" \
- 		  -e "s+@MODULEDIR+$(MODULE_DIR)+" \
- 		  -e "s+@GSSMODULEDIR+$(GSS_MODULE_DIR)+" \
- 		  -e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \
-+		  -e 's+@RUNSTATEDIR+$(RUNSTATEDIR)+' \
- 		  -e 's+@SYSCONFDIR+$(SYSCONFDIR)+' \
- 		  -e 's+@DYNOBJEXT+$(DYNOBJEXT)+' \
- 		  -e 's+@SYSCONFCONF+$(SYSCONFCONF)+'
-diff --git a/src/include/osconf.hin b/src/include/osconf.hin
-index 90ab86d..871503a 100644
---- a/src/include/osconf.hin
-+++ b/src/include/osconf.hin
-@@ -59,6 +59,7 @@
- #define PLUGIN_EXT              "@DYNOBJEXT"
- 
- #define KDC_DIR                 "@LOCALSTATEDIR/krb5kdc"
-+#define KDC_RUN_DIR             "@RUNSTATEDIR/krb5kdc"
- #define DEFAULT_KDB_FILE        KDC_DIR "/principal"
- #define DEFAULT_KEYFILE_STUB    KDC_DIR "/.k5."
- #define KRB5_DEFAULT_ADMIN_ACL  KDC_DIR "/krb5_adm.acl"
-diff --git a/src/man/Makefile.in b/src/man/Makefile.in
-index 4dd2448..2b9c892 100644
---- a/src/man/Makefile.in
-+++ b/src/man/Makefile.in
-@@ -5,6 +5,7 @@ SPHINX_BUILD=sphinx-build
- GROFF=@GROFF@
- GROFF_MAN=$(GROFF) -mtty-char -Tascii -mandoc -c
- localstatedir=@localstatedir@
-+runstatedir=@runstatedir@
- sysconfdir=@sysconfdir@
- DEFCCNAME=@DEFCCNAME@
- DEFKTNAME=@DEFKTNAME@
-@@ -44,6 +45,7 @@ $(docsrc)/version.py: $(top_srcdir)/patchlevel.h
- 	    -e 's|@SBINDIR@|$(SERVER_BINDIR)|g' \
- 	    -e 's|@LIBDIR@|$(KRB5_LIBDIR)|g' \
- 	    -e 's|@LOCALSTATEDIR@|$(localstatedir)|g' \
-+	    -e 's|@RUNSTATEDIR@|$(runstatedir)|g' \
- 	    -e 's|@SYSCONFDIR@|$(sysconfdir)|g' \
- 	    -e 's|@CCNAME@|$(DEFCCNAME)|g' \
- 	    -e 's|@KTNAME@|$(DEFKTNAME)|g' \
-diff --git a/src/plugins/preauth/otp/otp_state.c b/src/plugins/preauth/otp/otp_state.c
-index a4d7e3b..4643dff 100644
---- a/src/plugins/preauth/otp/otp_state.c
-+++ b/src/plugins/preauth/otp/otp_state.c
-@@ -40,7 +40,7 @@
- #endif
- 
- #define DEFAULT_TYPE_NAME "DEFAULT"
--#define DEFAULT_SOCKET_FMT KDC_DIR "/%s.socket"
-+#define DEFAULT_SOCKET_FMT KDC_RUN_DIR "/%s.socket"
- #define DEFAULT_TIMEOUT 5
- #define DEFAULT_RETRIES 3
- #define MAX_SECRET_LEN 1024
diff --git a/SOURCES/krb5-master-rcache-acquirecred-cleanup.patch b/SOURCES/krb5-master-rcache-acquirecred-cleanup.patch
deleted file mode 100644
index 72b97d3..0000000
--- a/SOURCES/krb5-master-rcache-acquirecred-cleanup.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-commit ef8e19af863158e4c1abc15fc710aa8cfad38406
-Author: Greg Hudson <ghudson@mit.edu>
-Date:   Wed Jan 15 12:51:42 2014 -0500
-
-    Clean up GSS krb5 acquire_accept_cred
-    
-    Use a cleanup handler instead of releasing kt in multiple error
-    clauses.  Wrap a long line and fix a comment with a missing word.
-    Rewrap the function arguments to use fewer lines.
-
-diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
-index 9547207..37cc6b5 100644
---- a/src/lib/gssapi/krb5/acquire_cred.c
-+++ b/src/lib/gssapi/krb5/acquire_cred.c
-@@ -179,13 +179,13 @@ cleanup:
- */
- 
- static OM_uint32
--acquire_accept_cred(krb5_context context,
--                    OM_uint32 *minor_status,
--                    krb5_keytab req_keytab,
--                    krb5_gss_cred_id_rec *cred)
-+acquire_accept_cred(krb5_context context, OM_uint32 *minor_status,
-+                    krb5_keytab req_keytab, krb5_gss_cred_id_rec *cred)
- {
-+    OM_uint32 major;
-     krb5_error_code code;
--    krb5_keytab kt;
-+    krb5_keytab kt = NULL;
-+    krb5_rcache rc = NULL;
- 
-     assert(cred->keytab == NULL);
- 
-@@ -202,46 +202,54 @@ acquire_accept_cred(krb5_context context,
-         }
-     }
-     if (code) {
--        *minor_status = code;
--        return GSS_S_CRED_UNAVAIL;
-+        major = GSS_S_CRED_UNAVAIL;
-+        goto cleanup;
-     }
- 
-     if (cred->name != NULL) {
--        /* Make sure we keys matching the desired name in the keytab. */
-+        /* Make sure we have keys matching the desired name in the keytab. */
-         code = check_keytab(context, kt, cred->name);
-         if (code) {
--            krb5_kt_close(context, kt);
-             if (code == KRB5_KT_NOTFOUND) {
-                 char *errstr = (char *)krb5_get_error_message(context, code);
--                krb5_set_error_message(context, KG_KEYTAB_NOMATCH, "%s", errstr);
-+                krb5_set_error_message(context, KG_KEYTAB_NOMATCH, "%s",
-+                                       errstr);
-                 krb5_free_error_message(context, errstr);
--                *minor_status = KG_KEYTAB_NOMATCH;
--            } else
--                *minor_status = code;
--            return GSS_S_CRED_UNAVAIL;
-+                code = KG_KEYTAB_NOMATCH;
-+            }
-+            major = GSS_S_CRED_UNAVAIL;
-+            goto cleanup;
-         }
- 
-         /* Open the replay cache for this principal. */
-         code = krb5_get_server_rcache(context, &cred->name->princ->data[0],
--                                      &cred->rcache);
-+                                      &rc);
-         if (code) {
--            krb5_kt_close(context, kt);
--            *minor_status = code;
--            return GSS_S_FAILURE;
-+            major = GSS_S_FAILURE;
-+            goto cleanup;
-         }
-     } else {
-         /* Make sure we have a keytab with keys in it. */
-         code = krb5_kt_have_content(context, kt);
-         if (code) {
--            krb5_kt_close(context, kt);
--            *minor_status = code;
--            return GSS_S_CRED_UNAVAIL;
-+            major = GSS_S_CRED_UNAVAIL;
-+            goto cleanup;
-         }
-     }
- 
-     cred->keytab = kt;
-+    kt = NULL;
-+    cred->rcache = rc;
-+    rc = NULL;
-+    major = GSS_S_COMPLETE;
- 
--    return GSS_S_COMPLETE;
-+cleanup:
-+    if (kt != NULL)
-+        krb5_kt_close(context, kt);
-+    if (rc != NULL)
-+        krb5_rc_close(context, rc);
-+    *minor_status = code;
-+    return major;
- }
- #endif /* LEAN_CLIENT */
- 
diff --git a/SOURCES/krb5-master-rcache-acquirecred-source.patch b/SOURCES/krb5-master-rcache-acquirecred-source.patch
deleted file mode 100644
index 71c3876..0000000
--- a/SOURCES/krb5-master-rcache-acquirecred-source.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-commit 7dad0bee30fbbde8cfc0eacd2d1487c198a004a1
-Author: Simo Sorce <simo@redhat.com>
-Date:   Thu Dec 26 19:05:34 2013 -0500
-
-    Add rcache feature to gss_acquire_cred_from
-    
-    The "rcache" cred store entry can specify a replay cache type and name
-    to be used with the credentials being acquired.
-    
-    [ghudson@mit.edu: split up, simplified, and altered to fit preparatory
-    commits]
-    
-    ticket: 7819 (new)
-
-diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
-index f625c0c..5d680f9 100644
---- a/src/lib/gssapi/krb5/acquire_cred.c
-+++ b/src/lib/gssapi/krb5/acquire_cred.c
-@@ -180,7 +180,8 @@ cleanup:
- 
- static OM_uint32
- acquire_accept_cred(krb5_context context, OM_uint32 *minor_status,
--                    krb5_keytab req_keytab, krb5_gss_cred_id_rec *cred)
-+                    krb5_keytab req_keytab, const char *rcname,
-+                    krb5_gss_cred_id_rec *cred)
- {
-     OM_uint32 major;
-     krb5_error_code code;
-@@ -189,6 +190,20 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status,
- 
-     assert(cred->keytab == NULL);
- 
-+    /* If we have an explicit rcache name, open it. */
-+    if (rcname != NULL) {
-+        code = krb5_rc_resolve_full(context, &rc, rcname);
-+        if (code) {
-+            major = GSS_S_FAILURE;
-+            goto cleanup;
-+        }
-+        code = krb5_rc_recover_or_initialize(context, rc, context->clockskew);
-+        if (code) {
-+            major = GSS_S_FAILURE;
-+            goto cleanup;
-+        }
-+    }
-+
-     if (req_keytab != NULL) {
-         code = krb5_kt_dup(context, req_keytab, &kt);
-     } else {
-@@ -221,12 +236,14 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status,
-             goto cleanup;
-         }
- 
--        /* Open the replay cache for this principal. */
--        code = krb5_get_server_rcache(context, &cred->name->princ->data[0],
--                                      &rc);
--        if (code) {
--            major = GSS_S_FAILURE;
--            goto cleanup;
-+        if (rc == NULL) {
-+            /* Open the replay cache for this principal. */
-+            code = krb5_get_server_rcache(context, &cred->name->princ->data[0],
-+                                          &rc);
-+            if (code) {
-+                major = GSS_S_FAILURE;
-+                goto cleanup;
-+            }
-         }
-     } else {
-         /* Make sure we have a keytab with keys in it. */
-@@ -718,8 +735,8 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
-                      gss_name_t desired_name, gss_buffer_t password,
-                      OM_uint32 time_req, gss_cred_usage_t cred_usage,
-                      krb5_ccache ccache, krb5_keytab client_keytab,
--                     krb5_keytab keytab, krb5_boolean iakerb,
--                     gss_cred_id_t *output_cred_handle,
-+                     krb5_keytab keytab, const char *rcname,
-+                     krb5_boolean iakerb, gss_cred_id_t *output_cred_handle,
-                      OM_uint32 *time_rec)
- {
-     krb5_gss_cred_id_t cred = NULL;
-@@ -775,7 +792,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
-      * in cred->name if desired_princ is specified.
-      */
-     if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
--        ret = acquire_accept_cred(context, minor_status, keytab, cred);
-+        ret = acquire_accept_cred(context, minor_status, keytab, rcname, cred);
-         if (ret != GSS_S_COMPLETE)
-             goto error_out;
-     }
-@@ -867,7 +884,7 @@ acquire_cred(OM_uint32 *minor_status, gss_name_t desired_name,
- 
-     ret = acquire_cred_context(context, minor_status, desired_name, password,
-                                time_req, cred_usage, ccache, NULL, keytab,
--                               iakerb, output_cred_handle, time_rec);
-+                               NULL, iakerb, output_cred_handle, time_rec);
- 
- out:
-     krb5_free_context(context);
-@@ -1135,7 +1152,7 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status,
-     krb5_keytab client_keytab = NULL;
-     krb5_keytab keytab = NULL;
-     krb5_ccache ccache = NULL;
--    const char *value;
-+    const char *rcname, *value;
-     OM_uint32 ret;
- 
-     code = gss_krb5int_initialize_library();
-@@ -1191,9 +1208,14 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status,
-         }
-     }
- 
-+    ret = kg_value_from_cred_store(cred_store, KRB5_CS_RCACHE_URN, &rcname);
-+    if (GSS_ERROR(ret))
-+        goto out;
-+
-     ret = acquire_cred_context(context, minor_status, desired_name, NULL,
-                                time_req, cred_usage, ccache, client_keytab,
--                               keytab, 0, output_cred_handle, time_rec);
-+                               keytab, rcname, 0, output_cred_handle,
-+                               time_rec);
- 
- out:
-     if (ccache != NULL)
-diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
-index 0167816..8e4f6d9 100644
---- a/src/lib/gssapi/krb5/gssapiP_krb5.h
-+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
-@@ -1260,6 +1260,7 @@ data_to_gss(krb5_data *input_k5data, gss_buffer_t output_buffer)
- #define KRB5_CS_CLI_KEYTAB_URN "client_keytab"
- #define KRB5_CS_KEYTAB_URN "keytab"
- #define KRB5_CS_CCACHE_URN "ccache"
-+#define KRB5_CS_RCACHE_URN "rcache"
- 
- OM_uint32
- kg_value_from_cred_store(gss_const_key_value_set_t cred_store,
diff --git a/SOURCES/krb5-master-rcache-acquirecred-test.patch b/SOURCES/krb5-master-rcache-acquirecred-test.patch
deleted file mode 100644
index e8eef5e..0000000
--- a/SOURCES/krb5-master-rcache-acquirecred-test.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-commit 6f8d5135334c9ddb674f9824e750872b3b0642ea
-Author: Greg Hudson <ghudson@mit.edu>
-Date:   Thu Jan 16 11:49:55 2014 -0500
-
-    Add test for gss_acquire_cred_from rcache feature
-
-diff --git a/src/tests/gssapi/t_credstore.c b/src/tests/gssapi/t_credstore.c
-index 575f96d..e28f5d0 100644
---- a/src/tests/gssapi/t_credstore.c
-+++ b/src/tests/gssapi/t_credstore.c
-@@ -46,7 +46,9 @@ main(int argc, char *argv[])
-     gss_cred_usage_t cred_usage = GSS_C_BOTH;
-     gss_OID_set mechs = GSS_C_NO_OID_SET;
-     gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
--    krb5_boolean store_creds = FALSE;
-+    gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT;
-+    gss_buffer_desc itok, atok;
-+    krb5_boolean store_creds = FALSE, replay = FALSE;
-     char opt;
- 
-     /* Parse options. */
-@@ -54,6 +56,8 @@ main(int argc, char *argv[])
-         opt = (*argv)[1];
-         if (opt == 's')
-             store_creds = TRUE;
-+        else if (opt == 'r')
-+            replay = TRUE;
-         else if (opt == 'a')
-             cred_usage = GSS_C_ACCEPT;
-         else if (opt == 'b')
-@@ -101,6 +105,31 @@ main(int argc, char *argv[])
-                                   &store, &cred, NULL, NULL);
-     check_gsserr("gss_acquire_cred_from", major, minor);
- 
-+    if (replay) {
-+        /* Induce a replay using cred as the acceptor cred, to test the replay
-+         * cache indicated by the store. */
-+        major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, name,
-+                                     &mech_krb5, 0, GSS_C_INDEFINITE,
-+                                     GSS_C_NO_CHANNEL_BINDINGS,
-+                                     GSS_C_NO_BUFFER, NULL, &itok, NULL, NULL);
-+        check_gsserr("gss_init_sec_context", major, minor);
-+        (void)gss_delete_sec_context(&minor, &ictx, NULL);
-+
-+        major = gss_accept_sec_context(&minor, &actx, cred, &itok,
-+                                       GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL,
-+                                       &atok, NULL, NULL, NULL);
-+        check_gsserr("gss_accept_sec_context(1)", major, minor);
-+        (void)gss_release_buffer(&minor, &atok);
-+        (void)gss_delete_sec_context(&minor, &actx, NULL);
-+
-+        major = gss_accept_sec_context(&minor, &actx, cred, &itok,
-+                                       GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL,
-+                                       &atok, NULL, NULL, NULL);
-+        check_gsserr("gss_accept_sec_context(2)", major, minor);
-+        (void)gss_release_buffer(&minor, &atok);
-+        (void)gss_delete_sec_context(&minor, &actx, NULL);
-+    }
-+
-     gss_release_name(&minor, &name);
-     gss_release_cred(&minor, &cred);
-     free(store.elements);
-diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py
-index 74139e4..106910d 100755
---- a/src/tests/gssapi/t_gssapi.py
-+++ b/src/tests/gssapi/t_gssapi.py
-@@ -91,6 +91,15 @@ realm.kinit(service_cs, None, ['-k', '-t', servicekeytab])
- realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache,
-            'keytab', servicekeytab])
- 
-+# Test rcache feature of cred stores.  t_credstore -r should produce a
-+# replay error normally, but not with rcache set to "none:".
-+output = realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ],
-+                   expected_code=1)
-+if 'gss_accept_sec_context(2): Request is a replay' not in output:
-+    fail('Expected replay error not seen in t_credstore output')
-+realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ,
-+           'rcache', 'none:'])
-+
- # Verify that we can't acquire acceptor creds without a keytab.
- os.remove(realm.keytab)
- output = realm.run(['./t_accname', 'p:abc'], expected_code=1)
diff --git a/SOURCES/krb5-master-rcache-internal-const.patch b/SOURCES/krb5-master-rcache-internal-const.patch
deleted file mode 100644
index 5cb1108..0000000
--- a/SOURCES/krb5-master-rcache-internal-const.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-commit 74ff6c4accb68bd1d6c652c55e66519720db9fc4
-Author: Greg Hudson <ghudson@mit.edu>
-Date:   Wed Jan 15 12:31:41 2014 -0500
-
-    Make rcache resolve functions take const char *
-
-diff --git a/src/include/k5-int.h b/src/include/k5-int.h
-index bbc7fab..b4757a9 100644
---- a/src/include/k5-int.h
-+++ b/src/include/k5-int.h
-@@ -1887,8 +1887,10 @@ krb5_error_code KRB5_CALLCONV
- krb5int_cc_user_set_default_name(krb5_context context, const char *name);
- 
- krb5_error_code krb5_rc_default(krb5_context, krb5_rcache *);
--krb5_error_code krb5_rc_resolve_type(krb5_context, krb5_rcache *,char *);
--krb5_error_code krb5_rc_resolve_full(krb5_context, krb5_rcache *,char *);
-+krb5_error_code krb5_rc_resolve_type(krb5_context, krb5_rcache *,
-+                                     const char *);
-+krb5_error_code krb5_rc_resolve_full(krb5_context, krb5_rcache *,
-+                                     const char *);
- char *krb5_rc_get_type(krb5_context, krb5_rcache);
- char *krb5_rc_default_type(krb5_context);
- char *krb5_rc_default_name(krb5_context);
-diff --git a/src/lib/krb5/rcache/rc_base.c b/src/lib/krb5/rcache/rc_base.c
-index 2fc96c5..373ac30 100644
---- a/src/lib/krb5/rcache/rc_base.c
-+++ b/src/lib/krb5/rcache/rc_base.c
-@@ -65,7 +65,8 @@ krb5_rc_register_type(krb5_context context, const krb5_rc_ops *ops)
- }
- 
- krb5_error_code
--krb5_rc_resolve_type(krb5_context context, krb5_rcache *idptr, char *type)
-+krb5_rc_resolve_type(krb5_context context, krb5_rcache *idptr,
-+                     const char *type)
- {
-     struct krb5_rc_typelist *t;
-     krb5_error_code err;
-@@ -146,7 +147,7 @@ krb5_rc_default(krb5_context context, krb5_rcache *idptr)
- 
- krb5_error_code
- krb5_rc_resolve_full(krb5_context context, krb5_rcache *idptr,
--                     char *string_name)
-+                     const char *string_name)
- {
-     char *type;
-     char *residual;
diff --git a/SOURCES/krb5-master-strdupcheck.patch b/SOURCES/krb5-master-strdupcheck.patch
deleted file mode 100644
index 4c9d0c1..0000000
--- a/SOURCES/krb5-master-strdupcheck.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-commit b6810da129512b6d0200580d78d22d38cc214e21
-Author: Lukas Slebodnik <lslebodn@redhat.com>
-Date:   Sat Jun 21 17:09:31 2014 +0200
-
-    Fix error check in krb5_ldap_parse_principal_name
-    
-    Test the correct variable for NULL to detect a strdup failure.
-    
-    [ghudson@mit.edu: clarified commit message]
-
-diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
-index 21695a9..44bf339 100644
---- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
-+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
-@@ -412,7 +412,7 @@ krb5_ldap_parse_principal_name(char *i_princ_name, char **o_princ_name)
-     at_rlm_name = strrchr(i_princ_name, '@');
-     if (!at_rlm_name) {
-         *o_princ_name = strdup(i_princ_name);
--        if (!o_princ_name)
-+        if (!*o_princ_name)
-             return ENOMEM;
-     } else {
-         k5_buf_init_dynamic(&buf);
diff --git a/SOURCES/krb5-tests_use_libs_from_build.patch b/SOURCES/krb5-tests_use_libs_from_build.patch
new file mode 100644
index 0000000..4538b1d
--- /dev/null
+++ b/SOURCES/krb5-tests_use_libs_from_build.patch
@@ -0,0 +1,96 @@
+#
+# krb5-tests_use_libs_from_build.patch - patch to ensure the tests
+# in the upstream sources use the libraries from the local tree
+# and not those from the underlying build system.
+3
+# Originally repoted as RedHat Bug #1164304 ("Upstream unit tests loads
+# the installed shared libraries instead the ones from the build")
+# 
+# 
+# Description of problem:
+# krb5-1.12.2/src/lib/kadm5/unit-test fails (segfaults) when
+# krb5-pkinit is installed on the sysytem.
+# Monitoring via audit showed that unit tests from this directory
+# loads pkinit.so from the installed package and not the one that
+# was built.
+# On top of that, monitoring showed that libs from the installed
+# krb5-libs (whatever version installed) are loaded too.
+# This questions the effectiveness of upstream testing.
+# 
+# Version-Release number of selected component (if applicable):
+# krb5-libs-1.12.2-8.el7
+# 
+# How reproducible:
+# always
+# 
+# Steps to Reproduce:
+# 
+# # rpm -qa krb5\*
+# krb5-devel-1.11.3-49.el7.ppc64
+# krb5-libs-1.11.3-49.el7.ppc64
+# krb5-pkinit-1.11.3-49.el7.ppc64
+# #
+# # rpm -ivh krb5-1.12.2-8.el7.src.rpm 
+# ... snip ...
+# # rpmbuild -bc ~/rpmbuild/SPECS/krb5.spec 
+# ... snip ...
+# #
+# # cd ~/rpmbuild/BUILD/krb5-1.12.2/src/
+# # make runenv.py
+# LD_LIBRARY_PATH=`echo -L./lib | sed -e "s/-L//g" -e "s/ /:/g"`; export LD_LIBRARY_PATH;  \
+# for i in LD_LIBRARY_PATH; do \
+# 	eval echo 'env['\\\'$i\\\''] = '\\\'\$$i\\\'; \
+# done > pyrunenv.vals
+# echo "proxy_tls_impl = 'openssl'" >> pyrunenv.vals
+# echo 'env = {}' > runenv.py
+# cat pyrunenv.vals >> runenv.py
+# # cd lib/kadm5/unit-test/
+# # make check
+# .. snip ...
+# 	KINIT=../../../clients/kinit/kinit \
+# 	KDESTROY=../../../clients/kdestroy/kdestroy \
+# 	KADMIN_LOCAL=../../../kadmin/cli/kadmin.local \
+# 	PRIOCNTL_HACK=0 VALGRIND="" \
+# 	
+# WARNING: Couldn't find the global config file.
+# WARNING: Couldn't find tool init file
+# Test Run By root on Fri Nov 14 10:30:35 2014
+# Native configuration is powerpc64-redhat-linux-gnu
+# 
+# 		=== api tests ===
+# 
+# Schedule of variations:
+#     unix
+# 
+# Running target unix
+# Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
+# Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
+# Using ./config/unix.exp as tool-and-target-specific interface file.
+# Running ./api.2/crte-policy.exp ...
+# FAIL: create-policy 1: eof
+# ERROR: create-policy 1: unexpected failure in init
+# ERROR: create-policy 2: unexpected failure in init
+# ERROR: create-policy 3: unexpected failure in init
+# 
+diff -ur krb5/src/kadmin/testing/proto/krb5.conf.proto krb5/src/kadmin/testing/proto/krb5.conf.proto
+--- krb5/src/kadmin/testing/proto/krb5.conf.proto	2014-11-14 10:16:22.106948323 -0500
++++ krb5/src/kadmin/testing/proto/krb5.conf.proto	2014-11-14 10:14:16.955948323 -0500
+@@ -2,6 +2,7 @@
+ 	default_realm = __REALM__
+ 	default_keytab_name = FILE:__K5ROOT__/v5srvtab
+ 	dns_fallback = no
++	plugin_base_dir = __PLUGIN_DIR__
+ 
+ [realms]
+ 	__REALM__ = {
+diff -ur krb5/src/kadmin/testing/scripts/start_servers krb5/src/kadmin/testing/scripts/start_servers
+--- krb5/src/kadmin/testing/scripts/start_servers	2014-08-11 18:46:27.000000000 -0400
++++ krb5/src/kadmin/testing/scripts/start_servers	2014-11-14 10:14:56.409948323 -0500
+@@ -40,6 +40,7 @@
+ 		-e "s/__KDCHOST__/$hostname/g" \
+ 		-e "s/__LOCALHOST__/$localname/g" \
+ 		-e "s#__MODDIR__#$TOP/../plugins/kdb#g"\
++		-e "s#__PLUGIN_DIR__#$TOP/../plugins#g"\
+ 		< $STESTDIR/proto/krb5.conf.proto > $K5ROOT/krb5.conf
+ 
+ # Using /usr/ucb/rsh and getting rid of "-k $REALM" until we get
diff --git a/SOURCES/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch b/SOURCES/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch
deleted file mode 100644
index c7bb9a2..0000000
--- a/SOURCES/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch
+++ /dev/null
@@ -1,331 +0,0 @@
-diff --git a/src/kadmin/server/kadm_rpc_svc.c b/src/kadmin/server/kadm_rpc_svc.c
-index 3837931..f4d2a7c 100644
---- a/src/kadmin/server/kadm_rpc_svc.c
-+++ b/src/kadmin/server/kadm_rpc_svc.c
-@@ -4,7 +4,7 @@
-  *
-  */
- 
--#include <k5-platform.h>
-+#include <k5-int.h>
- #include <gssrpc/rpc.h>
- #include <gssapi/gssapi_krb5.h> /* for gss_nt_krb5_name */
- #include <syslog.h>
-@@ -296,14 +296,8 @@ check_rpcsec_auth(struct svc_req *rqstp)
-      c1 = krb5_princ_component(kctx, princ, 0);
-      c2 = krb5_princ_component(kctx, princ, 1);
-      realm = krb5_princ_realm(kctx, princ);
--     if (strncmp(handle->params.realm, realm->data, realm->length) == 0
--	 && strncmp("kadmin", c1->data, c1->length) == 0) {
--
--	  if (strncmp("history", c2->data, c2->length) == 0)
--	       goto fail_princ;
--	  else
--	       success = 1;
--     }
-+     success = data_eq_string(*realm, handle->params.realm) &&
-+	     data_eq_string(*c1, "kadmin") && !data_eq_string(*c2, "history");
- 
- fail_princ:
-      if (!success) {
-diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c
-index b3d1db0..a18cfb0 100644
---- a/src/lib/gssapi/krb5/context_time.c
-+++ b/src/lib/gssapi/krb5/context_time.c
-@@ -40,7 +40,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec)
- 
-     ctx = (krb5_gss_ctx_id_rec *) context_handle;
- 
--    if (! ctx->established) {
-+    if (ctx->terminated || !ctx->established) {
-         *minor_status = KG_CTX_INCOMPLETE;
-         return(GSS_S_NO_CONTEXT);
-     }
-diff --git a/src/lib/gssapi/krb5/export_sec_context.c b/src/lib/gssapi/krb5/export_sec_context.c
-index 18a3a34..1b3de68 100644
---- a/src/lib/gssapi/krb5/export_sec_context.c
-+++ b/src/lib/gssapi/krb5/export_sec_context.c
-@@ -45,6 +45,11 @@ krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token)
-     *minor_status = 0;
- 
-     ctx = (krb5_gss_ctx_id_t) *context_handle;
-+    if (ctx->terminated) {
-+        *minor_status = KG_CTX_INCOMPLETE;
-+        return (GSS_S_NO_CONTEXT);
-+    }
-+
-     context = ctx->k5_context;
-     kret = krb5_gss_ser_init(context);
-     if (kret)
-diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
-index 0167816..42d16ad 100644
---- a/src/lib/gssapi/krb5/gssapiP_krb5.h
-+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
-@@ -204,6 +204,7 @@ typedef struct _krb5_gss_ctx_id_rec {
-     unsigned int established : 1;
-     unsigned int have_acceptor_subkey : 1;
-     unsigned int seed_init : 1;  /* XXX tested but never actually set */
-+    unsigned int terminated : 1;
-     OM_uint32 gss_flags;
-     unsigned char seed[16];
-     krb5_gss_name_t here;
-diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
-index a408259..088219a 100644
---- a/src/lib/gssapi/krb5/gssapi_krb5.c
-+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
-@@ -369,7 +369,7 @@ krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
- 
-     ctx = (krb5_gss_ctx_id_rec *) context_handle;
- 
--    if (!ctx->established)
-+    if (ctx->terminated || !ctx->established)
-         return GSS_S_NO_CONTEXT;
- 
-     for (i = 0; i < sizeof(krb5_gss_inquire_sec_context_by_oid_ops)/
-diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
-index eacb0fd..096df2a 100644
---- a/src/lib/gssapi/krb5/inq_context.c
-+++ b/src/lib/gssapi/krb5/inq_context.c
-@@ -105,7 +105,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
- 
-     ctx = (krb5_gss_ctx_id_rec *) context_handle;
- 
--    if (! ctx->established) {
-+    if (ctx->terminated || !ctx->established) {
-         *minor_status = KG_CTX_INCOMPLETE;
-         return(GSS_S_NO_CONTEXT);
-     }
-diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
-index bd1e2a6..b11b615 100644
---- a/src/lib/gssapi/krb5/k5seal.c
-+++ b/src/lib/gssapi/krb5/k5seal.c
-@@ -342,7 +342,7 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req,
- 
-     ctx = (krb5_gss_ctx_id_rec *) context_handle;
- 
--    if (! ctx->established) {
-+    if (ctx->terminated || !ctx->established) {
-         *minor_status = KG_CTX_INCOMPLETE;
-         return(GSS_S_NO_CONTEXT);
-     }
-diff --git a/src/lib/gssapi/krb5/k5sealiov.c b/src/lib/gssapi/krb5/k5sealiov.c
-index 0b99a77..0f80095 100644
---- a/src/lib/gssapi/krb5/k5sealiov.c
-+++ b/src/lib/gssapi/krb5/k5sealiov.c
-@@ -284,7 +284,7 @@ kg_seal_iov(OM_uint32 *minor_status,
-     }
- 
-     ctx = (krb5_gss_ctx_id_rec *)context_handle;
--    if (!ctx->established) {
-+    if (ctx->terminated || !ctx->established) {
-         *minor_status = KG_CTX_INCOMPLETE;
-         return GSS_S_NO_CONTEXT;
-     }
-diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
-index b65c83c..9e78550 100644
---- a/src/lib/gssapi/krb5/k5unseal.c
-+++ b/src/lib/gssapi/krb5/k5unseal.c
-@@ -492,7 +492,7 @@ kg_unseal(minor_status, context_handle, input_token_buffer,
- 
-     ctx = (krb5_gss_ctx_id_rec *) context_handle;
- 
--    if (! ctx->established) {
-+    if (ctx->terminated || !ctx->established) {
-         *minor_status = KG_CTX_INCOMPLETE;
-         return(GSS_S_NO_CONTEXT);
-     }
-diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
-index 8d6a2da..191de2c 100644
---- a/src/lib/gssapi/krb5/k5unsealiov.c
-+++ b/src/lib/gssapi/krb5/k5unsealiov.c
-@@ -628,7 +628,7 @@ kg_unseal_iov(OM_uint32 *minor_status,
-     OM_uint32 code;
- 
-     ctx = (krb5_gss_ctx_id_rec *)context_handle;
--    if (!ctx->established) {
-+    if (ctx->terminated || !ctx->established) {
-         *minor_status = KG_CTX_INCOMPLETE;
-         return GSS_S_NO_CONTEXT;
-     }
-diff --git a/src/lib/gssapi/krb5/lucid_context.c b/src/lib/gssapi/krb5/lucid_context.c
-index dc129e1..50d8cc9 100644
---- a/src/lib/gssapi/krb5/lucid_context.c
-+++ b/src/lib/gssapi/krb5/lucid_context.c
-@@ -75,6 +75,11 @@ gss_krb5int_export_lucid_sec_context(
-     *minor_status = 0;
-     *data_set = GSS_C_NO_BUFFER_SET;
- 
-+    if (ctx->terminated || !ctx->established) {
-+        *minor_status = KG_CTX_INCOMPLETE;
-+        return GSS_S_NO_CONTEXT;
-+    }
-+
-     retval = generic_gss_oid_decompose(minor_status,
-                                        GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID,
-                                        GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH,
-diff --git a/src/lib/gssapi/krb5/prf.c b/src/lib/gssapi/krb5/prf.c
-index a0fbcda..4831f9f 100644
---- a/src/lib/gssapi/krb5/prf.c
-+++ b/src/lib/gssapi/krb5/prf.c
-@@ -60,6 +60,10 @@ krb5_gss_pseudo_random(OM_uint32 *minor_status,
-     ns.data = NULL;
- 
-     ctx = (krb5_gss_ctx_id_t)context;
-+    if (ctx->terminated || !ctx->established) {
-+        *minor_status = KG_CTX_INCOMPLETE;
-+        return GSS_S_NO_CONTEXT;
-+    }
- 
-     switch (prf_key) {
-     case GSS_C_PRF_KEY_FULL:
-diff --git a/src/lib/gssapi/krb5/process_context_token.c b/src/lib/gssapi/krb5/process_context_token.c
-index ae33180..a672f48 100644
---- a/src/lib/gssapi/krb5/process_context_token.c
-+++ b/src/lib/gssapi/krb5/process_context_token.c
-@@ -39,11 +39,18 @@ krb5_gss_process_context_token(minor_status, context_handle,
- 
-     ctx = (krb5_gss_ctx_id_t) context_handle;
- 
--    if (! ctx->established) {
-+    if (ctx->terminated || !ctx->established) {
-         *minor_status = KG_CTX_INCOMPLETE;
-         return(GSS_S_NO_CONTEXT);
-     }
- 
-+    /* We only support context deletion tokens for now, and RFC 4121 does not
-+     * define a context deletion token. */
-+    if (ctx->proto) {
-+        *minor_status = 0;
-+        return(GSS_S_DEFECTIVE_TOKEN);
-+    }
-+
-     /* "unseal" the token */
- 
-     if (GSS_ERROR(majerr = kg_unseal(minor_status, context_handle,
-@@ -52,8 +59,8 @@ krb5_gss_process_context_token(minor_status, context_handle,
-                                      KG_TOK_DEL_CTX)))
-         return(majerr);
- 
--    /* that's it.  delete the context */
--
--    return(krb5_gss_delete_sec_context(minor_status, &context_handle,
--                                       GSS_C_NO_BUFFER));
-+    /* Mark the context as terminated, but do not delete it (as that would
-+     * leave the caller with a dangling context handle). */
-+    ctx->terminated = 1;
-+    return(GSS_S_COMPLETE);
- }
-diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c
-index 7bc4221..ed5c599 100644
---- a/src/lib/gssapi/krb5/wrap_size_limit.c
-+++ b/src/lib/gssapi/krb5/wrap_size_limit.c
-@@ -95,7 +95,7 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
-     }
- 
-     ctx = (krb5_gss_ctx_id_rec *) context_handle;
--    if (! ctx->established) {
-+    if (ctx->terminated || !ctx->established) {
-         *minor_status = KG_CTX_INCOMPLETE;
-         return(GSS_S_NO_CONTEXT);
-     }
-diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h
-index e56b9c1..2b5145e 100644
---- a/src/lib/gssapi/mechglue/mglueP.h
-+++ b/src/lib/gssapi/mechglue/mglueP.h
-@@ -25,7 +25,6 @@ do {								\
-  */
- typedef struct gss_union_ctx_id_struct {
- 	struct gss_union_ctx_id_struct *loopback;
--	struct gss_union_ctx_id_struct *interposer;
- 	gss_OID			mech_type;
- 	gss_ctx_id_t		internal_ctx_id;
- } gss_union_ctx_id_desc, *gss_union_ctx_id_t;
-diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
-index 42ac783..975f94c 100644
---- a/src/lib/kadm5/kadm_rpc_xdr.c
-+++ b/src/lib/kadm5/kadm_rpc_xdr.c
-@@ -320,6 +320,7 @@ bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data **tl_data_head)
- 	       free(tl);
- 	       tl = tl2;
- 	  }
-+	  *tl_data_head = NULL;
- 	  break;
- 
-      case XDR_ENCODE:
-@@ -1096,6 +1097,7 @@ xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
-     case XDR_FREE:
- 	if(*objp != NULL)
- 	    krb5_free_principal(context, *objp);
-+	*objp = NULL;
- 	break;
-     }
-     return TRUE;
-diff --git a/src/lib/rpc/auth_gssapi_misc.c b/src/lib/rpc/auth_gssapi_misc.c
-index 53bdb98..a05ea19 100644
---- a/src/lib/rpc/auth_gssapi_misc.c
-+++ b/src/lib/rpc/auth_gssapi_misc.c
-@@ -322,7 +322,6 @@ bool_t auth_gssapi_unwrap_data(
-      if (! (*xdr_func)(&temp_xdrs, xdr_ptr)) {
- 	  PRINTF(("gssapi_unwrap_data: deserializing arguments failed\n"));
- 	  gss_release_buffer(minor, &out_buf);
--	  xdr_free(xdr_func, xdr_ptr);
- 	  XDR_DESTROY(&temp_xdrs);
- 	  return FALSE;
-      }
-diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
-index 8da7003..ea8149b 100644
---- a/src/lib/rpc/svc_auth_gss.c
-+++ b/src/lib/rpc/svc_auth_gss.c
-@@ -68,16 +68,6 @@ extern const gss_OID_desc * const gss_mech_spkm3;
- 
- extern SVCAUTH svc_auth_none;
- 
--/*
-- * from mit-krb5-1.2.1 mechglue/mglueP.h:
-- * Array of context IDs typed by mechanism OID
-- */
--typedef struct gss_union_ctx_id_t {
--  gss_OID     mech_type;
--  gss_ctx_id_t    internal_ctx_id;
--} gss_union_ctx_id_desc, *gss_union_ctx_id_t;
--
--
- static auth_gssapi_log_badauth_func log_badauth = NULL;
- static caddr_t log_badauth_data = NULL;
- static auth_gssapi_log_badauth2_func log_badauth2 = NULL;
-@@ -242,16 +232,8 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst,
- 		gd->ctx = GSS_C_NO_CONTEXT;
- 		goto errout;
- 	}
--	/*
--	 * ANDROS: krb5 mechglue returns ctx of size 8 - two pointers,
--	 * one to the mechanism oid, one to the internal_ctx_id
--	 */
--	if ((gr->gr_ctx.value = mem_alloc(sizeof(gss_union_ctx_id_desc))) == NULL) {
--		fprintf(stderr, "svcauth_gss_accept_context: out of memory\n");
--		goto errout;
--	}
--	memcpy(gr->gr_ctx.value, gd->ctx, sizeof(gss_union_ctx_id_desc));
--	gr->gr_ctx.length = sizeof(gss_union_ctx_id_desc);
-+	gr->gr_ctx.value = "xxxx";
-+	gr->gr_ctx.length = 4;
- 
- 	/* gr->gr_win = 0x00000005; ANDROS: for debugging linux kernel version...  */
- 	gr->gr_win = sizeof(gd->seqmask) * 8;
-@@ -523,8 +505,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg,
- 
- 		if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win))) {
- 			gss_release_buffer(&min_stat, &gr.gr_token);
--			mem_free(gr.gr_ctx.value,
--				 sizeof(gss_union_ctx_id_desc));
- 			ret_freegc (AUTH_FAILED);
- 		}
- 		*no_dispatch = TRUE;
-@@ -534,7 +514,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg,
- 
- 		gss_release_buffer(&min_stat, &gr.gr_token);
- 		gss_release_buffer(&min_stat, &gd->checksum);
--		mem_free(gr.gr_ctx.value, sizeof(gss_union_ctx_id_desc));
- 		if (!call_stat)
- 			ret_freegc (AUTH_FAILED);
- 
diff --git a/SPECS/krb5.spec b/SPECS/krb5.spec
index dd47276..a0195cd 100644
--- a/SPECS/krb5.spec
+++ b/SPECS/krb5.spec
@@ -40,16 +40,19 @@
 
 Summary: The Kerberos network authentication system
 Name: krb5
-Version: 1.12.2
-Release: 15%{?dist}
-# Maybe we should explode from the now-available-to-everybody tarball instead?
-# http://web.mit.edu/kerberos/dist/krb5/1.12/krb5-1.12.2-signed.tar
+Version: 1.13.2
+Release: 10%{?dist}
+# - Maybe we should explode from the now-available-to-everybody tarball instead?
+# http://web.mit.edu/kerberos/dist/krb5/1.13/krb5-1.13.2-signed.tar
+# - The sources below are stored in a lookaside cache. Upload with
+# $ rhpkg upload krb5-1.13.2.tar.gz krb5-1.13.2.tar.gz.asc # (and don't
+# remove, otherwise you can't go back or branch from a previous point)
 Source0: krb5-%{version}.tar.gz
 Source1: krb5-%{version}.tar.gz.asc
-# Use a dummy krb5-%{version}-pdf.tar.xz the first time through, then
-#  tar cvJf $RPM_SOURCE_DIR/krb5-%%{version}-pdf.tar.xz build-pdf/*.pdf
+# Use a dummy krb5-%{version}-pdf.pax.xz the first time through, then
+# $ pax -wv -x ustar build-pdf/*.pdf | xz -9 >"krb5-%{version}-pdf.pax.xz.new" #
 # after the build phase finishes.
-Source3: krb5-%{version}-pdf.tar.xz
+Source3: krb5-%{version}-pdf.pax.xz
 Source2: kprop.service
 Source4: kadmin.service
 Source5: krb5kdc.service
@@ -70,70 +73,34 @@ Source37: kadmind.init
 Source38: krb5kdc.init
 Source39: krb5-krb5kdc.conf
 
-BuildRequires: cmake
+BuildRequires: cmake pax xz
 # Carry this locally until it's available in a packaged form.
 Source100: nss_wrapper-0.0-20140204195100.git3d58327.tar.xz
 Source101: noport.c
 Source102: socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz
 
-Patch1: krb5-1.12-pwdch-fast.patch
 Patch6: krb5-1.12-ksu-path.patch
 Patch12: krb5-1.12-ktany.patch
 Patch16: krb5-1.12-buildconf.patch
 Patch23: krb5-1.3.1-dns.patch
-Patch29: krb5-1.10-kprop-mktemp.patch
-Patch30: krb5-1.3.4-send-pr-tempfile.patch
 Patch39: krb5-1.12-api.patch
-Patch59: krb5-1.12ish-kpasswd_tcp.patch
 Patch60: krb5-1.12.1-pam.patch
-Patch63: krb5-1.12-selinux-label.patch
-Patch71: krb5-1.11-dirsrv-accountlock.patch
+Patch63: krb5-1.13-selinux-label.patch
+Patch71: krb5-1.13-dirsrv-accountlock.patch
 Patch86: krb5-1.9-debuginfo.patch
 Patch105: krb5-kvno-230379.patch
 Patch129: krb5-1.11-run_user_0.patch
 Patch134: krb5-1.11-kpasswdtest.patch
-Patch136: krb5-master-rcache-internal-const.patch
-Patch137: krb5-master-rcache-acquirecred-cleanup.patch
-Patch139: krb5-master-rcache-acquirecred-source.patch
-Patch141: krb5-master-rcache-acquirecred-test.patch
-Patch142: krb5-master-move-otp-sockets.patch
-Patch145: krb5-master-mechd.patch
-Patch146: krb5-master-strdupcheck.patch
-Patch147: krb5-master-compatible-keys.patch
-Patch148: krb5-1.12-system-exts.patch
-Patch201: 0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch
-Patch202: 0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch
-Patch203: 0003-Use-an-intermediate-memory-cache-in-ksu.patch
-Patch204: 0004-Make-ksu-respect-the-default_ccache_name-setting.patch
-Patch205: 0005-Copy-config-entries-to-the-ksu-target-ccache.patch
-Patch206: 0006-Use-more-randomness-for-ksu-secondary-cache-names.patch
-Patch207: 0007-Make-krb5_cc_new_unique-create-DIR-directories.patch
-Patch300: krb5-1.12-kpasswd-skip-address-check.patch
-Patch301: 0000-Refactor-cm-functions-in-sendto_kdc.c.patch
-Patch302: 0001-Simplify-sendto_kdc.c.patch
-Patch303: 0002-Add-helper-to-determine-if-a-KDC-is-the-master.patch
-Patch304: 0003-Use-k5_transport-_strategy-enums-for-k5_sendto.patch
-Patch305: 0004-Build-support-for-TLS-used-by-HTTPS-proxy-support.patch
-Patch306: 0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE.patch
-Patch307: 0006-Dispatch-style-protocol-switching-for-transport.patch
-Patch308: 0007-HTTPS-transport-Microsoft-KKDCPP-implementation.patch
-Patch309: 0008-Load-custom-anchors-when-using-KKDCP.patch
-Patch310: 0009-Check-names-in-the-server-s-cert-when-using-KKDCP.patch
-Patch311: 0010-Add-some-longer-form-docs-for-HTTPS.patch
-Patch312: 0011-Have-k5test.py-provide-runenv-to-python-tests.patch
-Patch313: 0012-Add-a-simple-KDC-proxy-test-server.patch
-Patch314: 0013-Add-tests-for-MS-KKDCP-client-support.patch
-Patch315: krb5-1.12ish-tls-plugins.patch
-Patch316: krb5-1.12-nodelete-plugins.patch
-Patch317: krb5-1.12-ksu-untyped-default-ccache-name.patch
-Patch318: krb5-1.12-ksu-no-ccache.patch
 Patch319: krb5-kadm5clntmit_libsoname_version_downgrade.patch
-Patch320: krb5-ksu_not_working_with_default_principal.patch
-Patch321: krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch
-Patch322: krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch
-Patch323: krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch
-Patch324: krb5-1.13_kinit_C_loop_krb5bug243.patch
-Patch325: krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad.patch
+
+Patch140: krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch
+Patch143: krb5-tests_use_libs_from_build.patch
+Patch144: krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch
+Patch145: krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad.patch
+Patch146: krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch
+Patch147: krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch
+Patch148: krb5-1.13.3-client_referrals.patch
+Patch149: krb5-1.13.3-client_referrals_test.patch
 
 License: MIT
 URL: http://web.mit.edu/kerberos/www/
@@ -143,7 +110,7 @@ BuildRequires: autoconf, bison, flex, gawk, gettext, pkgconfig, sed
 %if 0%{?fedora} >= 12 || 0%{?rhel} >= 6
 BuildRequires: libcom_err-devel, libedit-devel, libss-devel
 %endif
-BuildRequires: gzip, ncurses-devel, tar
+BuildRequires: gzip, ncurses-devel
 BuildRequires: python-sphinx, texlive-pdftex
 # The texlive package got a lot more complicated here.
 %if 0%{?fedora} > 17 || 0%{?rhel} > 6
@@ -266,8 +233,6 @@ Requires: chkconfig
 # we drop files in its directory, but we don't want to own that directory
 Requires: logrotate
 Requires(preun): initscripts
-# mktemp is used by krb5-send-pr
-Requires: coreutils
 # we specify /usr/share/dict/words as the default dict_file in kdc.conf
 Requires: /usr/share/dict/words
 %if %{WITH_SYSVERTO}
@@ -275,6 +240,15 @@ Requires: /usr/share/dict/words
 BuildRequires: libverto-module-base
 Requires: libverto-module-base
 %endif
+%ifarch x86_64
+Obsoletes: krb5-server-1.11.3-49.el7.i686
+%endif
+%ifarch ppc64
+Obsoletes: krb5-server-1.11.3-49.el7.ppc
+%endif
+%ifarch s390x
+Obsoletes: krb5-server-1.11.3-49.el7.s390
+%endif
 
 %description server
 Kerberos is a network authentication system. The krb5-server package
@@ -288,6 +262,15 @@ Group: System Environment/Daemons
 Summary: The LDAP storage plugin for the Kerberos 5 KDC
 Requires: %{name}-server%{?_isa} = %{version}-%{release}
 Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+%ifarch x86_64
+Obsoletes: krb5-server-ldap-1.11.3-49.el7.i686
+%endif
+%ifarch ppc64
+Obsoletes: krb5-server-ldap-1.11.3-49.el7.ppc
+%endif
+%ifarch s390x
+Obsoletes: krb5-server-ldap-1.11.3-49.el7.s390
+%endif
 
 %description server-ldap
 Kerberos is a network authentication system. The krb5-server package
@@ -336,37 +319,8 @@ certificate.
 %setup -q -a 3 -a 100 -a 102
 ln NOTICE LICENSE
 
-%patch201 -p1 -b .In-ksu-merge-krb5_ccache_copy-and-_restricted
-%patch202 -p1 -b .In-ksu-don-t-stat-not-on-disk-ccache-residuals
-%patch203 -p1 -b .Use-an-intermediate-memory-cache-in-ksu
-%patch204 -p1 -b .Make-ksu-respect-the-default_ccache_name-setting
-%patch205 -p1 -b .Copy-config-entries-to-the-ksu-target-ccache
-%patch206 -p1 -b .Use-more-randomness-for-ksu-secondary-cache-names
-%patch207 -p1 -b .Make-krb5_cc_new_unique-create-DIR-directories
-
-%patch300 -p1 -b .kpasswd-skip-address-check
-%patch301 -p1 -b .Refactor-cm-functions-in-sendto_kdc.c
-%patch302 -p1 -b .Simplify-sendto_kdc.c
-%patch303 -p1 -b .Add-helper-to-determine-if-a-KDC-is-the-master
-%patch304 -p1 -b .Use-k5_transport-_strategy-enums-for-k5_sendto
-%patch305 -p1 -b .Build-support-for-TLS-used-by-HTTPS-proxy-support
-%patch306 -p1 -b .Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE
-%patch307 -p1 -b .Dispatch-style-protocol-switching-for-transport
-%patch308 -p1 -b .HTTPS-transport-Microsoft-KKDCPP-implementation
-%patch309 -p1 -b .Load-custom-anchors-when-using-KKDCP
-%patch310 -p1 -b .Check-names-in-the-server-s-cert-when-using-KKDCP
-%patch311 -p1 -b .Add-some-longer-form-docs-for-HTTPS
-%patch312 -p1 -b .Have-k5test.py-provide-runenv-to-python-tests
-%patch313 -p1 -b .Add-a-simple-KDC-proxy-test-server
-%patch314 -p1 -b .Add-tests-for-MS-KKDCP-client-support
-%patch315 -p1 -b .tls-plugins
-%patch316 -p1 -b .nodelete-plugins
-%patch317 -p1 -b .ksu-untyped-default-ccache-name
-%patch318 -p1 -b .ksu-no-ccache
 chmod u+x src/util/paste-kdcproxy.py
 
-%patch1 -p1 -b .pwdch-fast
-
 %patch60 -p1 -b .pam
 
 %patch63 -p1 -b .selinux-label
@@ -375,10 +329,7 @@ chmod u+x src/util/paste-kdcproxy.py
 %patch12 -p1 -b .ktany
 %patch16 -p1 -b .buildconf %{?_rawbuild}
 %patch23 -p1 -b .dns %{?_rawbuild}
-%patch29 -p1 -b .kprop-mktemp
-%patch30 -p1 -b .send-pr-tempfile
 %patch39 -p1 -b .api
-%patch59 -p1 -b .kpasswd_tcp
 %patch71 -p1 -b .dirsrv-accountlock %{?_rawbuild}
 %patch86 -p0 -b .debuginfo
 %patch105 -p1 -b .kvno
@@ -389,30 +340,24 @@ chmod u+x src/util/paste-kdcproxy.py
 
 %patch134 -p1 -b .kpasswdtest
 
-%patch136 -p1 -b .rcache-internal-const
-%patch137 -p1 -b .rcache-acquirecred-cleanup
-%patch139 -p1 -b .rcache-acquirecred-source
-%patch141 -p1 -b .rcache-acquirecred-test
-%patch142 -p1 -b .move-otp-sockets
-%patch145 -p1 -b .master-mechd
-%patch146 -p1 -b .master-strdupcheck
-%patch147 -p1 -b .master-compatible-keys
-%patch148 -p1 -b .system-exts
 %patch319 -p1 -b .krb5-kadm5clntmit_libsoname_version_downgrade
-%patch320 -p1 -b .krb5-ksu_not_working_with_default_principal
-%patch321 -p1 -b .krb5-cve_2014_5353_fix_ldap_misused_policy_name_crash
-%patch322 -p1 -b .krb5-cve_2014_5354_support_keyless_principals_in_ldap
-%patch323 -p1 -b .krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final
-%patch324 -p1 -b .krb5_1_13_kinit_C_loop_krb5bug243
-%patch325 -p1 -b .krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad
- 
+
+%patch140 -p1 -b .krb5-1.14-support-kdc_err_more_preauth_data_required
+%patch143 -p1 -b .krb5-tests_use_libs_from_build
+%patch144 -p1 -b .krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial
+%patch145 -p1 -b .krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad
+%patch146 -p1 -b .krb5-1.14-resolve_krb5_gss_creds_if_time_rec_is_requested
+%patch147 -p1 -b .krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char
+
+%patch148 -p1 -b .krb5-1.13.3-client_referrals
+%patch149 -p1 -b .krb5-1.13.3-client_referrals_test
 
 # Take the execute bit off of documentation.
 chmod -x doc/krb5-protocol/*.txt doc/ccapi/*.html
 
 # Generate an FDS-compatible LDIF file.
 inldif=src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif
-cat > 60kerberos.ldif << EOF
+cat > '60kerberos.ldif' << EOF
 # This is a variation on kerberos.ldif which 389 Directory Server will like.
 dn: cn=schema
 EOF
@@ -437,9 +382,7 @@ mkdir -p socket_wrapper/build
 cfg="src/kadmin/testing/proto/kdc.conf.proto \
      src/kadmin/testing/proto/krb5.conf.proto \
      src/lib/kadm5/unit-test/api.current/init-v2.exp \
-     src/util/k5test.py \
-     src/tests/mk_migr/ldap_backend/input_conf/*.conf \
-     src/tests/mk_migr/db2_backend/input_conf/*.conf"
+     src/util/k5test.py"
 LONG_BIT=`getconf LONG_BIT`
 PORT=`expr 61000 + $LONG_BIT - 48`
 sed -i -e s,61000,`expr "$PORT" + 0`,g $cfg
@@ -457,7 +400,7 @@ sed -i -e s,7778,`expr "$PORT" + 1`,g $cfg
 
 %build
 # Go ahead and supply tcl info, because configure doesn't know how to find it.
-. %{_libdir}/tclConfig.sh
+source %{_libdir}/tclConfig.sh
 pushd src
 # Keep the old default if the package is built against older releases.
 %if 0%{?compile_default_ccache_name}
@@ -501,9 +444,11 @@ CPPFLAGS="`echo $DEFINES $INCLUDES`"
 %endif
 %if %{WITH_OPENSSL}
 	--with-pkinit-crypto-impl=openssl \
+	--with-tls-impl=openssl \
 %endif
 %if %{WITH_NSS}
 	--with-crypto-impl=nss \
+	--without-tls-impl \
 %endif
 %if %{WITH_SYSVERTO}
 	--with-system-verto \
@@ -535,6 +480,9 @@ sphinx-build -a -b latex -t pathsubs doc build-pdf
 for pdf in admin appdev basic build plugindev user ; do
 	test -s build-pdf/$pdf.pdf || make -C build-pdf
 done
+# new krb5-%{version}-pdf.pax.xz, see above
+pax -wv -x ustar build-pdf/*.pdf | xz -9 >"krb5-%{version}-pdf.pax.xz.new"
+# false
 
 # Build the test wrappers.
 pushd nss_wrapper/build
@@ -577,7 +525,7 @@ make -C src/clients check TMPDIR=%{_tmppath}
 keyctl session - make -C src/util check TMPDIR=%{_tmppath}
 
 %install
-[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
+[ "$RPM_BUILD_ROOT" != '/' ] && rm -rf -- $RPM_BUILD_ROOT
 
 # Sample KDC config files (bundled kdc.conf and kadm5.acl).
 mkdir -p $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc
@@ -682,7 +630,6 @@ done
 # Plug-in directories.
 install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/preauth
 install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/kdb
-install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/tls
 install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/authdata
 
 # The rest of the binaries, headers, libraries, and docs.
@@ -693,6 +640,16 @@ make -C src DESTDIR=$RPM_BUILD_ROOT EXAMPLEDIR=%{libsdocdir}/examples install
 # list of link flags, and it helps prevent file conflicts on multilib systems.
 sed -r -i -e 's|^libdir=/usr/lib(64)?$|libdir=/usr/lib|g' $RPM_BUILD_ROOT%{_bindir}/krb5-config
 
+# FIXME: Temporay workaround for RH bug #1204646 ("krb5-config
+# returns wrong -specs path") so that development of krb5
+# dependicies gets unstuck.
+sed -r -i -e "s/-specs=\/.+?\/redhat-hardened-ld//g" $RPM_BUILD_ROOT%{_bindir}/krb5-config
+
+if [[ "$(< $RPM_BUILD_ROOT%{_bindir}/krb5-config )" == *redhat-hardened-ld* ]] ; then
+       printf '# redhat-hardened-ld for krb5-config failed' 1>&2
+       exit 1
+fi
+
 %if %{separate_usr}
 # Move specific libraries from %%{_libdir} to /%%{_lib}, and fixup the symlinks.
 touch $RPM_BUILD_ROOT/rootfile
@@ -700,7 +657,7 @@ rellibdir=..
 while ! test -r $RPM_BUILD_ROOT/%{_libdir}/${rellibdir}/rootfile ; do
 	rellibdir=../${rellibdir}
 done
-rm -f $RPM_BUILD_ROOT/rootfile
+rm -f -- $RPM_BUILD_ROOT/rootfile
 mkdir -p $RPM_BUILD_ROOT/%{_lib}
 for library in libgssapi_krb5 libgssrpc libk5crypto libkrb5 libkrb5support ; do
 	mv $RPM_BUILD_ROOT/%{_libdir}/${library}.so.* $RPM_BUILD_ROOT/%{_lib}/
@@ -716,10 +673,14 @@ for section in 1 5 8 ; do
 		       $RPM_BUILD_ROOT/%{_mandir}/man${section}/
 done
 
+# This script just tells you to send bug reports to krb5-bugs@mit.edu, but
+# since we don't have a man page for it, just drop it.
+rm -- $RPM_BUILD_ROOT/%{_sbindir}/krb5-send-pr
+
 %find_lang %{gettext_domain}
 
 %clean
-[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
+[ "$RPM_BUILD_ROOT" != '/' ] && rm -rf -- $RPM_BUILD_ROOT
 
 %post libs -p /sbin/ldconfig
 
@@ -765,7 +726,7 @@ if ! grep -q default_ccache_name /etc/krb5.conf ; then
 	fi
 fi
 if test -n "$tmpfile" ; then
-	rm -f "$tmpfile"
+	rm -f -- "$tmpfile"
 fi
 %endif
 
@@ -891,12 +852,6 @@ exit 0
 %{_mandir}/man1/ksu.1*
 %config(noreplace) /etc/pam.d/ksu
 
-# Problem-reporting tool.
-%{_sbindir}/krb5-send-pr
-%dir %{_datadir}/gnats
-%{_datadir}/gnats/mit
-%{_mandir}/man1/krb5-send-pr.1*
-
 %files server
 %defattr(-,root,root,-)
 %docdir %{_mandir}
@@ -931,13 +886,6 @@ exit 0
 %dir %{_libdir}/krb5/plugins/authdata
 %{_libdir}/krb5/plugins/preauth/otp.so
 
-
-# Problem-reporting tool.
-%{_sbindir}/krb5-send-pr
-%dir %{_datadir}/gnats
-%{_datadir}/gnats/mit
-%{_mandir}/man1/krb5-send-pr.1*
-
 # KDC binaries and configuration.
 %{_mandir}/man5/kadm5.acl.5*
 %{_mandir}/man5/kdc.conf.5*
@@ -1085,12 +1033,147 @@ exit 0
 
 
 %changelog
-* Wed Aug 26 2015 Roland Mainz <rmainz@redhat.com> - 1.12.2-15
-- Add a patch to fix RedHat bug #1256870 ("KDC sends multiple
+* Fri Sep 04 2015 Robbie Harwood <rharwood@redhat.com> 1.13.2-9
+- Add patch and test case for "KDC does not return proper
+  client principal for client referrals"
+- Resolves: #1259846
+
+* Mon Aug 31 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-9
+- Ammend patch for RedHat bug #1252454 ('testsuite complains
+  "Lifetime has increased by 32436 sec while 0 sec passed!",
+  while rhel5-libkrb5 passes') to handle the newly introduced
+  valgrind hits.
+
+* Wed Aug 19 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-8
+- Add a patch to fix RH Bug #1250154 ("[s390x, ppc64, ppc64le]:
+  kadmind does not accept ACL if kadm5.acl does not end with EOL")
+  The code "accidently" works on x86/AMD64 because declaring a
+  variable |char| results in an |unsigned char| by default while
+  most other platforms (e.g. { s390x, ppc64, ppc64le, ...})
+  default to |signed char| (still have to use lint(1) to clean
+  up 38 more instances of this kind of bug).
+
+* Wed Aug 19 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-7
+- Obsolete multilib versions of server packages to fix RH
+  bug #1251913 ("krb5 should obsolete the multilib versions
+  of krb5-server and krb5-server-ldap").
+  The following packages are declared obsolete:
+  - krb5-server-1.11.3-49.el7.i686
+  - krb5-server-1.11.3-49.el7.ppc
+  - krb5-server-1.11.3-49.el7.s390
+  - krb5-server-ldap-1.11.3-49.el7.i686
+  - krb5-server-ldap-1.11.3-49.el7.ppc
+  - krb5-server-ldap-1.11.3-49.el7.s390
+
+* Wed Aug 19 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-6
+- Add a patch to fix RedHat bug #1252454 ('testsuite complains
+  "Lifetime has increased by 32436 sec while 0 sec passed!",
+  while rhel5-libkrb5 passes') so that krb5 resolves GSS creds
+  if |time_rec| is requested.
+
+* Fri Aug 7 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-5
+- Add a patch to fix RedHat bug #1251586 ("KDC sends multiple
   requests to ipa-otpd for the same authentication") which causes
   the KDC to send multiple retries to ipa-otpd for TCP transports
   while it should only be done for UDP.
 
+* Tue Jul 28 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-4
+- the rebase to krb5 1.13.2 in vers 1.13.2-0 also fixed:
+  - Redhat Bug #1247761 ("RFE: Minor krb5 spec file cleanup and sync
+    with recent Fedora 22/23 changes")
+  - Redhat Bug #1247751 ("krb5-config returns wrong -specs path")
+  - Redhat Bug #1247608 ('Add support for multi-hop preauth mechs
+    via |KDC_ERR_MORE_PREAUTH_DATA_REQUIRED| for RFC 6113 ("A
+    Generalized Framework for Kerberos Pre-Authentication")')
+- Removed "krb5-1.10-kprop-mktemp.patch" and
+  "krb5-1.3.4-send-pr-tempfile.patch", both are no longer used since
+  the rebase to krb5 1.13.1
+
+* Fri May 29 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-3
+- Add patch to fix Redhat Bug #1222903 ("[SELinux] AVC denials may appear
+  when kadmind starts"). The issue was caused by an unneeded |htons()|
+  which triggered SELinux AVC denials due to the "random" port usage.
+
+* Thu May 21 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-2
+- Add fix for RedHat Bug #1164304 ("Upstream unit tests loads
+  the installed shared libraries instead the ones from the build")
+
+* Fri May 15 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-1
+- the rebase to krb5 1.13.1 in vers 1.13.1-0 also fixed:
+  - Bug 1144498 ("Fix the race condition in the libkrb5 replay cache")
+  - Bug 1163402 ("kdb5_ldap_util view_policy does not shows ticket flags on s390x and ppc64")
+  - Bug 1185770 ("Missing upstream test in krb5-1.12.2: src/tests/gssapi/t_invalid.c")
+  - Bug 1204211 ("CVE-2014-5355 krb5: unauthenticated denial of service in recvauth_common() and other")
+
+* Fri May 15 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-0
+- Update to krb5-1.13.2
+  - drop patch for krb5-1.13.2-CVE_2015_2694_requires_preauth_bypass_in_PKINIT_enabled_KDC, fixed in krb5-1.13.2
+  - drop patch for krb5-1.12.1-CVE_2014_5355_fix_krb5_read_message_handling, fixed in krb5-1.13.2
+
+* Thu May 14 2015 Roland Mainz <rmainz@redhat.com> - 1.13.1-2
+- the rebase to krb5 1.13.1 in vers 1.13.1-0 also fixed RH
+  bug #1156144 ("krb5 upstream test t_kdb.py failure")
+
+* Mon May 4 2015 Roland Mainz <rmainz@redhat.com> - 1.13.1-1
+- fix for CVE-2015-2694 (#1218020) "requires_preauth bypass
+  in PKINIT-enabled KDC".
+  In MIT krb5 1.12 and later, when the KDC is configured with
+  PKINIT support, an unauthenticated remote attacker can
+  bypass the requires_preauth flag on a client principal and
+  obtain a ciphertext encrypted in the principal's long-term
+  key.  This ciphertext could be used to conduct an off-line
+  dictionary attack against the user's password.
+
+* Fri Apr 24 2015 Roland Mainz <rmainz@redhat.com> - 1.13.1-0
+- Update to krb5-1.13.1
+  - patch krb5-1.12-selinux-label was updated and renamed to krb5-1.13-selinux-label
+  - patch krb5-1.11-dirsrv-accountlock was updated and renamed to krb5-1.13-dirsrv-accountlock
+  - drop patch for krb5-1.12-pwdch-fast, fixed in krb5-1.13
+  - drop patch for krb5-1.12ish-kpasswd_tcp, fixed in krb5-1.13
+  - drop patch for krb5-master-rcache-internal-const, no longer needed
+  - drop patch for krb5-master-rcache-acquirecred-cleanup, no longer needed
+  - drop patch for krb5-master-rcache-acquirecred-source, no longer needed
+  - drop patch for krb5-master-rcache-acquirecred-test, no longer needed
+  - drop patch for krb5-master-move-otp-sockets, no longer needed
+  - drop patch for krb5-master-mechd, no longer needed
+  - drop patch for krb5-master-strdupcheck, no longer needed
+  - drop patch for krb5-master-compatible-keys, no longer needed
+  - drop patch for krb5-1.12-system-exts, fixed in krb5-1.13
+  - drop patch for 0001-In-ksu-merge-krb5_ccache_copy-and-_restricted, no longer needed
+  - drop patch for 0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals, no longer needed
+  - drop patch for 0003-Use-an-intermediate-memory-cache-in-ksu, no longer needed
+  - drop patch for 0004-Make-ksu-respect-the-default_ccache_name-setting, no longer needed
+  - drop patch for 0005-Copy-config-entries-to-the-ksu-target-ccache, no longer needed
+  - drop patch for 0006-Use-more-randomness-for-ksu-secondary-cache-names, no longer needed
+  - drop patch for 0007-Make-krb5_cc_new_unique-create-DIR-directories, no longer needed
+  - drop patch for krb5-1.12-kpasswd-skip-address-check, fixed in krb5-1.13
+  - drop patch for 0000-Refactor-cm-functions-in-sendto_kdc.c, no longer needed
+  - drop patch for 0001-Simplify-sendto_kdc.c, no longer needed
+  - drop patch for 0002-Add-helper-to-determine-if-a-KDC-is-the-master, no longer needed
+  - drop patch for 0003-Use-k5_transport-_strategy-enums-for-k5_sendto, no longer needed
+  - drop patch for 0004-Build-support-for-TLS-used-by-HTTPS-proxy-support, no longer needed
+  - drop patch for 0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE, no longer needed
+  - drop patch for 0006-Dispatch-style-protocol-switching-for-transport, no longer needed
+  - drop patch for 0007-HTTPS-transport-Microsoft-KKDCPP-implementation, no longer needed
+  - drop patch for 0008-Load-custom-anchors-when-using-KKDCP, no longer needed
+  - drop patch for 0009-Check-names-in-the-server-s-cert-when-using-KKDCP, no longer needed
+  - drop patch for 0010-Add-some-longer-form-docs-for-HTTPS, no longer needed
+  - drop patch for 0011-Have-k5test.py-provide-runenv-to-python-tests, no longer needed
+  - drop patch for 0012-Add-a-simple-KDC-proxy-test-server, no longer needed
+  - drop patch for 0013-Add-tests-for-MS-KKDCP-client-support, no longer needed
+  - drop patch for krb5-1.12ish-tls-plugins, fixed in krb5-1.13.1
+  - drop patch for krb5-1.12-nodelete-plugins, fixed in krb5-1.13.1
+  - drop patch for krb5-1.12-ksu-untyped-default-ccache-name, fixed in krb5-1.13.1
+  - drop patch for krb5-1.12-ksu-no-ccache, fixed in krb5-1.13.1
+  - drop patch for krb5-ksu_not_working_with_default_principal, fixed in krb5-1.13.1
+  - drop patch for CVE_2014_5353_fix_LDAP_misused_policy_name_crash, fixed in krb5-1.13.1
+  - drop patch for CVE_2014_5354_support_keyless_principals_in_ldap, fixed in krb5-1.13.1
+  - drop patch for kinit -C loops (MIT/krb5 bug #243), fixed in krb5-1.13.1
+  - drop patch for CVEs { 2014-9421, 2014-9422, 2014-9423, 2014-5352 }, fixed in krb5-1.13.1
+  - added patch krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED
+  - added patch krb5-1.12.1-CVE_2014_5355_fix_krb5_read_message_handling
+- Minor spec cleanup
+
 * Mon Jan 26 2015 Roland Mainz <rmainz@redhat.com> - 1.12.2-14
 - fix for kinit -C loops (#1184629, MIT/krb5 issue 243, "Do not
   loop on principal unknown errors").