diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f9809d6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+SOURCES/krb5-1.17-pdfs.tar
+SOURCES/krb5-1.17.tar.gz
diff --git a/.krb5.metadata b/.krb5.metadata
new file mode 100644
index 0000000..5858b94
--- /dev/null
+++ b/.krb5.metadata
@@ -0,0 +1,2 @@
+494c62bea08e5d26e01d47c409ac745b65e509c8 SOURCES/krb5-1.17-pdfs.tar
+0c404b081db9c996c581f636ce450ee28778f338 SOURCES/krb5-1.17.tar.gz
diff --git a/SOURCES/Add-function-and-enctype-flag-for-deprecations.patch b/SOURCES/Add-function-and-enctype-flag-for-deprecations.patch
new file mode 100644
index 0000000..2a094e7
--- /dev/null
+++ b/SOURCES/Add-function-and-enctype-flag-for-deprecations.patch
@@ -0,0 +1,183 @@
+From ba1fd0a44c74089d42af244ff2b315baf506fd2f Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 15 Jan 2019 16:16:57 -0500
+Subject: [PATCH] Add function and enctype flag for deprecations
+
+krb5int_c_deprecated_enctype() checks for the ETYPE_DEPRECATED flag on
+enctypes.  All ENCTYPE_WEAK enctypes are currently deprecated; not all
+deprecated enctypes are considered weak.  Deprecations follow RFC 6649
+and RFC 8429.
+
+(cherry picked from commit 484a6e7712f9b66e782b2520f07b0883889e116f)
+---
+ src/include/k5-int.h               |  1 +
+ src/lib/crypto/krb/crypto_int.h    |  9 ++++++++-
+ src/lib/crypto/krb/enctype_util.c  |  7 +++++++
+ src/lib/crypto/krb/etypes.c        | 19 ++++++++++---------
+ src/lib/crypto/libk5crypto.exports |  1 +
+ src/lib/krb5_32.def                |  3 +++
+ 6 files changed, 30 insertions(+), 10 deletions(-)
+
+diff --git a/src/include/k5-int.h b/src/include/k5-int.h
+index 8f9329c59..255cee822 100644
+--- a/src/include/k5-int.h
++++ b/src/include/k5-int.h
+@@ -2077,6 +2077,7 @@ krb5_get_tgs_ktypes(krb5_context, krb5_const_principal, krb5_enctype **);
+ krb5_boolean krb5_is_permitted_enctype(krb5_context, krb5_enctype);
+ 
+ krb5_boolean KRB5_CALLCONV krb5int_c_weak_enctype(krb5_enctype);
++krb5_boolean KRB5_CALLCONV krb5int_c_deprecated_enctype(krb5_enctype);
+ krb5_error_code k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out);
+ 
+ krb5_error_code krb5_kdc_rep_decrypt_proc(krb5_context, const krb5_keyblock *,
+diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
+index e5099291e..6c1c77cac 100644
+--- a/src/lib/crypto/krb/crypto_int.h
++++ b/src/lib/crypto/krb/crypto_int.h
+@@ -114,7 +114,14 @@ struct krb5_keytypes {
+     unsigned int ssf;
+ };
+ 
+-#define ETYPE_WEAK 1
++/*
++ * "Weak" means the enctype is believed to be vulnerable to practical attacks,
++ * and will be disabled unless allow_weak_crypto is set to true.  "Deprecated"
++ * means the enctype has been deprecated by the IETF, and affects display and
++ * logging.
++ */
++#define ETYPE_WEAK (1 << 0)
++#define ETYPE_DEPRECATED (1 << 1)
+ 
+ extern const struct krb5_keytypes krb5int_enctypes_list[];
+ extern const int krb5int_enctypes_length;
+diff --git a/src/lib/crypto/krb/enctype_util.c b/src/lib/crypto/krb/enctype_util.c
+index b1b40e7ec..e394f4e19 100644
+--- a/src/lib/crypto/krb/enctype_util.c
++++ b/src/lib/crypto/krb/enctype_util.c
+@@ -51,6 +51,13 @@ krb5int_c_weak_enctype(krb5_enctype etype)
+     return (ktp != NULL && (ktp->flags & ETYPE_WEAK) != 0);
+ }
+ 
++krb5_boolean KRB5_CALLCONV
++krb5int_c_deprecated_enctype(krb5_enctype etype)
++{
++    const struct krb5_keytypes *ktp = find_enctype(etype);
++    return ktp != NULL && (ktp->flags & ETYPE_DEPRECATED) != 0;
++}
++
+ krb5_error_code KRB5_CALLCONV
+ krb5_c_enctype_compare(krb5_context context, krb5_enctype e1, krb5_enctype e2,
+                        krb5_boolean *similar)
+diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c
+index 53d4a5c79..8f44c37e7 100644
+--- a/src/lib/crypto/krb/etypes.c
++++ b/src/lib/crypto/krb/etypes.c
+@@ -33,6 +33,7 @@
+    that the keytypes are all near each other.  I'd rather not make
+    that assumption. */
+ 
++/* Deprecations come from RFC 6649 and RFC 8249. */
+ const struct krb5_keytypes krb5int_enctypes_list[] = {
+     { ENCTYPE_DES_CBC_CRC,
+       "des-cbc-crc", { 0 }, "DES cbc mode with CRC-32",
+@@ -42,7 +43,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
+       krb5int_des_string_to_key, k5_rand2key_des,
+       krb5int_des_prf,
+       CKSUMTYPE_RSA_MD5_DES,
+-      ETYPE_WEAK, 56 },
++      ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
+     { ENCTYPE_DES_CBC_MD4,
+       "des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4",
+       &krb5int_enc_des, &krb5int_hash_md4,
+@@ -51,7 +52,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
+       krb5int_des_string_to_key, k5_rand2key_des,
+       krb5int_des_prf,
+       CKSUMTYPE_RSA_MD4_DES,
+-      ETYPE_WEAK, 56 },
++      ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
+     { ENCTYPE_DES_CBC_MD5,
+       "des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5",
+       &krb5int_enc_des, &krb5int_hash_md5,
+@@ -60,7 +61,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
+       krb5int_des_string_to_key, k5_rand2key_des,
+       krb5int_des_prf,
+       CKSUMTYPE_RSA_MD5_DES,
+-      ETYPE_WEAK, 56 },
++      ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
+     { ENCTYPE_DES_CBC_RAW,
+       "des-cbc-raw", { 0 }, "DES cbc mode raw",
+       &krb5int_enc_des, NULL,
+@@ -69,7 +70,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
+       krb5int_des_string_to_key, k5_rand2key_des,
+       krb5int_des_prf,
+       0,
+-      ETYPE_WEAK, 56 },
++      ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
+     { ENCTYPE_DES3_CBC_RAW,
+       "des3-cbc-raw", { 0 }, "Triple DES cbc mode raw",
+       &krb5int_enc_des3, NULL,
+@@ -78,7 +79,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
+       krb5int_dk_string_to_key, k5_rand2key_des3,
+       NULL, /*PRF*/
+       0,
+-      ETYPE_WEAK, 112 },
++      ETYPE_WEAK | ETYPE_DEPRECATED, 112 },
+ 
+     { ENCTYPE_DES3_CBC_SHA1,
+       "des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" },
+@@ -89,7 +90,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
+       krb5int_dk_string_to_key, k5_rand2key_des3,
+       krb5int_dk_prf,
+       CKSUMTYPE_HMAC_SHA1_DES3,
+-      0 /*flags*/, 112 },
++      ETYPE_DEPRECATED, 112 },
+ 
+     { ENCTYPE_DES_HMAC_SHA1,
+       "des-hmac-sha1", { 0 }, "DES with HMAC/sha1",
+@@ -99,7 +100,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
+       krb5int_dk_string_to_key, k5_rand2key_des,
+       NULL, /*PRF*/
+       0,
+-      ETYPE_WEAK, 56 },
++      ETYPE_WEAK | ETYPE_DEPRECATED, 56 },
+ 
+     /* rc4-hmac uses a 128-bit key, but due to weaknesses in the RC4 cipher, we
+      * consider its strength degraded and assign it an SSF value of 64. */
+@@ -113,7 +114,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
+       krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
+       k5_rand2key_direct, krb5int_arcfour_prf,
+       CKSUMTYPE_HMAC_MD5_ARCFOUR,
+-      0 /*flags*/, 64 },
++      ETYPE_DEPRECATED, 64 },
+     { ENCTYPE_ARCFOUR_HMAC_EXP,
+       "arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" },
+       "Exportable ArcFour with HMAC/md5",
+@@ -124,7 +125,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
+       krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
+       k5_rand2key_direct, krb5int_arcfour_prf,
+       CKSUMTYPE_HMAC_MD5_ARCFOUR,
+-      ETYPE_WEAK, 40
++      ETYPE_WEAK | ETYPE_DEPRECATED, 40
+     },
+ 
+     { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
+index 82eb5f30c..90afdf5f7 100644
+--- a/src/lib/crypto/libk5crypto.exports
++++ b/src/lib/crypto/libk5crypto.exports
+@@ -109,3 +109,4 @@ k5_allow_weak_pbkdf2iter
+ krb5_c_prfplus
+ krb5_c_derive_prfplus
+ k5_enctype_to_ssf
++krb5int_c_deprecated_enctype
+diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
+index c35022931..e6a487593 100644
+--- a/src/lib/krb5_32.def
++++ b/src/lib/krb5_32.def
+@@ -487,3 +487,6 @@ EXPORTS
+ 	encode_krb5_pa_spake				@444 ; PRIVATE
+ 	decode_krb5_pa_spake				@445 ; PRIVATE
+ 	k5_free_pa_spake				@446 ; PRIVATE
++
++; new in 1.18
++	krb5int_c_deprecated_enctype			@450 ; PRIVATE
diff --git a/SOURCES/Add-soft-pkcs11-source-code.patch b/SOURCES/Add-soft-pkcs11-source-code.patch
new file mode 100644
index 0000000..25488b5
--- /dev/null
+++ b/SOURCES/Add-soft-pkcs11-source-code.patch
@@ -0,0 +1,2072 @@
+From c4626f17ece51265eaa5446e96104b115ecbe31c Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Thu, 20 Jun 2019 10:45:18 -0400
+Subject: [PATCH] Add soft-pkcs11 source code
+
+soft-pkcs11 is no longer available upstream and is not generally
+packaged in distributions, making it inconvenient to use for tests.
+Import the 1.8 source code, detabified and with trailing whitespace
+removed but otherwise unmodified.
+
+(cherry picked from commit a4bc3e513a58b0d1292f3506ac3b35be8c178086)
+(cherry picked from commit a186597238ae40e167ce041857b5bd1f94ee2383)
+---
+ src/tests/softpkcs11/main.c | 2049 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 2049 insertions(+)
+ create mode 100644 src/tests/softpkcs11/main.c
+
+diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
+new file mode 100644
+index 000000000..2acec5169
+--- /dev/null
++++ b/src/tests/softpkcs11/main.c
+@@ -0,0 +1,2049 @@
++/*
++ * Copyright (c) 2004-2006, Stockholms universitet
++ * (Stockholm University, Stockholm Sweden)
++ * 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.
++ *
++ * 3. Neither the name of the university 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.
++ */
++
++#include "locl.h"
++
++/* RCSID("$Id: main.c,v 1.24 2006/01/11 12:42:53 lha Exp $"); */
++
++#define OBJECT_ID_MASK          0xfff
++#define HANDLE_OBJECT_ID(h)     ((h) & OBJECT_ID_MASK)
++#define OBJECT_ID(obj)          HANDLE_OBJECT_ID((obj)->object_handle)
++
++struct st_attr {
++    CK_ATTRIBUTE attribute;
++    int secret;
++};
++
++struct st_object {
++    CK_OBJECT_HANDLE object_handle;
++    struct st_attr *attrs;
++    int num_attributes;
++    enum {
++        STO_T_CERTIFICATE,
++        STO_T_PRIVATE_KEY,
++        STO_T_PUBLIC_KEY
++    } type;
++    union {
++        X509 *cert;
++        EVP_PKEY *public_key;
++        struct {
++            const char *file;
++            EVP_PKEY *key;
++            X509 *cert;
++        } private_key;
++    } u;
++};
++
++static struct soft_token {
++    CK_VOID_PTR application;
++    CK_NOTIFY notify;
++    struct {
++        struct st_object **objs;
++        int num_objs;
++    } object;
++    struct {
++        int hardware_slot;
++        int app_error_fatal;
++        int login_done;
++    } flags;
++    int open_sessions;
++    struct session_state {
++        CK_SESSION_HANDLE session_handle;
++
++        struct {
++            CK_ATTRIBUTE *attributes;
++            CK_ULONG num_attributes;
++            int next_object;
++        } find;
++
++        int encrypt_object;
++        CK_MECHANISM_PTR encrypt_mechanism;
++        int decrypt_object;
++        CK_MECHANISM_PTR decrypt_mechanism;
++        int sign_object;
++        CK_MECHANISM_PTR sign_mechanism;
++        int verify_object;
++        CK_MECHANISM_PTR verify_mechanism;
++        int digest_object;
++    } state[10];
++#define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))
++    FILE *logfile;
++} soft_token;
++
++static void
++application_error(const char *fmt, ...)
++{
++    va_list ap;
++    va_start(ap, fmt);
++    vprintf(fmt, ap);
++    va_end(ap);
++    if (soft_token.flags.app_error_fatal)
++        abort();
++}
++
++static void
++st_logf(const char *fmt, ...)
++{
++    va_list ap;
++    if (soft_token.logfile == NULL)
++        return;
++    va_start(ap, fmt);
++    vfprintf(soft_token.logfile, fmt, ap);
++    va_end(ap);
++    fflush(soft_token.logfile);
++}
++
++static void
++snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...)
++{
++    int len;
++    va_list ap;
++    len = vsnprintf(str, size, fmt, ap);
++    va_end(ap);
++    if (len < 0 || len > size)
++        return;
++    while(len < size)
++        str[len++] = fillchar;
++}
++
++#ifndef TEST_APP
++#define printf error_use_st_logf
++#endif
++
++#define VERIFY_SESSION_HANDLE(s, state)                 \
++{                                                       \
++    CK_RV ret;                                          \
++    ret = verify_session_handle(s, state);              \
++    if (ret != CKR_OK) {                                \
++        /* return CKR_OK */;                            \
++    }                                                   \
++}
++
++static CK_RV
++verify_session_handle(CK_SESSION_HANDLE hSession,
++                      struct session_state **state)
++{
++    int i;
++
++    for (i = 0; i < MAX_NUM_SESSION; i++){
++        if (soft_token.state[i].session_handle == hSession)
++            break;
++    }
++    if (i == MAX_NUM_SESSION) {
++        application_error("use of invalid handle: 0x%08lx\n",
++                          (unsigned long)hSession);
++        return CKR_SESSION_HANDLE_INVALID;
++    }
++    if (state)
++        *state = &soft_token.state[i];
++    return CKR_OK;
++}
++
++static CK_RV
++object_handle_to_object(CK_OBJECT_HANDLE handle,
++                        struct st_object **object)
++{
++    int i = HANDLE_OBJECT_ID(handle);
++
++    *object = NULL;
++    if (i >= soft_token.object.num_objs)
++        return CKR_ARGUMENTS_BAD;
++    if (soft_token.object.objs[i] == NULL)
++        return CKR_ARGUMENTS_BAD;
++    if (soft_token.object.objs[i]->object_handle != handle)
++        return CKR_ARGUMENTS_BAD;
++    *object = soft_token.object.objs[i];
++    return CKR_OK;
++}
++
++static int
++attributes_match(const struct st_object *obj,
++                 const CK_ATTRIBUTE *attributes,
++                 CK_ULONG num_attributes)
++{
++    CK_ULONG i;
++    int j;
++    st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj));
++
++    for (i = 0; i < num_attributes; i++) {
++        int match = 0;
++        for (j = 0; j < obj->num_attributes; j++) {
++            if (attributes[i].type == obj->attrs[j].attribute.type &&
++                attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen &&
++                memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue,
++                       attributes[i].ulValueLen) == 0) {
++                match = 1;
++                break;
++            }
++        }
++        if (match == 0) {
++            st_logf("type %d attribute have no match\n", attributes[i].type);
++            return 0;
++        }
++    }
++    st_logf("attribute matches\n");
++    return 1;
++}
++
++static void
++print_attributes(const CK_ATTRIBUTE *attributes,
++                 CK_ULONG num_attributes)
++{
++    CK_ULONG i;
++
++    st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes);
++
++    for (i = 0; i < num_attributes; i++) {
++        st_logf("  type: ");
++        switch (attributes[i].type) {
++        case CKA_TOKEN: {
++            CK_BBOOL *ck_true;
++            if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) {
++                application_error("token attribute wrong length\n");
++                break;
++            }
++            ck_true = attributes[i].pValue;
++            st_logf("token: %s", *ck_true ? "TRUE" : "FALSE");
++            break;
++        }
++        case CKA_CLASS: {
++            CK_OBJECT_CLASS *class;
++            if (attributes[i].ulValueLen != sizeof(CK_ULONG)) {
++                application_error("class attribute wrong length\n");
++                break;
++            }
++            class = attributes[i].pValue;
++            st_logf("class ");
++            switch (*class) {
++            case CKO_CERTIFICATE:
++                st_logf("certificate");
++                break;
++            case CKO_PUBLIC_KEY:
++                st_logf("public key");
++                break;
++            case CKO_PRIVATE_KEY:
++                st_logf("private key");
++                break;
++            case CKO_SECRET_KEY:
++                st_logf("secret key");
++                break;
++            case CKO_DOMAIN_PARAMETERS:
++                st_logf("domain parameters");
++                break;
++            default:
++                st_logf("[class %lx]", (long unsigned)*class);
++                break;
++            }
++            break;
++        }
++        case CKA_PRIVATE:
++            st_logf("private");
++            break;
++        case CKA_LABEL:
++            st_logf("label");
++            break;
++        case CKA_APPLICATION:
++            st_logf("application");
++            break;
++        case CKA_VALUE:
++            st_logf("value");
++            break;
++        case CKA_ID:
++            st_logf("id");
++            break;
++        default:
++            st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type);
++            break;
++        }
++        st_logf("\n");
++    }
++}
++
++static struct st_object *
++add_st_object(void)
++{
++    struct st_object *o, **objs;
++    int i;
++
++    o = malloc(sizeof(*o));
++    if (o == NULL)
++        return NULL;
++    memset(o, 0, sizeof(*o));
++    o->attrs = NULL;
++    o->num_attributes = 0;
++
++    for (i = 0; i < soft_token.object.num_objs; i++) {
++        if (soft_token.object.objs == NULL) {
++            soft_token.object.objs[i] = o;
++            break;
++        }
++    }
++    if (i == soft_token.object.num_objs) {
++        objs = realloc(soft_token.object.objs,
++                       (soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0]));
++        if (objs == NULL) {
++            free(o);
++            return NULL;
++        }
++        soft_token.object.objs = objs;
++        soft_token.object.objs[soft_token.object.num_objs++] = o;
++    }
++    soft_token.object.objs[i]->object_handle =
++        (random() & (~OBJECT_ID_MASK)) | i;
++
++    return o;
++}
++
++static CK_RV
++add_object_attribute(struct st_object *o,
++                     int secret,
++                     CK_ATTRIBUTE_TYPE type,
++                     CK_VOID_PTR pValue,
++                     CK_ULONG ulValueLen)
++{
++    struct st_attr *a;
++    int i;
++
++    i = o->num_attributes;
++    a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0]));
++    if (a == NULL)
++        return CKR_DEVICE_MEMORY;
++    o->attrs = a;
++    o->attrs[i].secret = secret;
++    o->attrs[i].attribute.type = type;
++    o->attrs[i].attribute.pValue = malloc(ulValueLen);
++    if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0)
++        return CKR_DEVICE_MEMORY;
++    memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen);
++    o->attrs[i].attribute.ulValueLen = ulValueLen;
++    o->num_attributes++;
++
++    return CKR_OK;
++}
++
++static CK_RV
++add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
++{
++    switch (key_type) {
++    case CKK_RSA: {
++        CK_BYTE *modulus = NULL;
++        size_t modulus_len = 0;
++        CK_ULONG modulus_bits = 0;
++        CK_BYTE *exponent = NULL;
++        size_t exponent_len = 0;
++
++        modulus_bits = BN_num_bits(key->pkey.rsa->n);
++
++        modulus_len = BN_num_bytes(key->pkey.rsa->n);
++        modulus = malloc(modulus_len);
++        BN_bn2bin(key->pkey.rsa->n, modulus);
++
++        exponent_len = BN_num_bytes(key->pkey.rsa->e);
++        exponent = malloc(exponent_len);
++        BN_bn2bin(key->pkey.rsa->e, exponent);
++
++        add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
++        add_object_attribute(o, 0, CKA_MODULUS_BITS,
++                             &modulus_bits, sizeof(modulus_bits));
++        add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
++                             exponent, exponent_len);
++
++        RSA_set_method(key->pkey.rsa, RSA_PKCS1_SSLeay());
++
++        free(modulus);
++        free(exponent);
++    }
++    default:
++        /* XXX */
++        break;
++    }
++    return CKR_OK;
++}
++
++
++static int
++pem_callback(char *buf, int num, int w, void *key)
++{
++    return -1;
++}
++
++
++static CK_RV
++add_certificate(char *label,
++                const char *cert_file,
++                const char *private_key_file,
++                char *id,
++                int anchor)
++{
++    struct st_object *o = NULL;
++    CK_BBOOL bool_true = CK_TRUE;
++    CK_BBOOL bool_false = CK_FALSE;
++    CK_OBJECT_CLASS c;
++    CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
++    CK_KEY_TYPE key_type;
++    CK_MECHANISM_TYPE mech_type;
++    void *cert_data = NULL;
++    size_t cert_length;
++    void *subject_data = NULL;
++    size_t subject_length;
++    void *issuer_data = NULL;
++    size_t issuer_length;
++    void *serial_data = NULL;
++    size_t serial_length;
++    CK_RV ret = CKR_GENERAL_ERROR;
++    X509 *cert;
++    EVP_PKEY *public_key;
++
++    size_t id_len = strlen(id);
++
++    {
++        FILE *f;
++
++        f = fopen(cert_file, "r");
++        if (f == NULL) {
++            st_logf("failed to open file %s\n", cert_file);
++            return CKR_GENERAL_ERROR;
++        }
++
++        cert = PEM_read_X509(f, NULL, NULL, NULL);
++        fclose(f);
++        if (cert == NULL) {
++            st_logf("failed reading PEM cert\n");
++            return CKR_GENERAL_ERROR;
++        }
++
++        OPENSSL_ASN1_MALLOC_ENCODE(X509, cert_data, cert_length, cert, ret);
++        if (ret)
++            goto out;
++
++        OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, issuer_data, issuer_length,
++                                   X509_get_issuer_name(cert), ret);
++        if (ret)
++            goto out;
++
++        OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, subject_data, subject_length,
++                                   X509_get_subject_name(cert), ret);
++        if (ret)
++            goto out;
++
++        OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, serial_data, serial_length,
++                                   X509_get_serialNumber(cert), ret);
++        if (ret)
++            goto out;
++
++    }
++
++    st_logf("done parsing, adding to internal structure\n");
++
++    o = add_st_object();
++    if (o == NULL) {
++        ret = CKR_DEVICE_MEMORY;
++        goto out;
++    }
++    o->type = STO_T_CERTIFICATE;
++    o->u.cert = cert;
++    public_key = X509_get_pubkey(o->u.cert);
++
++    switch (EVP_PKEY_type(public_key->type)) {
++    case EVP_PKEY_RSA:
++        key_type = CKK_RSA;
++        break;
++    case EVP_PKEY_DSA:
++        key_type = CKK_DSA;
++        break;
++    default:
++        /* XXX */
++        break;
++    }
++
++    c = CKO_CERTIFICATE;
++    add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
++    add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
++    add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));
++    add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
++    add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));
++
++    add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type));
++    add_object_attribute(o, 0, CKA_ID, id, id_len);
++
++    add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
++    add_object_attribute(o, 0, CKA_ISSUER, issuer_data, issuer_length);
++    add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data, serial_length);
++    add_object_attribute(o, 0, CKA_VALUE, cert_data, cert_length);
++    if (anchor)
++        add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));
++    else
++        add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false));
++
++    st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o));
++
++    o = add_st_object();
++    if (o == NULL) {
++        ret = CKR_DEVICE_MEMORY;
++        goto out;
++    }
++    o->type = STO_T_PUBLIC_KEY;
++    o->u.public_key = public_key;
++
++    c = CKO_PUBLIC_KEY;
++    add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
++    add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
++    add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));
++    add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
++    add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));
++
++    add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
++    add_object_attribute(o, 0, CKA_ID, id, id_len);
++    add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */
++    add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */
++    add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
++    add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
++    mech_type = CKM_RSA_X_509;
++    add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
++
++    add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
++    add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true));
++    add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true));
++    add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false));
++    add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true));
++    add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));
++
++    add_pubkey_info(o, key_type, public_key);
++
++    st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o));
++
++    if (private_key_file) {
++        CK_FLAGS flags;
++        FILE *f;
++
++        o = add_st_object();
++        if (o == NULL) {
++            ret = CKR_DEVICE_MEMORY;
++            goto out;
++        }
++        o->type = STO_T_PRIVATE_KEY;
++        o->u.private_key.file = strdup(private_key_file);
++        o->u.private_key.key = NULL;
++
++        o->u.private_key.cert = cert;
++
++        c = CKO_PRIVATE_KEY;
++        add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
++        add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
++        add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false));
++        add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
++        add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));
++
++        add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
++        add_object_attribute(o, 0, CKA_ID, id, id_len);
++        add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */
++        add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */
++        add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
++        add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
++        mech_type = CKM_RSA_X_509;
++        add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
++
++        add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
++        add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true));
++        add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true));
++        flags = 0;
++        add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags));
++
++        add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true));
++        add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true));
++        add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false));
++        add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true));
++        add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true));
++        add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false));
++
++        add_pubkey_info(o, key_type, public_key);
++
++        f = fopen(private_key_file, "r");
++        if (f == NULL) {
++            st_logf("failed to open private key\n");
++            return CKR_GENERAL_ERROR;
++        }
++
++        o->u.private_key.key = PEM_read_PrivateKey(f, NULL, pem_callback, NULL);
++        fclose(f);
++        if (o->u.private_key.key == NULL) {
++            st_logf("failed to read private key a startup\n");
++            /* don't bother with this failure for now,
++               fix it at C_Login time */;
++        } else {
++            /* XXX verify keytype */
++
++            if (key_type == CKK_RSA)
++                RSA_set_method(o->u.private_key.key->pkey.rsa,
++                               RSA_PKCS1_SSLeay());
++
++            if (X509_check_private_key(cert, o->u.private_key.key) != 1) {
++                EVP_PKEY_free(o->u.private_key.key);
++                o->u.private_key.key = NULL;
++                st_logf("private key doesn't verify\n");
++            } else {
++                st_logf("private key usable\n");
++                soft_token.flags.login_done = 1;
++            }
++        }
++    }
++
++    ret = CKR_OK;
++ out:
++    if (ret != CKR_OK) {
++        st_logf("something went wrong when adding cert!\n");
++
++        /* XXX wack o */;
++    }
++    free(cert_data);
++    free(serial_data);
++    free(issuer_data);
++    free(subject_data);
++
++    return ret;
++}
++
++static void
++find_object_final(struct session_state *state)
++{
++    if (state->find.attributes) {
++        CK_ULONG i;
++
++        for (i = 0; i < state->find.num_attributes; i++) {
++            if (state->find.attributes[i].pValue)
++                free(state->find.attributes[i].pValue);
++        }
++        free(state->find.attributes);
++        state->find.attributes = NULL;
++        state->find.num_attributes = 0;
++        state->find.next_object = -1;
++    }
++}
++
++static void
++reset_crypto_state(struct session_state *state)
++{
++    state->encrypt_object = -1;
++    if (state->encrypt_mechanism)
++        free(state->encrypt_mechanism);
++    state->encrypt_mechanism = NULL_PTR;
++    state->decrypt_object = -1;
++    if (state->decrypt_mechanism)
++        free(state->decrypt_mechanism);
++    state->decrypt_mechanism = NULL_PTR;
++    state->sign_object = -1;
++    if (state->sign_mechanism)
++        free(state->sign_mechanism);
++    state->sign_mechanism = NULL_PTR;
++    state->verify_object = -1;
++    if (state->verify_mechanism)
++        free(state->verify_mechanism);
++    state->verify_mechanism = NULL_PTR;
++    state->digest_object = -1;
++}
++
++static void
++close_session(struct session_state *state)
++{
++    if (state->find.attributes) {
++        application_error("application didn't do C_FindObjectsFinal\n");
++        find_object_final(state);
++    }
++
++    state->session_handle = CK_INVALID_HANDLE;
++    soft_token.application = NULL_PTR;
++    soft_token.notify = NULL_PTR;
++    reset_crypto_state(state);
++}
++
++static const char *
++has_session(void)
++{
++    return soft_token.open_sessions > 0 ? "yes" : "no";
++}
++
++static void
++read_conf_file(const char *fn)
++{
++    char buf[1024], *cert, *key, *id, *label, *s, *p;
++    int anchor;
++    FILE *f;
++
++    f = fopen(fn, "r");
++    if (f == NULL) {
++        st_logf("can't open configuration file %s\n", fn);
++        return;
++    }
++
++    while(fgets(buf, sizeof(buf), f) != NULL) {
++        buf[strcspn(buf, "\n")] = '\0';
++
++        anchor = 0;
++
++        st_logf("line: %s\n", buf);
++
++        p = buf;
++        while (isspace(*p))
++            p++;
++        if (*p == '#')
++            continue;
++        while (isspace(*p))
++            p++;
++
++        s = NULL;
++        id = strtok_r(p, "\t", &s);
++        if (id == NULL)
++            continue;
++        label = strtok_r(NULL, "\t", &s);
++        if (label == NULL)
++            continue;
++        cert = strtok_r(NULL, "\t", &s);
++        if (cert == NULL)
++            continue;
++        key = strtok_r(NULL, "\t", &s);
++
++        /* XXX */
++        if (strcmp(id, "anchor") == 0) {
++            id = "\x00\x00";
++            anchor = 1;
++        }
++
++        st_logf("adding: %s\n", label);
++
++        add_certificate(label, cert, key, id, anchor);
++    }
++}
++
++static CK_RV
++func_not_supported(void)
++{
++    st_logf("function not supported\n");
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_Initialize(CK_VOID_PTR a)
++{
++    CK_C_INITIALIZE_ARGS_PTR args = a;
++    st_logf("Initialize\n");
++    int i;
++
++    OpenSSL_add_all_algorithms();
++    ERR_load_crypto_strings();
++
++    srandom(getpid() ^ time(NULL));
++
++    for (i = 0; i < MAX_NUM_SESSION; i++) {
++        soft_token.state[i].session_handle = CK_INVALID_HANDLE;
++        soft_token.state[i].find.attributes = NULL;
++        soft_token.state[i].find.num_attributes = 0;
++        soft_token.state[i].find.next_object = -1;
++        reset_crypto_state(&soft_token.state[i]);
++    }
++
++    soft_token.flags.hardware_slot = 1;
++    soft_token.flags.app_error_fatal = 0;
++    soft_token.flags.login_done = 0;
++
++    soft_token.object.objs = NULL;
++    soft_token.object.num_objs = 0;
++
++    soft_token.logfile = NULL;
++#if 0
++    soft_token.logfile = stdout;
++#endif
++#if 0
++    soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a");
++#endif
++
++    if (a != NULL_PTR) {
++        st_logf("\tCreateMutex:\t%p\n", args->CreateMutex);
++        st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex);
++        st_logf("\tLockMutext\t%p\n", args->LockMutex);
++        st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex);
++        st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);
++    }
++
++    {
++        char *fn = NULL, *home = NULL;
++
++        if (getuid() == geteuid()) {
++            fn = getenv("SOFTPKCS11RC");
++            if (fn)
++                fn = strdup(fn);
++            home = getenv("HOME");
++        }
++        if (fn == NULL && home == NULL) {
++            struct passwd *pw = getpwuid(getuid());
++            if(pw != NULL)
++                home = pw->pw_dir;
++        }
++        if (fn == NULL) {
++            if (home)
++                asprintf(&fn, "%s/.soft-token.rc", home);
++            else
++                fn = strdup("/etc/soft-token.rc");
++        }
++
++        read_conf_file(fn);
++        free(fn);
++    }
++
++    return CKR_OK;
++}
++
++CK_RV
++C_Finalize(CK_VOID_PTR args)
++{
++    int i;
++
++    st_logf("Finalize\n");
++
++    for (i = 0; i < MAX_NUM_SESSION; i++) {
++        if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) {
++            application_error("application finalized without "
++                              "closing session\n");
++            close_session(&soft_token.state[i]);
++        }
++    }
++
++    return CKR_OK;
++}
++
++CK_RV
++C_GetInfo(CK_INFO_PTR args)
++{
++    st_logf("GetInfo\n");
++
++    memset(args, 17, sizeof(*args));
++    args->cryptokiVersion.major = 2;
++    args->cryptokiVersion.minor = 10;
++    snprintf_fill((char *)args->manufacturerID,
++                  sizeof(args->manufacturerID),
++                  ' ',
++                  "SoftToken");
++    snprintf_fill((char *)args->libraryDescription,
++                  sizeof(args->libraryDescription), ' ',
++                  "SoftToken");
++    args->libraryVersion.major = 1;
++    args->libraryVersion.minor = 8;
++
++    return CKR_OK;
++}
++
++extern CK_FUNCTION_LIST funcs;
++
++CK_RV
++C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
++{
++    *ppFunctionList = &funcs;
++    return CKR_OK;
++}
++
++CK_RV
++C_GetSlotList(CK_BBOOL tokenPresent,
++              CK_SLOT_ID_PTR pSlotList,
++              CK_ULONG_PTR   pulCount)
++{
++    st_logf("GetSlotList: %s\n",
++            tokenPresent ? "tokenPresent" : "token not Present");
++    if (pSlotList)
++        pSlotList[0] = 1;
++    *pulCount = 1;
++    return CKR_OK;
++}
++
++CK_RV
++C_GetSlotInfo(CK_SLOT_ID slotID,
++              CK_SLOT_INFO_PTR pInfo)
++{
++    st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session());
++
++    memset(pInfo, 18, sizeof(*pInfo));
++
++    if (slotID != 1)
++        return CKR_ARGUMENTS_BAD;
++
++    snprintf_fill((char *)pInfo->slotDescription,
++                  sizeof(pInfo->slotDescription),
++                  ' ',
++                  "SoftToken (slot)");
++    snprintf_fill((char *)pInfo->manufacturerID,
++                  sizeof(pInfo->manufacturerID),
++                  ' ',
++                  "SoftToken (slot)");
++    pInfo->flags = CKF_TOKEN_PRESENT;
++    if (soft_token.flags.hardware_slot)
++        pInfo->flags |= CKF_HW_SLOT;
++    pInfo->hardwareVersion.major = 1;
++    pInfo->hardwareVersion.minor = 0;
++    pInfo->firmwareVersion.major = 1;
++    pInfo->firmwareVersion.minor = 0;
++
++    return CKR_OK;
++}
++
++CK_RV
++C_GetTokenInfo(CK_SLOT_ID slotID,
++               CK_TOKEN_INFO_PTR pInfo)
++{
++    st_logf("GetTokenInfo: %s\n", has_session());
++
++    memset(pInfo, 19, sizeof(*pInfo));
++
++    snprintf_fill((char *)pInfo->label,
++                  sizeof(pInfo->label),
++                  ' ',
++                  "SoftToken (token)");
++    snprintf_fill((char *)pInfo->manufacturerID,
++                  sizeof(pInfo->manufacturerID),
++                  ' ',
++                  "SoftToken (token)");
++    snprintf_fill((char *)pInfo->model,
++                  sizeof(pInfo->model),
++                  ' ',
++                  "SoftToken (token)");
++    snprintf_fill((char *)pInfo->serialNumber,
++                  sizeof(pInfo->serialNumber),
++                  ' ',
++                  "4711");
++    pInfo->flags =
++        CKF_TOKEN_INITIALIZED |
++        CKF_USER_PIN_INITIALIZED;
++
++    if (soft_token.flags.login_done == 0)
++        pInfo->flags |= CKF_LOGIN_REQUIRED;
++
++    /* CFK_RNG |
++       CKF_RESTORE_KEY_NOT_NEEDED |
++    */
++    pInfo->ulMaxSessionCount = MAX_NUM_SESSION;
++    pInfo->ulSessionCount = soft_token.open_sessions;
++    pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION;
++    pInfo->ulRwSessionCount = soft_token.open_sessions;
++    pInfo->ulMaxPinLen = 1024;
++    pInfo->ulMinPinLen = 0;
++    pInfo->ulTotalPublicMemory = 4711;
++    pInfo->ulFreePublicMemory = 4712;
++    pInfo->ulTotalPrivateMemory = 4713;
++    pInfo->ulFreePrivateMemory = 4714;
++    pInfo->hardwareVersion.major = 2;
++    pInfo->hardwareVersion.minor = 0;
++    pInfo->firmwareVersion.major = 2;
++    pInfo->firmwareVersion.minor = 0;
++
++    return CKR_OK;
++}
++
++CK_RV
++C_GetMechanismList(CK_SLOT_ID slotID,
++                   CK_MECHANISM_TYPE_PTR pMechanismList,
++                   CK_ULONG_PTR pulCount)
++{
++    st_logf("GetMechanismList\n");
++
++    *pulCount = 2;
++    if (pMechanismList == NULL_PTR)
++        return CKR_OK;
++    pMechanismList[0] = CKM_RSA_X_509;
++    pMechanismList[1] = CKM_RSA_PKCS;
++
++    return CKR_OK;
++}
++
++CK_RV
++C_GetMechanismInfo(CK_SLOT_ID slotID,
++                   CK_MECHANISM_TYPE type,
++                   CK_MECHANISM_INFO_PTR pInfo)
++{
++    st_logf("GetMechanismInfo: slot %d type: %d\n",
++            (int)slotID, (int)type);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_InitToken(CK_SLOT_ID slotID,
++            CK_UTF8CHAR_PTR pPin,
++            CK_ULONG ulPinLen,
++            CK_UTF8CHAR_PTR pLabel)
++{
++    st_logf("InitToken: slot %d\n", (int)slotID);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_OpenSession(CK_SLOT_ID slotID,
++              CK_FLAGS flags,
++              CK_VOID_PTR pApplication,
++              CK_NOTIFY Notify,
++              CK_SESSION_HANDLE_PTR phSession)
++{
++    int i;
++
++    st_logf("OpenSession: slot: %d\n", (int)slotID);
++
++    if (soft_token.open_sessions == MAX_NUM_SESSION)
++        return CKR_SESSION_COUNT;
++
++    soft_token.application = pApplication;
++    soft_token.notify = Notify;
++
++    for (i = 0; i < MAX_NUM_SESSION; i++)
++        if (soft_token.state[i].session_handle == CK_INVALID_HANDLE)
++            break;
++    if (i == MAX_NUM_SESSION)
++        abort();
++
++    soft_token.open_sessions++;
++
++    soft_token.state[i].session_handle =
++        (CK_SESSION_HANDLE)(random() & 0xfffff);
++    *phSession = soft_token.state[i].session_handle;
++
++    return CKR_OK;
++}
++
++CK_RV
++C_CloseSession(CK_SESSION_HANDLE hSession)
++{
++    struct session_state *state;
++    st_logf("CloseSession\n");
++
++    if (verify_session_handle(hSession, &state) != CKR_OK)
++        application_error("closed session not open");
++    else
++        close_session(state);
++
++    return CKR_OK;
++}
++
++CK_RV
++C_CloseAllSessions(CK_SLOT_ID slotID)
++{
++    int i;
++
++    st_logf("CloseAllSessions\n");
++
++    for (i = 0; i < MAX_NUM_SESSION; i++)
++        if (soft_token.state[i].session_handle != CK_INVALID_HANDLE)
++            close_session(&soft_token.state[i]);
++
++    return CKR_OK;
++}
++
++CK_RV
++C_GetSessionInfo(CK_SESSION_HANDLE hSession,
++                 CK_SESSION_INFO_PTR pInfo)
++{
++    st_logf("GetSessionInfo\n");
++
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++
++    memset(pInfo, 20, sizeof(*pInfo));
++
++    pInfo->slotID = 1;
++    if (soft_token.flags.login_done)
++        pInfo->state = CKS_RO_USER_FUNCTIONS;
++    else
++        pInfo->state = CKS_RO_PUBLIC_SESSION;
++    pInfo->flags = CKF_SERIAL_SESSION;
++    pInfo->ulDeviceError = 0;
++
++    return CKR_OK;
++}
++
++CK_RV
++C_Login(CK_SESSION_HANDLE hSession,
++        CK_USER_TYPE userType,
++        CK_UTF8CHAR_PTR pPin,
++        CK_ULONG ulPinLen)
++{
++    char *pin = NULL;
++    int i;
++
++    st_logf("Login\n");
++
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++
++    if (pPin != NULL_PTR) {
++        asprintf(&pin, "%.*s", (int)ulPinLen, pPin);
++        st_logf("type: %d password: %s\n", (int)userType, pin);
++    }
++
++    for (i = 0; i < soft_token.object.num_objs; i++) {
++        struct st_object *o = soft_token.object.objs[i];
++        FILE *f;
++
++        if (o->type != STO_T_PRIVATE_KEY)
++            continue;
++
++        if (o->u.private_key.key)
++            continue;
++
++        f = fopen(o->u.private_key.file, "r");
++        if (f == NULL) {
++            st_logf("can't open private file: %s\n", o->u.private_key.file);
++            continue;
++        }
++
++        o->u.private_key.key = PEM_read_PrivateKey(f, NULL, NULL, pin);
++        fclose(f);
++        if (o->u.private_key.key == NULL) {
++            st_logf("failed to read key: %s error: %s\n",
++                    o->u.private_key.file,
++                    ERR_error_string(ERR_get_error(), NULL));
++            /* just ignore failure */;
++            continue;
++        }
++
++        /* XXX check keytype */
++        RSA_set_method(o->u.private_key.key->pkey.rsa, RSA_PKCS1_SSLeay());
++
++        if (X509_check_private_key(o->u.private_key.cert, o->u.private_key.key) != 1) {
++            EVP_PKEY_free(o->u.private_key.key);
++            o->u.private_key.key = NULL;
++            st_logf("private key %s doesn't verify\n", o->u.private_key.file);
++            continue;
++        }
++
++        soft_token.flags.login_done = 1;
++    }
++    free(pin);
++
++    return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT;
++}
++
++CK_RV
++C_Logout(CK_SESSION_HANDLE hSession)
++{
++    st_logf("Logout\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_GetObjectSize(CK_SESSION_HANDLE hSession,
++                CK_OBJECT_HANDLE hObject,
++                CK_ULONG_PTR pulSize)
++{
++    st_logf("GetObjectSize\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_GetAttributeValue(CK_SESSION_HANDLE hSession,
++                    CK_OBJECT_HANDLE hObject,
++                    CK_ATTRIBUTE_PTR pTemplate,
++                    CK_ULONG ulCount)
++{
++    struct session_state *state;
++    struct st_object *obj;
++    CK_ULONG i;
++    CK_RV ret;
++    int j;
++
++    st_logf("GetAttributeValue: %lx\n",
++            (unsigned long)HANDLE_OBJECT_ID(hObject));
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) {
++        st_logf("object not found: %lx\n",
++                (unsigned long)HANDLE_OBJECT_ID(hObject));
++        return ret;
++    }
++
++    for (i = 0; i < ulCount; i++) {
++        st_logf("       getting 0x%08lx\n", (unsigned long)pTemplate[i].type);
++        for (j = 0; j < obj->num_attributes; j++) {
++            if (obj->attrs[j].secret) {
++                pTemplate[i].ulValueLen = (CK_ULONG)-1;
++                break;
++            }
++            if (pTemplate[i].type == obj->attrs[j].attribute.type) {
++                if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) {
++                    if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen)
++                        memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue,
++                               obj->attrs[j].attribute.ulValueLen);
++                }
++                pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen;
++                break;
++            }
++        }
++        if (j == obj->num_attributes) {
++            st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type);
++            pTemplate[i].ulValueLen = (CK_ULONG)-1;
++        }
++
++    }
++    return CKR_OK;
++}
++
++CK_RV
++C_FindObjectsInit(CK_SESSION_HANDLE hSession,
++                  CK_ATTRIBUTE_PTR pTemplate,
++                  CK_ULONG ulCount)
++{
++    struct session_state *state;
++
++    st_logf("FindObjectsInit\n");
++
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    if (state->find.next_object != -1) {
++        application_error("application didn't do C_FindObjectsFinal\n");
++        find_object_final(state);
++    }
++    if (ulCount) {
++        CK_ULONG i;
++        size_t len;
++
++        print_attributes(pTemplate, ulCount);
++
++        state->find.attributes =
++            calloc(1, ulCount * sizeof(state->find.attributes[0]));
++        if (state->find.attributes == NULL)
++            return CKR_DEVICE_MEMORY;
++        for (i = 0; i < ulCount; i++) {
++            state->find.attributes[i].pValue =
++                malloc(pTemplate[i].ulValueLen);
++            if (state->find.attributes[i].pValue == NULL) {
++                find_object_final(state);
++                return CKR_DEVICE_MEMORY;
++            }
++            memcpy(state->find.attributes[i].pValue,
++                   pTemplate[i].pValue, pTemplate[i].ulValueLen);
++            state->find.attributes[i].type = pTemplate[i].type;
++            state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen;
++        }
++        state->find.num_attributes = ulCount;
++        state->find.next_object = 0;
++    } else {
++        st_logf("find all objects\n");
++        state->find.attributes = NULL;
++        state->find.num_attributes = 0;
++        state->find.next_object = 0;
++    }
++
++    return CKR_OK;
++}
++
++CK_RV
++C_FindObjects(CK_SESSION_HANDLE hSession,
++              CK_OBJECT_HANDLE_PTR phObject,
++              CK_ULONG ulMaxObjectCount,
++              CK_ULONG_PTR pulObjectCount)
++{
++    struct session_state *state;
++    int i;
++
++    st_logf("FindObjects\n");
++
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    if (state->find.next_object == -1) {
++        application_error("application didn't do C_FindObjectsInit\n");
++        return CKR_ARGUMENTS_BAD;
++    }
++    if (ulMaxObjectCount == 0) {
++        application_error("application asked for 0 objects\n");
++        return CKR_ARGUMENTS_BAD;
++    }
++    *pulObjectCount = 0;
++    for (i = state->find.next_object; i < soft_token.object.num_objs; i++) {
++        st_logf("FindObjects: %d\n", i);
++        state->find.next_object = i + 1;
++        if (attributes_match(soft_token.object.objs[i],
++                             state->find.attributes,
++                             state->find.num_attributes)) {
++            *phObject++ = soft_token.object.objs[i]->object_handle;
++            ulMaxObjectCount--;
++            (*pulObjectCount)++;
++            if (ulMaxObjectCount == 0)
++                break;
++        }
++    }
++    return CKR_OK;
++}
++
++CK_RV
++C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
++{
++    struct session_state *state;
++
++    st_logf("FindObjectsFinal\n");
++    VERIFY_SESSION_HANDLE(hSession, &state);
++    find_object_final(state);
++    return CKR_OK;
++}
++
++static CK_RV
++commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len,
++           const CK_MECHANISM_TYPE *mechs, int mechs_len,
++           const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey,
++           struct st_object **o)
++{
++    CK_RV ret;
++    int i;
++
++    *o = NULL;
++    if ((ret = object_handle_to_object(hKey, o)) != CKR_OK)
++        return ret;
++
++    ret = attributes_match(*o, attr_match, attr_match_len);
++    if (!ret) {
++        application_error("called commonInit on key that doesn't "
++                          "support required attr");
++        return CKR_ARGUMENTS_BAD;
++    }
++
++    for (i = 0; i < mechs_len; i++)
++        if (mechs[i] == pMechanism->mechanism)
++            break;
++    if (i == mechs_len) {
++        application_error("called mech (%08lx) not supported\n",
++                          pMechanism->mechanism);
++        return CKR_ARGUMENTS_BAD;
++    }
++    return CKR_OK;
++}
++
++
++static CK_RV
++dup_mechanism(CK_MECHANISM_PTR *dup, const CK_MECHANISM_PTR pMechanism)
++{
++    CK_MECHANISM_PTR p;
++
++    p = malloc(sizeof(*p));
++    if (p == NULL)
++        return CKR_DEVICE_MEMORY;
++
++    if (*dup)
++        free(*dup);
++    *dup = p;
++    memcpy(p, pMechanism, sizeof(*p));
++
++    return CKR_OK;
++}
++
++
++CK_RV
++C_EncryptInit(CK_SESSION_HANDLE hSession,
++              CK_MECHANISM_PTR pMechanism,
++              CK_OBJECT_HANDLE hKey)
++{
++    struct session_state *state;
++    CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
++    CK_BBOOL bool_true = CK_TRUE;
++    CK_ATTRIBUTE attr[] = {
++        { CKA_ENCRYPT, &bool_true, sizeof(bool_true) }
++    };
++    struct st_object *o;
++    CK_RV ret;
++
++    st_logf("EncryptInit\n");
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
++                     mechs, sizeof(mechs)/sizeof(mechs[0]),
++                     pMechanism, hKey, &o);
++    if (ret)
++        return ret;
++
++    ret = dup_mechanism(&state->encrypt_mechanism, pMechanism);
++    if (ret == CKR_OK)
++        state->encrypt_object = OBJECT_ID(o);
++
++    return ret;
++}
++
++CK_RV
++C_Encrypt(CK_SESSION_HANDLE hSession,
++          CK_BYTE_PTR pData,
++          CK_ULONG ulDataLen,
++          CK_BYTE_PTR pEncryptedData,
++          CK_ULONG_PTR pulEncryptedDataLen)
++{
++    struct session_state *state;
++    struct st_object *o;
++    void *buffer = NULL;
++    CK_RV ret;
++    RSA *rsa;
++    int padding, len, buffer_len, padding_len;
++
++    st_logf("Encrypt\n");
++
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    if (state->encrypt_object == -1)
++        return CKR_ARGUMENTS_BAD;
++
++    o = soft_token.object.objs[state->encrypt_object];
++
++    if (o->u.public_key == NULL) {
++        st_logf("public key NULL\n");
++        return CKR_ARGUMENTS_BAD;
++    }
++
++    rsa = o->u.public_key->pkey.rsa;
++
++    if (rsa == NULL)
++        return CKR_ARGUMENTS_BAD;
++
++    RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
++
++    buffer_len = RSA_size(rsa);
++
++    buffer = malloc(buffer_len);
++    if (buffer == NULL) {
++        ret = CKR_DEVICE_MEMORY;
++        goto out;
++    }
++
++    ret = CKR_OK;
++    switch(state->encrypt_mechanism->mechanism) {
++    case CKM_RSA_PKCS:
++        padding = RSA_PKCS1_PADDING;
++        padding_len = RSA_PKCS1_PADDING_SIZE;
++        break;
++    case CKM_RSA_X_509:
++        padding = RSA_NO_PADDING;
++        padding_len = 0;
++        break;
++    default:
++        ret = CKR_FUNCTION_NOT_SUPPORTED;
++        goto out;
++    }
++
++    if (buffer_len + padding_len < ulDataLen) {
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    if (pulEncryptedDataLen == NULL) {
++        st_logf("pulEncryptedDataLen NULL\n");
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    if (pData == NULL_PTR) {
++        st_logf("data NULL\n");
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    len = RSA_public_encrypt(ulDataLen, pData, buffer, rsa, padding);
++    if (len <= 0) {
++        ret = CKR_DEVICE_ERROR;
++        goto out;
++    }
++    if (len > buffer_len)
++        abort();
++
++    if (pEncryptedData != NULL_PTR)
++        memcpy(pEncryptedData, buffer, len);
++    *pulEncryptedDataLen = len;
++
++ out:
++    if (buffer) {
++        memset(buffer, 0, buffer_len);
++        free(buffer);
++    }
++    return ret;
++}
++
++CK_RV
++C_EncryptUpdate(CK_SESSION_HANDLE hSession,
++                CK_BYTE_PTR pPart,
++                CK_ULONG ulPartLen,
++                CK_BYTE_PTR pEncryptedPart,
++                CK_ULONG_PTR pulEncryptedPartLen)
++{
++    st_logf("EncryptUpdate\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++
++CK_RV
++C_EncryptFinal(CK_SESSION_HANDLE hSession,
++               CK_BYTE_PTR pLastEncryptedPart,
++               CK_ULONG_PTR pulLastEncryptedPartLen)
++{
++    st_logf("EncryptFinal\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++
++/* C_DecryptInit initializes a decryption operation. */
++CK_RV
++C_DecryptInit(CK_SESSION_HANDLE hSession,
++              CK_MECHANISM_PTR pMechanism,
++              CK_OBJECT_HANDLE hKey)
++{
++    struct session_state *state;
++    CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
++    CK_BBOOL bool_true = CK_TRUE;
++    CK_ATTRIBUTE attr[] = {
++        { CKA_DECRYPT, &bool_true, sizeof(bool_true) }
++    };
++    struct st_object *o;
++    CK_RV ret;
++
++    st_logf("DecryptInit\n");
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
++                     mechs, sizeof(mechs)/sizeof(mechs[0]),
++                     pMechanism, hKey, &o);
++    if (ret)
++        return ret;
++
++    ret = dup_mechanism(&state->decrypt_mechanism, pMechanism);
++    if (ret == CKR_OK)
++        state->decrypt_object = OBJECT_ID(o);
++
++    return CKR_OK;
++}
++
++
++CK_RV
++C_Decrypt(CK_SESSION_HANDLE hSession,
++          CK_BYTE_PTR       pEncryptedData,
++          CK_ULONG          ulEncryptedDataLen,
++          CK_BYTE_PTR       pData,
++          CK_ULONG_PTR      pulDataLen)
++{
++    struct session_state *state;
++    struct st_object *o;
++    void *buffer = NULL;
++    CK_RV ret;
++    RSA *rsa;
++    int padding, len, buffer_len, padding_len;
++
++    st_logf("Decrypt\n");
++
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    if (state->decrypt_object == -1)
++        return CKR_ARGUMENTS_BAD;
++
++    o = soft_token.object.objs[state->decrypt_object];
++
++    if (o->u.private_key.key == NULL) {
++        st_logf("private key NULL\n");
++        return CKR_ARGUMENTS_BAD;
++    }
++
++    rsa = o->u.private_key.key->pkey.rsa;
++
++    if (rsa == NULL)
++        return CKR_ARGUMENTS_BAD;
++
++    RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
++
++    buffer_len = RSA_size(rsa);
++
++    buffer = malloc(buffer_len);
++    if (buffer == NULL) {
++        ret = CKR_DEVICE_MEMORY;
++        goto out;
++    }
++
++    ret = CKR_OK;
++    switch(state->decrypt_mechanism->mechanism) {
++    case CKM_RSA_PKCS:
++        padding = RSA_PKCS1_PADDING;
++        padding_len = RSA_PKCS1_PADDING_SIZE;
++        break;
++    case CKM_RSA_X_509:
++        padding = RSA_NO_PADDING;
++        padding_len = 0;
++        break;
++    default:
++        ret = CKR_FUNCTION_NOT_SUPPORTED;
++        goto out;
++    }
++
++    if (buffer_len + padding_len < ulEncryptedDataLen) {
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    if (pulDataLen == NULL) {
++        st_logf("pulDataLen NULL\n");
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    if (pEncryptedData == NULL_PTR) {
++        st_logf("data NULL\n");
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    len = RSA_private_decrypt(ulEncryptedDataLen, pEncryptedData, buffer,
++                              rsa, padding);
++    if (len <= 0) {
++        ret = CKR_DEVICE_ERROR;
++        goto out;
++    }
++    if (len > buffer_len)
++        abort();
++
++    if (pData != NULL_PTR)
++        memcpy(pData, buffer, len);
++    *pulDataLen = len;
++
++ out:
++    if (buffer) {
++        memset(buffer, 0, buffer_len);
++        free(buffer);
++    }
++    return ret;
++}
++
++
++CK_RV
++C_DecryptUpdate(CK_SESSION_HANDLE hSession,
++                CK_BYTE_PTR pEncryptedPart,
++                CK_ULONG ulEncryptedPartLen,
++                CK_BYTE_PTR pPart,
++                CK_ULONG_PTR pulPartLen)
++
++{
++    st_logf("DecryptUpdate\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++
++CK_RV
++C_DecryptFinal(CK_SESSION_HANDLE hSession,
++               CK_BYTE_PTR pLastPart,
++               CK_ULONG_PTR pulLastPartLen)
++{
++    st_logf("DecryptFinal\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_DigestInit(CK_SESSION_HANDLE hSession,
++             CK_MECHANISM_PTR pMechanism)
++{
++    st_logf("DigestInit\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_SignInit(CK_SESSION_HANDLE hSession,
++           CK_MECHANISM_PTR pMechanism,
++           CK_OBJECT_HANDLE hKey)
++{
++    struct session_state *state;
++    CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
++    CK_BBOOL bool_true = CK_TRUE;
++    CK_ATTRIBUTE attr[] = {
++        { CKA_SIGN, &bool_true, sizeof(bool_true) }
++    };
++    struct st_object *o;
++    CK_RV ret;
++
++    st_logf("SignInit\n");
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
++                     mechs, sizeof(mechs)/sizeof(mechs[0]),
++                     pMechanism, hKey, &o);
++    if (ret)
++        return ret;
++
++    ret = dup_mechanism(&state->sign_mechanism, pMechanism);
++    if (ret == CKR_OK)
++        state->sign_object = OBJECT_ID(o);
++
++    return CKR_OK;
++}
++
++CK_RV
++C_Sign(CK_SESSION_HANDLE hSession,
++       CK_BYTE_PTR pData,
++       CK_ULONG ulDataLen,
++       CK_BYTE_PTR pSignature,
++       CK_ULONG_PTR pulSignatureLen)
++{
++    struct session_state *state;
++    struct st_object *o;
++    void *buffer = NULL;
++    CK_RV ret;
++    RSA *rsa;
++    int padding, len, buffer_len, padding_len;
++
++    st_logf("Sign\n");
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    if (state->sign_object == -1)
++        return CKR_ARGUMENTS_BAD;
++
++    o = soft_token.object.objs[state->sign_object];
++
++    if (o->u.private_key.key == NULL) {
++        st_logf("private key NULL\n");
++        return CKR_ARGUMENTS_BAD;
++    }
++
++    rsa = o->u.private_key.key->pkey.rsa;
++
++    if (rsa == NULL)
++        return CKR_ARGUMENTS_BAD;
++
++    RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
++
++    buffer_len = RSA_size(rsa);
++
++    buffer = malloc(buffer_len);
++    if (buffer == NULL) {
++        ret = CKR_DEVICE_MEMORY;
++        goto out;
++    }
++
++    switch(state->sign_mechanism->mechanism) {
++    case CKM_RSA_PKCS:
++        padding = RSA_PKCS1_PADDING;
++        padding_len = RSA_PKCS1_PADDING_SIZE;
++        break;
++    case CKM_RSA_X_509:
++        padding = RSA_NO_PADDING;
++        padding_len = 0;
++        break;
++    default:
++        ret = CKR_FUNCTION_NOT_SUPPORTED;
++        goto out;
++    }
++
++    if (buffer_len < ulDataLen + padding_len) {
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    if (pulSignatureLen == NULL) {
++        st_logf("signature len NULL\n");
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    if (pData == NULL_PTR) {
++        st_logf("data NULL\n");
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    len = RSA_private_encrypt(ulDataLen, pData, buffer, rsa, padding);
++    st_logf("private encrypt done\n");
++    if (len <= 0) {
++        ret = CKR_DEVICE_ERROR;
++        goto out;
++    }
++    if (len > buffer_len)
++        abort();
++
++    if (pSignature != NULL_PTR)
++        memcpy(pSignature, buffer, len);
++    *pulSignatureLen = len;
++
++    ret = CKR_OK;
++
++ out:
++    if (buffer) {
++        memset(buffer, 0, buffer_len);
++        free(buffer);
++    }
++    return ret;
++}
++
++CK_RV
++C_SignUpdate(CK_SESSION_HANDLE hSession,
++             CK_BYTE_PTR pPart,
++             CK_ULONG ulPartLen)
++{
++    st_logf("SignUpdate\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++
++CK_RV
++C_SignFinal(CK_SESSION_HANDLE hSession,
++            CK_BYTE_PTR pSignature,
++            CK_ULONG_PTR pulSignatureLen)
++{
++    st_logf("SignUpdate\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_VerifyInit(CK_SESSION_HANDLE hSession,
++             CK_MECHANISM_PTR pMechanism,
++             CK_OBJECT_HANDLE hKey)
++{
++    struct session_state *state;
++    CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
++    CK_BBOOL bool_true = CK_TRUE;
++    CK_ATTRIBUTE attr[] = {
++        { CKA_VERIFY, &bool_true, sizeof(bool_true) }
++    };
++    struct st_object *o;
++    CK_RV ret;
++
++    st_logf("VerifyInit\n");
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
++                     mechs, sizeof(mechs)/sizeof(mechs[0]),
++                     pMechanism, hKey, &o);
++    if (ret)
++        return ret;
++
++    ret = dup_mechanism(&state->verify_mechanism, pMechanism);
++    if (ret == CKR_OK)
++        state->verify_object = OBJECT_ID(o);
++
++    return ret;
++}
++
++CK_RV
++C_Verify(CK_SESSION_HANDLE hSession,
++         CK_BYTE_PTR pData,
++         CK_ULONG ulDataLen,
++         CK_BYTE_PTR pSignature,
++         CK_ULONG ulSignatureLen)
++{
++    struct session_state *state;
++    struct st_object *o;
++    void *buffer = NULL;
++    CK_RV ret;
++    RSA *rsa;
++    int padding, len, buffer_len;
++
++    st_logf("Verify\n");
++    VERIFY_SESSION_HANDLE(hSession, &state);
++
++    if (state->verify_object == -1)
++        return CKR_ARGUMENTS_BAD;
++
++    o = soft_token.object.objs[state->verify_object];
++
++    if (o->u.public_key == NULL) {
++        st_logf("public key NULL\n");
++        return CKR_ARGUMENTS_BAD;
++    }
++
++    rsa = o->u.public_key->pkey.rsa;
++
++    if (rsa == NULL)
++        return CKR_ARGUMENTS_BAD;
++
++    RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
++
++    buffer_len = RSA_size(rsa);
++
++    buffer = malloc(buffer_len);
++    if (buffer == NULL) {
++        ret = CKR_DEVICE_MEMORY;
++        goto out;
++    }
++
++    ret = CKR_OK;
++    switch(state->verify_mechanism->mechanism) {
++    case CKM_RSA_PKCS:
++        padding = RSA_PKCS1_PADDING;
++        break;
++    case CKM_RSA_X_509:
++        padding = RSA_NO_PADDING;
++        break;
++    default:
++        ret = CKR_FUNCTION_NOT_SUPPORTED;
++        goto out;
++    }
++
++    if (buffer_len < ulDataLen) {
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    if (pSignature == NULL) {
++        st_logf("signature NULL\n");
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    if (pData == NULL_PTR) {
++        st_logf("data NULL\n");
++        ret = CKR_ARGUMENTS_BAD;
++        goto out;
++    }
++
++    len = RSA_public_decrypt(ulDataLen, pData, buffer, rsa, padding);
++    st_logf("private encrypt done\n");
++    if (len <= 0) {
++        ret = CKR_DEVICE_ERROR;
++        goto out;
++    }
++    if (len > buffer_len)
++        abort();
++
++    if (len != ulSignatureLen) {
++        ret = CKR_GENERAL_ERROR;
++        goto out;
++    }
++
++    if (memcmp(pSignature, buffer, len) != 0) {
++        ret = CKR_GENERAL_ERROR;
++        goto out;
++    }
++
++ out:
++    if (buffer) {
++        memset(buffer, 0, buffer_len);
++        free(buffer);
++    }
++    return ret;
++}
++
++
++CK_RV
++C_VerifyUpdate(CK_SESSION_HANDLE hSession,
++               CK_BYTE_PTR pPart,
++               CK_ULONG ulPartLen)
++{
++    st_logf("VerifyUpdate\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_VerifyFinal(CK_SESSION_HANDLE hSession,
++              CK_BYTE_PTR pSignature,
++              CK_ULONG ulSignatureLen)
++{
++    st_logf("VerifyFinal\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++CK_RV
++C_GenerateRandom(CK_SESSION_HANDLE hSession,
++                 CK_BYTE_PTR RandomData,
++                 CK_ULONG ulRandomLen)
++{
++    st_logf("GenerateRandom\n");
++    VERIFY_SESSION_HANDLE(hSession, NULL);
++    return CKR_FUNCTION_NOT_SUPPORTED;
++}
++
++
++CK_FUNCTION_LIST funcs = {
++    { 2, 11 },
++    C_Initialize,
++    C_Finalize,
++    C_GetInfo,
++    C_GetFunctionList,
++    C_GetSlotList,
++    C_GetSlotInfo,
++    C_GetTokenInfo,
++    C_GetMechanismList,
++    C_GetMechanismInfo,
++    C_InitToken,
++    (void *)func_not_supported, /* C_InitPIN */
++    (void *)func_not_supported, /* C_SetPIN */
++    C_OpenSession,
++    C_CloseSession,
++    C_CloseAllSessions,
++    C_GetSessionInfo,
++    (void *)func_not_supported, /* C_GetOperationState */
++    (void *)func_not_supported, /* C_SetOperationState */
++    C_Login,
++    C_Logout,
++    (void *)func_not_supported, /* C_CreateObject */
++    (void *)func_not_supported, /* C_CopyObject */
++    (void *)func_not_supported, /* C_DestroyObject */
++    (void *)func_not_supported, /* C_GetObjectSize */
++    C_GetAttributeValue,
++    (void *)func_not_supported, /* C_SetAttributeValue */
++    C_FindObjectsInit,
++    C_FindObjects,
++    C_FindObjectsFinal,
++    C_EncryptInit,
++    C_Encrypt,
++    C_EncryptUpdate,
++    C_EncryptFinal,
++    C_DecryptInit,
++    C_Decrypt,
++    C_DecryptUpdate,
++    C_DecryptFinal,
++    C_DigestInit,
++    (void *)func_not_supported, /* C_Digest */
++    (void *)func_not_supported, /* C_DigestUpdate */
++    (void *)func_not_supported, /* C_DigestKey */
++    (void *)func_not_supported, /* C_DigestFinal */
++    C_SignInit,
++    C_Sign,
++    C_SignUpdate,
++    C_SignFinal,
++    (void *)func_not_supported, /* C_SignRecoverInit */
++    (void *)func_not_supported, /* C_SignRecover */
++    C_VerifyInit,
++    C_Verify,
++    C_VerifyUpdate,
++    C_VerifyFinal,
++    (void *)func_not_supported, /* C_VerifyRecoverInit */
++    (void *)func_not_supported, /* C_VerifyRecover */
++    (void *)func_not_supported, /* C_DigestEncryptUpdate */
++    (void *)func_not_supported, /* C_DecryptDigestUpdate */
++    (void *)func_not_supported, /* C_SignEncryptUpdate */
++    (void *)func_not_supported, /* C_DecryptVerifyUpdate */
++    (void *)func_not_supported, /* C_GenerateKey */
++    (void *)func_not_supported, /* C_GenerateKeyPair */
++    (void *)func_not_supported, /* C_WrapKey */
++    (void *)func_not_supported, /* C_UnwrapKey */
++    (void *)func_not_supported, /* C_DeriveKey */
++    (void *)func_not_supported, /* C_SeedRandom */
++    C_GenerateRandom,
++    (void *)func_not_supported, /* C_GetFunctionStatus */
++    (void *)func_not_supported, /* C_CancelFunction */
++    (void *)func_not_supported  /* C_WaitForSlotEvent */
++};
diff --git a/SOURCES/Add-tests-for-KCM-ccache-type.patch b/SOURCES/Add-tests-for-KCM-ccache-type.patch
new file mode 100644
index 0000000..f572041
--- /dev/null
+++ b/SOURCES/Add-tests-for-KCM-ccache-type.patch
@@ -0,0 +1,295 @@
+From 7ab0bbac058d2b82aa3432759c600b22012f8afe Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Thu, 22 Nov 2018 00:27:35 -0500
+Subject: [PATCH] Add tests for KCM ccache type
+
+Using a trivial Python implementation of a KCM server, run the
+t_ccache.py tests against the KCM ccache type.
+
+(cherry picked from commit f0bcb86131e385b2603ccf0f3c7d65aa3891b220)
+(cherry picked from commit 5ecbe8d3ab4f53c0923a0442273bf18a9ff04fd5)
+---
+ src/tests/kcmserver.py | 246 +++++++++++++++++++++++++++++++++++++++++
+ src/tests/t_ccache.py  |   9 +-
+ 2 files changed, 254 insertions(+), 1 deletion(-)
+ create mode 100644 src/tests/kcmserver.py
+
+diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py
+new file mode 100644
+index 000000000..57432e5a7
+--- /dev/null
++++ b/src/tests/kcmserver.py
+@@ -0,0 +1,246 @@
++# This is a simple KCM test server, used to exercise the KCM ccache
++# client code.  It will generally throw an uncaught exception if the
++# client sends anything unexpected, so is unsuitable for production.
++# (It also imposes no namespace or access constraints, and blocks
++# while reading requests and writing responses.)
++
++# This code knows nothing about how to marshal and unmarshal principal
++# names and credentials as is required in the KCM protocol; instead,
++# it just remembers the marshalled forms and replays them to the
++# client when asked.  This works because marshalled creds and
++# principal names are always the last part of marshalled request
++# arguments, and because we don't need to implement remove_cred (which
++# would need to know how to match a cred tag against previously stored
++# credentials).
++
++# The following code is useful for debugging if anything appears to be
++# going wrong in the server, since daemon output is generally not
++# visible in Python test scripts.
++#
++# import sys, traceback
++# def ehook(etype, value, tb):
++#     with open('/tmp/exception', 'w') as f:
++#         traceback.print_exception(etype, value, tb, file=f)
++# sys.excepthook = ehook
++
++import select
++import socket
++import struct
++import sys
++
++caches = {}
++cache_uuidmap = {}
++defname = b'default'
++next_unique = 1
++next_uuid = 1
++
++class KCMOpcodes(object):
++    GEN_NEW = 3
++    INITIALIZE = 4
++    DESTROY = 5
++    STORE = 6
++    GET_PRINCIPAL = 8
++    GET_CRED_UUID_LIST = 9
++    GET_CRED_BY_UUID = 10
++    REMOVE_CRED = 11
++    GET_CACHE_UUID_LIST = 18
++    GET_CACHE_BY_UUID = 19
++    GET_DEFAULT_CACHE = 20
++    SET_DEFAULT_CACHE = 21
++    GET_KDC_OFFSET = 22
++    SET_KDC_OFFSET = 23
++
++
++class KRB5Errors(object):
++    KRB5_CC_END = -1765328242
++    KRB5_CC_NOSUPP = -1765328137
++    KRB5_FCC_NOFILE = -1765328189
++
++
++def make_uuid():
++    global next_uuid
++    uuid = bytes(12) + struct.pack('>L', next_uuid)
++    next_uuid = next_uuid + 1
++    return uuid
++
++
++class Cache(object):
++    def __init__(self, name):
++        self.name = name
++        self.princ = None
++        self.uuid = make_uuid()
++        self.cred_uuids = []
++        self.creds = {}
++        self.time_offset = 0
++
++
++def get_cache(name):
++    if name in caches:
++        return caches[name]
++    cache = Cache(name)
++    caches[name] = cache
++    cache_uuidmap[cache.uuid] = cache
++    return cache
++
++
++def unmarshal_name(argbytes):
++    offset = argbytes.find(b'\0')
++    return argbytes[0:offset], argbytes[offset+1:]
++
++
++def op_gen_new(argbytes):
++    # Does not actually check for uniqueness.
++    global next_unique
++    name = b'unique' + str(next_unique).encode('ascii')
++    next_unique += 1
++    return 0, name + b'\0'
++
++
++def op_initialize(argbytes):
++    name, princ = unmarshal_name(argbytes)
++    cache = get_cache(name)
++    cache.princ = princ
++    cache.cred_uuids = []
++    cache.creds = {}
++    cache.time_offset = 0
++    return 0, b''
++
++
++def op_destroy(argbytes):
++    name, rest = unmarshal_name(argbytes)
++    cache = get_cache(name)
++    del cache_uuidmap[cache.uuid]
++    del caches[name]
++    return 0, b''
++
++
++def op_store(argbytes):
++    name, cred = unmarshal_name(argbytes)
++    cache = get_cache(name)
++    uuid = make_uuid()
++    cache.creds[uuid] = cred
++    cache.cred_uuids.append(uuid)
++    return 0, b''
++
++
++def op_get_principal(argbytes):
++    name, rest = unmarshal_name(argbytes)
++    cache = get_cache(name)
++    if cache.princ is None:
++        return KRB5Errors.KRB5_FCC_NOFILE, b''
++    return 0, cache.princ + b'\0'
++
++
++def op_get_cred_uuid_list(argbytes):
++    name, rest = unmarshal_name(argbytes)
++    cache = get_cache(name)
++    return 0, b''.join(cache.cred_uuids)
++
++
++def op_get_cred_by_uuid(argbytes):
++    name, uuid = unmarshal_name(argbytes)
++    cache = get_cache(name)
++    if uuid not in cache.creds:
++        return KRB5Errors.KRB5_CC_END, b''
++    return 0, cache.creds[uuid]
++
++
++def op_remove_cred(argbytes):
++    return KRB5Errors.KRB5_CC_NOSUPP, b''
++
++
++def op_get_cache_uuid_list(argbytes):
++    return 0, b''.join(cache_uuidmap.keys())
++
++
++def op_get_cache_by_uuid(argbytes):
++    uuid = argbytes
++    if uuid not in cache_uuidmap:
++        return KRB5Errors.KRB5_CC_END, b''
++    return 0, cache_uuidmap[uuid].name + b'\0'
++
++
++def op_get_default_cache(argbytes):
++    return 0, defname + b'\0'
++
++
++def op_set_default_cache(argbytes):
++    global defname
++    defname, rest = unmarshal_name(argbytes)
++    return 0, b''
++
++
++def op_get_kdc_offset(argbytes):
++    name, rest = unmarshal_name(argbytes)
++    cache = get_cache(name)
++    return 0, struct.pack('>l', cache.time_offset)
++
++
++def op_set_kdc_offset(argbytes):
++    name, obytes = unmarshal_name(argbytes)
++    cache = get_cache(name)
++    cache.time_offset, = struct.unpack('>l', obytes)
++    return 0, b''
++
++
++ophandlers = {
++    KCMOpcodes.GEN_NEW : op_gen_new,
++    KCMOpcodes.INITIALIZE : op_initialize,
++    KCMOpcodes.DESTROY : op_destroy,
++    KCMOpcodes.STORE : op_store,
++    KCMOpcodes.GET_PRINCIPAL : op_get_principal,
++    KCMOpcodes.GET_CRED_UUID_LIST : op_get_cred_uuid_list,
++    KCMOpcodes.GET_CRED_BY_UUID : op_get_cred_by_uuid,
++    KCMOpcodes.REMOVE_CRED : op_remove_cred,
++    KCMOpcodes.GET_CACHE_UUID_LIST : op_get_cache_uuid_list,
++    KCMOpcodes.GET_CACHE_BY_UUID : op_get_cache_by_uuid,
++    KCMOpcodes.GET_DEFAULT_CACHE : op_get_default_cache,
++    KCMOpcodes.SET_DEFAULT_CACHE : op_set_default_cache,
++    KCMOpcodes.GET_KDC_OFFSET : op_get_kdc_offset,
++    KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset
++}
++
++# Read and respond to a request from the socket s.
++def service_request(s):
++    lenbytes = b''
++    while len(lenbytes) < 4:
++        lenbytes += s.recv(4 - len(lenbytes))
++        if lenbytes == b'':
++                return False
++
++    reqlen, = struct.unpack('>L', lenbytes)
++    req = b''
++    while len(req) < reqlen:
++        req += s.recv(reqlen - len(req))
++
++    majver, minver, op = struct.unpack('>BBH', req[:4])
++    argbytes = req[4:]
++    code, payload = ophandlers[op](argbytes)
++
++    # The KCM response is the code (4 bytes) and the response payload.
++    # The Heimdal IPC response is the length of the KCM response (4
++    # bytes), a status code which is essentially always 0 (4 bytes),
++    # and the KCM response.
++    kcm_response = struct.pack('>l', code) + payload
++    hipc_response = struct.pack('>LL', len(kcm_response), 0) + kcm_response
++    s.sendall(hipc_response)
++    return True
++
++
++server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
++server.bind(sys.argv[1])
++server.listen(5)
++select_input = [server,]
++sys.stderr.write('starting...\n')
++sys.stderr.flush()
++
++while True:
++    iready, oready, xready = select.select(select_input, [], [])
++    for s in iready:
++        if s == server:
++            client, addr = server.accept()
++            select_input.append(client)
++        else:
++            if not service_request(s):
++                select_input.remove(s)
++                s.close()
+diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py
+index fcf1a611e..66804afa5 100755
+--- a/src/tests/t_ccache.py
++++ b/src/tests/t_ccache.py
+@@ -22,7 +22,10 @@
+ 
+ from k5test import *
+ 
+-realm = K5Realm(create_host=False)
++kcm_socket_path = os.path.join(os.getcwd(), 'testdir', 'kcm')
++conf = {'libdefaults': {'kcm_socket': kcm_socket_path,
++                        'kcm_mach_service': '-'}}
++realm = K5Realm(create_host=False, krb5_conf=conf)
+ 
+ keyctl = which('keyctl')
+ out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1)
+@@ -122,6 +125,10 @@ def collection_test(realm, ccname):
+ 
+ 
+ collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc'))
++kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py')
++realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
++                   'starting...')
++collection_test(realm, 'KCM:')
+ if test_keyring:
+     def cleanup_keyring(anchor, name):
+         out = realm.run(['keyctl', 'list', anchor])
diff --git a/SOURCES/Address-some-optimized-out-memset-calls.patch b/SOURCES/Address-some-optimized-out-memset-calls.patch
new file mode 100644
index 0000000..372e527
--- /dev/null
+++ b/SOURCES/Address-some-optimized-out-memset-calls.patch
@@ -0,0 +1,95 @@
+From 722247aa6201d18a7ee69c4a9a05315226fe6383 Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Sun, 30 Dec 2018 16:40:28 -0500
+Subject: [PATCH] Address some optimized-out memset() calls
+
+Ilja Van Sprundel reported a list of memset() calls which gcc
+optimizes out.  In krb_auth_su.c, use zap() to clear the password, and
+remove two memset() calls when there is no password to clear.  In
+iakerb.c, remove an unnecessary memset() before setting the only two
+fields of the IAKERB header structure.  In svr_principal.c, use
+krb5_free_key_keyblock_contents() instead of hand-freeing key data.
+In asn1_k_encode.c, remove an unnecessary memset() of the kdc_req_hack
+shell before returning.
+
+(cherry picked from commit 1057b0befec1f1c0e9d4da5521a58496e2dc0997)
+(cherry picked from commit 1dfff7202448a950c9133cdfe43d650092d930fd)
+---
+ src/clients/ksu/krb_auth_su.c      |  4 +---
+ src/lib/gssapi/krb5/iakerb.c       |  1 -
+ src/lib/kadm5/srv/svr_principal.c  | 10 ++--------
+ src/lib/krb5/asn.1/asn1_k_encode.c |  1 -
+ 4 files changed, 3 insertions(+), 13 deletions(-)
+
+diff --git a/src/clients/ksu/krb_auth_su.c b/src/clients/ksu/krb_auth_su.c
+index 7af48195c..e39685fff 100644
+--- a/src/clients/ksu/krb_auth_su.c
++++ b/src/clients/ksu/krb_auth_su.c
+@@ -183,21 +183,19 @@ krb5_boolean ksu_get_tgt_via_passwd(context, client, options, zero_password,
+     if (code ) {
+         com_err(prog_name, code, _("while reading password for '%s'\n"),
+                 client_name);
+-        memset(password, 0, sizeof(password));
+         return (FALSE);
+     }
+ 
+     if ( pwsize == 0) {
+         fprintf(stderr, _("No password given\n"));
+         *zero_password = TRUE;
+-        memset(password, 0, sizeof(password));
+         return (FALSE);
+     }
+ 
+     code = krb5_get_init_creds_password(context, &creds, client, password,
+                                         krb5_prompter_posix, NULL, 0, NULL,
+                                         options);
+-    memset(password, 0, sizeof(password));
++    zap(password, sizeof(password));
+ 
+ 
+     if (code) {
+diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
+index bb1072fe4..47c161ec9 100644
+--- a/src/lib/gssapi/krb5/iakerb.c
++++ b/src/lib/gssapi/krb5/iakerb.c
+@@ -262,7 +262,6 @@ iakerb_make_token(iakerb_ctx_id_t ctx,
+     /*
+      * Assemble the IAKERB-HEADER from the realm and cookie
+      */
+-    memset(&iah, 0, sizeof(iah));
+     iah.target_realm = *realm;
+     iah.cookie = cookie;
+ 
+diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
+index 21c53ece1..9ab2c5a74 100644
+--- a/src/lib/kadm5/srv/svr_principal.c
++++ b/src/lib/kadm5/srv/svr_principal.c
+@@ -2093,14 +2093,8 @@ static int decrypt_key_data(krb5_context context,
+         ret = krb5_dbe_decrypt_key_data(context, NULL, &key_data[i], &keys[i],
+                                         NULL);
+         if (ret) {
+-            for (; i >= 0; i--) {
+-                if (keys[i].contents) {
+-                    memset (keys[i].contents, 0, keys[i].length);
+-                    free( keys[i].contents );
+-                }
+-            }
+-
+-            memset(keys, 0, n_key_data*sizeof(krb5_keyblock));
++            for (; i >= 0; i--)
++                krb5_free_keyblock_contents(context, &keys[i]);
+             free(keys);
+             return ret;
+         }
+diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
+index 65c84be2f..81a34bac9 100644
+--- a/src/lib/krb5/asn.1/asn1_k_encode.c
++++ b/src/lib/krb5/asn.1/asn1_k_encode.c
+@@ -528,7 +528,6 @@ decode_kdc_req_body(const taginfo *t, const uint8_t *asn1, size_t len,
+         if (ret) {
+             free_kdc_req_body(b);
+             free(h.server_realm.data);
+-            memset(&h, 0, sizeof(h));
+             return ret;
+         }
+         b->server->realm = h.server_realm;
diff --git a/SOURCES/Avoid-alignment-warnings-in-openssl-rc4.c.patch b/SOURCES/Avoid-alignment-warnings-in-openssl-rc4.c.patch
new file mode 100644
index 0000000..e684c88
--- /dev/null
+++ b/SOURCES/Avoid-alignment-warnings-in-openssl-rc4.c.patch
@@ -0,0 +1,63 @@
+From e22f3e2439903aa05321ca339be6a12067b2c4db Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Mon, 6 May 2019 15:14:49 -0400
+Subject: [PATCH] Avoid alignment warnings in openssl rc4.c
+
+Add a comment to k5_arcfour_init_state() explaining how we stretch the
+krb5_data cipher state contract.  Use void * casts when interpreting
+the data pointer to avoid alignment warnings.
+
+[ghudson@mit.edu: moved and expanded comment; rewrote commit message]
+
+(cherry picked from commit 1cd41d76c12fc1cea0a8bf0d6a40f34623c60d6d)
+---
+ src/lib/crypto/openssl/enc_provider/rc4.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
+index 7f3c086ed..a65d57b7a 100644
+--- a/src/lib/crypto/openssl/enc_provider/rc4.c
++++ b/src/lib/crypto/openssl/enc_provider/rc4.c
+@@ -57,7 +57,7 @@ struct arcfour_state {
+ 
+ /* In-place IOV crypto */
+ static krb5_error_code
+-k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
++k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
+                    size_t num_data)
+ {
+     size_t i;
+@@ -66,7 +66,7 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
+     EVP_CIPHER_CTX *ctx = NULL;
+     struct arcfour_state *arcstate;
+ 
+-    arcstate = (state != NULL) ? (struct arcfour_state *) state->data : NULL;
++    arcstate = (state != NULL) ? (void *)state->data : NULL;
+     if (arcstate != NULL) {
+         ctx = arcstate->ctx;
+         if (arcstate->loopback != arcstate)
+@@ -113,7 +113,7 @@ k5_arcfour_docrypt(krb5_key key,const krb5_data *state, krb5_crypto_iov *data,
+ static void
+ k5_arcfour_free_state(krb5_data *state)
+ {
+-    struct arcfour_state *arcstate = (struct arcfour_state *) state->data;
++    struct arcfour_state *arcstate = (void *)state->data;
+ 
+     EVP_CIPHER_CTX_free(arcstate->ctx);
+     free(arcstate);
+@@ -125,6 +125,15 @@ k5_arcfour_init_state(const krb5_keyblock *key,
+ {
+     struct arcfour_state *arcstate;
+ 
++    /*
++     * The cipher state here is a saved pointer to a struct arcfour_state
++     * object, rather than a flat byte array as in most enc providers.  The
++     * object includes a loopback pointer to detect if if the caller made a
++     * copy of the krb5_data value or otherwise assumed it was a simple byte
++     * array.  When we cast the data pointer back, we need to go through void *
++     * to avoid increased alignment warnings.
++     */
++
+     /* Create a state structure with an uninitialized context. */
+     arcstate = calloc(1, sizeof(*arcstate));
+     if (arcstate == NULL)
diff --git a/SOURCES/Fix-Coverity-defects-in-soft-pkcs11-test-code.patch b/SOURCES/Fix-Coverity-defects-in-soft-pkcs11-test-code.patch
new file mode 100644
index 0000000..359335d
--- /dev/null
+++ b/SOURCES/Fix-Coverity-defects-in-soft-pkcs11-test-code.patch
@@ -0,0 +1,207 @@
+From 44b429df9ac4bb8ad84a090fee1bd70d83adcf23 Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Sat, 20 Jul 2019 00:51:52 -0400
+Subject: [PATCH] Fix Coverity defects in soft-pkcs11 test code
+
+Nothing in the code removes objects from soft_token.object.obs, so
+simplify add_st_object() not to search for an empty slot.  Avoid using
+random() by using a counter for session handles and just the array
+slot number for object handles.  Add a helper get_rcfilename() to
+facilitate checking the result of asprintf().  Properly initialize ap
+in sprintf_fill().  Close the file handle in read_conf_file().
+
+(cherry picked from commit b4831515b2f3b6fd7d7fd4bff4558c10c710891d)
+(cherry picked from commit 28db01445d2807d51b5045c0a04d5e49905de504)
+---
+ src/tests/softpkcs11/main.c | 102 +++++++++++++++++++-----------------
+ 1 file changed, 53 insertions(+), 49 deletions(-)
+
+diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
+index 5255323d3..2d1448ca2 100644
+--- a/src/tests/softpkcs11/main.c
++++ b/src/tests/softpkcs11/main.c
+@@ -78,6 +78,7 @@ compat_rsa_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e,
+                 (BL) = i2d_##T((S), &p);                \
+                 if ((BL) <= 0) {                        \
+                     free((B));                          \
++                    (B) = NULL;                         \
+                     (R) = EINVAL;                       \
+                 }                                       \
+             }                                           \
+@@ -149,6 +150,7 @@ static struct soft_token {
+     } state[10];
+ #define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))
+     FILE *logfile;
++    CK_SESSION_HANDLE next_session_handle;
+ } soft_token;
+ 
+ static void
+@@ -179,6 +181,7 @@ snprintf_fill(char *str, int size, char fillchar, const char *fmt, ...)
+ {
+     int len;
+     va_list ap;
++    va_start(ap, fmt);
+     len = vsnprintf(str, size, fmt, ap);
+     va_end(ap);
+     if (len < 0 || len > size)
+@@ -344,7 +347,13 @@ static struct st_object *
+ add_st_object(void)
+ {
+     struct st_object *o, **objs;
+-    int i;
++
++    objs = realloc(soft_token.object.objs,
++                   (soft_token.object.num_objs + 1) *
++                   sizeof(soft_token.object.objs[0]));
++    if (objs == NULL)
++        return NULL;
++    soft_token.object.objs = objs;
+ 
+     o = malloc(sizeof(*o));
+     if (o == NULL)
+@@ -352,26 +361,9 @@ add_st_object(void)
+     memset(o, 0, sizeof(*o));
+     o->attrs = NULL;
+     o->num_attributes = 0;
++    o->object_handle = soft_token.object.num_objs;
+ 
+-    for (i = 0; i < soft_token.object.num_objs; i++) {
+-        if (soft_token.object.objs == NULL) {
+-            soft_token.object.objs[i] = o;
+-            break;
+-        }
+-    }
+-    if (i == soft_token.object.num_objs) {
+-        objs = realloc(soft_token.object.objs,
+-                       (soft_token.object.num_objs + 1) * sizeof(soft_token.object.objs[0]));
+-        if (objs == NULL) {
+-            free(o);
+-            return NULL;
+-        }
+-        soft_token.object.objs = objs;
+-        soft_token.object.objs[soft_token.object.num_objs++] = o;
+-    }
+-    soft_token.object.objs[i]->object_handle =
+-        (random() & (~OBJECT_ID_MASK)) | i;
+-
++    soft_token.object.objs[soft_token.object.num_objs++] = o;
+     return o;
+ }
+ 
+@@ -797,6 +789,8 @@ read_conf_file(const char *fn)
+ 
+         add_certificate(label, cert, key, id, anchor);
+     }
++
++    fclose(f);
+ }
+ 
+ static CK_RV
+@@ -806,19 +800,47 @@ func_not_supported(void)
+     return CKR_FUNCTION_NOT_SUPPORTED;
+ }
+ 
++static char *
++get_rcfilename()
++{
++    struct passwd *pw;
++    const char *home = NULL;
++    char *fn;
++
++    if (getuid() == geteuid()) {
++        fn = getenv("SOFTPKCS11RC");
++        if (fn != NULL)
++            return strdup(fn);
++
++        home = getenv("HOME");
++    }
++
++    if (home == NULL) {
++        pw = getpwuid(getuid());
++        if (pw != NULL)
++            home = pw->pw_dir;
++    }
++
++    if (home == NULL)
++        return strdup("/etc/soft-token.rc");
++
++    if (asprintf(&fn, "%s/.soft-token.rc", home) < 0)
++        return NULL;
++    return fn;
++}
++
+ CK_RV
+ C_Initialize(CK_VOID_PTR a)
+ {
+     CK_C_INITIALIZE_ARGS_PTR args = a;
+     size_t i;
++    char *fn;
+ 
+     st_logf("Initialize\n");
+ 
+     OpenSSL_add_all_algorithms();
+     ERR_load_crypto_strings();
+ 
+-    srandom(getpid() ^ time(NULL));
+-
+     for (i = 0; i < MAX_NUM_SESSION; i++) {
+         soft_token.state[i].session_handle = CK_INVALID_HANDLE;
+         soft_token.state[i].find.attributes = NULL;
+@@ -850,31 +872,13 @@ C_Initialize(CK_VOID_PTR a)
+         st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);
+     }
+ 
+-    {
+-        char *fn = NULL, *home = NULL;
+-
+-        if (getuid() == geteuid()) {
+-            fn = getenv("SOFTPKCS11RC");
+-            if (fn)
+-                fn = strdup(fn);
+-            home = getenv("HOME");
+-        }
+-        if (fn == NULL && home == NULL) {
+-            struct passwd *pw = getpwuid(getuid());
+-            if(pw != NULL)
+-                home = pw->pw_dir;
+-        }
+-        if (fn == NULL) {
+-            if (home)
+-                asprintf(&fn, "%s/.soft-token.rc", home);
+-            else
+-                fn = strdup("/etc/soft-token.rc");
+-        }
+-
+-        read_conf_file(fn);
+-        free(fn);
+-    }
++    soft_token.next_session_handle = 0;
+ 
++    fn = get_rcfilename();
++    if (fn == NULL)
++        return CKR_DEVICE_MEMORY;
++    read_conf_file(fn);
++    free(fn);
+     return CKR_OK;
+ }
+ 
+@@ -1082,8 +1086,7 @@ C_OpenSession(CK_SLOT_ID slotID,
+ 
+     soft_token.open_sessions++;
+ 
+-    soft_token.state[i].session_handle =
+-        (CK_SESSION_HANDLE)(random() & 0xfffff);
++    soft_token.state[i].session_handle = soft_token.next_session_handle++;
+     *phSession = soft_token.state[i].session_handle;
+ 
+     return CKR_OK;
+@@ -1152,7 +1155,8 @@ C_Login(CK_SESSION_HANDLE hSession,
+     VERIFY_SESSION_HANDLE(hSession, NULL);
+ 
+     if (pPin != NULL_PTR) {
+-        asprintf(&pin, "%.*s", (int)ulPinLen, pPin);
++        if (asprintf(&pin, "%.*s", (int)ulPinLen, pPin) < 0)
++            return CKR_DEVICE_MEMORY;
+         st_logf("type: %d password: %s\n", (int)userType, pin);
+     }
+ 
diff --git a/SOURCES/Fix-KCM-client-time-offset-propagation.patch b/SOURCES/Fix-KCM-client-time-offset-propagation.patch
new file mode 100644
index 0000000..eedc4c0
--- /dev/null
+++ b/SOURCES/Fix-KCM-client-time-offset-propagation.patch
@@ -0,0 +1,33 @@
+From 7e4576cc62a16fa77030c42dcc43c61cdfa5b4e6 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Wed, 14 Aug 2019 13:52:27 -0400
+Subject: [PATCH] Fix KCM client time offset propagation
+
+An inverted status check in get_kdc_offset() would cause querying the
+offset time from the ccache to always fail (silently) on KCM.  Fix the
+status check so that KCM can properly handle desync.
+
+ticket: 8826 (new)
+tags: pullup
+target_version: 1.17-next
+target_verison: 1.16-next
+
+(cherry picked from commit 323abb6d1ebe5469d6c2167c29aa5d696d099b90)
+(cherry picked from commit 7e81b8077cf2cf186dadb96b064573f7c221fbf3)
+---
+ src/lib/krb5/ccache/cc_kcm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
+index 092ab7daf..fe93ca3dc 100644
+--- a/src/lib/krb5/ccache/cc_kcm.c
++++ b/src/lib/krb5/ccache/cc_kcm.c
+@@ -583,7 +583,7 @@ get_kdc_offset(krb5_context context, krb5_ccache cache)
+     if (cache_call(context, cache, &req, FALSE) != 0)
+         goto cleanup;
+     time_offset = k5_input_get_uint32_be(&req.reply);
+-    if (!req.reply.status)
++    if (req.reply.status)
+         goto cleanup;
+     context->os_context.time_offset = time_offset;
+     context->os_context.usec_offset = 0;
diff --git a/SOURCES/Fix-argument-order-on-strlcpy-in-enctype_name.patch b/SOURCES/Fix-argument-order-on-strlcpy-in-enctype_name.patch
new file mode 100644
index 0000000..99648bd
--- /dev/null
+++ b/SOURCES/Fix-argument-order-on-strlcpy-in-enctype_name.patch
@@ -0,0 +1,22 @@
+From 9a38af6aa136fdc92d5e0f1591c1647aec498f5a Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 17 Sep 2019 18:29:15 -0400
+Subject: [PATCH] Fix argument order on strlcpy() in enctype_name()
+
+---
+ src/kdc/kdc_util.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
+index 96c88edc1..6d1861a3b 100644
+--- a/src/kdc/kdc_util.c
++++ b/src/kdc/kdc_util.c
+@@ -1081,7 +1081,7 @@ enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
+     else
+         return krb5_enctype_to_name(ktype, FALSE, buf, buflen);
+ 
+-    if (strlcpy(name, buf, buflen) >= buflen)
++    if (strlcpy(buf, name, buflen) >= buflen)
+         return ENOMEM;
+     return 0;
+ }
diff --git a/SOURCES/Fix-memory-leak-in-none-replay-cache-type.patch b/SOURCES/Fix-memory-leak-in-none-replay-cache-type.patch
new file mode 100644
index 0000000..166ef05
--- /dev/null
+++ b/SOURCES/Fix-memory-leak-in-none-replay-cache-type.patch
@@ -0,0 +1,34 @@
+From 74a3b8448949130d91417b261c3e1c316ffa8796 Mon Sep 17 00:00:00 2001
+From: Corene Casper <C.Casper@Dell.com>
+Date: Sat, 16 Feb 2019 00:49:26 -0500
+Subject: [PATCH] Fix memory leak in 'none' replay cache type
+
+Commit 0f06098e2ab419d02e89a1ca6bc9f2828f6bdb1e fixed part of a memory
+leak in the 'none' replay cache type by freeing the outer container,
+but we also need to free the mutex.
+
+[ghudson@mit.edu: wrote commit message]
+
+ticket: 8783
+tags: pullup
+target_version: 1.17-next
+target_version: 1.16-next
+
+(cherry picked from commit af2a3115cb8feb5174151b4b40223ae45aa9db17)
+(cherry picked from commit ff79351c4755d6df7c3245274708454311c25731)
+---
+ src/lib/krb5/rcache/rc_none.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/lib/krb5/rcache/rc_none.c b/src/lib/krb5/rcache/rc_none.c
+index e30aed09f..0b2274df7 100644
+--- a/src/lib/krb5/rcache/rc_none.c
++++ b/src/lib/krb5/rcache/rc_none.c
+@@ -50,6 +50,7 @@ krb5_rc_none_noargs(krb5_context ctx, krb5_rcache rc)
+ static krb5_error_code KRB5_CALLCONV
+ krb5_rc_none_close(krb5_context ctx, krb5_rcache rc)
+ {
++    k5_mutex_destroy(&rc->lock);
+     free (rc);
+     return 0;
+ }
diff --git a/SOURCES/Fix-memory-leaks-in-soft-pkcs11-code.patch b/SOURCES/Fix-memory-leaks-in-soft-pkcs11-code.patch
new file mode 100644
index 0000000..01e41fc
--- /dev/null
+++ b/SOURCES/Fix-memory-leaks-in-soft-pkcs11-code.patch
@@ -0,0 +1,123 @@
+From 604f5dcbb018fca8ea27e00314ed615133b861e1 Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Mon, 5 Aug 2019 01:53:51 -0400
+Subject: [PATCH] Fix memory leaks in soft-pkcs11 code
+
+Fix leaks detected by asan in t_pkinit.py.  Add a helper to free a
+struct st_object and free objects in C_Finalize().  Duplicate the X509
+cert in add_certificate() instead of creating aliases so it can be
+properly freed.  Start the session handle counter at 1 so that
+C_Finalize() won't confuse the first session handle with
+CK_INVALID_HANDLE (defined to 0 in pkinit.h) and will properly clean
+the session object.
+
+(cherry picked from commit 15bcaf8bcb4af25ff89820ad3bf23ad5a324e863)
+(cherry picked from commit 5cc80472e7a8b0fb3002f229ffb104dccf8bd120)
+---
+ src/tests/softpkcs11/main.c | 44 +++++++++++++++++++++++++++++++++----
+ 1 file changed, 40 insertions(+), 4 deletions(-)
+
+diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
+index 2d1448ca2..a4c3ae78e 100644
+--- a/src/tests/softpkcs11/main.c
++++ b/src/tests/softpkcs11/main.c
+@@ -109,7 +109,7 @@ struct st_object {
+         X509 *cert;
+         EVP_PKEY *public_key;
+         struct {
+-            const char *file;
++            char *file;
+             EVP_PKEY *key;
+             X509 *cert;
+         } private_key;
+@@ -343,6 +343,26 @@ print_attributes(const CK_ATTRIBUTE *attributes,
+     }
+ }
+ 
++static void
++free_st_object(struct st_object *o)
++{
++    int i;
++
++    for (i = 0; i < o->num_attributes; i++)
++        free(o->attrs[i].attribute.pValue);
++    free(o->attrs);
++    if (o->type == STO_T_CERTIFICATE) {
++        X509_free(o->u.cert);
++    } else if (o->type == STO_T_PRIVATE_KEY) {
++        free(o->u.private_key.file);
++        EVP_PKEY_free(o->u.private_key.key);
++        X509_free(o->u.private_key.cert);
++    } else if (o->type == STO_T_PUBLIC_KEY) {
++        EVP_PKEY_free(o->u.public_key);
++    }
++    free(o);
++}
++
+ static struct st_object *
+ add_st_object(void)
+ {
+@@ -518,7 +538,11 @@ add_certificate(char *label,
+         goto out;
+     }
+     o->type = STO_T_CERTIFICATE;
+-    o->u.cert = cert;
++    o->u.cert = X509_dup(cert);
++    if (o->u.cert == NULL) {
++        ret = CKR_DEVICE_MEMORY;
++        goto out;
++    }
+     public_key = X509_get_pubkey(o->u.cert);
+ 
+     switch (EVP_PKEY_base_id(public_key)) {
+@@ -602,7 +626,11 @@ add_certificate(char *label,
+         o->u.private_key.file = strdup(private_key_file);
+         o->u.private_key.key = NULL;
+ 
+-        o->u.private_key.cert = cert;
++        o->u.private_key.cert = X509_dup(cert);
++        if (o->u.private_key.cert == NULL) {
++            ret = CKR_DEVICE_MEMORY;
++            goto out;
++        }
+ 
+         c = CKO_PRIVATE_KEY;
+         add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
+@@ -676,6 +704,7 @@ add_certificate(char *label,
+     free(serial_data);
+     free(issuer_data);
+     free(subject_data);
++    X509_free(cert);
+ 
+     return ret;
+ }
+@@ -872,7 +901,7 @@ C_Initialize(CK_VOID_PTR a)
+         st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);
+     }
+ 
+-    soft_token.next_session_handle = 0;
++    soft_token.next_session_handle = 1;
+ 
+     fn = get_rcfilename();
+     if (fn == NULL)
+@@ -886,6 +915,7 @@ CK_RV
+ C_Finalize(CK_VOID_PTR args)
+ {
+     size_t i;
++    int j;
+ 
+     st_logf("Finalize\n");
+ 
+@@ -897,6 +927,12 @@ C_Finalize(CK_VOID_PTR args)
+         }
+     }
+ 
++    for (j = 0; j < soft_token.object.num_objs; j++)
++        free_st_object(soft_token.object.objs[j]);
++    free(soft_token.object.objs);
++    soft_token.object.objs = NULL;
++    soft_token.object.num_objs = 0;
++
+     return CKR_OK;
+ }
+ 
diff --git a/SOURCES/In-kpropd-debug-log-proper-ticket-enctype-names.patch b/SOURCES/In-kpropd-debug-log-proper-ticket-enctype-names.patch
new file mode 100644
index 0000000..8a20e3d
--- /dev/null
+++ b/SOURCES/In-kpropd-debug-log-proper-ticket-enctype-names.patch
@@ -0,0 +1,28 @@
+From 30f112f8dc1c5241da5ba301cb45a06bb5bb4c01 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 15 Jan 2019 13:41:16 -0500
+Subject: [PATCH] In kpropd, debug-log proper ticket enctype names
+
+This change replaces the last call of krb5_enctype_to_string() in our
+sources with krb5_enctype_to_name(), ensuring that we log consistently
+to users using readily discoverable strings.
+
+(cherry picked from commit 30e12a2ecdf7e2a034a91626a03b5c9909e4c68d)
+---
+ src/kprop/kpropd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
+index 4cc035dc6..0c7bffa24 100644
+--- a/src/kprop/kpropd.c
++++ b/src/kprop/kpropd.c
+@@ -1279,7 +1279,8 @@ kerberos_authenticate(krb5_context context, int fd, krb5_principal *clientp,
+             exit(1);
+         }
+ 
+-        retval = krb5_enctype_to_string(*etype, etypebuf, sizeof(etypebuf));
++        retval = krb5_enctype_to_name(*etype, FALSE, etypebuf,
++                                      sizeof(etypebuf));
+         if (retval) {
+             com_err(progname, retval, _("while unparsing ticket etype"));
+             exit(1);
diff --git a/SOURCES/In-rd_req_dec-always-log-non-permitted-enctypes.patch b/SOURCES/In-rd_req_dec-always-log-non-permitted-enctypes.patch
new file mode 100644
index 0000000..6ca3da0
--- /dev/null
+++ b/SOURCES/In-rd_req_dec-always-log-non-permitted-enctypes.patch
@@ -0,0 +1,54 @@
+From 2b4521f3ba3dad064e3f64bfd56b88d5cb5d0955 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Mon, 14 Jan 2019 17:14:42 -0500
+Subject: [PATCH] In rd_req_dec, always log non-permitted enctypes
+
+The buffer specified in negotiate_etype() is too small for use with
+the AES enctypes when used with krb5_enctype_to_string(), so switch to
+using krb5_enctype_to_name().
+
+(cherry picked from commit bf75ebf583a51bf00005a96d17924818d19377be)
+---
+ src/lib/krb5/krb/rd_req_dec.c  | 5 ++---
+ src/tests/gssapi/t_enctypes.py | 5 +++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c
+index 4cd429a11..e75192fee 100644
+--- a/src/lib/krb5/krb/rd_req_dec.c
++++ b/src/lib/krb5/krb/rd_req_dec.c
+@@ -864,9 +864,8 @@ negotiate_etype(krb5_context context,
+         if (permitted == FALSE) {
+             char enctype_name[30];
+ 
+-            if (krb5_enctype_to_string(desired_etypes[i],
+-                                       enctype_name,
+-                                       sizeof(enctype_name)) == 0)
++            if (krb5_enctype_to_name(desired_etypes[i], FALSE, enctype_name,
++                                     sizeof(enctype_name)) == 0)
+                 k5_setmsg(context, KRB5_NOPERM_ETYPE,
+                           _("Encryption type %s not permitted"), enctype_name);
+             return KRB5_NOPERM_ETYPE;
+diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
+index ee43ff028..5d9f80e04 100755
+--- a/src/tests/gssapi/t_enctypes.py
++++ b/src/tests/gssapi/t_enctypes.py
+@@ -85,7 +85,8 @@ test('both aes128', 'aes128-cts', 'aes128-cts',
+ # If only the acceptor constrains the permitted session enctypes to
+ # aes128, subkey negotiation fails because the acceptor considers the
+ # aes256 session key to be non-permitted.
+-test_err('acc aes128', None, 'aes128-cts', 'Encryption type not permitted')
++test_err('acc aes128', None, 'aes128-cts',
++         'Encryption type aes256-cts-hmac-sha1-96 not permitted')
+ 
+ # If the initiator constrains the permitted session enctypes to des3,
+ # no acceptor subkey will be generated because we can't upgrade to a
+@@ -128,7 +129,7 @@ test('upgrade init des3+rc4', 'des3 rc4', None,
+ # is only for the sake of the kernel, since we could upgrade to an
+ # aes128 subkey, but it's the current semantics.)
+ test_err('upgrade acc aes128', None, 'aes128-cts',
+-         'Encryption type ArcFour with HMAC/md5 not permitted')
++         'Encryption type arcfour-hmac not permitted')
+ 
+ # If the acceptor permits rc4 but prefers aes128, it will negotiate an
+ # upgrade to aes128.
diff --git a/SOURCES/Make-etype-names-in-KDC-logs-human-readable.patch b/SOURCES/Make-etype-names-in-KDC-logs-human-readable.patch
new file mode 100644
index 0000000..8b3413b
--- /dev/null
+++ b/SOURCES/Make-etype-names-in-KDC-logs-human-readable.patch
@@ -0,0 +1,296 @@
+From f815140182976e882445a38ee5a0a77f56da7c8a Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 8 Jan 2019 17:42:35 -0500
+Subject: [PATCH] Make etype names in KDC logs human-readable
+
+Introduce enctype_name() as a wrapper over krb5_enctype_to_name for
+converting between registered constants and names.  Adjust signatures
+and rewrite ktypes2str() and rep_etypes2str() to operate on dynamic
+buffers.
+
+ticket: 8772 (new)
+(cherry picked from commit a649279727490687d54becad91fde8cf7429d951)
+---
+ src/kdc/kdc_log.c  |  42 +++++++--------
+ src/kdc/kdc_util.c | 131 +++++++++++++++++++++++----------------------
+ src/kdc/kdc_util.h |   6 +--
+ 3 files changed, 90 insertions(+), 89 deletions(-)
+
+diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c
+index 4eec50373..b160ba21a 100644
+--- a/src/kdc/kdc_log.c
++++ b/src/kdc/kdc_log.c
+@@ -65,7 +65,7 @@ log_as_req(krb5_context context,
+ {
+     const char *fromstring = 0;
+     char fromstringbuf[70];
+-    char ktypestr[128];
++    char *ktypestr = NULL;
+     const char *cname2 = cname ? cname : "<unknown client>";
+     const char *sname2 = sname ? sname : "<unknown server>";
+ 
+@@ -74,26 +74,29 @@ log_as_req(krb5_context context,
+                            fromstringbuf, sizeof(fromstringbuf));
+     if (!fromstring)
+         fromstring = "<unknown>";
+-    ktypes2str(ktypestr, sizeof(ktypestr),
+-               request->nktypes, request->ktype);
++
++    ktypestr = ktypes2str(request->ktype, request->nktypes);
+ 
+     if (status == NULL) {
+         /* success */
+-        char rep_etypestr[128];
+-        rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply);
++        char *rep_etypestr = rep_etypes2str(reply);
+         krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %u, %s, "
+                                      "%s for %s"),
+-                         ktypestr, fromstring, (unsigned int)authtime,
+-                         rep_etypestr, cname2, sname2);
++                         ktypestr ? ktypestr : "", fromstring,
++                         (unsigned int)authtime,
++                         rep_etypestr ? rep_etypestr : "", cname2, sname2);
++        free(rep_etypestr);
+     } else {
+         /* fail */
+         krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: %s: %s for %s%s%s"),
+-                         ktypestr, fromstring, status,
+-                         cname2, sname2, emsg ? ", " : "", emsg ? emsg : "");
++                         ktypestr ? ktypestr : "", fromstring, status, cname2,
++                         sname2, emsg ? ", " : "", emsg ? emsg : "");
+     }
+     krb5_db_audit_as_req(context, request,
+                          local_addr->address, remote_addr->address,
+                          client, server, authtime, errcode);
++
++    free(ktypestr);
+ }
+ 
+ /*
+@@ -122,10 +125,9 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
+             unsigned int c_flags,
+             const char *status, krb5_error_code errcode, const char *emsg)
+ {
+-    char ktypestr[128];
++    char *ktypestr = NULL, *rep_etypestr = NULL;
+     const char *fromstring = 0;
+     char fromstringbuf[70];
+-    char rep_etypestr[128];
+     char *cname = NULL, *sname = NULL, *altcname = NULL;
+     char *logcname = NULL, *logsname = NULL, *logaltcname = NULL;
+ 
+@@ -134,11 +136,6 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
+                            fromstringbuf, sizeof(fromstringbuf));
+     if (!fromstring)
+         fromstring = "<unknown>";
+-    ktypes2str(ktypestr, sizeof(ktypestr), request->nktypes, request->ktype);
+-    if (!errcode)
+-        rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply);
+-    else
+-        rep_etypestr[0] = 0;
+ 
+     unparse_and_limit(ctx, cprinc, &cname);
+     logcname = (cname != NULL) ? cname : "<unknown client>";
+@@ -151,10 +148,14 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
+        name (useful), and doesn't log ktypestr (probably not
+        important).  */
+     if (errcode != KRB5KDC_ERR_SERVER_NOMATCH) {
++        ktypestr = ktypes2str(request->ktype, request->nktypes);
++        rep_etypestr = rep_etypes2str(reply);
+         krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %u, %s%s "
+                                      "%s for %s%s%s"),
+-                         ktypestr, fromstring, status, (unsigned int)authtime,
+-                         rep_etypestr, !errcode ? "," : "", logcname, logsname,
++                         ktypestr ? ktypestr : "", fromstring, status,
++                         (unsigned int)authtime,
++                         rep_etypestr ? rep_etypestr : "",
++                         !errcode ? "," : "", logcname, logsname,
+                          errcode ? ", " : "", errcode ? emsg : "");
+         if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION))
+             krb5_klog_syslog(LOG_INFO,
+@@ -171,9 +172,8 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from,
+                          fromstring, status, (unsigned int)authtime,
+                          logcname, logsname, logaltcname);
+ 
+-    /* OpenSolaris: audit_krb5kdc_tgs_req(...)  or
+-       audit_krb5kdc_tgs_req_2ndtktmm(...) */
+-
++    free(rep_etypestr);
++    free(ktypestr);
+     krb5_free_unparsed_name(ctx, cname);
+     krb5_free_unparsed_name(ctx, sname);
+     krb5_free_unparsed_name(ctx, altcname);
+diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
+index 0155c28c6..f5c581c82 100644
+--- a/src/kdc/kdc_util.c
++++ b/src/kdc/kdc_util.c
+@@ -1043,84 +1043,87 @@ void limit_string(char *name)
+     return;
+ }
+ 
+-/*
+- * L10_2 = log10(2**x), rounded up; log10(2) ~= 0.301.
+- */
+-#define L10_2(x) ((int)(((x * 301) + 999) / 1000))
+-
+-/*
+- * Max length of sprintf("%ld") for an int of type T; includes leading
+- * minus sign and terminating NUL.
+- */
+-#define D_LEN(t) (L10_2(sizeof(t) * CHAR_BIT) + 2)
+-
+-void
+-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype)
++/* Wrapper of krb5_enctype_to_name() to include the PKINIT types. */
++static krb5_error_code
++enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
+ {
+-    int i;
+-    char stmp[D_LEN(krb5_enctype) + 1];
+-    char *p;
++    char *name;
+ 
+-    if (nktypes < 0
+-        || len < (sizeof(" etypes {...}") + D_LEN(int))) {
+-        *s = '\0';
+-        return;
+-    }
++    if (buflen == 0)
++        return EINVAL;
++    *buf = '\0'; /* ensure these are always valid C-strings */
+ 
+-    snprintf(s, len, "%d etypes {", nktypes);
+-    for (i = 0; i < nktypes; i++) {
+-        snprintf(stmp, sizeof(stmp), "%s%ld", i ? " " : "", (long)ktype[i]);
+-        if (strlen(s) + strlen(stmp) + sizeof("}") > len)
+-            break;
+-        strlcat(s, stmp, len);
+-    }
+-    if (i < nktypes) {
+-        /*
+-         * We broke out of the loop. Try to truncate the list.
+-         */
+-        p = s + strlen(s);
+-        while (p - s + sizeof("...}") > len) {
+-            while (p > s && *p != ' ' && *p != '{')
+-                *p-- = '\0';
+-            if (p > s && *p == ' ') {
+-                *p-- = '\0';
+-                continue;
+-            }
+-        }
+-        strlcat(s, "...", len);
+-    }
+-    strlcat(s, "}", len);
+-    return;
++    /* rfc4556 recommends that clients wishing to indicate support for these
++     * pkinit algorithms include them in the etype field of the AS-REQ. */
++    if (ktype == ENCTYPE_DSA_SHA1_CMS)
++        name = "id-dsa-with-sha1-CmsOID";
++    else if (ktype == ENCTYPE_MD5_RSA_CMS)
++        name = "md5WithRSAEncryption-CmsOID";
++    else if (ktype == ENCTYPE_SHA1_RSA_CMS)
++        name = "sha-1WithRSAEncryption-CmsOID";
++    else if (ktype == ENCTYPE_RC2_CBC_ENV)
++        name = "rc2-cbc-EnvOID";
++    else if (ktype == ENCTYPE_RSA_ENV)
++        name = "rsaEncryption-EnvOID";
++    else if (ktype == ENCTYPE_RSA_ES_OAEP_ENV)
++        name = "id-RSAES-OAEP-EnvOID";
++    else if (ktype == ENCTYPE_DES3_CBC_ENV)
++        name = "des-ede3-cbc-EnvOID";
++    else
++        return krb5_enctype_to_name(ktype, FALSE, buf, buflen);
++
++    if (strlcpy(name, buf, buflen) >= buflen)
++        return ENOMEM;
++    return 0;
+ }
+ 
+-void
+-rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep)
++char *
++ktypes2str(krb5_enctype *ktype, int nktypes)
+ {
+-    char stmp[sizeof("ses=") + D_LEN(krb5_enctype)];
++    struct k5buf buf;
++    int i;
++    char name[64];
+ 
+-    if (len < (3 * D_LEN(krb5_enctype)
+-               + sizeof("etypes {rep= tkt= ses=}"))) {
+-        *s = '\0';
+-        return;
++    if (nktypes < 0)
++        return NULL;
++
++    k5_buf_init_dynamic(&buf);
++    k5_buf_add_fmt(&buf, "%d etypes {", nktypes);
++    for (i = 0; i < nktypes; i++) {
++        enctype_name(ktype[i], name, sizeof(name));
++        k5_buf_add_fmt(&buf, "%s%s(%ld)", i ? ", " : "", name, (long)ktype[i]);
+     }
++    k5_buf_add(&buf, "}");
++    return buf.data;
++}
+ 
+-    snprintf(s, len, "etypes {rep=%ld", (long)rep->enc_part.enctype);
++char *
++rep_etypes2str(krb5_kdc_rep *rep)
++{
++    struct k5buf buf;
++    char name[64];
++    krb5_enctype etype;
++
++    k5_buf_init_dynamic(&buf);
++    k5_buf_add(&buf, "etypes {rep=");
++    enctype_name(rep->enc_part.enctype, name, sizeof(name));
++    k5_buf_add_fmt(&buf, "%s(%ld)", name, (long)rep->enc_part.enctype);
+ 
+     if (rep->ticket != NULL) {
+-        snprintf(stmp, sizeof(stmp),
+-                 " tkt=%ld", (long)rep->ticket->enc_part.enctype);
+-        strlcat(s, stmp, len);
++        etype = rep->ticket->enc_part.enctype;
++        enctype_name(etype, name, sizeof(name));
++        k5_buf_add_fmt(&buf, ", tkt=%s(%ld)", name, (long)etype);
+     }
+ 
+-    if (rep->ticket != NULL
+-        && rep->ticket->enc_part2 != NULL
+-        && rep->ticket->enc_part2->session != NULL) {
+-        snprintf(stmp, sizeof(stmp), " ses=%ld",
+-                 (long)rep->ticket->enc_part2->session->enctype);
+-        strlcat(s, stmp, len);
++    if (rep->ticket != NULL && rep->ticket->enc_part2 != NULL &&
++        rep->ticket->enc_part2->session != NULL) {
++        etype = rep->ticket->enc_part2->session->enctype;
++        enctype_name(etype, name, sizeof(name));
++        k5_buf_add_fmt(&buf, ", ses=%s(%ld)", name, (long)etype);
+     }
+-    strlcat(s, "}", len);
+-    return;
++
++    k5_buf_add(&buf, "}");
++    return buf.data;
+ }
+ 
+ static krb5_error_code
+diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
+index 6ec645fc3..25077cbf5 100644
+--- a/src/kdc/kdc_util.h
++++ b/src/kdc/kdc_util.h
+@@ -110,11 +110,9 @@ select_session_keytype (kdc_realm_t *kdc_active_realm,
+ 
+ void limit_string (char *name);
+ 
+-void
+-ktypes2str(char *s, size_t len, int nktypes, krb5_enctype *ktype);
++char *ktypes2str(krb5_enctype *ktype, int nktypes);
+ 
+-void
+-rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep);
++char *rep_etypes2str(krb5_kdc_rep *rep);
+ 
+ /* authind.c */
+ krb5_boolean
diff --git a/SOURCES/Mark-deprecated-enctypes-when-used.patch b/SOURCES/Mark-deprecated-enctypes-when-used.patch
new file mode 100644
index 0000000..4ded20a
--- /dev/null
+++ b/SOURCES/Mark-deprecated-enctypes-when-used.patch
@@ -0,0 +1,250 @@
+From 6306a2a8697c94f968a02d66204f7d357aa0e7f6 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Thu, 10 Jan 2019 16:34:54 -0500
+Subject: [PATCH] Mark deprecated enctypes when used
+
+Preface ETYPE_DEPRECATED enctypes with "DEPRECATED:" in klist output,
+KDC logs, and kadmin interactions.  Also complain in krb5kdc when the
+stash file has a deprecated enctype or a deprecated enctype is
+requested with -k.
+
+ticket: 8773 (new)
+(cherry picked from commit 8d8e68283b599e680f9fe45eff8af397e827bd6c)
+---
+ src/clients/klist/klist.c      | 14 ++++++++++----
+ src/kadmin/cli/kadmin.c        |  6 +++++-
+ src/kdc/kdc_util.c             |  9 +++++++++
+ src/kdc/main.c                 | 19 +++++++++++++++++++
+ src/tests/gssapi/t_enctypes.py | 15 +++++++++------
+ src/tests/t_keyrollover.py     |  8 +++++---
+ src/tests/t_sesskeynego.py     |  4 ++--
+ 7 files changed, 59 insertions(+), 16 deletions(-)
+
+diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
+index 70adb54e8..8c307151a 100644
+--- a/src/clients/klist/klist.c
++++ b/src/clients/klist/klist.c
+@@ -571,11 +571,17 @@ static char *
+ etype_string(krb5_enctype enctype)
+ {
+     static char buf[100];
+-    krb5_error_code ret;
++    char *bp = buf;
++    size_t deplen, buflen = sizeof(buf);
+ 
+-    ret = krb5_enctype_to_name(enctype, FALSE, buf, sizeof(buf));
+-    if (ret)
+-        snprintf(buf, sizeof(buf), "etype %d", enctype);
++    if (krb5int_c_deprecated_enctype(enctype)) {
++        deplen = strlcpy(bp, "DEPRECATED:", buflen);
++        buflen -= deplen;
++        bp += deplen;
++    }
++
++    if (krb5_enctype_to_name(enctype, FALSE, bp, buflen))
++        snprintf(bp, buflen, "etype %d", enctype);
+     return buf;
+ }
+ 
+diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c
+index ed581ee79..cc74921bf 100644
+--- a/src/kadmin/cli/kadmin.c
++++ b/src/kadmin/cli/kadmin.c
+@@ -1451,12 +1451,16 @@ kadmin_getprinc(int argc, char *argv[])
+         for (i = 0; i < dprinc.n_key_data; i++) {
+             krb5_key_data *key_data = &dprinc.key_data[i];
+             char enctype[BUFSIZ], salttype[BUFSIZ];
++            char *deprecated = "";
+ 
+             if (krb5_enctype_to_name(key_data->key_data_type[0], FALSE,
+                                      enctype, sizeof(enctype)))
+                 snprintf(enctype, sizeof(enctype), _("<Encryption type 0x%x>"),
+                          key_data->key_data_type[0]);
+-            printf("Key: vno %d, %s", key_data->key_data_kvno, enctype);
++            if (krb5int_c_deprecated_enctype(key_data->key_data_type[0]))
++                deprecated = "DEPRECATED:";
++            printf("Key: vno %d, %s%s", key_data->key_data_kvno, deprecated,
++                   enctype);
+             if (key_data->key_data_ver > 1 &&
+                 key_data->key_data_type[1] != KRB5_KDB_SALTTYPE_NORMAL) {
+                 if (krb5_salttype_to_string(key_data->key_data_type[1],
+diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
+index f5c581c82..96c88edc1 100644
+--- a/src/kdc/kdc_util.c
++++ b/src/kdc/kdc_util.c
+@@ -1048,11 +1048,20 @@ static krb5_error_code
+ enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
+ {
+     char *name;
++    size_t len;
+ 
+     if (buflen == 0)
+         return EINVAL;
+     *buf = '\0'; /* ensure these are always valid C-strings */
+ 
++    if (krb5int_c_deprecated_enctype(ktype)) {
++        len = strlcpy(buf, "DEPRECATED:", buflen);
++        if (len >= buflen)
++            return ENOMEM;
++        buflen -= len;
++        buf += len;
++    }
++
+     /* rfc4556 recommends that clients wishing to indicate support for these
+      * pkinit algorithms include them in the etype field of the AS-REQ. */
+     if (ktype == ENCTYPE_DSA_SHA1_CMS)
+diff --git a/src/kdc/main.c b/src/kdc/main.c
+index 663fd6303..60092a0df 100644
+--- a/src/kdc/main.c
++++ b/src/kdc/main.c
+@@ -210,12 +210,23 @@ init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm,
+     char                *svalue = NULL;
+     const char          *hierarchy[4];
+     krb5_kvno       mkvno = IGNORE_VNO;
++    char ename[32];
+ 
+     memset(rdp, 0, sizeof(kdc_realm_t));
+     if (!realm) {
+         kret = EINVAL;
+         goto whoops;
+     }
++
++    if (def_enctype != ENCTYPE_UNKNOWN &&
++        krb5int_c_deprecated_enctype(def_enctype)) {
++        if (krb5_enctype_to_name(def_enctype, FALSE, ename, sizeof(ename)))
++            ename[0] = '\0';
++        fprintf(stderr,
++                _("Requested master password enctype %s in %s is DEPRECATED!"),
++                ename, realm);
++    }
++
+     hierarchy[0] = KRB5_CONF_REALMS;
+     hierarchy[1] = realm;
+     hierarchy[3] = NULL;
+@@ -370,6 +381,14 @@ init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm,
+         goto whoops;
+     }
+ 
++    if (krb5int_c_deprecated_enctype(rdp->realm_mkey.enctype)) {
++        if (krb5_enctype_to_name(rdp->realm_mkey.enctype, FALSE, ename,
++                                 sizeof(ename)))
++            ename[0] = '\0';
++        fprintf(stderr, _("Stash file %s uses DEPRECATED enctype %s!"),
++                rdp->realm_stash, ename);
++    }
++
+     if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc,
+                                         &rdp->realm_mkey))) {
+         kdc_err(rdp->realm_context, kret,
+diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
+index 5d9f80e04..ca3d32d21 100755
+--- a/src/tests/gssapi/t_enctypes.py
++++ b/src/tests/gssapi/t_enctypes.py
+@@ -9,8 +9,11 @@ from k5test import *
+ aes256 = 'aes256-cts-hmac-sha1-96'
+ aes128 = 'aes128-cts-hmac-sha1-96'
+ des3 = 'des3-cbc-sha1'
++d_des3 = 'DEPRECATED:des3-cbc-sha1'
+ des3raw = 'des3-cbc-raw'
++d_des3raw = 'DEPRECATED:des3-cbc-raw'
+ rc4 = 'arcfour-hmac'
++d_rc4 = 'DEPRECATED:arcfour-hmac'
+ 
+ # These tests make assumptions about the default enctype lists, so set
+ # them explicitly rather than relying on the library defaults.
+@@ -92,7 +95,7 @@ test_err('acc aes128', None, 'aes128-cts',
+ # no acceptor subkey will be generated because we can't upgrade to a
+ # CFX enctype.
+ test('init des3', 'des3', None,
+-     tktenc=aes256, tktsession=des3,
++     tktenc=aes256, tktsession=d_des3,
+      proto='rfc1964', isubkey=des3raw, asubkey=None)
+ 
+ # Force the ticket session key to be rc4, so we can test some subkey
+@@ -103,7 +106,7 @@ realm.run([kadminl, 'setstr', realm.host_princ, 'session_enctypes', 'rc4'])
+ # [aes256 aes128 des3] and the acceptor should upgrade to an aes256
+ # subkey.
+ test('upgrade noargs', None, None,
+-     tktenc=aes256, tktsession=rc4,
++     tktenc=aes256, tktsession=d_rc4,
+      proto='cfx', isubkey=rc4, asubkey=aes256)
+ 
+ # If the initiator won't permit rc4 as a session key, it won't be able
+@@ -113,14 +116,14 @@ test_err('upgrade init aes', 'aes', None, 'no support for encryption type')
+ # If the initiator permits rc4 but prefers aes128, it will send an
+ # upgrade list of [aes128] and the acceptor will upgrade to aes128.
+ test('upgrade init aes128+rc4', 'aes128-cts rc4', None,
+-     tktenc=aes256, tktsession=rc4,
++     tktenc=aes256, tktsession=d_rc4,
+      proto='cfx', isubkey=rc4, asubkey=aes128)
+ 
+ # If the initiator permits rc4 but prefers des3, it will send an
+ # upgrade list of [des3], but the acceptor won't generate a subkey
+ # because des3 isn't a CFX enctype.
+ test('upgrade init des3+rc4', 'des3 rc4', None,
+-     tktenc=aes256, tktsession=rc4,
++     tktenc=aes256, tktsession=d_rc4,
+      proto='rfc1964', isubkey=rc4, asubkey=None)
+ 
+ # If the acceptor permits only aes128, subkey negotiation will fail
+@@ -134,14 +137,14 @@ test_err('upgrade acc aes128', None, 'aes128-cts',
+ # If the acceptor permits rc4 but prefers aes128, it will negotiate an
+ # upgrade to aes128.
+ test('upgrade acc aes128 rc4', None, 'aes128-cts rc4',
+-     tktenc=aes256, tktsession=rc4,
++     tktenc=aes256, tktsession=d_rc4,
+      proto='cfx', isubkey=rc4, asubkey=aes128)
+ 
+ # In this test, the initiator and acceptor each prefer an AES enctype
+ # to rc4, but they can't agree on which one, so no subkey is
+ # generated.
+ test('upgrade mismatch', 'aes128-cts rc4', 'aes256-cts rc4',
+-     tktenc=aes256, tktsession=rc4,
++     tktenc=aes256, tktsession=d_rc4,
+      proto='rfc1964', isubkey=rc4, asubkey=None)
+ 
+ success('gss_krb5_set_allowable_enctypes tests')
+diff --git a/src/tests/t_keyrollover.py b/src/tests/t_keyrollover.py
+index 7c8d828f0..4af6804f2 100755
+--- a/src/tests/t_keyrollover.py
++++ b/src/tests/t_keyrollover.py
+@@ -22,8 +22,9 @@ realm.run([kvno, princ1])
+ realm.run([kadminl, 'purgekeys', realm.krbtgt_princ])
+ # Make sure an old TGT fails after purging old TGS key.
+ realm.run([kvno, princ2], expected_code=1)
+-msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): des-cbc-crc, des-cbc-crc' % \
+-    (realm.realm, realm.realm)
++ddes = "DEPRECATED:des-cbc-crc"
++msg = 'krbtgt/%s@%s\n\tEtype (skey, tkt): %s, %s' % \
++    (realm.realm, realm.realm, ddes, ddes)
+ realm.run([klist, '-e'], expected_msg=msg)
+ 
+ # Check that new key actually works.
+@@ -48,7 +49,8 @@ realm.run([kadminl, 'cpw', '-randkey', '-keepold', '-e', 'aes256-cts',
+            realm.krbtgt_princ])
+ realm.run([kadminl, 'modprinc', '-kvno', '1', realm.krbtgt_princ])
+ out = realm.run([kadminl, 'getprinc', realm.krbtgt_princ])
+-if 'vno 1, aes256' not in out or 'vno 1, des3' not in out:
++if 'vno 1, aes256-cts' not in out or \
++   'vno 1, DEPRECATED:des3-cbc-sha1' not in out:
+     fail('keyrollover: setup for TGS enctype test failed')
+ # Now present the DES3 ticket to the KDC and make sure it's rejected.
+ realm.run([kvno, realm.host_princ], expected_code=1)
+diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
+index 448092387..da02f224a 100755
+--- a/src/tests/t_sesskeynego.py
++++ b/src/tests/t_sesskeynego.py
+@@ -62,11 +62,11 @@ test_kvno(realm, 'aes128-cts-hmac-sha1-96', 'aes256-cts-hmac-sha1-96')
+ # 3b: Negotiate rc4-hmac session key when principal only has aes256 long-term.
+ realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
+            'rc4-hmac,aes128-cts,aes256-cts'])
+-test_kvno(realm, 'arcfour-hmac', 'aes256-cts-hmac-sha1-96')
++test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
+ 
+ # 3c: Test des-cbc-crc default assumption.
+ realm.run([kadminl, 'delstr', 'server', 'session_enctypes'])
+-test_kvno(realm, 'des-cbc-crc', 'aes256-cts-hmac-sha1-96')
++test_kvno(realm, 'DEPRECATED:des-cbc-crc', 'aes256-cts-hmac-sha1-96')
+ realm.stop()
+ 
+ # Last go: test that we can disable the des-cbc-crc assumption
diff --git a/SOURCES/Properly-size-ifdef-in-k5_cccol_lock.patch b/SOURCES/Properly-size-ifdef-in-k5_cccol_lock.patch
new file mode 100644
index 0000000..b1e4563
--- /dev/null
+++ b/SOURCES/Properly-size-ifdef-in-k5_cccol_lock.patch
@@ -0,0 +1,34 @@
+From bad6d4390e6e23099cc2295d94e2553575687561 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Thu, 14 Feb 2019 11:50:35 -0500
+Subject: [PATCH] Properly size #ifdef in k5_cccol_lock()
+
+The cleanup code only could get executed in the USE_CCAPI_V3 case, so
+move it inside that block.  Reported by Coverity.
+
+(cherry picked from commit 444a15f9cf82b9a6c1bca3f20307f82fee91c228)
+(cherry picked from commit e2a0e04fb3be9297a8c532dd35a7c1045cae88f4)
+---
+ src/lib/krb5/ccache/ccbase.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/lib/krb5/ccache/ccbase.c b/src/lib/krb5/ccache/ccbase.c
+index 8198f2b9b..2702bef69 100644
+--- a/src/lib/krb5/ccache/ccbase.c
++++ b/src/lib/krb5/ccache/ccbase.c
+@@ -511,7 +511,6 @@ krb5_cccol_lock(krb5_context context)
+ #endif
+ #ifdef USE_CCAPI_V3
+     ret = krb5_stdccv3_context_lock(context);
+-#endif
+     if (ret) {
+         k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);
+         k5_cc_mutex_unlock(context, &krb5int_cc_file_mutex);
+@@ -519,6 +518,7 @@ krb5_cccol_lock(krb5_context context)
+         k5_cc_mutex_unlock(context, &cccol_lock);
+         return ret;
+     }
++#endif
+     k5_mutex_unlock(&cc_typelist_lock);
+     return ret;
+ }
diff --git a/SOURCES/Put-KDB-authdata-first.patch b/SOURCES/Put-KDB-authdata-first.patch
new file mode 100644
index 0000000..998fa0e
--- /dev/null
+++ b/SOURCES/Put-KDB-authdata-first.patch
@@ -0,0 +1,45 @@
+From 684821fc68fd27ddcc5f809a37819edd35365a9d Mon Sep 17 00:00:00 2001
+From: Isaac Boukris <iboukris@gmail.com>
+Date: Sat, 1 Feb 2020 16:13:30 +0100
+Subject: [PATCH] Put KDB authdata first
+
+Windows services, as well as some versions of Samba, may refuse
+tickets if the PAC is not in the first AD-IF-RELEVANT container.  In
+fetch_kdb_authdata(), change the merge order so that authdata from the
+KDB module appears first.
+
+[ghudson@mit.edu: added comment and clarified commit message]
+
+ticket: 8872 (new)
+tags: pullup
+target_version: 1.18
+target_version: 1.17-next
+
+(cherry picked from commit 331fa4bdd34263ea20667a0f51338cb84357fdaa)
+(cherry picked from commit 1678270de3fda699114122447b1f06b08fb4e53e)
+---
+ src/kdc/kdc_authdata.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
+index 1b067cb0b..616c3eadc 100644
+--- a/src/kdc/kdc_authdata.c
++++ b/src/kdc/kdc_authdata.c
+@@ -383,11 +383,14 @@ fetch_kdb_authdata(krb5_context context, unsigned int flags,
+     if (ret)
+         return (ret == KRB5_PLUGIN_OP_NOTSUPP) ? 0 : ret;
+ 
+-    /* Add the KDB authdata to the ticket, without copying or filtering. */
+-    ret = merge_authdata(context, db_authdata,
+-                         &enc_tkt_reply->authorization_data, FALSE, FALSE);
++    /* Put the KDB authdata first in the ticket.  A successful merge places the
++     * combined list in db_authdata and releases the old ticket authdata. */
++    ret = merge_authdata(context, enc_tkt_reply->authorization_data,
++                         &db_authdata, FALSE, FALSE);
+     if (ret)
+         krb5_free_authdata(context, db_authdata);
++    else
++        enc_tkt_reply->authorization_data = db_authdata;
+     return ret;
+ }
+ 
diff --git a/SOURCES/Use-backported-version-of-OpenSSL-3-KDF-interface.patch b/SOURCES/Use-backported-version-of-OpenSSL-3-KDF-interface.patch
new file mode 100644
index 0000000..b8d3916
--- /dev/null
+++ b/SOURCES/Use-backported-version-of-OpenSSL-3-KDF-interface.patch
@@ -0,0 +1,751 @@
+From 5e147f7f2924edfd278940dea8b1d8ed09d6872c Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Fri, 15 Nov 2019 20:05:16 +0000
+Subject: [PATCH] Use backported version of OpenSSL-3 KDF interface
+
+(cherry picked from commit 0e20daf7ccfe50518c89735c3dae2fde08d92325)
+---
+ src/configure.in                              |   4 +
+ src/lib/crypto/krb/derive.c                   | 356 +++++++++++++-----
+ .../preauth/pkinit/pkinit_crypto_openssl.c    | 257 ++++++++-----
+ 3 files changed, 428 insertions(+), 189 deletions(-)
+
+diff --git a/src/configure.in b/src/configure.in
+index 9f6b67b44..cf4b1139a 100644
+--- a/src/configure.in
++++ b/src/configure.in
+@@ -269,6 +269,10 @@ AC_SUBST(CRYPTO_IMPL)
+ AC_SUBST(CRYPTO_IMPL_CFLAGS)
+ AC_SUBST(CRYPTO_IMPL_LIBS)
+ 
++AC_CHECK_FUNCS(EVP_KDF_CTX_new_id EVP_KDF_ctrl EVP_KDF_derive,
++               AC_DEFINE(OSSL_KDFS, 1, [Define if using OpenSSL KDFs]),
++               AC_MSG_ERROR([backported OpenSSL KDFs not found]))
++
+ AC_ARG_WITH([prng-alg],
+ AC_HELP_STRING([--with-prng-alg=ALG], [use specified PRNG algorithm. @<:@fortuna@:>@]),
+ [PRNG_ALG=$withval
+diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c
+index 6707a7308..915a173dd 100644
+--- a/src/lib/crypto/krb/derive.c
++++ b/src/lib/crypto/krb/derive.c
+@@ -27,6 +27,13 @@
+ 
+ #include "crypto_int.h"
+ 
++#ifdef OSSL_KDFS
++#include <openssl/evp.h>
++#include <openssl/kdf.h>
++#else
++#error "Refusing to build without OpenSSL KDFs!"
++#endif
++
+ static krb5_key
+ find_cached_dkey(struct derived_key *list, const krb5_data *constant)
+ {
+@@ -77,55 +84,193 @@ cleanup:
+     return ENOMEM;
+ }
+ 
++#ifdef OSSL_KDFS
+ static krb5_error_code
+-derive_random_rfc3961(const struct krb5_enc_provider *enc,
+-                      krb5_key inkey, krb5_data *outrnd,
+-                      const krb5_data *in_constant)
++openssl_kbdkf_counter_hmac(const struct krb5_hash_provider *hash,
++                           krb5_key inkey, krb5_data *outrnd,
++                           const krb5_data *label, const krb5_data *context)
+ {
+-    size_t blocksize, keybytes, n;
++    krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
++    EVP_KDF_CTX *ctx = NULL;
++    const EVP_MD *digest;
++
++    if (!strcmp(hash->hash_name, "SHA1"))
++        digest = EVP_sha1();
++    else if (!strcmp(hash->hash_name, "SHA-256"))
++        digest = EVP_sha256();
++    else if (!strcmp(hash->hash_name, "SHA-384"))
++        digest = EVP_sha384();
++    else
++        goto done;
++
++    ctx = EVP_KDF_CTX_new_id(EVP_KDF_KB);
++    if (!ctx)
++        goto done;
++
++    if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MAC_TYPE,
++                     EVP_KDF_KB_MAC_TYPE_HMAC) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
++                     inkey->keyblock.length) != 1 ||
++        (context->length > 0 &&
++         EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_INFO, context->data,
++                      context->length) != 1) ||
++        (label->length > 0 &&
++         EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SALT, label->data,
++                      label->length) != 1) ||
++        EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
++                       outrnd->length) != 1)
++        goto done;
++
++    ret = 0;
++done:
++    if (ret)
++        zap(outrnd->data, outrnd->length);
++    EVP_KDF_CTX_free(ctx);
++    return ret;
++}
++
++static krb5_error_code
++openssl_kbkdf_feedback_cmac(const struct krb5_enc_provider *enc,
++                            krb5_key inkey, krb5_data *outrnd,
++                            const krb5_data *in_constant)
++{
++    krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
++    EVP_KDF_CTX *ctx = NULL;
++    const EVP_CIPHER *cipher;
++    static unsigned char zeroes[16];
++
++    memset(zeroes, 0, sizeof(zeroes));
++
++    if (enc->keylength == 16)
++        cipher = EVP_camellia_128_cbc();
++    else if (enc->keylength == 32)
++        cipher = EVP_camellia_256_cbc();
++    else
++        goto done;
++
++    ctx = EVP_KDF_CTX_new_id(EVP_KDF_KB);
++    if (!ctx)
++        goto done;
++
++    if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MODE,
++                     EVP_KDF_KB_MODE_FEEDBACK) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MAC_TYPE,
++                     EVP_KDF_KB_MAC_TYPE_CMAC) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_CIPHER, cipher) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
++                     inkey->keyblock.length) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SALT, in_constant->data,
++                     in_constant->length) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_SEED, zeroes,
++                     sizeof(zeroes)) != 1 ||
++        EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
++                       outrnd->length) != 1)
++        goto done;
++
++    ret = 0;
++done:
++    if (ret)
++        zap(outrnd->data, outrnd->length);
++    EVP_KDF_CTX_free(ctx);
++    return ret;
++}
++
++static krb5_error_code
++openssl_krb5kdf(const struct krb5_enc_provider *enc, krb5_key inkey,
++                krb5_data *outrnd, const krb5_data *in_constant)
++{
++    krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
++    EVP_KDF_CTX *ctx = NULL;
++    const EVP_CIPHER *cipher;
++
++    if (inkey->keyblock.length != enc->keylength ||
++        outrnd->length != enc->keybytes) {
++        return KRB5_CRYPTO_INTERNAL;
++    }
++
++    if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 16)
++        cipher = EVP_aes_128_cbc();
++    else if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 32)
++        cipher = EVP_aes_256_cbc();
++    else if (enc->keylength == 24)
++        cipher = EVP_des_ede3_cbc();
++    else
++        goto done;
++
++    ctx = EVP_KDF_CTX_new_id(EVP_KDF_KRB5KDF);
++    if (ctx == NULL)
++        goto done;
++
++    if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_CIPHER, cipher) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
++                     inkey->keyblock.length) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KRB5KDF_CONSTANT,
++                     in_constant->data, in_constant->length) != 1 ||
++        EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
++                       outrnd->length) != 1)
++        goto done;
++
++    ret = 0;
++done:
++    if (ret)
++        zap(outrnd->data, outrnd->length);
++    EVP_KDF_CTX_free(ctx);
++    return ret;
++}
++
++#else /* OSSL_KDFS */
++
++/*
++ * NIST SP800-108 KDF in counter mode (section 5.1).
++ * Parameters:
++ *   - HMAC (with hash as the hash provider) is the PRF.
++ *   - A block counter of four bytes is used.
++ *   - Four bytes are used to encode the output length in the PRF input.
++ *
++ * There are no uses requiring more than a single PRF invocation.
++ */
++static krb5_error_code
++builtin_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
++                               krb5_key inkey, krb5_data *outrnd,
++                               const krb5_data *label,
++                               const krb5_data *context)
++{
++    krb5_crypto_iov iov[5];
+     krb5_error_code ret;
+-    krb5_data block = empty_data();
++    krb5_data prf;
++    unsigned char ibuf[4], lbuf[4];
+ 
+-    blocksize = enc->block_size;
+-    keybytes = enc->keybytes;
+-
+-    if (blocksize == 1)
+-        return KRB5_BAD_ENCTYPE;
+-    if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
++    if (hash == NULL || outrnd->length > hash->hashsize)
+         return KRB5_CRYPTO_INTERNAL;
+ 
+     /* Allocate encryption data buffer. */
+-    ret = alloc_data(&block, blocksize);
++    ret = alloc_data(&prf, hash->hashsize);
+     if (ret)
+         return ret;
+ 
+-    /* Initialize the input block. */
+-    if (in_constant->length == blocksize) {
+-        memcpy(block.data, in_constant->data, blocksize);
+-    } else {
+-        krb5int_nfold(in_constant->length * 8,
+-                      (unsigned char *) in_constant->data,
+-                      blocksize * 8, (unsigned char *) block.data);
+-    }
++    /* [i]2: four-byte big-endian binary string giving the block counter (1) */
++    iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
++    iov[0].data = make_data(ibuf, sizeof(ibuf));
++    store_32_be(1, ibuf);
++    /* Label */
++    iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
++    iov[1].data = *label;
++    /* 0x00: separator byte */
++    iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
++    iov[2].data = make_data("", 1);
++    /* Context */
++    iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
++    iov[3].data = *context;
++    /* [L]2: four-byte big-endian binary string giving the output length */
++    iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
++    iov[4].data = make_data(lbuf, sizeof(lbuf));
++    store_32_be(outrnd->length * 8, lbuf);
+ 
+-    /* Loop encrypting the blocks until enough key bytes are generated. */
+-    n = 0;
+-    while (n < keybytes) {
+-        ret = encrypt_block(enc, inkey, &block);
+-        if (ret)
+-            goto cleanup;
+-
+-        if ((keybytes - n) <= blocksize) {
+-            memcpy(outrnd->data + n, block.data, (keybytes - n));
+-            break;
+-        }
+-
+-        memcpy(outrnd->data + n, block.data, blocksize);
+-        n += blocksize;
+-    }
+-
+-cleanup:
+-    zapfree(block.data, blocksize);
++    ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
++    if (!ret)
++        memcpy(outrnd->data, prf.data, outrnd->length);
++    zapfree(prf.data, prf.length);
+     return ret;
+ }
+ 
+@@ -139,9 +284,9 @@ cleanup:
+  *   - Four bytes are used to encode the output length in the PRF input.
+  */
+ static krb5_error_code
+-derive_random_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
+-                                      krb5_key inkey, krb5_data *outrnd,
+-                                      const krb5_data *in_constant)
++builtin_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
++                                krb5_key inkey, krb5_data *outrnd,
++                                const krb5_data *in_constant)
+ {
+     size_t blocksize, keybytes, n;
+     krb5_crypto_iov iov[6];
+@@ -204,56 +349,94 @@ cleanup:
+     return ret;
+ }
+ 
+-/*
+- * NIST SP800-108 KDF in counter mode (section 5.1).
+- * Parameters:
+- *   - HMAC (with hash as the hash provider) is the PRF.
+- *   - A block counter of four bytes is used.
+- *   - Four bytes are used to encode the output length in the PRF input.
+- *
+- * There are no uses requiring more than a single PRF invocation.
+- */
++static krb5_error_code
++builtin_derive_random_rfc3961(const struct krb5_enc_provider *enc,
++                              krb5_key inkey, krb5_data *outrnd,
++                              const krb5_data *in_constant)
++{
++    size_t blocksize, keybytes, n;
++    krb5_error_code ret;
++    krb5_data block = empty_data();
++
++    blocksize = enc->block_size;
++    keybytes = enc->keybytes;
++
++    if (blocksize == 1)
++        return KRB5_BAD_ENCTYPE;
++    if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
++        return KRB5_CRYPTO_INTERNAL;
++
++    /* Allocate encryption data buffer. */
++    ret = alloc_data(&block, blocksize);
++    if (ret)
++        return ret;
++
++    /* Initialize the input block. */
++    if (in_constant->length == blocksize) {
++        memcpy(block.data, in_constant->data, blocksize);
++    } else {
++        krb5int_nfold(in_constant->length * 8,
++                      (unsigned char *) in_constant->data,
++                      blocksize * 8, (unsigned char *) block.data);
++    }
++
++    /* Loop encrypting the blocks until enough key bytes are generated. */
++    n = 0;
++    while (n < keybytes) {
++        ret = encrypt_block(enc, inkey, &block);
++        if (ret)
++            goto cleanup;
++
++        if ((keybytes - n) <= blocksize) {
++            memcpy(outrnd->data + n, block.data, (keybytes - n));
++            break;
++        }
++
++        memcpy(outrnd->data + n, block.data, blocksize);
++        n += blocksize;
++    }
++
++cleanup:
++    zapfree(block.data, blocksize);
++    return ret;
++}
++#endif /* OSSL_KDFS */
++
+ krb5_error_code
+ k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
+                           krb5_key inkey, krb5_data *outrnd,
+                           const krb5_data *label, const krb5_data *context)
+ {
+-    krb5_crypto_iov iov[5];
+-    krb5_error_code ret;
+-    krb5_data prf;
+-    unsigned char ibuf[4], lbuf[4];
++#ifdef OSSL_KDFS
++    return openssl_kbdkf_counter_hmac(hash, inkey, outrnd, label, context);
++#else
++    return builtin_sp800_108_counter_hmac(hash, inkey, outrnd, label,
++                                          context);
++#endif
++}
+ 
+-    if (hash == NULL || outrnd->length > hash->hashsize)
+-        return KRB5_CRYPTO_INTERNAL;
++static krb5_error_code
++k5_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
++                           krb5_key inkey, krb5_data *outrnd,
++                           const krb5_data *in_constant)
++{
++#ifdef OSSL_KDFS
++    return openssl_kbkdf_feedback_cmac(enc, inkey, outrnd, in_constant);
++#else
++    return builtin_sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
++#endif
++}
+ 
+-    /* Allocate encryption data buffer. */
+-    ret = alloc_data(&prf, hash->hashsize);
+-    if (ret)
+-        return ret;
+-
+-    /* [i]2: four-byte big-endian binary string giving the block counter (1) */
+-    iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
+-    iov[0].data = make_data(ibuf, sizeof(ibuf));
+-    store_32_be(1, ibuf);
+-    /* Label */
+-    iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
+-    iov[1].data = *label;
+-    /* 0x00: separator byte */
+-    iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
+-    iov[2].data = make_data("", 1);
+-    /* Context */
+-    iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
+-    iov[3].data = *context;
+-    /* [L]2: four-byte big-endian binary string giving the output length */
+-    iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
+-    iov[4].data = make_data(lbuf, sizeof(lbuf));
+-    store_32_be(outrnd->length * 8, lbuf);
+-
+-    ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
+-    if (!ret)
+-        memcpy(outrnd->data, prf.data, outrnd->length);
+-    zapfree(prf.data, prf.length);
+-    return ret;
++static krb5_error_code
++k5_derive_random_rfc3961(const struct krb5_enc_provider *enc,
++                         krb5_key inkey, krb5_data *outrnd,
++                         const krb5_data *in_constant)
++{
++#ifdef OSSL_KDFS
++    return openssl_krb5kdf(enc, inkey, outrnd, in_constant);
++#else
++    return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
++#endif
+ }
+ 
+ krb5_error_code
+@@ -266,10 +449,9 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
+ 
+     switch (alg) {
+     case DERIVE_RFC3961:
+-        return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
++        return k5_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
+     case DERIVE_SP800_108_CMAC:
+-        return derive_random_sp800_108_feedback_cmac(enc, inkey, outrnd,
+-                                                     in_constant);
++        return k5_sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
+     case DERIVE_SP800_108_HMAC:
+         return k5_sp800_108_counter_hmac(hash, inkey, outrnd, in_constant,
+                                          &empty);
+diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+index 5ff81d8cf..8d2c230c8 100644
+--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+@@ -38,6 +38,13 @@
+ #include <dirent.h>
+ #include <arpa/inet.h>
+ 
++#ifdef OSSL_KDFS
++#include <openssl/evp.h>
++#include <openssl/kdf.h>
++#else
++#error "Refusing to build without OpenSSL KDFs!"
++#endif
++
+ static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
+ static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
+ 
+@@ -2460,11 +2467,51 @@ pkinit_alg_values(krb5_context context,
+     }
+ } /* pkinit_alg_values() */
+ 
++#ifdef OSSL_KDFS
++static krb5_error_code
++openssl_sskdf(krb5_context context, size_t hash_bytes, krb5_data *key,
++              krb5_data *info, char *out, size_t out_len)
++{
++    krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
++    EVP_KDF_CTX *ctx = NULL;
++    const EVP_MD *digest;
+ 
+-/* pkinit_alg_agility_kdf() --
+- * This function generates a key using the KDF described in
+- * draft_ietf_krb_wg_pkinit_alg_agility-04.txt.  The algorithm is
+- * described as follows:
++    /* RFC 8636 defines a SHA384 variant, but we don't use it. */
++    if (hash_bytes == 20) {
++        digest = EVP_sha1();
++    } else if (hash_bytes == 32) {
++        digest = EVP_sha256();
++    } else if (hash_bytes == 64) {
++        digest = EVP_sha512();
++    } else {
++        krb5_set_error_message(context, ret, "Bad hash type for SSKDF");
++        goto done;
++    }
++
++    ctx = EVP_KDF_CTX_new_id(EVP_KDF_SS);
++    if (!ctx) {
++        oerr(context, ret, _("Failed to instantiate SSKDF"));
++        goto done;
++    }
++
++    if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, key->data,
++                     key->length) != 1 ||
++        EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSKDF_INFO, info->data,
++                     info->length) != 1 ||
++        EVP_KDF_derive(ctx, (unsigned char *)out, out_len) != 1)
++        goto done;
++
++    ret = 0;
++done:
++    EVP_KDF_CTX_free(ctx);
++    return ret;
++}
++#else
++/*
++ * Generate a key using the KDF described in RFC 8636, also known as SSKDF
++ * (single-step kdf).  Our caller precomputes `reps`, but otherwise the
++ * algorithm is as follows:
+  *
+  *     1.  reps = keydatalen (K) / hash length (H)
+  *
+@@ -2478,95 +2525,16 @@ pkinit_alg_values(krb5_context context,
+  *
+  *     4.  Set key = Hash1 || Hash2 || ... so that length of key is K bytes.
+  */
+-krb5_error_code
+-pkinit_alg_agility_kdf(krb5_context context,
+-                       krb5_data *secret,
+-                       krb5_data *alg_oid,
+-                       krb5_const_principal party_u_info,
+-                       krb5_const_principal party_v_info,
+-                       krb5_enctype enctype,
+-                       krb5_data *as_req,
+-                       krb5_data *pk_as_rep,
+-                       krb5_keyblock *key_block)
++static krb5_error_code
++builtin_sskdf(krb5_context context, unsigned int reps, size_t hash_len,
++              const EVP_MD *(*EVP_func)(void), krb5_data *secret,
++              krb5_data *other_info, char *out, size_t out_len)
+ {
+     krb5_error_code retval = 0;
+ 
+-    unsigned int reps = 0;
+-    uint32_t counter = 1;       /* Does this type work on Windows? */
++    uint32_t counter = 1;
+     size_t offset = 0;
+-    size_t hash_len = 0;
+-    size_t rand_len = 0;
+-    size_t key_len = 0;
+-    krb5_data random_data;
+-    krb5_sp80056a_other_info other_info_fields;
+-    krb5_pkinit_supp_pub_info supp_pub_info_fields;
+-    krb5_data *other_info = NULL;
+-    krb5_data *supp_pub_info = NULL;
+-    krb5_algorithm_identifier alg_id;
+     EVP_MD_CTX *ctx = NULL;
+-    const EVP_MD *(*EVP_func)(void);
+-
+-    /* initialize random_data here to make clean-up safe */
+-    random_data.length = 0;
+-    random_data.data = NULL;
+-
+-    /* allocate and initialize the key block */
+-    key_block->magic = 0;
+-    key_block->enctype = enctype;
+-    if (0 != (retval = krb5_c_keylengths(context, enctype, &rand_len,
+-                                         &key_len)))
+-        goto cleanup;
+-
+-    random_data.length = rand_len;
+-    key_block->length = key_len;
+-
+-    if (NULL == (key_block->contents = malloc(key_block->length))) {
+-        retval = ENOMEM;
+-        goto cleanup;
+-    }
+-
+-    memset (key_block->contents, 0, key_block->length);
+-
+-    /* If this is anonymous pkinit, use the anonymous principle for party_u_info */
+-    if (party_u_info && krb5_principal_compare_any_realm(context, party_u_info,
+-                                                         krb5_anonymous_principal()))
+-        party_u_info = (krb5_principal)krb5_anonymous_principal();
+-
+-    if (0 != (retval = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func)))
+-        goto cleanup;
+-
+-    /* 1.  reps = keydatalen (K) / hash length (H) */
+-    reps = key_block->length/hash_len;
+-
+-    /* ... and round up, if necessary */
+-    if (key_block->length > (reps * hash_len))
+-        reps++;
+-
+-    /* Allocate enough space in the random data buffer to hash directly into
+-     * it, even if the last hash will make it bigger than the key length. */
+-    if (NULL == (random_data.data = malloc(reps * hash_len))) {
+-        retval = ENOMEM;
+-        goto cleanup;
+-    }
+-
+-    /* Encode the ASN.1 octet string for "SuppPubInfo" */
+-    supp_pub_info_fields.enctype = enctype;
+-    supp_pub_info_fields.as_req = *as_req;
+-    supp_pub_info_fields.pk_as_rep = *pk_as_rep;
+-    if (0 != ((retval = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
+-                                                         &supp_pub_info))))
+-        goto cleanup;
+-
+-    /* Now encode the ASN.1 octet string for "OtherInfo" */
+-    memset(&alg_id, 0, sizeof alg_id);
+-    alg_id.algorithm = *alg_oid; /*alias*/
+-
+-    other_info_fields.algorithm_identifier = alg_id;
+-    other_info_fields.party_u_info = (krb5_principal) party_u_info;
+-    other_info_fields.party_v_info = (krb5_principal) party_v_info;
+-    other_info_fields.supp_pub_info = *supp_pub_info;
+-    if (0 != (retval = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info)))
+-        goto cleanup;
+ 
+     /* 2.  Initialize a 32-bit, big-endian bit string counter as 1.
+      * 3.  For i = 1 to reps by 1, do the following:
+@@ -2600,8 +2568,9 @@ pkinit_alg_agility_kdf(krb5_context context,
+             goto cleanup;
+         }
+ 
+-        /* 4.  Set key = Hash1 || Hash2 || ... so that length of key is K bytes. */
+-        if (!EVP_DigestFinal(ctx, (uint8_t *)random_data.data + offset, &s)) {
++        /* 4.  Set key = Hash1 || Hash2 || ... so that length of key is K
++         * bytes. */
++        if (!EVP_DigestFinal(ctx, (unsigned char *)out + offset, &s)) {
+             krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL,
+                                    "Call to OpenSSL EVP_DigestUpdate() returned an error.");
+             retval = KRB5_CRYPTO_INTERNAL;
+@@ -2613,26 +2582,110 @@ pkinit_alg_agility_kdf(krb5_context context,
+         EVP_MD_CTX_free(ctx);
+         ctx = NULL;
+     }
+-
+-    retval = krb5_c_random_to_key(context, enctype, &random_data,
+-                                  key_block);
+-
+ cleanup:
+     EVP_MD_CTX_free(ctx);
++    return retval;
++} /* builtin_sskdf() */
++#endif /* OSSL_KDFS */
+ 
+-    /* If this has been an error, free the allocated key_block, if any */
+-    if (retval) {
+-        krb5_free_keyblock_contents(context, key_block);
++/* id-pkinit-kdf family, as specified by RFC 8636. */
++krb5_error_code
++pkinit_alg_agility_kdf(krb5_context context, krb5_data *secret,
++                       krb5_data *alg_oid, krb5_const_principal party_u_info,
++                       krb5_const_principal party_v_info,
++                       krb5_enctype enctype, krb5_data *as_req,
++                       krb5_data *pk_as_rep, krb5_keyblock *key_block)
++{
++    krb5_error_code retval;
++    size_t hash_len = 0, rand_len = 0, key_len = 0;
++    const EVP_MD *(*EVP_func)(void);
++    krb5_sp80056a_other_info other_info_fields;
++    krb5_pkinit_supp_pub_info supp_pub_info_fields;
++    krb5_data *other_info = NULL, *supp_pub_info = NULL;
++    krb5_data random_data = empty_data();
++    krb5_algorithm_identifier alg_id;
++    unsigned int reps;
++
++    /* Allocate and initialize the key block. */
++    key_block->magic = 0;
++    key_block->enctype = enctype;
++
++    /* Use separate variables to avoid alignment restriction problems. */
++    retval = krb5_c_keylengths(context, enctype, &rand_len, &key_len);
++    if (retval)
++        goto cleanup;
++    random_data.length = rand_len;
++    key_block->length = key_len;
++
++    key_block->contents = k5calloc(key_block->length, 1, &retval);
++    if (key_block->contents == NULL)
++        goto cleanup;
++
++    /* If this is anonymous pkinit, use the anonymous principle for
++     * party_u_info. */
++    if (party_u_info &&
++        krb5_principal_compare_any_realm(context, party_u_info,
++                                         krb5_anonymous_principal())) {
++        party_u_info = (krb5_principal)krb5_anonymous_principal();
+     }
+ 
+-    /* free other allocated resources, either way */
+-    if (random_data.data)
+-        free(random_data.data);
++    retval = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func);
++    if (retval)
++        goto cleanup;
++
++    /* 1.  reps = keydatalen (K) / hash length (H) */
++    reps = key_block->length / hash_len;
++
++    /* ... and round up, if necessary. */
++    if (key_block->length > (reps * hash_len))
++        reps++;
++
++    /* Allocate enough space in the random data buffer to hash directly into
++     * it, even if the last hash will make it bigger than the key length. */
++    random_data.data = k5alloc(reps * hash_len, &retval);
++    if (random_data.data == NULL)
++        goto cleanup;
++
++    /* Encode the ASN.1 octet string for "SuppPubInfo". */
++    supp_pub_info_fields.enctype = enctype;
++    supp_pub_info_fields.as_req = *as_req;
++    supp_pub_info_fields.pk_as_rep = *pk_as_rep;
++    retval = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
++                                              &supp_pub_info);
++    if (retval)
++        goto cleanup;
++
++    /* Now encode the ASN.1 octet string for "OtherInfo". */
++    memset(&alg_id, 0, sizeof(alg_id));
++    alg_id.algorithm = *alg_oid;
++    other_info_fields.algorithm_identifier = alg_id;
++    other_info_fields.party_u_info = (krb5_principal)party_u_info;
++    other_info_fields.party_v_info = (krb5_principal)party_v_info;
++    other_info_fields.supp_pub_info = *supp_pub_info;
++    retval = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info);
++    if (retval)
++        goto cleanup;
++
++#ifdef OSSL_KDFS
++    retval = openssl_sskdf(context, hash_len, secret, other_info,
++                           random_data.data, key_block->length);
++#else
++    retval = builtin_sskdf(context, reps, hash_len, EVP_func, secret,
++                           other_info, random_data.data, key_block->length);
++#endif
++    if (retval)
++        goto cleanup;
++
++    retval = krb5_c_random_to_key(context, enctype, &random_data, key_block);
++cleanup:
++    if (retval)
++        krb5_free_keyblock_contents(context, key_block);
++
++    zapfree(random_data.data, random_data.length);
+     krb5_free_data(context, other_info);
+     krb5_free_data(context, supp_pub_info);
+-
+     return retval;
+-} /*pkinit_alg_agility_kdf() */
++}
+ 
+ /* Call DH_compute_key() and ensure that we left-pad short results instead of
+  * leaving junk bytes at the end of the buffer. */
diff --git a/SOURCES/Use-imported-soft-pkcs11-for-tests.patch b/SOURCES/Use-imported-soft-pkcs11-for-tests.patch
new file mode 100644
index 0000000..0be2d97
--- /dev/null
+++ b/SOURCES/Use-imported-soft-pkcs11-for-tests.patch
@@ -0,0 +1,472 @@
+From 43f5837eecd5022c525efcfb3605af16958dc59a Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Thu, 20 Jun 2019 13:41:57 -0400
+Subject: [PATCH] Use imported soft-pkcs11 for tests
+
+Update the soft-pkcs11 code for OpenSSL 1.1, fix some warnings,
+integrate it into the build system, and use it for the PKINIT tests.
+
+(cherry picked from commit e5ef7b69765353ea62ad8712a229ed4e90a8fe17)
+(cherry picked from commit 47e66724b9d5cfef84965d99c83d29e4739932e3)
+---
+ src/configure.in                        |   1 +
+ src/tests/Makefile.in                   |   2 +-
+ src/tests/softpkcs11/Makefile.in        |  21 ++++
+ src/tests/softpkcs11/deps               |   6 ++
+ src/tests/softpkcs11/main.c             | 124 +++++++++++++++++-------
+ src/tests/softpkcs11/softpkcs11.exports |  39 ++++++++
+ src/tests/t_pkinit.py                   |  18 +---
+ 7 files changed, 162 insertions(+), 49 deletions(-)
+ create mode 100644 src/tests/softpkcs11/Makefile.in
+ create mode 100644 src/tests/softpkcs11/deps
+ create mode 100644 src/tests/softpkcs11/softpkcs11.exports
+
+diff --git a/src/configure.in b/src/configure.in
+index 93aec682e..9f6b67b44 100644
+--- a/src/configure.in
++++ b/src/configure.in
+@@ -1086,6 +1086,7 @@ int i = 1;
+ fi
+ if test "$k5_cv_openssl_version_okay" = yes && (test "$enable_pkinit" = yes || test "$enable_pkinit" = try); then
+   K5_GEN_MAKEFILE(plugins/preauth/pkinit)
++  K5_GEN_MAKEFILE(tests/softpkcs11)
+   PKINIT=yes
+   AC_CHECK_LIB(crypto, CMS_get0_content, [AC_DEFINE([HAVE_OPENSSL_CMS], 1, [Define if OpenSSL supports cms.])])
+ elif test "$k5_cv_openssl_version_okay" = no && test "$enable_pkinit" = yes; then
+diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
+index e27617ee2..ab958eb4c 100644
+--- a/src/tests/Makefile.in
++++ b/src/tests/Makefile.in
+@@ -1,7 +1,7 @@
+ mydir=tests
+ BUILDTOP=$(REL)..
+ SUBDIRS = resolve asn.1 create hammer verify gssapi dejagnu shlib \
+-	gss-threads misc threads
++	gss-threads misc threads softpkcs11
+ 
+ RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \
+ 	LC_ALL=C $(VALGRIND)
+diff --git a/src/tests/softpkcs11/Makefile.in b/src/tests/softpkcs11/Makefile.in
+new file mode 100644
+index 000000000..e89678154
+--- /dev/null
++++ b/src/tests/softpkcs11/Makefile.in
+@@ -0,0 +1,21 @@
++mydir=tests$(S)softpkcs11
++BUILDTOP=$(REL)..$(S)..
++
++LOCALINCLUDES = -I$(top_srcdir)/plugins/preauth/pkinit
++
++LIBBASE=softpkcs11
++LIBMAJOR=0
++LIBMINOR=0
++
++SHLIB_EXPLIBS=$(SUPPORT_LIB) -lcrypto
++SHLIB_EXPDEPS=$(SUPPORT_DEPLIB)
++
++STLIBOBJS=main.o
++
++SRCS=$(srcdir)/main.c
++
++all-unix: all-libs
++clean-unix:: clean-libs clean-libobjs
++
++@libnover_frag@
++@libobj_frag@
+diff --git a/src/tests/softpkcs11/deps b/src/tests/softpkcs11/deps
+new file mode 100644
+index 000000000..1e82d9572
+--- /dev/null
++++ b/src/tests/softpkcs11/deps
+@@ -0,0 +1,6 @@
++#
++# Generated makefile dependencies follow.
++#
++main.so main.po $(OUTPRE)main.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
++  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
++  $(top_srcdir)/plugins/preauth/pkinit/pkcs11.h main.c
+diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
+index 2acec5169..5255323d3 100644
+--- a/src/tests/softpkcs11/main.c
++++ b/src/tests/softpkcs11/main.c
+@@ -1,3 +1,4 @@
++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+ /*
+  * Copyright (c) 2004-2006, Stockholms universitet
+  * (Stockholm University, Stockholm Sweden)
+@@ -31,7 +32,57 @@
+  * POSSIBILITY OF SUCH DAMAGE.
+  */
+ 
+-#include "locl.h"
++#include "k5-platform.h"
++
++#include <openssl/err.h>
++#include <openssl/evp.h>
++#include <openssl/pem.h>
++#include <openssl/rand.h>
++#include <openssl/x509.h>
++
++#include <ctype.h>
++#include <pwd.h>
++
++#include <pkcs11.h>
++
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#define EVP_PKEY_get0_RSA(key) ((key)->pkey.rsa)
++#define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay
++#define RSA_get0_key compat_rsa_get0_key
++static void
++compat_rsa_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e,
++                    const BIGNUM **d)
++{
++    if (n != NULL)
++        *n = rsa->n;
++    if (e != NULL)
++        *e = rsa->e;
++    if (d != NULL)
++        *d = rsa->d;
++}
++#endif
++
++#define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R)      \
++    {                                                   \
++        unsigned char *p;                               \
++        (BL) = i2d_##T((S), NULL);                      \
++        if ((BL) <= 0) {                                \
++            (R) = EINVAL;                               \
++        } else {                                        \
++            (B) = malloc((BL));                         \
++            if ((B) == NULL) {                          \
++                (R) = ENOMEM;                           \
++            } else {                                    \
++                p = (B);                                \
++                (R) = 0;                                \
++                (BL) = i2d_##T((S), &p);                \
++                if ((BL) <= 0) {                        \
++                    free((B));                          \
++                    (R) = EINVAL;                       \
++                }                                       \
++            }                                           \
++        }                                               \
++    }
+ 
+ /* RCSID("$Id: main.c,v 1.24 2006/01/11 12:42:53 lha Exp $"); */
+ 
+@@ -124,7 +175,7 @@ st_logf(const char *fmt, ...)
+ }
+ 
+ static void
+-snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...)
++snprintf_fill(char *str, int size, char fillchar, const char *fmt, ...)
+ {
+     int len;
+     va_list ap;
+@@ -141,19 +192,19 @@ snprintf_fill(char *str, size_t size, char fillchar, const char *fmt, ...)
+ #endif
+ 
+ #define VERIFY_SESSION_HANDLE(s, state)                 \
+-{                                                       \
+-    CK_RV ret;                                          \
+-    ret = verify_session_handle(s, state);              \
+-    if (ret != CKR_OK) {                                \
+-        /* return CKR_OK */;                            \
+-    }                                                   \
+-}
++    {                                                   \
++        CK_RV vshret;                                   \
++        vshret = verify_session_handle(s, state);       \
++        if (vshret != CKR_OK) {                         \
++            /* return CKR_OK */;                        \
++        }                                               \
++    }
+ 
+ static CK_RV
+ verify_session_handle(CK_SESSION_HANDLE hSession,
+                       struct session_state **state)
+ {
+-    int i;
++    size_t i;
+ 
+     for (i = 0; i < MAX_NUM_SESSION; i++){
+         if (soft_token.state[i].session_handle == hSession)
+@@ -361,16 +412,20 @@ add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
+         CK_ULONG modulus_bits = 0;
+         CK_BYTE *exponent = NULL;
+         size_t exponent_len = 0;
++        RSA *rsa;
++        const BIGNUM *n, *e;
+ 
+-        modulus_bits = BN_num_bits(key->pkey.rsa->n);
++        rsa = EVP_PKEY_get0_RSA(key);
++        RSA_get0_key(rsa, &n, &e, NULL);
++        modulus_bits = BN_num_bits(n);
+ 
+-        modulus_len = BN_num_bytes(key->pkey.rsa->n);
++        modulus_len = BN_num_bytes(n);
+         modulus = malloc(modulus_len);
+-        BN_bn2bin(key->pkey.rsa->n, modulus);
++        BN_bn2bin(n, modulus);
+ 
+-        exponent_len = BN_num_bytes(key->pkey.rsa->e);
++        exponent_len = BN_num_bytes(e);
+         exponent = malloc(exponent_len);
+-        BN_bn2bin(key->pkey.rsa->e, exponent);
++        BN_bn2bin(e, exponent);
+ 
+         add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
+         add_object_attribute(o, 0, CKA_MODULUS_BITS,
+@@ -378,7 +433,7 @@ add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
+         add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
+                              exponent, exponent_len);
+ 
+-        RSA_set_method(key->pkey.rsa, RSA_PKCS1_SSLeay());
++        RSA_set_method(rsa, RSA_PKCS1_OpenSSL());
+ 
+         free(modulus);
+         free(exponent);
+@@ -474,7 +529,7 @@ add_certificate(char *label,
+     o->u.cert = cert;
+     public_key = X509_get_pubkey(o->u.cert);
+ 
+-    switch (EVP_PKEY_type(public_key->type)) {
++    switch (EVP_PKEY_base_id(public_key)) {
+     case EVP_PKEY_RSA:
+         key_type = CKK_RSA;
+         break;
+@@ -604,8 +659,8 @@ add_certificate(char *label,
+             /* XXX verify keytype */
+ 
+             if (key_type == CKK_RSA)
+-                RSA_set_method(o->u.private_key.key->pkey.rsa,
+-                               RSA_PKCS1_SSLeay());
++                RSA_set_method(EVP_PKEY_get0_RSA(o->u.private_key.key),
++                               RSA_PKCS1_OpenSSL());
+ 
+             if (X509_check_private_key(cert, o->u.private_key.key) != 1) {
+                 EVP_PKEY_free(o->u.private_key.key);
+@@ -755,8 +810,9 @@ CK_RV
+ C_Initialize(CK_VOID_PTR a)
+ {
+     CK_C_INITIALIZE_ARGS_PTR args = a;
++    size_t i;
++
+     st_logf("Initialize\n");
+-    int i;
+ 
+     OpenSSL_add_all_algorithms();
+     ERR_load_crypto_strings();
+@@ -825,7 +881,7 @@ C_Initialize(CK_VOID_PTR a)
+ CK_RV
+ C_Finalize(CK_VOID_PTR args)
+ {
+-    int i;
++    size_t i;
+ 
+     st_logf("Finalize\n");
+ 
+@@ -1008,7 +1064,7 @@ C_OpenSession(CK_SLOT_ID slotID,
+               CK_NOTIFY Notify,
+               CK_SESSION_HANDLE_PTR phSession)
+ {
+-    int i;
++    size_t i;
+ 
+     st_logf("OpenSession: slot: %d\n", (int)slotID);
+ 
+@@ -1050,7 +1106,7 @@ C_CloseSession(CK_SESSION_HANDLE hSession)
+ CK_RV
+ C_CloseAllSessions(CK_SLOT_ID slotID)
+ {
+-    int i;
++    size_t i;
+ 
+     st_logf("CloseAllSessions\n");
+ 
+@@ -1127,7 +1183,8 @@ C_Login(CK_SESSION_HANDLE hSession,
+         }
+ 
+         /* XXX check keytype */
+-        RSA_set_method(o->u.private_key.key->pkey.rsa, RSA_PKCS1_SSLeay());
++        RSA_set_method(EVP_PKEY_get0_RSA(o->u.private_key.key),
++                       RSA_PKCS1_OpenSSL());
+ 
+         if (X509_check_private_key(o->u.private_key.cert, o->u.private_key.key) != 1) {
+             EVP_PKEY_free(o->u.private_key.key);
+@@ -1226,7 +1283,6 @@ C_FindObjectsInit(CK_SESSION_HANDLE hSession,
+     }
+     if (ulCount) {
+         CK_ULONG i;
+-        size_t len;
+ 
+         print_attributes(pTemplate, ulCount);
+ 
+@@ -1415,7 +1471,7 @@ C_Encrypt(CK_SESSION_HANDLE hSession,
+         return CKR_ARGUMENTS_BAD;
+     }
+ 
+-    rsa = o->u.public_key->pkey.rsa;
++    rsa = EVP_PKEY_get0_RSA(o->u.public_key);
+ 
+     if (rsa == NULL)
+         return CKR_ARGUMENTS_BAD;
+@@ -1445,7 +1501,7 @@ C_Encrypt(CK_SESSION_HANDLE hSession,
+         goto out;
+     }
+ 
+-    if (buffer_len + padding_len < ulDataLen) {
++    if ((CK_ULONG)buffer_len + padding_len < ulDataLen) {
+         ret = CKR_ARGUMENTS_BAD;
+         goto out;
+     }
+@@ -1566,7 +1622,7 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
+         return CKR_ARGUMENTS_BAD;
+     }
+ 
+-    rsa = o->u.private_key.key->pkey.rsa;
++    rsa = EVP_PKEY_get0_RSA(o->u.private_key.key);
+ 
+     if (rsa == NULL)
+         return CKR_ARGUMENTS_BAD;
+@@ -1596,7 +1652,7 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
+         goto out;
+     }
+ 
+-    if (buffer_len + padding_len < ulEncryptedDataLen) {
++    if ((CK_ULONG)buffer_len + padding_len < ulEncryptedDataLen) {
+         ret = CKR_ARGUMENTS_BAD;
+         goto out;
+     }
+@@ -1725,7 +1781,7 @@ C_Sign(CK_SESSION_HANDLE hSession,
+         return CKR_ARGUMENTS_BAD;
+     }
+ 
+-    rsa = o->u.private_key.key->pkey.rsa;
++    rsa = EVP_PKEY_get0_RSA(o->u.private_key.key);
+ 
+     if (rsa == NULL)
+         return CKR_ARGUMENTS_BAD;
+@@ -1754,7 +1810,7 @@ C_Sign(CK_SESSION_HANDLE hSession,
+         goto out;
+     }
+ 
+-    if (buffer_len < ulDataLen + padding_len) {
++    if ((CK_ULONG)buffer_len < ulDataLen + padding_len) {
+         ret = CKR_ARGUMENTS_BAD;
+         goto out;
+     }
+@@ -1872,7 +1928,7 @@ C_Verify(CK_SESSION_HANDLE hSession,
+         return CKR_ARGUMENTS_BAD;
+     }
+ 
+-    rsa = o->u.public_key->pkey.rsa;
++    rsa = EVP_PKEY_get0_RSA(o->u.public_key);
+ 
+     if (rsa == NULL)
+         return CKR_ARGUMENTS_BAD;
+@@ -1900,7 +1956,7 @@ C_Verify(CK_SESSION_HANDLE hSession,
+         goto out;
+     }
+ 
+-    if (buffer_len < ulDataLen) {
++    if ((CK_ULONG)buffer_len < ulDataLen) {
+         ret = CKR_ARGUMENTS_BAD;
+         goto out;
+     }
+@@ -1926,7 +1982,7 @@ C_Verify(CK_SESSION_HANDLE hSession,
+     if (len > buffer_len)
+         abort();
+ 
+-    if (len != ulSignatureLen) {
++    if ((CK_ULONG)len != ulSignatureLen) {
+         ret = CKR_GENERAL_ERROR;
+         goto out;
+     }
+diff --git a/src/tests/softpkcs11/softpkcs11.exports b/src/tests/softpkcs11/softpkcs11.exports
+new file mode 100644
+index 000000000..aa7284511
+--- /dev/null
++++ b/src/tests/softpkcs11/softpkcs11.exports
+@@ -0,0 +1,39 @@
++C_CloseAllSessions
++C_CloseSession
++C_Decrypt
++C_DecryptFinal
++C_DecryptInit
++C_DecryptUpdate
++C_DigestInit
++C_Encrypt
++C_EncryptFinal
++C_EncryptInit
++C_EncryptUpdate
++C_Finalize
++C_FindObjects
++C_FindObjectsFinal
++C_FindObjectsInit
++C_GenerateRandom
++C_GetAttributeValue
++C_GetFunctionList
++C_GetInfo
++C_GetMechanismInfo
++C_GetMechanismList
++C_GetObjectSize
++C_GetSessionInfo
++C_GetSlotInfo
++C_GetSlotList
++C_GetTokenInfo
++C_Initialize
++C_InitToken
++C_Login
++C_Logout
++C_OpenSession
++C_Sign
++C_SignFinal
++C_SignInit
++C_SignUpdate
++C_Verify
++C_VerifyFinal
++C_VerifyInit
++C_VerifyUpdate
+diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
+index 1dadb1b96..384bf1426 100755
+--- a/src/tests/t_pkinit.py
++++ b/src/tests/t_pkinit.py
+@@ -4,14 +4,7 @@ from k5test import *
+ if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')):
+     skip_rest('PKINIT tests', 'PKINIT module not built')
+ 
+-# Check if soft-pkcs11.so is available.
+-try:
+-    import ctypes
+-    lib = ctypes.LibraryLoader(ctypes.CDLL).LoadLibrary('soft-pkcs11.so')
+-    del lib
+-    have_soft_pkcs11 = True
+-except:
+-    have_soft_pkcs11 = False
++soft_pkcs11 = os.path.join(buildtop, 'tests', 'softpkcs11', 'softpkcs11.so')
+ 
+ # Construct a krb5.conf fragment configuring pkinit.
+ certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs')
+@@ -69,9 +62,9 @@ p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12
+ p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12
+ p12_generic_identity = 'PKCS12:%s' % generic_p12
+ p12_enc_identity = 'PKCS12:%s' % user_enc_p12
+-p11_identity = 'PKCS11:soft-pkcs11.so'
+-p11_token_identity = ('PKCS11:module_name=soft-pkcs11.so:'
+-                      'slotid=1:token=SoftToken (token)')
++p11_identity = 'PKCS11:' + soft_pkcs11
++p11_token_identity = ('PKCS11:module_name=' + soft_pkcs11 +
++                      ':slotid=1:token=SoftToken (token)')
+ 
+ # Start a realm with the test kdb module for the following UPN SAN tests.
+ realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=alias_kdc_conf,
+@@ -398,9 +391,6 @@ realm.klist(realm.user_princ)
+ realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=,'],
+             expected_code=1, expected_msg='Preauthentication failed while')
+ 
+-if not have_soft_pkcs11:
+-    skip_rest('PKINIT PKCS11 tests', 'soft-pkcs11.so not found')
+-
+ softpkcs11rc = os.path.join(os.getcwd(), 'testdir', 'soft-pkcs11.rc')
+ realm.env['SOFTPKCS11RC'] = softpkcs11rc
+ 
diff --git a/SOURCES/kadm5.acl b/SOURCES/kadm5.acl
new file mode 100644
index 0000000..dc93eb0
--- /dev/null
+++ b/SOURCES/kadm5.acl
@@ -0,0 +1 @@
+*/admin@EXAMPLE.COM	*
diff --git a/SOURCES/kadmin.service b/SOURCES/kadmin.service
new file mode 100644
index 0000000..f1677c6
--- /dev/null
+++ b/SOURCES/kadmin.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Kerberos 5 Password-changing and Administration
+Wants=network-online.target
+After=syslog.target network.target network-online.target
+AssertPathExists=!/var/kerberos/krb5kdc/kpropd.acl
+
+[Service]
+Type=forking
+PIDFile=/var/run/kadmind.pid
+EnvironmentFile=-/etc/sysconfig/kadmin
+ExecStart=/usr/sbin/kadmind -P /var/run/kadmind.pid $KADMIND_ARGS
+ExecReload=/bin/kill -HUP $MAINPID
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/kadmin.sysconfig b/SOURCES/kadmin.sysconfig
new file mode 100644
index 0000000..fa72039
--- /dev/null
+++ b/SOURCES/kadmin.sysconfig
@@ -0,0 +1 @@
+KADMIND_ARGS=
diff --git a/SOURCES/kadmind.logrotate b/SOURCES/kadmind.logrotate
new file mode 100644
index 0000000..52a66c4
--- /dev/null
+++ b/SOURCES/kadmind.logrotate
@@ -0,0 +1,9 @@
+/var/log/kadmind.log {
+    missingok
+    notifempty
+    monthly
+    rotate 12
+    postrotate
+	/bin/kill -HUP `cat /var/run/kadmind.pid 2>/dev/null` 2> /dev/null || true
+    endscript
+}
diff --git a/SOURCES/kdc.conf b/SOURCES/kdc.conf
new file mode 100644
index 0000000..b2e5e9b
--- /dev/null
+++ b/SOURCES/kdc.conf
@@ -0,0 +1,13 @@
+[kdcdefaults]
+    kdc_ports = 88
+    kdc_tcp_ports = 88
+    spake_preauth_kdc_challenge = edwards25519
+
+[realms]
+EXAMPLE.COM = {
+     #master_key_type = aes256-cts
+     acl_file = /var/kerberos/krb5kdc/kadm5.acl
+     dict_file = /usr/share/dict/words
+     admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
+     supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal
+}
diff --git a/SOURCES/kprop.service b/SOURCES/kprop.service
new file mode 100644
index 0000000..7b5d4b9
--- /dev/null
+++ b/SOURCES/kprop.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Kerberos 5 Propagation
+Wants=network-online.target
+After=syslog.target network.target network-online.target
+AssertPathExists=/var/kerberos/krb5kdc/kpropd.acl
+
+[Service]
+Type=forking
+EnvironmentFile=-/etc/sysconfig/kprop
+ExecStart=/usr/sbin/kpropd $KPROPD_ARGS
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/kprop.sysconfig b/SOURCES/kprop.sysconfig
new file mode 100644
index 0000000..f43e8bb
--- /dev/null
+++ b/SOURCES/kprop.sysconfig
@@ -0,0 +1 @@
+KPROPD_ARGS=
diff --git a/SOURCES/krb5-1.11-kpasswdtest.patch b/SOURCES/krb5-1.11-kpasswdtest.patch
new file mode 100644
index 0000000..7da7384
--- /dev/null
+++ b/SOURCES/krb5-1.11-kpasswdtest.patch
@@ -0,0 +1,21 @@
+From 174fddfa0c7d0d5c0f12d1531bc791865b630596 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:52:01 -0400
+Subject: [PATCH] krb5-1.11-kpasswdtest.patch
+
+---
+ src/kadmin/testing/proto/krb5.conf.proto | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/kadmin/testing/proto/krb5.conf.proto b/src/kadmin/testing/proto/krb5.conf.proto
+index 00c442978..9c4bc1de7 100644
+--- a/src/kadmin/testing/proto/krb5.conf.proto
++++ b/src/kadmin/testing/proto/krb5.conf.proto
+@@ -9,6 +9,7 @@
+ 	__REALM__ = {
+ 		kdc = __KDCHOST__:1750
+ 		admin_server = __KDCHOST__:1751
++		kpasswd_server = __KDCHOST__:1752
+ 		database_module = foobar_db2_module_blah
+ 	}
+ 
diff --git a/SOURCES/krb5-1.11-run_user_0.patch b/SOURCES/krb5-1.11-run_user_0.patch
new file mode 100644
index 0000000..7a38d43
--- /dev/null
+++ b/SOURCES/krb5-1.11-run_user_0.patch
@@ -0,0 +1,44 @@
+From f19ee759c49fac6477ef77eb4a0be41118add1f5 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:49:57 -0400
+Subject: [PATCH] krb5-1.11-run_user_0.patch
+
+A hack: if we're looking at creating a ccache directory directly below
+the /run/user/0 directory, and /run/user/0 doesn't exist, try to create
+it, too.
+---
+ src/lib/krb5/ccache/cc_dir.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
+index 73f0fe62d..4850c0d07 100644
+--- a/src/lib/krb5/ccache/cc_dir.c
++++ b/src/lib/krb5/ccache/cc_dir.c
+@@ -61,6 +61,8 @@
+ 
+ #include <dirent.h>
+ 
++#define ROOT_SPECIAL_DCC_PARENT "/run/user/0"
++
+ extern const krb5_cc_ops krb5_dcc_ops;
+ extern const krb5_cc_ops krb5_fcc_ops;
+ 
+@@ -237,6 +239,18 @@ verify_dir(krb5_context context, const char *dirname)
+ 
+     if (stat(dirname, &st) < 0) {
+         if (errno == ENOENT) {
++            if (strncmp(dirname, ROOT_SPECIAL_DCC_PARENT "/",
++                        sizeof(ROOT_SPECIAL_DCC_PARENT)) == 0 &&
++                stat(ROOT_SPECIAL_DCC_PARENT, &st) < 0 &&
++                errno == ENOENT) {
++#ifdef USE_SELINUX
++                selabel = krb5int_push_fscreatecon_for(ROOT_SPECIAL_DCC_PARENT);
++#endif
++                status = mkdir(ROOT_SPECIAL_DCC_PARENT, S_IRWXU);
++#ifdef USE_SELINUX
++                krb5int_pop_fscreatecon(selabel);
++#endif
++            }
+ #ifdef USE_SELINUX
+             selabel = krb5int_push_fscreatecon_for(dirname);
+ #endif
diff --git a/SOURCES/krb5-1.12-api.patch b/SOURCES/krb5-1.12-api.patch
new file mode 100644
index 0000000..4e42414
--- /dev/null
+++ b/SOURCES/krb5-1.12-api.patch
@@ -0,0 +1,37 @@
+From 3bac1a71756c634fe6b8cb3858ee9df87b1a660d Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:47:00 -0400
+Subject: [PATCH] krb5-1.12-api.patch
+
+Reference docs don't define what happens if you call krb5_realm_compare() with
+malformed krb5_principal structures.  Define a behavior which keeps it from
+crashing if applications don't check ahead of time.
+---
+ src/lib/krb5/krb/princ_comp.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/lib/krb5/krb/princ_comp.c b/src/lib/krb5/krb/princ_comp.c
+index a6936107d..0ed78833b 100644
+--- a/src/lib/krb5/krb/princ_comp.c
++++ b/src/lib/krb5/krb/princ_comp.c
+@@ -36,6 +36,10 @@ realm_compare_flags(krb5_context context,
+     const krb5_data *realm1 = &princ1->realm;
+     const krb5_data *realm2 = &princ2->realm;
+ 
++    if (princ1 == NULL || princ2 == NULL)
++        return FALSE;
++    if (realm1 == NULL || realm2 == NULL)
++        return FALSE;
+     if (realm1->length != realm2->length)
+         return FALSE;
+     if (realm1->length == 0)
+@@ -88,6 +92,9 @@ krb5_principal_compare_flags(krb5_context context,
+     krb5_principal upn2 = NULL;
+     krb5_boolean ret = FALSE;
+ 
++    if (princ1 == NULL || princ2 == NULL)
++        return FALSE;
++
+     if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) {
+         /* Treat UPNs as if they were real principals */
+         if (princ1->type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
diff --git a/SOURCES/krb5-1.12-ksu-path.patch b/SOURCES/krb5-1.12-ksu-path.patch
new file mode 100644
index 0000000..25b805a
--- /dev/null
+++ b/SOURCES/krb5-1.12-ksu-path.patch
@@ -0,0 +1,22 @@
+From ef8aa0a18c2bd2f960942380202a5fa992e2c7b3 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:32:09 -0400
+Subject: [PATCH] krb5-1.12-ksu-path.patch
+
+Set the default PATH to the one set by login.
+---
+ src/clients/ksu/Makefile.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
+index 5755bb58a..9d58f29b5 100644
+--- a/src/clients/ksu/Makefile.in
++++ b/src/clients/ksu/Makefile.in
+@@ -1,6 +1,6 @@
+ mydir=clients$(S)ksu
+ BUILDTOP=$(REL)..$(S)..
+-DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"'
++DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"'
+ 
+ KSU_LIBS=@KSU_LIBS@
+ PAM_LIBS=@PAM_LIBS@
diff --git a/SOURCES/krb5-1.12-ktany.patch b/SOURCES/krb5-1.12-ktany.patch
new file mode 100644
index 0000000..26d36df
--- /dev/null
+++ b/SOURCES/krb5-1.12-ktany.patch
@@ -0,0 +1,366 @@
+From 2ca8d242b1cac8abdb35bf0068e5d78300e07c3c Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:33:53 -0400
+Subject: [PATCH] krb5-1.12-ktany.patch
+
+Adds an "ANY" keytab type which is a list of other keytab locations to search
+when searching for a specific entry.  When iterated through, it only presents
+the contents of the first keytab.
+---
+ src/lib/krb5/keytab/Makefile.in |   3 +
+ src/lib/krb5/keytab/kt_any.c    | 292 ++++++++++++++++++++++++++++++++
+ src/lib/krb5/keytab/ktbase.c    |   7 +-
+ 3 files changed, 301 insertions(+), 1 deletion(-)
+ create mode 100644 src/lib/krb5/keytab/kt_any.c
+
+diff --git a/src/lib/krb5/keytab/Makefile.in b/src/lib/krb5/keytab/Makefile.in
+index 2a8fceb00..ffd179fb2 100644
+--- a/src/lib/krb5/keytab/Makefile.in
++++ b/src/lib/krb5/keytab/Makefile.in
+@@ -12,6 +12,7 @@ STLIBOBJS= \
+ 	ktfr_entry.o	\
+ 	ktremove.o	\
+ 	ktfns.o		\
++	kt_any.o	\
+ 	kt_file.o	\
+ 	kt_memory.o	\
+ 	kt_srvtab.o	\
+@@ -24,6 +25,7 @@ OBJS=	\
+ 	$(OUTPRE)ktfr_entry.$(OBJEXT)	\
+ 	$(OUTPRE)ktremove.$(OBJEXT)	\
+ 	$(OUTPRE)ktfns.$(OBJEXT)	\
++	$(OUTPRE)kt_any.$(OBJEXT)	\
+ 	$(OUTPRE)kt_file.$(OBJEXT)	\
+ 	$(OUTPRE)kt_memory.$(OBJEXT)	\
+ 	$(OUTPRE)kt_srvtab.$(OBJEXT)	\
+@@ -36,6 +38,7 @@ SRCS=	\
+ 	$(srcdir)/ktfr_entry.c	\
+ 	$(srcdir)/ktremove.c	\
+ 	$(srcdir)/ktfns.c	\
++	$(srcdir)/kt_any.c	\
+ 	$(srcdir)/kt_file.c	\
+ 	$(srcdir)/kt_memory.c	\
+ 	$(srcdir)/kt_srvtab.c	\
+diff --git a/src/lib/krb5/keytab/kt_any.c b/src/lib/krb5/keytab/kt_any.c
+new file mode 100644
+index 000000000..1b9b7765b
+--- /dev/null
++++ b/src/lib/krb5/keytab/kt_any.c
+@@ -0,0 +1,292 @@
++/*
++ * lib/krb5/keytab/kt_any.c
++ *
++ * Copyright 1998, 1999 by the Massachusetts Institute of Technology.
++ * All Rights Reserved.
++ *
++ * Export of this software from the United States of America may
++ *   require a specific license from the United States Government.
++ *   It is the responsibility of any person or organization contemplating
++ *   export to obtain such a license before exporting.
++ * 
++ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
++ * distribute this software and its documentation for any purpose and
++ * without fee is hereby granted, provided that the above copyright
++ * notice appear in all copies and that both that copyright notice and
++ * this permission notice appear in supporting documentation, and that
++ * the name of M.I.T. not be used in advertising or publicity pertaining
++ * to distribution of the software without specific, written prior
++ * permission.  M.I.T. makes no representations about the suitability of
++ * this software for any purpose.  It is provided "as is" without express
++ * or implied warranty.
++ * 
++ *
++ * krb5_kta_ops
++ */
++
++#include "k5-int.h"
++
++typedef struct _krb5_ktany_data {
++    char *name;
++    krb5_keytab *choices;
++    int nchoices;
++} krb5_ktany_data;
++
++typedef struct _krb5_ktany_cursor_data {
++    int which;
++    krb5_kt_cursor cursor;
++} krb5_ktany_cursor_data;
++
++static krb5_error_code krb5_ktany_resolve
++	          (krb5_context,
++		   const char *,
++		   krb5_keytab *);
++static krb5_error_code krb5_ktany_get_name
++	          (krb5_context context,
++		   krb5_keytab id,
++		   char *name,
++		   unsigned int len);
++static krb5_error_code krb5_ktany_close
++	          (krb5_context context,
++		   krb5_keytab id);
++static krb5_error_code krb5_ktany_get_entry
++	          (krb5_context context,
++		   krb5_keytab id,
++		   krb5_const_principal principal,
++		   krb5_kvno kvno,
++		   krb5_enctype enctype,
++		   krb5_keytab_entry *entry);
++static krb5_error_code krb5_ktany_start_seq_get
++	          (krb5_context context,
++		   krb5_keytab id,
++		   krb5_kt_cursor *cursorp);
++static krb5_error_code krb5_ktany_next_entry
++	          (krb5_context context,
++		   krb5_keytab id,
++		   krb5_keytab_entry *entry,
++		   krb5_kt_cursor *cursor);
++static krb5_error_code krb5_ktany_end_seq_get
++	          (krb5_context context,
++		   krb5_keytab id,
++		   krb5_kt_cursor *cursor);
++static void cleanup
++	          (krb5_context context,
++		   krb5_ktany_data *data,
++		   int nchoices);
++
++struct _krb5_kt_ops krb5_kta_ops = {
++    0,
++    "ANY", 	/* Prefix -- this string should not appear anywhere else! */
++    krb5_ktany_resolve,
++    krb5_ktany_get_name,
++    krb5_ktany_close,
++    krb5_ktany_get_entry,
++    krb5_ktany_start_seq_get,
++    krb5_ktany_next_entry,
++    krb5_ktany_end_seq_get,
++    NULL,
++    NULL,
++    NULL,
++};
++
++static krb5_error_code
++krb5_ktany_resolve(context, name, id)
++    krb5_context context;
++    const char *name;
++    krb5_keytab *id;
++{
++    const char *p, *q;
++    char *copy;
++    krb5_error_code kerror;
++    krb5_ktany_data *data;
++    int i;
++
++    /* Allocate space for our data and remember a copy of the name. */
++    if ((data = (krb5_ktany_data *)malloc(sizeof(krb5_ktany_data))) == NULL)
++	return(ENOMEM);
++    if ((data->name = (char *)malloc(strlen(name) + 1)) == NULL) {
++	free(data);
++	return(ENOMEM);
++    }
++    strcpy(data->name, name);
++
++    /* Count the number of choices and allocate memory for them. */
++    data->nchoices = 1;
++    for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1)
++	data->nchoices++;
++    if ((data->choices = (krb5_keytab *)
++	 malloc(data->nchoices * sizeof(krb5_keytab))) == NULL) {
++	free(data->name);
++	free(data);
++	return(ENOMEM);
++    }
++
++    /* Resolve each of the choices. */
++    i = 0;
++    for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) {
++	/* Make a copy of the choice name so we can terminate it. */
++	if ((copy = (char *)malloc(q - p + 1)) == NULL) {
++	    cleanup(context, data, i);
++	    return(ENOMEM);
++	}
++	memcpy(copy, p, q - p);
++	copy[q - p] = 0;
++
++	/* Try resolving the choice name. */
++	kerror = krb5_kt_resolve(context, copy, &data->choices[i]);
++	free(copy);
++	if (kerror) {
++	    cleanup(context, data, i);
++	    return(kerror);
++	}
++	i++;
++    }
++    if ((kerror = krb5_kt_resolve(context, p, &data->choices[i]))) {
++	cleanup(context, data, i);
++	return(kerror);
++    }
++
++    /* Allocate and fill in an ID for the caller. */
++    if ((*id = (krb5_keytab)malloc(sizeof(**id))) == NULL) {
++	cleanup(context, data, i);
++	return(ENOMEM);
++    }
++    (*id)->ops = &krb5_kta_ops;
++    (*id)->data = (krb5_pointer)data;
++    (*id)->magic = KV5M_KEYTAB;
++
++    return(0);
++}
++
++static krb5_error_code
++krb5_ktany_get_name(context, id, name, len)
++    krb5_context context;
++    krb5_keytab id;
++    char *name;
++    unsigned int len;
++{
++    krb5_ktany_data *data = (krb5_ktany_data *)id->data;
++
++    if (len < strlen(data->name) + 1)
++	return(KRB5_KT_NAME_TOOLONG);
++    strcpy(name, data->name);
++    return(0);
++}
++
++static krb5_error_code
++krb5_ktany_close(context, id)
++    krb5_context context;
++    krb5_keytab id;
++{
++    krb5_ktany_data *data = (krb5_ktany_data *)id->data;
++
++    cleanup(context, data, data->nchoices);
++    id->ops = 0;
++    free(id);
++    return(0);
++}
++
++static krb5_error_code
++krb5_ktany_get_entry(context, id, principal, kvno, enctype, entry)
++    krb5_context context;
++    krb5_keytab id;
++    krb5_const_principal principal;
++    krb5_kvno kvno;
++    krb5_enctype enctype;
++    krb5_keytab_entry *entry;
++{
++    krb5_ktany_data *data = (krb5_ktany_data *)id->data;
++    krb5_error_code kerror = KRB5_KT_NOTFOUND;
++    int i;
++
++    for (i = 0; i < data->nchoices; i++) {
++	if ((kerror = krb5_kt_get_entry(context, data->choices[i], principal,
++					kvno, enctype, entry)) != ENOENT)
++	    return kerror;
++    }
++    return kerror;
++}
++
++static krb5_error_code
++krb5_ktany_start_seq_get(context, id, cursorp)
++    krb5_context context;
++    krb5_keytab id;
++    krb5_kt_cursor *cursorp;
++{
++    krb5_ktany_data *data = (krb5_ktany_data *)id->data;
++    krb5_ktany_cursor_data *cdata;
++    krb5_error_code kerror = ENOENT;
++    int i;
++
++    if ((cdata = (krb5_ktany_cursor_data *)
++	 malloc(sizeof(krb5_ktany_cursor_data))) == NULL)
++	return(ENOMEM);
++
++    /* Find a choice which can handle the serialization request. */
++    for (i = 0; i < data->nchoices; i++) {
++	if ((kerror = krb5_kt_start_seq_get(context, data->choices[i],
++					    &cdata->cursor)) == 0)
++	    break;
++	else if (kerror != ENOENT) {
++	    free(cdata);
++	    return(kerror);
++	}
++    }
++
++    if (i == data->nchoices) {
++	/* Everyone returned ENOENT, so no go. */
++	free(cdata);
++	return(kerror);
++    }
++
++    cdata->which = i;
++    *cursorp = (krb5_kt_cursor)cdata;
++    return(0);
++}
++
++static krb5_error_code
++krb5_ktany_next_entry(context, id, entry, cursor)
++    krb5_context context;
++    krb5_keytab id;
++    krb5_keytab_entry *entry;
++    krb5_kt_cursor *cursor;
++{
++    krb5_ktany_data *data = (krb5_ktany_data *)id->data;
++    krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor;
++    krb5_keytab choice_id;
++
++    choice_id = data->choices[cdata->which];
++    return(krb5_kt_next_entry(context, choice_id, entry, &cdata->cursor));
++}
++
++static krb5_error_code
++krb5_ktany_end_seq_get(context, id, cursor)
++    krb5_context context;
++    krb5_keytab id;
++    krb5_kt_cursor *cursor;
++{
++    krb5_ktany_data *data = (krb5_ktany_data *)id->data;
++    krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor;
++    krb5_keytab choice_id;
++    krb5_error_code kerror;
++
++    choice_id = data->choices[cdata->which];
++    kerror = krb5_kt_end_seq_get(context, choice_id, &cdata->cursor);
++    free(cdata);
++    return(kerror);
++}
++
++static void
++cleanup(context, data, nchoices)
++    krb5_context context;
++    krb5_ktany_data *data;
++    int nchoices;
++{
++    int i;
++
++    free(data->name);
++    for (i = 0; i < nchoices; i++)
++	krb5_kt_close(context, data->choices[i]);
++    free(data->choices);
++    free(data);
++}
+diff --git a/src/lib/krb5/keytab/ktbase.c b/src/lib/krb5/keytab/ktbase.c
+index 0d39b2940..6534d7c52 100644
+--- a/src/lib/krb5/keytab/ktbase.c
++++ b/src/lib/krb5/keytab/ktbase.c
+@@ -57,14 +57,19 @@ extern const krb5_kt_ops krb5_ktf_ops;
+ extern const krb5_kt_ops krb5_ktf_writable_ops;
+ extern const krb5_kt_ops krb5_kts_ops;
+ extern const krb5_kt_ops krb5_mkt_ops;
++extern const krb5_kt_ops krb5_kta_ops;
+ 
+ struct krb5_kt_typelist {
+     const krb5_kt_ops *ops;
+     const struct krb5_kt_typelist *next;
+ };
++static struct krb5_kt_typelist krb5_kt_typelist_any = {
++    &krb5_kta_ops,
++    NULL
++};
+ const static struct krb5_kt_typelist krb5_kt_typelist_srvtab = {
+     &krb5_kts_ops,
+-    NULL
++    &krb5_kt_typelist_any
+ };
+ const static struct krb5_kt_typelist krb5_kt_typelist_memory = {
+     &krb5_mkt_ops,
diff --git a/SOURCES/krb5-1.12.1-pam.patch b/SOURCES/krb5-1.12.1-pam.patch
new file mode 100644
index 0000000..c5b5e78
--- /dev/null
+++ b/SOURCES/krb5-1.12.1-pam.patch
@@ -0,0 +1,770 @@
+From 02a10f4b9a8decc8d10f3e045282a0ae7ed1c00d Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:29:58 -0400
+Subject: [PATCH] krb5-1.12.1-pam.patch
+
+Modify ksu so that it performs account and session management on behalf of
+the target user account, mimicking the action of regular su.  The default
+service name is "ksu", because on Fedora at least the configuration used
+is determined by whether or not a login shell is being opened, and so
+this may need to vary, too.  At run-time, ksu's behavior can be reset to
+the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu]
+section of /etc/krb5.conf.
+
+When enabled, ksu gains a dependency on libpam.
+
+Originally RT#5939, though it's changed since then to perform the account
+and session management before dropping privileges, and to apply on top of
+changes we're proposing for how it handles cache collections.
+---
+ src/aclocal.m4              |  67 +++++++
+ src/clients/ksu/Makefile.in |   8 +-
+ src/clients/ksu/main.c      |  88 +++++++-
+ src/clients/ksu/pam.c       | 389 ++++++++++++++++++++++++++++++++++++
+ src/clients/ksu/pam.h       |  57 ++++++
+ src/configure.in            |   2 +
+ 6 files changed, 608 insertions(+), 3 deletions(-)
+ create mode 100644 src/clients/ksu/pam.c
+ create mode 100644 src/clients/ksu/pam.h
+
+diff --git a/src/aclocal.m4 b/src/aclocal.m4
+index 3752d9bd5..340546d80 100644
+--- a/src/aclocal.m4
++++ b/src/aclocal.m4
+@@ -1697,3 +1697,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[
+       ]))
+ ])dnl
+ dnl
++dnl
++dnl Use PAM instead of local crypt() compare for checking local passwords,
++dnl and perform PAM account, session management, and password-changing where
++dnl appropriate.
++dnl 
++AC_DEFUN(KRB5_WITH_PAM,[
++AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])],
++	    withpam="$withval",withpam=auto)
++AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])],
++	    withksupamservice="$withval",withksupamservice=ksu)
++old_LIBS="$LIBS"
++if test "$withpam" != no ; then
++	AC_MSG_RESULT([checking for PAM...])
++	PAM_LIBS=
++
++	AC_CHECK_HEADERS(security/pam_appl.h)
++	if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then
++		if test "$withpam" = auto ; then
++			AC_MSG_RESULT([Unable to locate security/pam_appl.h.])
++			withpam=no
++		else
++			AC_MSG_ERROR([Unable to locate security/pam_appl.h.])
++		fi
++	fi
++
++	LIBS=
++	unset ac_cv_func_pam_start
++	AC_CHECK_FUNCS(putenv pam_start)
++	if test "x$ac_cv_func_pam_start" = xno ; then
++		unset ac_cv_func_pam_start
++		AC_CHECK_LIB(dl,dlopen)
++		AC_CHECK_FUNCS(pam_start)
++		if test "x$ac_cv_func_pam_start" = xno ; then
++			AC_CHECK_LIB(pam,pam_start)
++			unset ac_cv_func_pam_start
++			unset ac_cv_func_pam_getenvlist
++			AC_CHECK_FUNCS(pam_start pam_getenvlist)
++			if test "x$ac_cv_func_pam_start" = xyes ; then
++				PAM_LIBS="$LIBS"
++			else
++				if test "$withpam" = auto ; then
++					AC_MSG_RESULT([Unable to locate libpam.])
++					withpam=no
++				else
++					AC_MSG_ERROR([Unable to locate libpam.])
++				fi
++			fi
++		fi
++	fi
++	if test "$withpam" != no ; then
++		AC_MSG_NOTICE([building with PAM support])
++		AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM])
++		AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice",
++				   [Define to the name of the PAM service name to be used by ksu.])
++		PAM_LIBS="$LIBS"
++		NON_PAM_MAN=".\\\" "
++		PAM_MAN=
++	else
++		PAM_MAN=".\\\" "
++		NON_PAM_MAN=
++	fi
++fi
++LIBS="$old_LIBS"
++AC_SUBST(PAM_LIBS)
++AC_SUBST(PAM_MAN)
++AC_SUBST(NON_PAM_MAN)
++])dnl
+diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
+index b2fcbf240..5755bb58a 100644
+--- a/src/clients/ksu/Makefile.in
++++ b/src/clients/ksu/Makefile.in
+@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S)..
+ DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"'
+ 
+ KSU_LIBS=@KSU_LIBS@
++PAM_LIBS=@PAM_LIBS@
+ 
+ SRCS = \
+ 	$(srcdir)/krb_auth_su.c \
+ 	$(srcdir)/ccache.c \
+ 	$(srcdir)/authorization.c \
+ 	$(srcdir)/main.c \
++	$(srcdir)/pam.c \
+ 	$(srcdir)/heuristic.c \
+ 	$(srcdir)/xmalloc.c \
+ 	$(srcdir)/setenv.c
+@@ -17,13 +19,17 @@ OBJS = \
+ 	ccache.o \
+ 	authorization.o \
+ 	main.o \
++	pam.o \
+ 	heuristic.o \
+ 	xmalloc.o @SETENVOBJ@
+ 
+ all: ksu
+ 
+ ksu: $(OBJS) $(KRB5_BASE_DEPLIBS)
+-	$(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS)
++	$(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS)
++
++pam.o: pam.c
++	$(CC) $(ALL_CFLAGS) -c $<
+ 
+ clean:
+ 	$(RM) ksu
+diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
+index d9596d948..ec06788bc 100644
+--- a/src/clients/ksu/main.c
++++ b/src/clients/ksu/main.c
+@@ -26,6 +26,7 @@
+  * KSU was writen by:  Ari Medvinsky, ari@isi.edu
+  */
+ 
++#include "autoconf.h"
+ #include "ksu.h"
+ #include "adm_proto.h"
+ #include <sys/types.h>
+@@ -33,6 +34,10 @@
+ #include <signal.h>
+ #include <grp.h>
+ 
++#ifdef USE_PAM
++#include "pam.h"
++#endif
++
+ /* globals */
+ char * prog_name;
+ int auth_debug =0;
+@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN];
+ char k5users_path[MAXPATHLEN];
+ char * gb_err = NULL;
+ int quiet = 0;
++int force_fork = 0;
+ /***********/
+ 
+ #define KS_TEMPORARY_CACHE "MEMORY:_ksu"
+@@ -528,6 +534,23 @@ main (argc, argv)
+                prog_name,target_user,client_name,
+                source_user,ontty());
+ 
++#ifdef USE_PAM
++        if (appl_pam_enabled(ksu_context, "ksu")) {
++            if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
++                                   NULL, source_user,
++                                   ttyname(STDERR_FILENO)) != 0) {
++                fprintf(stderr, "Access denied for %s.\n", target_user);
++                exit(1);
++            }
++            if (appl_pam_requires_chauthtok()) {
++                fprintf(stderr, "Password change required for %s.\n",
++                        target_user);
++                exit(1);
++            }
++            force_fork++;
++        }
++#endif
++
+         /* Run authorization as target.*/
+         if (krb5_seteuid(target_uid)) {
+             com_err(prog_name, errno, _("while switching to target for "
+@@ -588,6 +611,24 @@ main (argc, argv)
+ 
+             exit(1);
+         }
++#ifdef USE_PAM
++    } else {
++        /* we always do PAM account management, even for root */
++        if (appl_pam_enabled(ksu_context, "ksu")) {
++            if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
++                                   NULL, source_user,
++                                   ttyname(STDERR_FILENO)) != 0) {
++                fprintf(stderr, "Access denied for %s.\n", target_user);
++                exit(1);
++            }
++            if (appl_pam_requires_chauthtok()) {
++                fprintf(stderr, "Password change required for %s.\n",
++                        target_user);
++                exit(1);
++            }
++            force_fork++;
++        }
++#endif
+     }
+ 
+     if( some_rest_copy){
+@@ -645,6 +686,30 @@ main (argc, argv)
+         exit(1);
+     }
+ 
++#ifdef USE_PAM
++    if (appl_pam_enabled(ksu_context, "ksu")) {
++        if (appl_pam_session_open() != 0) {
++            fprintf(stderr, "Error opening session for %s.\n", target_user);
++            exit(1);
++        }
++#ifdef DEBUG
++        if (auth_debug){
++            printf(" Opened PAM session.\n");
++        }
++#endif
++        if (appl_pam_cred_init()) {
++            fprintf(stderr, "Error initializing credentials for %s.\n",
++                    target_user);
++            exit(1);
++        }
++#ifdef DEBUG
++        if (auth_debug){
++            printf(" Initialized PAM credentials.\n");
++        }
++#endif
++    }
++#endif
++
+     /* set permissions */
+     if (setgid(target_pwd->pw_gid) < 0) {
+         perror("ksu: setgid");
+@@ -742,7 +807,7 @@ main (argc, argv)
+         fprintf(stderr, "program to be execed %s\n",params[0]);
+     }
+ 
+-    if( keep_target_cache ) {
++    if( keep_target_cache && !force_fork ) {
+         execv(params[0], params);
+         com_err(prog_name, errno, _("while trying to execv %s"), params[0]);
+         sweep_up(ksu_context, cc_target);
+@@ -772,16 +837,35 @@ main (argc, argv)
+             if (ret_pid == -1) {
+                 com_err(prog_name, errno, _("while calling waitpid"));
+             }
+-            sweep_up(ksu_context, cc_target);
++            if( !keep_target_cache ) {
++                sweep_up(ksu_context, cc_target);
++            }
+             exit (statusp);
+         case -1:
+             com_err(prog_name, errno, _("while trying to fork."));
+             sweep_up(ksu_context, cc_target);
+             exit (1);
+         case 0:
++#ifdef USE_PAM
++            if (appl_pam_enabled(ksu_context, "ksu")) {
++                if (appl_pam_setenv() != 0) {
++                    fprintf(stderr, "Error setting up environment for %s.\n",
++                            target_user);
++                    exit (1);
++                }
++#ifdef DEBUG
++                if (auth_debug){
++                    printf(" Set up PAM environment.\n");
++                }
++#endif
++            }
++#endif
+             execv(params[0], params);
+             com_err(prog_name, errno, _("while trying to execv %s"),
+                     params[0]);
++            if( keep_target_cache ) {
++                sweep_up(ksu_context, cc_target);
++            }
+             exit (1);
+         }
+     }
+diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c
+new file mode 100644
+index 000000000..cbfe48704
+--- /dev/null
++++ b/src/clients/ksu/pam.c
+@@ -0,0 +1,389 @@
++/*
++ * src/clients/ksu/pam.c
++ *
++ * Copyright 2007,2009,2010 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.
++ * 
++ * Convenience wrappers for using PAM.
++ */
++
++#include "autoconf.h"
++#ifdef USE_PAM
++#include <sys/types.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include "k5-int.h"
++#include "pam.h"
++
++#ifndef MAXPWSIZE
++#define MAXPWSIZE 128
++#endif
++
++static int appl_pam_started;
++static pid_t appl_pam_starter = -1;
++static int appl_pam_session_opened;
++static int appl_pam_creds_initialized;
++static int appl_pam_pwchange_required;
++static pam_handle_t *appl_pamh;
++static struct pam_conv appl_pam_conv;
++static char *appl_pam_user;
++struct appl_pam_non_interactive_args {
++	const char *user;
++	const char *password;
++};
++
++int
++appl_pam_enabled(krb5_context context, const char *section)
++{
++	int enabled = 1;
++	if ((context != NULL) && (context->profile != NULL)) {
++		if (profile_get_boolean(context->profile,
++					section,
++					USE_PAM_CONFIGURATION_KEYWORD,
++					NULL,
++					enabled, &enabled) != 0) {
++			enabled = 1;
++		}
++	}
++	return enabled;
++}
++
++void
++appl_pam_cleanup(void)
++{
++	if (getpid() != appl_pam_starter) {
++		return;
++	}
++#ifdef DEBUG
++	printf("Called to clean up PAM.\n");
++#endif
++	if (appl_pam_creds_initialized) {
++#ifdef DEBUG
++		printf("Deleting PAM credentials.\n");
++#endif
++		pam_setcred(appl_pamh, PAM_DELETE_CRED);
++		appl_pam_creds_initialized = 0;
++	}
++	if (appl_pam_session_opened) {
++#ifdef DEBUG
++		printf("Closing PAM session.\n");
++#endif
++		pam_close_session(appl_pamh, 0);
++		appl_pam_session_opened = 0;
++	}
++	appl_pam_pwchange_required = 0;
++	if (appl_pam_started) {
++#ifdef DEBUG
++		printf("Shutting down PAM.\n");
++#endif
++		pam_end(appl_pamh, 0);
++		appl_pam_started = 0;
++		appl_pam_starter = -1;
++		free(appl_pam_user);
++		appl_pam_user = NULL;
++	}
++}
++static int
++appl_pam_interactive_converse(int num_msg, const struct pam_message **msg,
++			      struct pam_response **presp, void *appdata_ptr)
++{
++	const struct pam_message *message;
++	struct pam_response *resp;
++	int i, code;
++	char *pwstring, pwbuf[MAXPWSIZE];
++	unsigned int pwsize;
++	resp = malloc(sizeof(struct pam_response) * num_msg);
++	if (resp == NULL) {
++		return PAM_BUF_ERR;
++	}
++	memset(resp, 0, sizeof(struct pam_response) * num_msg);
++	code = PAM_SUCCESS;
++	for (i = 0; i < num_msg; i++) {
++		message = &(msg[0][i]); /* XXX */
++		message = msg[i]; /* XXX */
++		pwstring = NULL;
++		switch (message->msg_style) {
++		case PAM_TEXT_INFO:
++		case PAM_ERROR_MSG:
++			printf("[%s]\n", message->msg ? message->msg : "");
++			fflush(stdout);
++			resp[i].resp = NULL;
++			resp[i].resp_retcode = PAM_SUCCESS;
++			break;
++		case PAM_PROMPT_ECHO_ON:
++		case PAM_PROMPT_ECHO_OFF:
++			if (message->msg_style == PAM_PROMPT_ECHO_ON) {
++				if (fgets(pwbuf, sizeof(pwbuf),
++					  stdin) != NULL) {
++					pwbuf[strcspn(pwbuf, "\r\n")] = '\0';
++					pwstring = pwbuf;
++				}
++			} else {
++				pwstring = getpass(message->msg ?
++						   message->msg :
++						   "");
++			}
++			if ((pwstring != NULL) && (pwstring[0] != '\0')) {
++				pwsize = strlen(pwstring);
++				resp[i].resp = malloc(pwsize + 1);
++				if (resp[i].resp == NULL) {
++					resp[i].resp_retcode = PAM_BUF_ERR;
++				} else {
++					memcpy(resp[i].resp, pwstring, pwsize);
++					resp[i].resp[pwsize] = '\0';
++					resp[i].resp_retcode = PAM_SUCCESS;
++				}
++			} else {
++				resp[i].resp_retcode = PAM_CONV_ERR;
++				code = PAM_CONV_ERR;
++			}
++			break;
++		default:
++			break;
++		}
++	}
++	*presp = resp;
++	return code;
++}
++static int
++appl_pam_non_interactive_converse(int num_msg,
++				  const struct pam_message **msg,
++				  struct pam_response **presp,
++				  void *appdata_ptr)
++{
++	const struct pam_message *message;
++	struct pam_response *resp;
++	int i, code;
++	unsigned int pwsize;
++	struct appl_pam_non_interactive_args *args;
++	const char *pwstring;
++	resp = malloc(sizeof(struct pam_response) * num_msg);
++	if (resp == NULL) {
++		return PAM_BUF_ERR;
++	}
++	args = appdata_ptr;
++	memset(resp, 0, sizeof(struct pam_response) * num_msg);
++	code = PAM_SUCCESS;
++	for (i = 0; i < num_msg; i++) {
++		message = &((*msg)[i]);
++		message = msg[i];
++		pwstring = NULL;
++		switch (message->msg_style) {
++		case PAM_TEXT_INFO:
++		case PAM_ERROR_MSG:
++			break;
++		case PAM_PROMPT_ECHO_ON:
++		case PAM_PROMPT_ECHO_OFF:
++			if (message->msg_style == PAM_PROMPT_ECHO_ON) {
++				/* assume "user" */
++				pwstring = args->user;
++			} else {
++				/* assume "password" */
++				pwstring = args->password;
++			}
++			if ((pwstring != NULL) && (pwstring[0] != '\0')) {
++				pwsize = strlen(pwstring);
++				resp[i].resp = malloc(pwsize + 1);
++				if (resp[i].resp == NULL) {
++					resp[i].resp_retcode = PAM_BUF_ERR;
++				} else {
++					memcpy(resp[i].resp, pwstring, pwsize);
++					resp[i].resp[pwsize] = '\0';
++					resp[i].resp_retcode = PAM_SUCCESS;
++				}
++			} else {
++				resp[i].resp_retcode = PAM_CONV_ERR;
++				code = PAM_CONV_ERR;
++			}
++			break;
++		default:
++			break;
++		}
++	}
++	*presp = resp;
++	return code;
++}
++static int
++appl_pam_start(const char *service, int interactive,
++	       const char *login_username,
++	       const char *non_interactive_password,
++	       const char *hostname,
++	       const char *ruser,
++	       const char *tty)
++{
++	static int exit_handler_registered;
++	static struct appl_pam_non_interactive_args args;
++	int ret = 0;
++	if (appl_pam_started &&
++	    (strcmp(login_username, appl_pam_user) != 0)) {
++		appl_pam_cleanup();
++		appl_pam_user = NULL;
++	}
++	if (!appl_pam_started) {
++#ifdef DEBUG
++		printf("Starting PAM up (service=\"%s\",user=\"%s\").\n",
++		       service, login_username);
++#endif
++		memset(&appl_pam_conv, 0, sizeof(appl_pam_conv));
++		appl_pam_conv.conv = interactive ?
++				     &appl_pam_interactive_converse :
++				     &appl_pam_non_interactive_converse;
++		memset(&args, 0, sizeof(args));
++		args.user = strdup(login_username);
++		args.password = non_interactive_password ?
++				strdup(non_interactive_password) :
++				NULL;
++		appl_pam_conv.appdata_ptr = &args;
++		ret = pam_start(service, login_username,
++				&appl_pam_conv, &appl_pamh);
++		if (ret == 0) {
++			if (hostname != NULL) {
++#ifdef DEBUG
++				printf("Setting PAM_RHOST to \"%s\".\n", hostname);
++#endif
++				pam_set_item(appl_pamh, PAM_RHOST, hostname);
++			}
++			if (ruser != NULL) {
++#ifdef DEBUG
++				printf("Setting PAM_RUSER to \"%s\".\n", ruser);
++#endif
++				pam_set_item(appl_pamh, PAM_RUSER, ruser);
++			}
++			if (tty != NULL) {
++#ifdef DEBUG
++				printf("Setting PAM_TTY to \"%s\".\n", tty);
++#endif
++				pam_set_item(appl_pamh, PAM_TTY, tty);
++			}
++			if (!exit_handler_registered &&
++			    (atexit(appl_pam_cleanup) != 0)) {
++				pam_end(appl_pamh, 0);
++				appl_pamh = NULL;
++				ret = -1;
++			} else {
++				appl_pam_started = 1;
++				appl_pam_starter = getpid();
++				appl_pam_user = strdup(login_username);
++				exit_handler_registered = 1;
++			}
++		}
++	}
++	return ret;
++}
++int
++appl_pam_acct_mgmt(const char *service, int interactive,
++		   const char *login_username,
++		   const char *non_interactive_password,
++		   const char *hostname,
++		   const char *ruser,
++		   const char *tty)
++{
++	int ret;
++	appl_pam_pwchange_required = 0;
++	ret = appl_pam_start(service, interactive, login_username,
++			     non_interactive_password, hostname, ruser, tty);
++	if (ret == 0) {
++#ifdef DEBUG
++		printf("Calling pam_acct_mgmt().\n");
++#endif
++		ret = pam_acct_mgmt(appl_pamh, 0);
++		switch (ret) {
++		case PAM_IGNORE:
++			ret = 0;
++			break;
++		case PAM_NEW_AUTHTOK_REQD:
++			appl_pam_pwchange_required = 1;
++			ret = 0;
++			break;
++		default:
++			break;
++		}
++	}
++	return ret;
++}
++int
++appl_pam_requires_chauthtok(void)
++{
++	return appl_pam_pwchange_required;
++}
++int
++appl_pam_session_open(void)
++{
++	int ret = 0;
++	if (appl_pam_started) {
++#ifdef DEBUG
++		printf("Opening PAM session.\n");
++#endif
++		ret = pam_open_session(appl_pamh, 0);
++		if (ret == 0) {
++			appl_pam_session_opened = 1;
++		}
++	}
++	return ret;
++}
++int
++appl_pam_setenv(void)
++{
++	int ret = 0;
++#ifdef HAVE_PAM_GETENVLIST
++#ifdef HAVE_PUTENV
++	int i;
++	char **list;
++	if (appl_pam_started) {
++		list = pam_getenvlist(appl_pamh);
++		for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) {
++#ifdef DEBUG
++			printf("Setting \"%s\" in environment.\n", list[i]);
++#endif
++			putenv(list[i]);
++		}
++	}
++#endif
++#endif
++	return ret;
++}
++int
++appl_pam_cred_init(void)
++{
++	int ret = 0;
++	if (appl_pam_started) {
++#ifdef DEBUG
++		printf("Initializing PAM credentials.\n");
++#endif
++		ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED);
++		if (ret == 0) {
++			appl_pam_creds_initialized = 1;
++		}
++	}
++	return ret;
++}
++#endif
+diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h
+new file mode 100644
+index 000000000..0ab76569c
+--- /dev/null
++++ b/src/clients/ksu/pam.h
+@@ -0,0 +1,57 @@
++/*
++ * src/clients/ksu/pam.h
++ *
++ * Copyright 2007,2009,2010 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.
++ * 
++ * Convenience wrappers for using PAM.
++ */
++
++#include <krb5.h>
++#ifdef HAVE_SECURITY_PAM_APPL_H
++#include <security/pam_appl.h>
++#endif
++
++#define USE_PAM_CONFIGURATION_KEYWORD "use_pam"
++
++#ifdef USE_PAM
++int appl_pam_enabled(krb5_context context, const char *section);
++int appl_pam_acct_mgmt(const char *service, int interactive,
++		       const char *local_username,
++		       const char *non_interactive_password,
++		       const char *hostname,
++		       const char *ruser,
++		       const char *tty);
++int appl_pam_requires_chauthtok(void);
++int appl_pam_session_open(void);
++int appl_pam_setenv(void);
++int appl_pam_cred_init(void);
++void appl_pam_cleanup(void);
++#endif
+diff --git a/src/configure.in b/src/configure.in
+index 61ef738dc..e9a12ac16 100644
+--- a/src/configure.in
++++ b/src/configure.in
+@@ -1352,6 +1352,8 @@ AC_SUBST([VERTO_VERSION])
+ 
+ AC_PATH_PROG(GROFF, groff)
+ 
++KRB5_WITH_PAM
++
+ # Make localedir work in autoconf 2.5x.
+ if test "${localedir+set}" != set; then
+     localedir='$(datadir)/locale'
diff --git a/SOURCES/krb5-1.13-dirsrv-accountlock.patch b/SOURCES/krb5-1.13-dirsrv-accountlock.patch
new file mode 100644
index 0000000..db48910
--- /dev/null
+++ b/SOURCES/krb5-1.13-dirsrv-accountlock.patch
@@ -0,0 +1,75 @@
+From 1dc051d5964aba0b8cd3d01f063ffc28253456de Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:47:44 -0400
+Subject: [PATCH] krb5-1.13-dirsrv-accountlock.patch
+
+Treat 'nsAccountLock: true' the same as 'loginDisabled: true'.  Updated from
+original version filed as RT#5891.
+---
+ src/aclocal.m4                                  |  9 +++++++++
+ src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c    | 17 +++++++++++++++++
+ .../kdb/ldap/libkdb_ldap/ldap_principal.c       |  3 +++
+ 3 files changed, 29 insertions(+)
+
+diff --git a/src/aclocal.m4 b/src/aclocal.m4
+index db18226ed..518b1a547 100644
+--- a/src/aclocal.m4
++++ b/src/aclocal.m4
+@@ -1678,6 +1678,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 --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
+index 5b9d1e9fa..4e7270065 100644
+--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
+@@ -1652,6 +1652,23 @@ populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context,
+     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)
+diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+index d722dbfa6..5e8e9a897 100644
+--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+@@ -54,6 +54,9 @@ char     *principal_attributes[] = { "krbprincipalname",
+                                      "krbLastFailedAuth",
+                                      "krbLoginFailedCount",
+                                      "krbLastSuccessfulAuth",
++#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING
++                                     "nsAccountLock",
++#endif
+                                      "krbLastPwdChange",
+                                      "krbLastAdminUnlock",
+                                      "krbPrincipalAuthInd",
diff --git a/SOURCES/krb5-1.15-beta1-buildconf.patch b/SOURCES/krb5-1.15-beta1-buildconf.patch
new file mode 100644
index 0000000..6d1e151
--- /dev/null
+++ b/SOURCES/krb5-1.15-beta1-buildconf.patch
@@ -0,0 +1,70 @@
+From 90bf9e3c4a80e7e46e6e00b9d541c6144968cad4 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:45:26 -0400
+Subject: [PATCH] krb5-1.15-beta1-buildconf.patch
+
+Build binaries in this package as RELRO PIEs, libraries as partial RELRO,
+and install shared libraries with the execute bit set on them.  Prune out
+the -L/usr/lib* and PIE flags where they might leak out and affect
+apps which just want to link with the libraries. FIXME: needs to check and
+not just assume that the compiler supports using these flags.
+---
+ src/build-tools/krb5-config.in | 7 +++++++
+ src/config/pre.in              | 2 +-
+ src/config/shlib.conf          | 5 +++--
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
+index c17cb5eb5..1891dea99 100755
+--- a/src/build-tools/krb5-config.in
++++ b/src/build-tools/krb5-config.in
+@@ -226,6 +226,13 @@ if test -n "$do_libs"; then
+ 	    -e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \
+ 	    -e 's#\$(CFLAGS)##'`
+ 
++    if test `dirname $libdir` = /usr ; then
++        lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e "s#$RPATH_FLAG$libdir##"`
++    fi
++    lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"`
++    lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"`
++    lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"`
++
+     if test $library = 'kdb'; then
+ 	lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB"
+ 	library=krb5
+diff --git a/src/config/pre.in b/src/config/pre.in
+index 917357df9..a8540ae2a 100644
+--- a/src/config/pre.in
++++ b/src/config/pre.in
+@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)
+ INSTALL_SCRIPT=@INSTALL_PROGRAM@
+ INSTALL_DATA=@INSTALL_DATA@
+ INSTALL_SHLIB=@INSTALL_SHLIB@
+-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
++INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755
+ ## This is needed because autoconf will sometimes define @exec_prefix@ to be
+ ## ${prefix}.
+ prefix=@prefix@
+diff --git a/src/config/shlib.conf b/src/config/shlib.conf
+index 3e4af6c02..2b20c3fda 100644
+--- a/src/config/shlib.conf
++++ b/src/config/shlib.conf
+@@ -423,7 +423,7 @@ mips-*-netbsd*)
+ 	# Linux ld doesn't default to stuffing the SONAME field...
+ 	# Use objdump -x to examine the fields of the library
+ 	# UNDEF_CHECK is suppressed by --enable-asan
+-	LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)'
++	LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)  -Wl,-z,relro -Wl,--warn-shared-textrel'
+ 	UNDEF_CHECK='-Wl,--no-undefined'
+ 	# $(EXPORT_CHECK) runs export-check.pl when in maintainer mode.
+ 	LDCOMBINE_TAIL='-Wl,--version-script binutils.versions $(EXPORT_CHECK)'
+@@ -435,7 +435,8 @@ mips-*-netbsd*)
+ 	SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
+ 	PROFFLAGS=-pg
+ 	PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)'
+-	CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)'
++	CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) -pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)'
++	INSTALL_SHLIB='${INSTALL} -m755'
+ 	CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)'
+ 	CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)'
+ 	CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)'
diff --git a/SOURCES/krb5-1.17-beta1-selinux-label.patch b/SOURCES/krb5-1.17-beta1-selinux-label.patch
new file mode 100644
index 0000000..3f874f5
--- /dev/null
+++ b/SOURCES/krb5-1.17-beta1-selinux-label.patch
@@ -0,0 +1,1065 @@
+From 46946e305e4536a56866ff21ac1f6e8ed7c3b814 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:30:53 -0400
+Subject: [PATCH] krb5-1.17-beta1-selinux-label.patch
+
+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.
+---
+ src/aclocal.m4                                |  49 +++
+ src/build-tools/krb5-config.in                |   3 +-
+ src/config/pre.in                             |   3 +-
+ src/configure.in                              |   2 +
+ src/include/k5-int.h                          |   1 +
+ src/include/k5-label.h                        |  32 ++
+ src/include/krb5/krb5.hin                     |   6 +
+ src/kadmin/dbutil/dump.c                      |  11 +-
+ src/kdc/main.c                                |   2 +-
+ src/kprop/kpropd.c                            |   9 +
+ src/lib/kadm5/logger.c                        |   4 +-
+ src/lib/kdb/kdb_log.c                         |   2 +-
+ src/lib/krb5/ccache/cc_dir.c                  |  26 +-
+ src/lib/krb5/keytab/kt_file.c                 |   4 +-
+ src/lib/krb5/os/trace.c                       |   2 +-
+ src/lib/krb5/rcache/rc_dfl.c                  |  13 +
+ src/plugins/kdb/db2/adb_openclose.c           |   2 +-
+ src/plugins/kdb/db2/kdb_db2.c                 |   4 +-
+ src/plugins/kdb/db2/libdb2/btree/bt_open.c    |   3 +-
+ src/plugins/kdb/db2/libdb2/hash/hash.c        |   3 +-
+ src/plugins/kdb/db2/libdb2/recno/rec_open.c   |   4 +-
+ .../kdb/ldap/ldap_util/kdb5_ldap_services.c   |  11 +-
+ src/util/profile/prof_file.c                  |   3 +-
+ src/util/support/Makefile.in                  |   3 +-
+ src/util/support/selinux.c                    | 406 ++++++++++++++++++
+ 25 files changed, 587 insertions(+), 21 deletions(-)
+ create mode 100644 src/include/k5-label.h
+ create mode 100644 src/util/support/selinux.c
+
+diff --git a/src/aclocal.m4 b/src/aclocal.m4
+index 340546d80..a7afec09e 100644
+--- a/src/aclocal.m4
++++ b/src/aclocal.m4
+@@ -89,6 +89,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
+@@ -1764,3 +1765,51 @@ AC_SUBST(PAM_LIBS)
+ 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
+diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
+index f6184da3f..c17cb5eb5 100755
+--- a/src/build-tools/krb5-config.in
++++ b/src/build-tools/krb5-config.in
+@@ -41,6 +41,7 @@ DL_LIB='@DL_LIB@'
+ DEFCCNAME='@DEFCCNAME@'
+ DEFKTNAME='@DEFKTNAME@'
+ DEFCKTNAME='@DEFCKTNAME@'
++SELINUX_LIBS='@SELINUX_LIBS@'
+ 
+ LIBS='@LIBS@'
+ GEN_LIB=@GEN_LIB@
+@@ -255,7 +256,7 @@ if test -n "$do_libs"; then
+     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
+diff --git a/src/config/pre.in b/src/config/pre.in
+index ce87e21ca..917357df9 100644
+--- a/src/config/pre.in
++++ b/src/config/pre.in
+@@ -177,6 +177,7 @@ LD = $(PURE) @LD@
+ KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include
+ LDFLAGS = @LDFLAGS@
+ LIBS = @LIBS@
++SELINUX_LIBS=@SELINUX_LIBS@
+ 
+ INSTALL=@INSTALL@
+ INSTALL_STRIP=
+@@ -402,7 +403,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 macOS!
+diff --git a/src/configure.in b/src/configure.in
+index e9a12ac16..93aec682e 100644
+--- a/src/configure.in
++++ b/src/configure.in
+@@ -1354,6 +1354,8 @@ AC_PATH_PROG(GROFF, groff)
+ 
+ KRB5_WITH_PAM
+ 
++KRB5_WITH_SELINUX
++
+ # Make localedir work in autoconf 2.5x.
+ if test "${localedir+set}" != set; then
+     localedir='$(datadir)/locale'
+diff --git a/src/include/k5-int.h b/src/include/k5-int.h
+index 652242207..8f9329c59 100644
+--- a/src/include/k5-int.h
++++ b/src/include/k5-int.h
+@@ -128,6 +128,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 */
+diff --git a/src/include/k5-label.h b/src/include/k5-label.h
+new file mode 100644
+index 000000000..dfaaa847c
+--- /dev/null
++++ b/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
+diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
+index c40a6cca8..3ff86d7ff 100644
+--- a/src/include/krb5/krb5.hin
++++ b/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>
+diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
+index c9574c6e1..8301a33d0 100644
+--- a/src/kadmin/dbutil/dump.c
++++ b/src/kadmin/dbutil/dump.c
+@@ -148,12 +148,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;
+ 
+@@ -197,7 +206,7 @@ prep_ok_file(krb5_context context, char *file_name, int *fd_out)
+         goto cleanup;
+     }
+ 
+-    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);
+         goto cleanup;
+diff --git a/src/kdc/main.c b/src/kdc/main.c
+index 408c723f5..663fd6303 100644
+--- a/src/kdc/main.c
++++ b/src/kdc/main.c
+@@ -858,7 +858,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();
+diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
+index 68323dd0f..4cc035dc6 100644
+--- a/src/kprop/kpropd.c
++++ b/src/kprop/kpropd.c
+@@ -488,6 +488,9 @@ doit(int 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);
+@@ -543,9 +546,15 @@ doit(int 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) {
+diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c
+index c6885edf2..9aec3c05e 100644
+--- a/src/lib/kadm5/logger.c
++++ b/src/lib/kadm5/logger.c
+@@ -309,7 +309,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do
+                      */
+                     append = (cp[4] == ':') ? O_APPEND : 0;
+                     if (append || cp[4] == '=') {
+-                        fd = open(&cp[5], O_CREAT | O_WRONLY | append,
++                        fd = THREEPARAMOPEN(&cp[5], O_CREAT | O_WRONLY | append,
+                                   S_IRUSR | S_IWUSR | S_IRGRP);
+                         if (fd != -1)
+                             f = fdopen(fd, append ? "a" : "w");
+@@ -776,7 +776,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;
+diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
+index 2659a2501..e9b95fce5 100644
+--- a/src/lib/kdb/kdb_log.c
++++ b/src/lib/kdb/kdb_log.c
+@@ -480,7 +480,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries)
+         return ENOMEM;
+ 
+     if (stat(logname, &st) == -1) {
+-        log_ctx->ulogfd = open(logname, O_RDWR | O_CREAT, 0600);
++        log_ctx->ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600);
+         if (log_ctx->ulogfd == -1) {
+             retval = errno;
+             goto cleanup;
+diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
+index bba64e516..73f0fe62d 100644
+--- a/src/lib/krb5/ccache/cc_dir.c
++++ b/src/lib/krb5/ccache/cc_dir.c
+@@ -183,10 +183,19 @@ write_primary_file(const char *primary_path, const char *contents)
+     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
+@@ -221,10 +230,23 @@ static krb5_error_code
+ 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);
+diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
+index 89cb68680..21c80d419 100644
+--- a/src/lib/krb5/keytab/kt_file.c
++++ b/src/lib/krb5/keytab/kt_file.c
+@@ -1024,14 +1024,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
+ 
+     KTCHECKLOCK(id);
+     errno = 0;
+-    KTFILEP(id) = fopen(KTFILENAME(id),
++    KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id),
+                         (mode == KRB5_LOCKMODE_EXCLUSIVE) ? "rb+" : "rb");
+     if (!KTFILEP(id)) {
+         if ((mode == KRB5_LOCKMODE_EXCLUSIVE) && (errno == ENOENT)) {
+             /* try making it first time around */
+             k5_create_secure_file(context, KTFILENAME(id));
+             errno = 0;
+-            KTFILEP(id) = fopen(KTFILENAME(id), "rb+");
++            KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), "rb+");
+             if (!KTFILEP(id))
+                 goto report_errno;
+             writevno = 1;
+diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
+index 4fff8f38c..40a9e7b10 100644
+--- a/src/lib/krb5/os/trace.c
++++ b/src/lib/krb5/os/trace.c
+@@ -458,7 +458,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
+     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;
+diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c
+index 1e0cb22c9..f5e93b1ab 100644
+--- a/src/lib/krb5/rcache/rc_dfl.c
++++ b/src/lib/krb5/rcache/rc_dfl.c
+@@ -793,6 +793,9 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
+     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;
+@@ -814,7 +817,17 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
+     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) {
+diff --git a/src/plugins/kdb/db2/adb_openclose.c b/src/plugins/kdb/db2/adb_openclose.c
+index 7db30a33b..2b9d01921 100644
+--- a/src/plugins/kdb/db2/adb_openclose.c
++++ b/src/plugins/kdb/db2/adb_openclose.c
+@@ -152,7 +152,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char *filename, char *lockfilename,
+          * needs be open read/write so that write locking can work with
+          * POSIX systems
+          */
+-        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?
+diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c
+index 5106a5c99..e481e8121 100644
+--- a/src/plugins/kdb/db2/kdb_db2.c
++++ b/src/plugins/kdb/db2/kdb_db2.c
+@@ -694,8 +694,8 @@ ctx_create_db(krb5_context context, krb5_db2_context *dbc)
+     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;
+diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_open.c b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
+index 2977b17f3..d5809a5a9 100644
+--- a/src/plugins/kdb/db2/libdb2/btree/bt_open.c
++++ b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
+@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c	8.11 (Berkeley) 11/2/95";
+ #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, dflags)
+ 			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 {
+diff --git a/src/plugins/kdb/db2/libdb2/hash/hash.c b/src/plugins/kdb/db2/libdb2/hash/hash.c
+index 862dbb164..686a960c9 100644
+--- a/src/plugins/kdb/db2/libdb2/hash/hash.c
++++ b/src/plugins/kdb/db2/libdb2/hash/hash.c
+@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c	8.12 (Berkeley) 11/7/95";
+ #include <assert.h>
+ #endif
+ 
++#include "k5-int.h"
+ #include "db-int.h"
+ #include "hash.h"
+ #include "page.h"
+@@ -129,7 +130,7 @@ __kdb2_hash_open(file, flags, mode, info, dflags)
+ 		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);
+ 	}
+diff --git a/src/plugins/kdb/db2/libdb2/recno/rec_open.c b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
+index d8b26e701..b0daa7c02 100644
+--- a/src/plugins/kdb/db2/libdb2/recno/rec_open.c
++++ b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
+@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)rec_open.c	8.12 (Berkeley) 11/18/94";
+ #include <stdio.h>
+ #include <unistd.h>
+ 
++#include "k5-int.h"
+ #include "db-int.h"
+ #include "recno.h"
+ 
+@@ -68,7 +69,8 @@ __rec_open(fname, flags, mode, openinfo, dflags)
+ 	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) {
+diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
+index 1ed72afe9..ce038fc3d 100644
+--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
++++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
+@@ -194,7 +194,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
+ 
+     /* 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));
+@@ -235,6 +235,9 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
+          * Delete the existing entry and add the new entry
+          */
+         FILE *newfile;
++#ifdef USE_SELINUX
++        void *selabel;
++#endif
+ 
+         mode_t omask;
+ 
+@@ -246,7 +249,13 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
+         }
+ 
+         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);
+diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c
+index 24e41fb80..0dcb6b543 100644
+--- a/src/util/profile/prof_file.c
++++ b/src/util/profile/prof_file.c
+@@ -33,6 +33,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 */
+@@ -391,7 +392,7 @@ static errcode_t write_data_to_file(prf_data_t data, const char *outfile,
+ 
+     errno = 0;
+ 
+-    f = fopen(new_file, "w");
++    f = WRITABLEFOPEN(new_file, "w");
+     if (!f) {
+         retval = errno;
+         if (retval == 0)
+diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
+index db7b030b8..321672bcb 100644
+--- a/src/util/support/Makefile.in
++++ b/src/util/support/Makefile.in
+@@ -69,6 +69,7 @@ IPC_SYMS= \
+ 
+ STLIBOBJS= \
+ 	threads.o \
++	selinux.o \
+ 	init-addrinfo.o \
+ 	plugins.o \
+ 	errors.o \
+@@ -160,7 +161,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=
+ 
+diff --git a/src/util/support/selinux.c b/src/util/support/selinux.c
+new file mode 100644
+index 000000000..6d41f3244
+--- /dev/null
++++ b/src/util/support/selinux.c
+@@ -0,0 +1,406 @@
++/*
++ * Copyright 2007,2008,2009,2011,2012,2013,2016 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>
++#include <selinux/label.h>
++
++/* #define DEBUG 1 */
++static void
++debug_log(const char *fmt, ...)
++{
++#ifdef DEBUG
++    va_list ap;
++    va_start(ap, fmt);
++    if (isatty(fileno(stderr))) {
++        vfprintf(stderr, fmt, ap);
++    }
++    va_end(ap);
++#endif
++
++    return;
++}
++
++/* 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);
++}
++
++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;
++    }
++}
++
++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;
++    char *genpath;
++
++    previous = configuredsc = currentsc = derivedsc = NULL;
++    current = derived = NULL;
++    genpath = NULL;
++
++    fullpath = pathname;
++
++    if (!is_selinux_enabled()) {
++        goto fail;
++    }
++
++    if (getfscreatecon(&previous) != 0) {
++        goto fail;
++    }
++
++    /* Canonicalize pathname */
++    if (pathname[0] != '/') {
++        char *wd;
++        size_t len;
++        len = 0;
++
++        wd = getcwd(NULL, len);
++        if (wd == NULL) {
++            goto fail;
++        }
++
++        len = strlen(wd) + 1 + strlen(pathname) + 1;
++        genpath = malloc(len);
++        if (genpath == NULL) {
++            free(wd);
++            goto fail;
++        }
++
++        sprintf(genpath, "%s/%s", wd, pathname);
++        free(wd);
++        fullpath = genpath;
++    }
++
++    debug_log("Looking up context for \"%s\"(%05o).\n", fullpath, mode);
++
++    /* Check whether context file has changed under us */
++    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) {
++            cleanup_fscreatecon();
++
++            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 &&
++        selabel_lookup(selabel_ctx, &configuredsc, fullpath, mode) != 0) {
++        goto fail;
++    }
++
++    if (genpath != NULL) {
++        free(genpath);
++        genpath = NULL;
++    }
++
++    if (configuredsc == NULL) {
++        goto fail;
++    }
++
++    getcon(&currentsc);
++
++    /* AAAAAAAA */
++    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);
++    }
++
++    debug_log("Setting file creation context to \"%s\".\n", configuredsc);
++    if (setfscreatecon(configuredsc) != 0) {
++        debug_log("Unable to determine current context.\n");
++        goto fail;
++    }
++
++    freecon(configuredsc);
++    return previous;
++
++fail:
++    if (previous != NULL) {
++        freecon(previous);
++    }
++    if (genpath != NULL) {
++        free(genpath);
++    }
++    if (configuredsc != NULL) {
++        freecon(configuredsc);
++    }
++
++    cleanup_fscreatecon();
++    return NULL;
++}
++
++static void
++pop_fscreatecon(security_context_t previous)
++{
++    if (!is_selinux_enabled()) {
++        return;
++    }
++
++    if (previous != NULL) {
++        debug_log("Resetting file creation context to \"%s\".\n", previous);
++    } else {
++        debug_log("Resetting file creation context to default.\n");
++    }
++
++    /* NULL resets to default */
++    setfscreatecon(previous);
++
++    if (previous != NULL) {
++        freecon(previous);
++    }
++
++    /* Need to clean this up here otherwise it leaks */
++    cleanup_fscreatecon();
++}
++
++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 /* USE_SELINUX */
diff --git a/SOURCES/krb5-1.17.tar.gz.asc b/SOURCES/krb5-1.17.tar.gz.asc
new file mode 100644
index 0000000..90f7148
--- /dev/null
+++ b/SOURCES/krb5-1.17.tar.gz.asc
@@ -0,0 +1,17 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1
+
+iQIcBAABAgAGBQJcNMxOAAoJEAy6CFdfg3LfjAwP/2/oQe+4Bs/XwZTwNfakTbBl
+YHSY8MNAHIKsLh6Bn+SJBQQXSE0fEsm0hYH+JWz85+mzlZk7TbNZUI+zeikhLxi6
++d8MMQBpk2mQN0dkIeWjTdfkcThGCDSL7l0fh3MuEfN5C7QPAPD1JL1ZeqXPH5AV
+PSQRC9s2wiOTwwuHM2i27rZ7gdhL/xfJ3ZPUFJH4klRgszwp9j10I/nh4/XyS/wB
+82umjfusFPa9VNSPzm1jm94oRmALkR3CHGvmku2XD3YOv/f5yO8C1cHWNNLxg+5h
+EqVv05ddb6iLku4fRhkEjfN3VgCtEvXuMkuAXppkDJJ7wWxMBWgCIr1DS/x7LfbL
+CI0ZTejn8HCUBNmRWsKkUuebgHJ7ccch8p/Fp0cV4eT1FL35N2oV51u7+/zK6R8y
+1dygUF2VWFOqwm8cyczdFue7dFQVDGCw7R2eK5lXY3NpZVmJblQ/gNLMcbOxGBis
+H2dOzSn+CnxlD/2LqOZnhQ1WnGBhOMxoINwX/MQsIvkwAFaM1EsdhPIP/6mSVA/g
+p04+YQ2u2ag7Pq3zHsMIonC18w4ZqDPcvXvOXqCHtlQBDAMtb927XvjoTNj5W8Ei
+jywxqdWuuqalmrKGPEsKVOJZN6xg7UTgaKzcvQTvW7D3gLbrTT2iM++VKB3vh9V9
+SkULnR3c7fKMzFeLb/Q2
+=4hZX
+-----END PGP SIGNATURE-----
diff --git a/SOURCES/krb5-1.17post2-DES-3DES-fixups.patch b/SOURCES/krb5-1.17post2-DES-3DES-fixups.patch
new file mode 100644
index 0000000..0fcb76c
--- /dev/null
+++ b/SOURCES/krb5-1.17post2-DES-3DES-fixups.patch
@@ -0,0 +1,103 @@
+From fe66536c1b7aec67233739df97cbe0301ee6475e Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 19 Nov 2019 15:03:19 -0500
+Subject: [PATCH] krb5-1.17post2 DES/3DES fixups
+
+Kept separate from the other patch because rawhide doesn't have DES.
+
+post2 adds krb5kdf workarounds.
+---
+ src/lib/crypto/krb/derive.c                | 6 +++++-
+ src/lib/crypto/openssl/enc_provider/des.c  | 9 +++++++++
+ src/lib/crypto/openssl/enc_provider/des3.c | 6 ++++++
+ 3 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c
+index 915a173dd..ebdab69bc 100644
+--- a/src/lib/crypto/krb/derive.c
++++ b/src/lib/crypto/krb/derive.c
+@@ -348,6 +348,7 @@ cleanup:
+     zapfree(prf.data, blocksize);
+     return ret;
+ }
++#endif /* OSSL_KDFS */
+ 
+ static krb5_error_code
+ builtin_derive_random_rfc3961(const struct krb5_enc_provider *enc,
+@@ -400,7 +401,6 @@ cleanup:
+     zapfree(block.data, blocksize);
+     return ret;
+ }
+-#endif /* OSSL_KDFS */
+ 
+ krb5_error_code
+ k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
+@@ -432,6 +432,10 @@ k5_derive_random_rfc3961(const struct krb5_enc_provider *enc,
+                          krb5_key inkey, krb5_data *outrnd,
+                          const krb5_data *in_constant)
+ {
++    /* DES (single and triple).  They'll be gone very soon. */
++    if (enc->keylength == 8 || enc->keylength == 24)
++        return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
++
+ #ifdef OSSL_KDFS
+     return openssl_krb5kdf(enc, inkey, outrnd, in_constant);
+ #else
+diff --git a/src/lib/crypto/openssl/enc_provider/des.c b/src/lib/crypto/openssl/enc_provider/des.c
+index a662db512..7d17d287e 100644
+--- a/src/lib/crypto/openssl/enc_provider/des.c
++++ b/src/lib/crypto/openssl/enc_provider/des.c
+@@ -85,6 +85,9 @@ k5_des_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+     EVP_CIPHER_CTX *ctx;
+     krb5_boolean empty;
+ 
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     ret = validate(key, ivec, data, num_data, &empty);
+     if (ret != 0 || empty)
+         return ret;
+@@ -133,6 +136,9 @@ k5_des_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+     EVP_CIPHER_CTX *ctx;
+     krb5_boolean empty;
+ 
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     ret = validate(key, ivec, data, num_data, &empty);
+     if (ret != 0 || empty)
+         return ret;
+@@ -182,6 +188,9 @@ k5_des_cbc_mac(krb5_key key, const krb5_crypto_iov *data, size_t num_data,
+     DES_key_schedule sched;
+     krb5_boolean empty;
+ 
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     ret = validate(key, ivec, data, num_data, &empty);
+     if (ret != 0)
+         return ret;
+diff --git a/src/lib/crypto/openssl/enc_provider/des3.c b/src/lib/crypto/openssl/enc_provider/des3.c
+index 1c439c2cd..8be555a8d 100644
+--- a/src/lib/crypto/openssl/enc_provider/des3.c
++++ b/src/lib/crypto/openssl/enc_provider/des3.c
+@@ -84,6 +84,9 @@ k5_des3_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+     EVP_CIPHER_CTX *ctx;
+     krb5_boolean empty;
+ 
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     ret = validate(key, ivec, data, num_data, &empty);
+     if (ret != 0 || empty)
+         return ret;
+@@ -133,6 +136,9 @@ k5_des3_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
+     EVP_CIPHER_CTX *ctx;
+     krb5_boolean empty;
+ 
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     ret = validate(key, ivec, data, num_data, &empty);
+     if (ret != 0 || empty)
+         return ret;
diff --git a/SOURCES/krb5-1.17post6-FIPS-with-PRNG-and-RADIUS-and-MD4.patch b/SOURCES/krb5-1.17post6-FIPS-with-PRNG-and-RADIUS-and-MD4.patch
new file mode 100644
index 0000000..308137f
--- /dev/null
+++ b/SOURCES/krb5-1.17post6-FIPS-with-PRNG-and-RADIUS-and-MD4.patch
@@ -0,0 +1,568 @@
+From 2a4e2418875b41c3273db5f6b4e9e1b01c1fb5ff Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Fri, 9 Nov 2018 15:12:21 -0500
+Subject: [PATCH] krb5-1.17post6 FIPS with PRNG and RADIUS and MD4
+
+NB: Use openssl's PRNG in FIPS mode and taint within krad.
+
+A lot of the FIPS error conditions from OpenSSL are incredibly
+mysterious (at best, things return NULL unexpectedly; at worst,
+internal assertions are tripped; most of the time, you just get
+ENOMEM).  In order to cope with this, we need to have some level of
+awareness of what we can and can't safely call.
+
+This will slow down some calls slightly (FIPS_mode() takes multiple
+locks), but not for any ciphers we care about - which is to say that
+AES is fine.  Shame about SPAKE though.
+
+post6 restores MD4 (and therefore keygen-only RC4).
+
+(cherry picked from commit 80b56b04d90fcacd9f78fed305c7d5528d863b38)
+---
+ src/lib/crypto/krb/prng.c                     | 11 ++++-
+ .../crypto/openssl/enc_provider/camellia.c    |  6 +++
+ src/lib/crypto/openssl/enc_provider/rc4.c     | 13 +++++-
+ .../crypto/openssl/hash_provider/hash_evp.c   | 12 +++++
+ src/lib/crypto/openssl/hmac.c                 |  6 ++-
+ src/lib/krad/attr.c                           | 45 ++++++++++++++-----
+ src/lib/krad/attrset.c                        |  5 ++-
+ src/lib/krad/internal.h                       | 13 +++++-
+ src/lib/krad/packet.c                         | 22 ++++-----
+ src/lib/krad/remote.c                         | 10 ++++-
+ src/lib/krad/t_attr.c                         |  3 +-
+ src/lib/krad/t_attrset.c                      |  4 +-
+ src/plugins/preauth/spake/spake_client.c      |  6 +++
+ src/plugins/preauth/spake/spake_kdc.c         |  6 +++
+ 14 files changed, 129 insertions(+), 33 deletions(-)
+
+diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
+index cb9ca9b98..f0e9984ca 100644
+--- a/src/lib/crypto/krb/prng.c
++++ b/src/lib/crypto/krb/prng.c
+@@ -26,6 +26,8 @@
+ 
+ #include "crypto_int.h"
+ 
++#include <openssl/rand.h>
++
+ krb5_error_code KRB5_CALLCONV
+ krb5_c_random_seed(krb5_context context, krb5_data *data)
+ {
+@@ -99,9 +101,16 @@ krb5_boolean
+ k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
+ {
+     const char *device;
+-#if defined(__linux__) && defined(SYS_getrandom)
+     int r;
+ 
++    /* A wild FIPS mode appeared! */
++    if (FIPS_mode()) {
++        /* The return codes on this API are not good */
++        r = RAND_bytes(buf, len);
++        return r == 1;
++    }
++
++#if defined(__linux__) && defined(SYS_getrandom)
+     while (len > 0) {
+         /*
+          * Pull from the /dev/urandom pool, but require it to have been seeded.
+diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
+index 2da691329..f79679a0b 100644
+--- a/src/lib/crypto/openssl/enc_provider/camellia.c
++++ b/src/lib/crypto/openssl/enc_provider/camellia.c
+@@ -304,6 +304,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
+     unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE];
+     struct iov_cursor cursor;
+ 
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     if (output->length < CAMELLIA_BLOCK_SIZE)
+         return KRB5_BAD_MSIZE;
+ 
+@@ -331,6 +334,9 @@ static krb5_error_code
+ krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
+                              krb5_data *state)
+ {
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     state->length = 16;
+     state->data = (void *) malloc(16);
+     if (state->data == NULL)
+diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
+index a65d57b7a..6ccaca94a 100644
+--- a/src/lib/crypto/openssl/enc_provider/rc4.c
++++ b/src/lib/crypto/openssl/enc_provider/rc4.c
+@@ -66,6 +66,9 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
+     EVP_CIPHER_CTX *ctx = NULL;
+     struct arcfour_state *arcstate;
+ 
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     arcstate = (state != NULL) ? (void *)state->data : NULL;
+     if (arcstate != NULL) {
+         ctx = arcstate->ctx;
+@@ -113,7 +116,12 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
+ static void
+ k5_arcfour_free_state(krb5_data *state)
+ {
+-    struct arcfour_state *arcstate = (void *)state->data;
++    struct arcfour_state *arcstate;
++
++    if (FIPS_mode())
++        return;
++
++    arcstate = (void *) state->data;
+ 
+     EVP_CIPHER_CTX_free(arcstate->ctx);
+     free(arcstate);
+@@ -125,6 +133,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
+ {
+     struct arcfour_state *arcstate;
+ 
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     /*
+      * The cipher state here is a saved pointer to a struct arcfour_state
+      * object, rather than a flat byte array as in most enc providers.  The
+diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
+index 957ed8d9c..915da9dbe 100644
+--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
++++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
+@@ -49,6 +49,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
+     if (ctx == NULL)
+         return ENOMEM;
+ 
++    if (type == EVP_md4()) {
++        /* See comment below in hash_md4(). */
++        EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
++    }
++
+     ok = EVP_DigestInit_ex(ctx, type, NULL);
+     for (i = 0; i < num_data; i++) {
+         if (!SIGN_IOV(&data[i]))
+@@ -64,12 +69,19 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
+ static krb5_error_code
+ hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+ {
++    /*
++     * MD4 is needed in FIPS mode to perform key generation for RC4 keys used
++     * by IPA.  These keys are only used along a (separately) secured channel
++     * for legacy reasons when performing trusts to Active Directory.
++     */
+     return hash_evp(EVP_md4(), data, num_data, output);
+ }
+ 
+ static krb5_error_code
+ hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
+ {
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
+     return hash_evp(EVP_md5(), data, num_data, output);
+ }
+ 
+diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
+index b2db6ec02..d94d9ac94 100644
+--- a/src/lib/crypto/openssl/hmac.c
++++ b/src/lib/crypto/openssl/hmac.c
+@@ -103,7 +103,11 @@ map_digest(const struct krb5_hash_provider *hash)
+         return EVP_sha256();
+     else if (!strncmp(hash->hash_name, "SHA-384",7))
+         return EVP_sha384();
+-    else if (!strncmp(hash->hash_name, "MD5", 3))
++
++    if (FIPS_mode())
++        return NULL;
++
++    if (!strncmp(hash->hash_name, "MD5", 3))
+         return EVP_md5();
+     else if (!strncmp(hash->hash_name, "MD4", 3))
+         return EVP_md4();
+diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
+index 9c13d9d75..275327e67 100644
+--- a/src/lib/krad/attr.c
++++ b/src/lib/krad/attr.c
+@@ -30,6 +30,7 @@
+ #include <k5-int.h>
+ #include "internal.h"
+ 
++#include <openssl/crypto.h>
+ #include <string.h>
+ 
+ /* RFC 2865 */
+@@ -38,7 +39,8 @@
+ typedef krb5_error_code
+ (*attribute_transform_fn)(krb5_context ctx, const char *secret,
+                           const unsigned char *auth, const krb5_data *in,
+-                          unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
++                          unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
++                          krb5_boolean *is_fips);
+ 
+ typedef struct {
+     const char *name;
+@@ -51,12 +53,14 @@ typedef struct {
+ static krb5_error_code
+ user_password_encode(krb5_context ctx, const char *secret,
+                      const unsigned char *auth, const krb5_data *in,
+-                     unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
++                     unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
++                     krb5_boolean *is_fips);
+ 
+ static krb5_error_code
+ user_password_decode(krb5_context ctx, const char *secret,
+                      const unsigned char *auth, const krb5_data *in,
+-                     unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
++                     unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
++                     krb5_boolean *ignored);
+ 
+ static const attribute_record attributes[UCHAR_MAX] = {
+     {"User-Name", 1, MAX_ATTRSIZE, NULL, NULL},
+@@ -128,7 +132,8 @@ static const attribute_record attributes[UCHAR_MAX] = {
+ static krb5_error_code
+ user_password_encode(krb5_context ctx, const char *secret,
+                      const unsigned char *auth, const krb5_data *in,
+-                     unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
++                     unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
++                     krb5_boolean *is_fips)
+ {
+     const unsigned char *indx;
+     krb5_error_code retval;
+@@ -154,8 +159,14 @@ user_password_encode(krb5_context ctx, const char *secret,
+     for (blck = 0, indx = auth; blck * BLOCKSIZE < len; blck++) {
+         memcpy(tmp.data + seclen, indx, BLOCKSIZE);
+ 
+-        retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
+-                                      &sum);
++        if (FIPS_mode()) {
++            /* Skip encryption here.  Taint so that we won't pass it out of
++             * the machine by accident. */
++            *is_fips = TRUE;
++            sum.contents = calloc(1, BLOCKSIZE);
++        } else
++            retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
++                                          &sum);
+         if (retval != 0) {
+             zap(tmp.data, tmp.length);
+             zap(outbuf, len);
+@@ -180,7 +191,8 @@ user_password_encode(krb5_context ctx, const char *secret,
+ static krb5_error_code
+ user_password_decode(krb5_context ctx, const char *secret,
+                      const unsigned char *auth, const krb5_data *in,
+-                     unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
++                     unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
++                     krb5_boolean *is_fips)
+ {
+     const unsigned char *indx;
+     krb5_error_code retval;
+@@ -204,8 +216,14 @@ user_password_decode(krb5_context ctx, const char *secret,
+     for (blck = 0, indx = auth; blck * BLOCKSIZE < in->length; blck++) {
+         memcpy(tmp.data + seclen, indx, BLOCKSIZE);
+ 
+-        retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
+-                                      &tmp, &sum);
++        if (FIPS_mode()) {
++            /* Skip encryption here.  Taint so that we won't pass it out of
++             * the machine by accident. */
++            *is_fips = TRUE;
++            sum.contents = calloc(1, BLOCKSIZE);
++        } else
++            retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
++                                          &tmp, &sum);
+         if (retval != 0) {
+             zap(tmp.data, tmp.length);
+             zap(outbuf, in->length);
+@@ -248,7 +266,7 @@ krb5_error_code
+ kr_attr_encode(krb5_context ctx, const char *secret,
+                const unsigned char *auth, krad_attr type,
+                const krb5_data *in, unsigned char outbuf[MAX_ATTRSIZE],
+-               size_t *outlen)
++               size_t *outlen, krb5_boolean *is_fips)
+ {
+     krb5_error_code retval;
+ 
+@@ -265,7 +283,8 @@ kr_attr_encode(krb5_context ctx, const char *secret,
+         return 0;
+     }
+ 
+-    return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen);
++    return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen,
++                                       is_fips);
+ }
+ 
+ krb5_error_code
+@@ -274,6 +293,7 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
+                unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
+ {
+     krb5_error_code retval;
++    krb5_boolean ignored;
+ 
+     retval = kr_attr_valid(type, in);
+     if (retval != 0)
+@@ -288,7 +308,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
+         return 0;
+     }
+ 
+-    return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen);
++    return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen,
++                                       &ignored);
+ }
+ 
+ krad_attr
+diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
+index 03c613716..d89982a13 100644
+--- a/src/lib/krad/attrset.c
++++ b/src/lib/krad/attrset.c
+@@ -167,7 +167,8 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
+ krb5_error_code
+ kr_attrset_encode(const krad_attrset *set, const char *secret,
+                   const unsigned char *auth,
+-                  unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen)
++                  unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
++                  krb5_boolean *is_fips)
+ {
+     unsigned char buffer[MAX_ATTRSIZE];
+     krb5_error_code retval;
+@@ -181,7 +182,7 @@ kr_attrset_encode(const krad_attrset *set, const char *secret,
+ 
+     K5_TAILQ_FOREACH(a, &set->list, list) {
+         retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr,
+-                                buffer, &attrlen);
++                                buffer, &attrlen, is_fips);
+         if (retval != 0)
+             return retval;
+ 
+diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
+index 996a89372..a53ce31ce 100644
+--- a/src/lib/krad/internal.h
++++ b/src/lib/krad/internal.h
+@@ -49,6 +49,13 @@
+ 
+ typedef struct krad_remote_st krad_remote;
+ 
++struct krad_packet_st {
++    char buffer[KRAD_PACKET_SIZE_MAX];
++    krad_attrset *attrset;
++    krb5_data pkt;
++    krb5_boolean is_fips;
++};
++
+ /* Validate constraints of an attribute. */
+ krb5_error_code
+ kr_attr_valid(krad_attr type, const krb5_data *data);
+@@ -57,7 +64,8 @@ kr_attr_valid(krad_attr type, const krb5_data *data);
+ krb5_error_code
+ kr_attr_encode(krb5_context ctx, const char *secret, const unsigned char *auth,
+                krad_attr type, const krb5_data *in,
+-               unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
++               unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
++               krb5_boolean *is_fips);
+ 
+ /* Decode an attribute. */
+ krb5_error_code
+@@ -69,7 +77,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
+ krb5_error_code
+ kr_attrset_encode(const krad_attrset *set, const char *secret,
+                   const unsigned char *auth,
+-                  unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen);
++                  unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
++                  krb5_boolean *is_fips);
+ 
+ /* Decode attributes from a buffer. */
+ krb5_error_code
+diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
+index c597174b6..794ac84c4 100644
+--- a/src/lib/krad/packet.c
++++ b/src/lib/krad/packet.c
+@@ -32,6 +32,7 @@
+ #include <string.h>
+ 
+ #include <arpa/inet.h>
++#include <openssl/crypto.h>
+ 
+ typedef unsigned char uchar;
+ 
+@@ -53,12 +54,6 @@ typedef unsigned char uchar;
+ #define pkt_auth(p) ((uchar *)offset(&(p)->pkt, OFFSET_AUTH))
+ #define pkt_attr(p) ((unsigned char *)offset(&(p)->pkt, OFFSET_ATTR))
+ 
+-struct krad_packet_st {
+-    char buffer[KRAD_PACKET_SIZE_MAX];
+-    krad_attrset *attrset;
+-    krb5_data pkt;
+-};
+-
+ typedef struct {
+     uchar x[(UCHAR_MAX + 1) / 8];
+ } idmap;
+@@ -187,8 +182,13 @@ auth_generate_response(krb5_context ctx, const char *secret,
+     memcpy(data.data + response->pkt.length, secret, strlen(secret));
+ 
+     /* Hash it. */
+-    retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
+-                                  &hash);
++    if (FIPS_mode()) {
++        /* This checksum does very little security-wise anyway, so don't
++         * taint. */
++        hash.contents = calloc(1, AUTH_FIELD_SIZE);
++    } else
++        retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
++                                      &hash);
+     free(data.data);
+     if (retval != 0)
+         return retval;
+@@ -276,7 +276,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
+ 
+     /* Encode the attributes. */
+     retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
+-                               &attrset_len);
++                               &attrset_len, &pkt->is_fips);
+     if (retval != 0)
+         goto error;
+ 
+@@ -314,7 +314,7 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
+ 
+     /* Encode the attributes. */
+     retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
+-                               &attrset_len);
++                               &attrset_len, &pkt->is_fips);
+     if (retval != 0)
+         goto error;
+ 
+@@ -451,6 +451,8 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
+ const krb5_data *
+ krad_packet_encode(const krad_packet *pkt)
+ {
++    if (pkt->is_fips)
++        return NULL;
+     return &pkt->pkt;
+ }
+ 
+diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
+index 437f7e91a..0f90443ce 100644
+--- a/src/lib/krad/remote.c
++++ b/src/lib/krad/remote.c
+@@ -263,7 +263,7 @@ on_io_write(krad_remote *rr)
+     request *r;
+ 
+     K5_TAILQ_FOREACH(r, &rr->list, list) {
+-        tmp = krad_packet_encode(r->request);
++        tmp = &r->request->pkt;
+ 
+         /* If the packet has already been sent, do nothing. */
+         if (r->sent == tmp->length)
+@@ -359,7 +359,7 @@ on_io_read(krad_remote *rr)
+     if (req != NULL) {
+         K5_TAILQ_FOREACH(r, &rr->list, list) {
+             if (r->request == req &&
+-                r->sent == krad_packet_encode(req)->length) {
++                r->sent == req->pkt.length) {
+                 request_finish(r, 0, rsp);
+                 break;
+             }
+@@ -455,6 +455,12 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
+                                      (krad_packet_iter_cb)iterator, &r, &tmp);
+     if (retval != 0)
+         goto error;
++    else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL &&
++        rr->info->ai_family != AF_UNIX) {
++        /* This would expose cleartext passwords, so abort. */
++        retval = ESOCKTNOSUPPORT;
++        goto error;
++    }
+ 
+     K5_TAILQ_FOREACH(r, &rr->list, list) {
+         if (r->request == tmp) {
+diff --git a/src/lib/krad/t_attr.c b/src/lib/krad/t_attr.c
+index eb2a780c8..4d285ad9d 100644
+--- a/src/lib/krad/t_attr.c
++++ b/src/lib/krad/t_attr.c
+@@ -50,6 +50,7 @@ main()
+     const char *tmp;
+     krb5_data in;
+     size_t len;
++    krb5_boolean is_fips = FALSE;
+ 
+     noerror(krb5_init_context(&ctx));
+ 
+@@ -73,7 +74,7 @@ main()
+     in = string2data((char *)decoded);
+     retval = kr_attr_encode(ctx, secret, auth,
+                             krad_attr_name2num("User-Password"),
+-                            &in, outbuf, &len);
++                            &in, outbuf, &len, &is_fips);
+     insist(retval == 0);
+     insist(len == sizeof(encoded));
+     insist(memcmp(outbuf, encoded, len) == 0);
+diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
+index 7928335ca..0f9576253 100644
+--- a/src/lib/krad/t_attrset.c
++++ b/src/lib/krad/t_attrset.c
+@@ -49,6 +49,7 @@ main()
+     krb5_context ctx;
+     size_t len = 0, encode_len;
+     krb5_data tmp;
++    krb5_boolean is_fips = FALSE;
+ 
+     noerror(krb5_init_context(&ctx));
+     noerror(krad_attrset_new(ctx, &set));
+@@ -62,7 +63,8 @@ main()
+     noerror(krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp));
+ 
+     /* Encode attrset. */
+-    noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len));
++    noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len,
++                              &is_fips));
+     krad_attrset_free(set);
+ 
+     /* Manually encode User-Name. */
+diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
+index 00734a13b..a3ce22b70 100644
+--- a/src/plugins/preauth/spake/spake_client.c
++++ b/src/plugins/preauth/spake/spake_client.c
+@@ -38,6 +38,8 @@
+ #include "groups.h"
+ #include <krb5/clpreauth_plugin.h>
+ 
++#include <openssl/crypto.h>
++
+ typedef struct reqstate_st {
+     krb5_pa_spake *msg;         /* set in prep_questions, used in process */
+     krb5_keyblock *initial_key;
+@@ -375,6 +377,10 @@ clpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
+ 
+     if (maj_ver != 1)
+         return KRB5_PLUGIN_VER_NOTSUPP;
++
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     vt = (krb5_clpreauth_vtable)vtable;
+     vt->name = "spake";
+     vt->pa_type_list = pa_types;
+diff --git a/src/plugins/preauth/spake/spake_kdc.c b/src/plugins/preauth/spake/spake_kdc.c
+index 59e88409e..1b3e569e9 100644
+--- a/src/plugins/preauth/spake/spake_kdc.c
++++ b/src/plugins/preauth/spake/spake_kdc.c
+@@ -41,6 +41,8 @@
+ 
+ #include <krb5/kdcpreauth_plugin.h>
+ 
++#include <openssl/crypto.h>
++
+ /*
+  * The SPAKE kdcpreauth module uses a secure cookie containing the following
+  * concatenated fields (all integer fields are big-endian):
+@@ -578,6 +580,10 @@ kdcpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
+ 
+     if (maj_ver != 1)
+         return KRB5_PLUGIN_VER_NOTSUPP;
++
++    if (FIPS_mode())
++        return KRB5_CRYPTO_INTERNAL;
++
+     vt = (krb5_kdcpreauth_vtable)vtable;
+     vt->name = "spake";
+     vt->pa_type_list = pa_types;
diff --git a/SOURCES/krb5-1.3.1-dns.patch b/SOURCES/krb5-1.3.1-dns.patch
new file mode 100644
index 0000000..819bf9f
--- /dev/null
+++ b/SOURCES/krb5-1.3.1-dns.patch
@@ -0,0 +1,22 @@
+From 19f0dc268c127fb51c4bb8c106104eee67119cca Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:46:21 -0400
+Subject: [PATCH] krb5-1.3.1-dns.patch
+
+We want to be able to use --with-netlib and --enable-dns at the same time.
+---
+ src/aclocal.m4 | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/aclocal.m4 b/src/aclocal.m4
+index a7afec09e..db18226ed 100644
+--- a/src/aclocal.m4
++++ b/src/aclocal.m4
+@@ -726,6 +726,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),
+ 	LIBS="$LIBS $withval"
+ 	AC_MSG_RESULT("netlib will use \'$withval\'")
+   fi
++  KRB5_AC_ENABLE_DNS
+ ],dnl
+ [AC_LIBRARY_NET]
+ )])dnl
diff --git a/SOURCES/krb5-1.9-debuginfo.patch b/SOURCES/krb5-1.9-debuginfo.patch
new file mode 100644
index 0000000..21971ff
--- /dev/null
+++ b/SOURCES/krb5-1.9-debuginfo.patch
@@ -0,0 +1,39 @@
+From 56954a72afe83cce5168bc139139d7f74c3685d6 Mon Sep 17 00:00:00 2001
+From: Robbie Harwood <rharwood@redhat.com>
+Date: Tue, 23 Aug 2016 16:49:25 -0400
+Subject: [PATCH] krb5-1.9-debuginfo.patch
+
+We want to keep these y.tab.c files around because the debuginfo points to
+them.  It would be more elegant at the end to use symbolic links, but that
+could mess up people working in the tree on other things.
+---
+ src/kadmin/cli/Makefile.in                 | 5 +++++
+ src/plugins/kdb/ldap/ldap_util/Makefile.in | 2 +-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/kadmin/cli/Makefile.in b/src/kadmin/cli/Makefile.in
+index adfea6e2b..d1327e400 100644
+--- a/src/kadmin/cli/Makefile.in
++++ b/src/kadmin/cli/Makefile.in
+@@ -37,3 +37,8 @@ clean-unix::
+ # CC_LINK is not meant for compilation and this use may break in the future.
+ datetest: getdate.c
+ 	$(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c
++
++%.c: %.y
++	$(RM) y.tab.c $@
++	$(YACC.y) $< 
++	$(CP) y.tab.c $@
+diff --git a/src/plugins/kdb/ldap/ldap_util/Makefile.in b/src/plugins/kdb/ldap/ldap_util/Makefile.in
+index 8669c2436..a22f23c02 100644
+--- a/src/plugins/kdb/ldap/ldap_util/Makefile.in
++++ b/src/plugins/kdb/ldap/ldap_util/Makefile.in
+@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIB) $(GETDATE)
+ getdate.c: $(GETDATE)
+ 	$(RM) getdate.c y.tab.c
+ 	$(YACC) $(GETDATE)
+-	$(MV) y.tab.c getdate.c
++	$(CP) y.tab.c getdate.c
+ 
+ install:
+ 	$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)
diff --git a/SOURCES/krb5-krb5kdc.conf b/SOURCES/krb5-krb5kdc.conf
new file mode 100644
index 0000000..eadeb51
--- /dev/null
+++ b/SOURCES/krb5-krb5kdc.conf
@@ -0,0 +1 @@
+d /var/run/krb5kdc 0755 root root
diff --git a/SOURCES/krb5.conf b/SOURCES/krb5.conf
new file mode 100644
index 0000000..c45f388
--- /dev/null
+++ b/SOURCES/krb5.conf
@@ -0,0 +1,28 @@
+# To opt out of the system crypto-policies configuration of krb5, remove the
+# symlink at /etc/krb5.conf.d/crypto-policies which will not be recreated.
+includedir /etc/krb5.conf.d/
+
+[logging]
+    default = FILE:/var/log/krb5libs.log
+    kdc = FILE:/var/log/krb5kdc.log
+    admin_server = FILE:/var/log/kadmind.log
+
+[libdefaults]
+    dns_lookup_realm = false
+    ticket_lifetime = 24h
+    renew_lifetime = 7d
+    forwardable = true
+    rdns = false
+    pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
+    spake_preauth_groups = edwards25519
+#    default_realm = EXAMPLE.COM
+
+[realms]
+# EXAMPLE.COM = {
+#     kdc = kerberos.example.com
+#     admin_server = kerberos.example.com
+# }
+
+[domain_realm]
+# .example.com = EXAMPLE.COM
+# example.com = EXAMPLE.COM
diff --git a/SOURCES/krb5kdc.logrotate b/SOURCES/krb5kdc.logrotate
new file mode 100644
index 0000000..1100ed3
--- /dev/null
+++ b/SOURCES/krb5kdc.logrotate
@@ -0,0 +1,9 @@
+/var/log/krb5kdc.log {
+    missingok
+    notifempty
+    monthly
+    rotate 12
+    postrotate
+	/bin/kill -HUP `cat /var/run/krb5kdc.pid 2>/dev/null` 2> /dev/null || true
+    endscript
+}
diff --git a/SOURCES/krb5kdc.service b/SOURCES/krb5kdc.service
new file mode 100644
index 0000000..806b062
--- /dev/null
+++ b/SOURCES/krb5kdc.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Kerberos 5 KDC
+Wants=network-online.target
+After=syslog.target network.target network-online.target
+
+[Service]
+Type=forking
+PIDFile=/var/run/krb5kdc.pid
+EnvironmentFile=-/etc/sysconfig/krb5kdc
+ExecStart=/usr/sbin/krb5kdc -P /var/run/krb5kdc.pid $KRB5KDC_ARGS
+ExecReload=/bin/kill -HUP $MAINPID
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/krb5kdc.sysconfig b/SOURCES/krb5kdc.sysconfig
new file mode 100644
index 0000000..791216d
--- /dev/null
+++ b/SOURCES/krb5kdc.sysconfig
@@ -0,0 +1 @@
+KRB5KDC_ARGS=
diff --git a/SOURCES/ksu.pamd b/SOURCES/ksu.pamd
new file mode 100644
index 0000000..66f5b2c
--- /dev/null
+++ b/SOURCES/ksu.pamd
@@ -0,0 +1,4 @@
+#%PAM-1.0
+auth    include  su
+account include  su
+session include  su
diff --git a/SPECS/krb5.spec b/SPECS/krb5.spec
new file mode 100644
index 0000000..b285a4b
--- /dev/null
+++ b/SPECS/krb5.spec
@@ -0,0 +1,3714 @@
+%global WITH_DIRSRV 1
+
+# Set this so that find-lang.sh will recognize the .po files.
+%global gettext_domain mit-krb5
+# Guess where the -libs subpackage's docs are going to go.
+%define libsdocdir %{?_pkgdocdir:%(echo %{_pkgdocdir} | sed -e s,krb5,krb5-libs,g)}%{!?_pkgdocdir:%{_docdir}/%{name}-libs-%{version}}
+# Figure out where the default ccache lives and how we set it.
+%global configure_default_ccache_name 1
+%global configured_default_ccache_name KEYRING:persistent:%%{uid}
+
+# leave empty or set to e.g., -beta2
+%global prerelease %{nil}
+
+# Should be in form 5.0, 6.1, etc.
+%global kdbversion 7.0
+
+Summary: The Kerberos network authentication system
+Name: krb5
+Version: 1.17
+# for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces)
+Release: 18%{?dist}
+
+# lookaside-cached sources; two downloads and a build artifact
+Source0: https://web.mit.edu/kerberos/dist/krb5/1.17/krb5-%{version}%{prerelease}.tar.gz
+# rharwood has trust path to signing key and verifies on check-in
+Source1: https://web.mit.edu/kerberos/dist/krb5/1.17/krb5-%{version}%{prerelease}.tar.gz.asc
+# This source is generated during the build because it is documentation.
+# To override this behavior (e.g., new upstream version), do:
+#     tar cfT krb5-1.15.2-pdfs.tar /dev/null
+# or the like.  This logic persists due to how slow the stranger Fedora
+# architecture builders are.  5 minutes on my laptop, 45 on koji easy.
+Source3: krb5-%{version}%{prerelease}-pdfs.tar
+
+# Numbering is a relic of old init systems etc.  It's easiest to just leave.
+Source2: kprop.service
+Source4: kadmin.service
+Source5: krb5kdc.service
+Source6: krb5.conf
+Source10: kdc.conf
+Source11: kadm5.acl
+Source19: krb5kdc.sysconfig
+Source20: kadmin.sysconfig
+Source21: kprop.sysconfig
+Source29: ksu.pamd
+Source33: krb5kdc.logrotate
+Source34: kadmind.logrotate
+Source39: krb5-krb5kdc.conf
+
+Patch26: krb5-1.12.1-pam.patch
+Patch27: krb5-1.17-beta1-selinux-label.patch
+Patch28: krb5-1.12-ksu-path.patch
+Patch29: krb5-1.12-ktany.patch
+Patch30: krb5-1.15-beta1-buildconf.patch
+Patch31: krb5-1.3.1-dns.patch
+Patch32: krb5-1.12-api.patch
+Patch33: krb5-1.13-dirsrv-accountlock.patch
+Patch34: krb5-1.9-debuginfo.patch
+Patch35: krb5-1.11-run_user_0.patch
+Patch36: krb5-1.11-kpasswdtest.patch
+Patch88: Add-tests-for-KCM-ccache-type.patch
+Patch89: Properly-size-ifdef-in-k5_cccol_lock.patch
+Patch90: Fix-memory-leak-in-none-replay-cache-type.patch
+Patch91: Address-some-optimized-out-memset-calls.patch
+Patch95: In-rd_req_dec-always-log-non-permitted-enctypes.patch
+Patch96: In-kpropd-debug-log-proper-ticket-enctype-names.patch
+Patch97: Make-etype-names-in-KDC-logs-human-readable.patch
+Patch98: Mark-deprecated-enctypes-when-used.patch
+Patch99: Add-function-and-enctype-flag-for-deprecations.patch
+Patch100: Fix-argument-order-on-strlcpy-in-enctype_name.patch
+Patch101: Fix-KCM-client-time-offset-propagation.patch
+Patch102: Add-soft-pkcs11-source-code.patch
+Patch103: Use-imported-soft-pkcs11-for-tests.patch
+Patch104: Fix-Coverity-defects-in-soft-pkcs11-test-code.patch
+Patch105: Fix-memory-leaks-in-soft-pkcs11-code.patch
+Patch106: Avoid-alignment-warnings-in-openssl-rc4.c.patch
+Patch107: Use-backported-version-of-OpenSSL-3-KDF-interface.patch
+Patch108: krb5-1.17post6-FIPS-with-PRNG-and-RADIUS-and-MD4.patch
+Patch109: krb5-1.17post2-DES-3DES-fixups.patch
+Patch110: Put-KDB-authdata-first.patch
+
+License: MIT
+URL: http://web.mit.edu/kerberos/www/
+Group: System Environment/Libraries
+
+BuildRequires: autoconf, bison, cmake, flex, gawk, gettext, pkgconfig, sed
+BuildRequires: gcc
+BuildRequires: libcom_err-devel, libedit-devel, libss-devel
+BuildRequires: gzip, ncurses-devel
+BuildRequires: python3-sphinx, texlive-pdftex, latexmk
+BuildRequires: libverto-devel
+BuildRequires: openldap-devel
+BuildRequires: python3
+BuildRequires: keyutils, keyutils-libs-devel >= 1.5.8
+BuildRequires: libselinux-devel
+BuildRequires: pam-devel
+BuildRequires: tcl-devel
+BuildRequires: openssl-devel >= 1:1.1.1c-4
+
+# For autosetup
+BuildRequires: git
+
+# Originally from \usepackage directives produced by sphinx:
+BuildRequires: tex(babel.sty)
+BuildRequires: tex(bookmark.sty)
+BuildRequires: tex(capt-of.sty)
+BuildRequires: tex(eqparbox.sty)
+BuildRequires: tex(fancybox.sty)
+BuildRequires: tex(fncychap.sty)
+BuildRequires: tex(fontenc.sty)
+BuildRequires: tex(framed.sty)
+BuildRequires: tex(hyperref.sty)
+BuildRequires: tex(ifthen.sty)
+BuildRequires: tex(inputenc.sty)
+BuildRequires: tex(longtable.sty)
+BuildRequires: tex(multirow.sty)
+BuildRequires: tex(needspace.sty)
+BuildRequires: tex(report.cls)
+BuildRequires: tex(tabulary.sty)
+BuildRequires: tex(threeparttable.sty)
+BuildRequires: tex(times.sty)
+BuildRequires: tex(titlesec.sty)
+BuildRequires: tex(upquote.sty)
+BuildRequires: tex(wrapfig.sty)
+
+# Typical fonts, and the commands which we need to have present.
+BuildRequires: texlive, texlive-latex, texlive-texmf-fonts
+BuildRequires: /usr/bin/pdflatex /usr/bin/makeindex
+BuildRequires: systemd-units
+
+%ifarch %{ix86} x86_64
+BuildRequires: yasm
+%endif
+
+%description
+Kerberos V5 is a trusted-third-party network authentication system,
+which can improve your network's security by eliminating the insecure
+practice of sending passwords over the network in unencrypted form.
+
+%package devel
+Summary: Development files needed to compile Kerberos 5 programs
+Group: Development/Libraries
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+Requires: libkadm5%{?_isa} = %{version}-%{release}
+Requires: libcom_err-devel
+Requires: keyutils-libs-devel, libselinux-devel
+Requires: libverto-devel
+Provides: krb5-kdb-devel-version = %{kdbversion}
+# IPA wants ^ to be a separate symbol because they don't trust package
+# managers to match -server and -devel in version.  Just go with it.
+
+%description devel
+Kerberos is a network authentication system. The krb5-devel package
+contains the header files and libraries needed for compiling Kerberos
+5 programs. If you want to develop Kerberos-aware programs, you need
+to install this package.
+
+%package libs
+Summary: The non-admin shared libraries used by Kerberos 5
+Group: System Environment/Libraries
+Requires: coreutils, gawk, grep, sed
+Requires: keyutils-libs >= 1.5.8
+Requires: openssl-libs >= 1:1.1.1c-4
+Requires: /etc/crypto-policies/back-ends/krb5.config
+
+%description libs
+Kerberos is a network authentication system. The krb5-libs package
+contains the shared libraries needed by Kerberos 5. If you are using
+Kerberos, you need to install this package.
+
+%package server
+Group: System Environment/Daemons
+Summary: The KDC and related programs for Kerberos 5
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+Requires(post): systemd-units
+Requires(preun): systemd-units
+Requires(postun): systemd-units
+# we drop files in its directory, but we don't want to own that directory
+Requires: logrotate
+# we specify /usr/share/dict/words as the default dict_file in kdc.conf
+Requires: /usr/share/dict/words
+# for run-time, and for parts of the test suite
+BuildRequires: libverto-module-base
+Requires: libverto-module-base
+%ifarch x86_64
+Obsoletes: %{name}-server-%{version}-%{release}.i686
+%endif
+%ifarch ppc64
+Obsoletes: %{name}-server-%{version}-%{release}.ppc
+%endif
+%ifarch s390x
+Obsoletes: %{name}-server-%{version}-%{release}.s390
+%endif
+Requires: libkadm5%{?_isa} = %{version}-%{release}
+Provides: krb5-kdb-version = %{kdbversion}
+
+%description server
+Kerberos is a network authentication system. The krb5-server package
+contains the programs that must be installed on a Kerberos 5 key
+distribution center (KDC).  If you are installing a Kerberos 5 KDC,
+you need to install this package (in other words, most people should
+NOT install this package).
+
+%package server-ldap
+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}
+Requires: libkadm5%{?_isa} = %{version}-%{release}
+%ifarch x86_64
+Obsoletes: %{name}-server-ldap-%{version}-%{release}.i686
+%endif
+%ifarch ppc64
+Obsoletes: %{name}-server-ldap-%{version}-%{release}.ppc
+%endif
+%ifarch s390x
+Obsoletes: %{name}-server-ldap-%{version}-%{release}.s390
+%endif
+
+%description server-ldap
+Kerberos is a network authentication system. The krb5-server package
+contains the programs that must be installed on a Kerberos 5 key
+distribution center (KDC).  If you are installing a Kerberos 5 KDC,
+and you wish to use a directory server to store the data for your
+realm, you need to install this package.
+
+%package workstation
+Summary: Kerberos 5 programs for use on workstations
+Group: System Environment/Base
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+Requires: libkadm5%{?_isa} = %{version}-%{release}
+
+%description workstation
+Kerberos is a network authentication system. The krb5-workstation
+package contains the basic Kerberos programs (kinit, klist, kdestroy,
+kpasswd). If your network uses Kerberos, this package should be
+installed on every workstation.
+
+%package pkinit
+Summary: The PKINIT module for Kerberos 5
+Group: System Environment/Libraries
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+Obsoletes: krb5-pkinit-openssl < %{version}-%{release}
+Provides: krb5-pkinit-openssl = %{version}-%{release}
+
+%description pkinit
+Kerberos is a network authentication system. The krb5-pkinit
+package contains the PKINIT plugin, which allows clients
+to obtain initial credentials from a KDC using a private key and a
+certificate.
+
+%package -n libkadm5
+Summary: Kerberos 5 Administrative libraries
+Group: System Environment/Base
+Requires: %{name}-libs%{?_isa} = %{version}-%{release}
+
+%description -n libkadm5
+Kerberos is a network authentication system. The libkadm5 package
+contains only the libkadm5clnt and libkadm5serv shared objects. This
+interface is not considered stable.
+
+%prep
+%autosetup -S git -n %{name}-%{version}%{prerelease} -a 3
+ln NOTICE LICENSE
+
+# Take the execute bit off of documentation.
+chmod -x doc/ccapi/*.html
+
+# Generate an FDS-compatible LDIF file.
+inldif=src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif
+cat > '60kerberos.ldif' << EOF
+# This is a variation on kerberos.ldif which 389 Directory Server will like.
+dn: cn=schema
+EOF
+egrep -iv '(^$|^dn:|^changetype:|^add:)' $inldif | \
+sed -r 's,^		,                ,g' | \
+sed -r 's,^	,        ,g' >> 60kerberos.ldif
+touch -r $inldif 60kerberos.ldif
+
+# Rebuild the configure scripts.
+pushd src
+autoreconf -fiv
+popd
+
+# Mess with some of the default ports that we use for testing, so that multiple
+# builds going on the same host don't step on each other.
+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"
+LONG_BIT=`getconf LONG_BIT`
+PORT=`expr 61000 + $LONG_BIT - 48`
+sed -i -e s,61000,`expr "$PORT" + 0`,g $cfg
+PORT=`expr 1750 + $LONG_BIT - 48`
+sed -i -e s,1750,`expr "$PORT" + 0`,g $cfg
+sed -i -e s,1751,`expr "$PORT" + 1`,g $cfg
+sed -i -e s,1752,`expr "$PORT" + 2`,g $cfg
+PORT=`expr 8888 + $LONG_BIT - 48`
+sed -i -e s,8888,`expr "$PORT" - 0`,g $cfg
+sed -i -e s,8887,`expr "$PORT" - 1`,g $cfg
+sed -i -e s,8886,`expr "$PORT" - 2`,g $cfg
+PORT=`expr 7777 + $LONG_BIT - 48`
+sed -i -e s,7777,`expr "$PORT" + 0`,g $cfg
+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.
+source %{_libdir}/tclConfig.sh
+pushd src
+
+# Set this so that configure will have a value even if the current version of
+# autoconf doesn't set one.
+export runstatedir=%{_localstatedir}/run
+# Work out the CFLAGS and CPPFLAGS which we intend to use.
+INCLUDES=-I%{_includedir}/et
+CFLAGS="`echo $RPM_OPT_FLAGS $DEFINES $INCLUDES -fPIC -fno-strict-aliasing -fstack-protector-all`"
+CPPFLAGS="`echo $DEFINES $INCLUDES`"
+%configure \
+	CC="%{__cc}" \
+	CFLAGS="$CFLAGS" \
+	CPPFLAGS="$CPPFLAGS" \
+	SS_LIB="-lss" \
+	--enable-shared \
+	--localstatedir=%{_var}/kerberos \
+	--disable-rpath \
+	--without-krb5-config \
+	--with-system-et \
+	--with-system-ss \
+	--with-netlib=-lresolv \
+	--with-tcl \
+	--enable-dns-for-realm \
+	--with-ldap \
+%if %{WITH_DIRSRV}
+	--with-dirsrv-account-locking \
+%endif
+	--enable-pkinit \
+	--with-crypto-impl=openssl \
+	--with-pkinit-crypto-impl=openssl \
+	--with-tls-impl=openssl \
+	--with-system-verto \
+	--with-pam \
+	--with-selinux \
+	--with-prng-alg=os \
+	|| (cat config.log; exit 1)
+# Now build it.
+make
+popd
+
+# Sanity check the KDC_RUN_DIR.
+configured_kdcrundir=`grep KDC_RUN_DIR src/include/osconf.h | awk '{print $NF}'`
+configured_kdcrundir=`eval echo $configured_kdcrundir`
+if test "$configured_kdcrundir" != %{_localstatedir}/run/krb5kdc ; then
+	exit 1
+fi
+
+# Build the docs.
+make -C src/doc paths.py version.py
+cp src/doc/paths.py doc/
+mkdir -p build-man build-html build-pdf
+sphinx-build -a -b man   -t pathsubs doc build-man
+sphinx-build -a -b html  -t pathsubs doc build-html
+rm -fr build-html/_sources
+sphinx-build -a -b latex -t pathsubs doc build-pdf
+# Build the PDFs if we didn't have pre-built ones.
+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
+tar -cf "krb5-%{version}%{prerelease}-pdfs.tar.new" build-pdf/*.pdf
+
+%install
+[ "$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
+install -pm 600 %{SOURCE10} $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc/
+install -pm 600 %{SOURCE11} $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc/
+
+# Where per-user keytabs live by default.
+mkdir -p $RPM_BUILD_ROOT%{_var}/kerberos/krb5/user
+
+# Default configuration file for everything.
+mkdir -p $RPM_BUILD_ROOT/etc
+install -pm 644 %{SOURCE6} $RPM_BUILD_ROOT/etc/krb5.conf
+
+# Default include on this directory
+mkdir -p $RPM_BUILD_ROOT/etc/krb5.conf.d
+ln -sv /etc/crypto-policies/back-ends/krb5.config $RPM_BUILD_ROOT/etc/krb5.conf.d/crypto-policies
+
+# Parent of configuration file for list of loadable GSS mechs ("mechs").  This
+# location is not relative to sysconfdir, but is hard-coded in g_initialize.c.
+mkdir -m 755 -p $RPM_BUILD_ROOT/etc/gss
+# Parent of groups of configuration files for a list of loadable GSS mechs
+# ("mechs").  This location is not relative to sysconfdir, and is also
+# hard-coded in g_initialize.c.
+mkdir -m 755 -p $RPM_BUILD_ROOT/etc/gss/mech.d
+
+# If the default configuration needs to start specifying a default cache
+# location, add it now, then fixup the timestamp so that it looks the same.
+%if 0%{?configure_default_ccache_name}
+export DEFCCNAME="%{configured_default_ccache_name}"
+awk '{print}
+     /^#    default_realm/{print "    default_ccache_name =", ENVIRON["DEFCCNAME"]}' \
+     %{SOURCE6} > $RPM_BUILD_ROOT/etc/krb5.conf
+touch -r %{SOURCE6} $RPM_BUILD_ROOT/etc/krb5.conf
+grep default_ccache_name $RPM_BUILD_ROOT/etc/krb5.conf
+%endif
+
+# Server init scripts (krb5kdc,kadmind,kpropd) and their sysconfig files.
+mkdir -p $RPM_BUILD_ROOT%{_unitdir}
+for unit in \
+	%{SOURCE5}\
+	%{SOURCE4} \
+	%{SOURCE2} ; do
+	# In the past, the init script was supposed to be named after the
+	# service that the started daemon provided.  Changing their names
+	# is an upgrade-time problem I'm in no hurry to deal with.
+	install -pm 644 ${unit} $RPM_BUILD_ROOT%{_unitdir}
+done
+mkdir -p $RPM_BUILD_ROOT/%{_tmpfilesdir}
+install -pm 644 %{SOURCE39} $RPM_BUILD_ROOT/%{_tmpfilesdir}/
+mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/run/krb5kdc
+
+mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
+for sysconfig in \
+	%{SOURCE19}\
+	%{SOURCE20}\
+	%{SOURCE21} ; do
+	install -pm 644 ${sysconfig} \
+	$RPM_BUILD_ROOT/etc/sysconfig/`basename ${sysconfig} .sysconfig`
+done
+
+# logrotate configuration files
+mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d/
+for logrotate in \
+	%{SOURCE33} \
+	%{SOURCE34} ; do
+	install -pm 644 ${logrotate} \
+	$RPM_BUILD_ROOT/etc/logrotate.d/`basename ${logrotate} .logrotate`
+done
+
+# PAM configuration files.
+mkdir -p $RPM_BUILD_ROOT/etc/pam.d/
+for pam in \
+	%{SOURCE29} ; do
+	install -pm 644 ${pam} \
+	$RPM_BUILD_ROOT/etc/pam.d/`basename ${pam} .pamd`
+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/authdata
+
+# The rest of the binaries, headers, libraries, and docs.
+make -C src DESTDIR=$RPM_BUILD_ROOT EXAMPLEDIR=%{libsdocdir}/examples install
+
+# Munge krb5-config yet again.  This is totally wrong for 64-bit, but chunks
+# of the buildconf patch already conspire to strip out /usr/<anything> from the
+# 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
+
+# Temporay workaround for krb5-config reading too much from LDFLAGS.
+# Upstream: http://krbdev.mit.edu/rt/Ticket/Display.html?id=8159
+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
+
+# Install processed man pages.
+for section in 1 5 8 ; do
+	install -m 644 build-man/*.${section} \
+		       $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"
+
+# These files are already packaged elsewhere
+rm -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/kdc.conf"
+rm -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/krb5.conf"
+rm -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/services.append"
+
+# This is only needed for tests
+rm -- "$RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/preauth/test.so"
+
+%find_lang %{gettext_domain}
+
+%ldconfig_scriptlets libs
+
+%triggerun libs -- krb5-libs < 1.15.1-5
+if ! grep -q 'includedir /etc/krb5.conf.d' /etc/krb5.conf ; then
+    sed -i '1i # To opt out of the system crypto-policies configuration of krb5, remove the\n# symlink at /etc/krb5.conf.d/crypto-policies which will not be recreated.\nincludedir /etc/krb5.conf.d/\n' /etc/krb5.conf
+fi
+exit 0
+
+%ldconfig_scriptlets server-ldap
+
+%post server
+%systemd_post krb5kdc.service kadmin.service kprop.service
+# assert sanity.  A cleaner solution probably exists but it is opaque
+/bin/systemctl daemon-reload
+exit 0
+
+%preun server
+%systemd_preun krb5kdc.service kadmin.service kprop.service
+exit 0
+
+%postun server
+%systemd_postun_with_restart krb5kdc.service kadmin.service kprop.service
+exit 0
+
+%ldconfig_scriptlets -n libkadm5
+
+%files workstation
+%doc src/config-files/services.append
+%doc src/config-files/krb5.conf
+%doc build-html/*
+%doc build-pdf/user.pdf build-pdf/basic.pdf
+%attr(0755,root,root) %doc src/config-files/convert-config-files
+
+# Clients of the KDC, including tools you're likely to need if you're running
+# app servers other than those built from this source package.
+%{_bindir}/kdestroy
+%{_mandir}/man1/kdestroy.1*
+%{_bindir}/kinit
+%{_mandir}/man1/kinit.1*
+%{_bindir}/klist
+%{_mandir}/man1/klist.1*
+%{_bindir}/kpasswd
+%{_mandir}/man1/kpasswd.1*
+%{_bindir}/kswitch
+%{_mandir}/man1/kswitch.1*
+
+%{_bindir}/kvno
+%{_mandir}/man1/kvno.1*
+%{_bindir}/kadmin
+%{_mandir}/man1/kadmin.1*
+%{_bindir}/k5srvutil
+%{_mandir}/man1/k5srvutil.1*
+%{_bindir}/ktutil
+%{_mandir}/man1/ktutil.1*
+
+# Doesn't really fit anywhere else.
+%attr(4755,root,root) %{_bindir}/ksu
+%{_mandir}/man1/ksu.1*
+%config(noreplace) /etc/pam.d/ksu
+
+%files server
+%docdir %{_mandir}
+%doc build-pdf/admin.pdf build-pdf/build.pdf
+%doc src/config-files/kdc.conf
+%{_unitdir}/krb5kdc.service
+%{_unitdir}/kadmin.service
+%{_unitdir}/kprop.service
+%{_tmpfilesdir}/krb5-krb5kdc.conf
+%dir %{_localstatedir}/run/krb5kdc
+%config(noreplace) /etc/sysconfig/krb5kdc
+%config(noreplace) /etc/sysconfig/kadmin
+%config(noreplace) /etc/sysconfig/kprop
+%config(noreplace) /etc/logrotate.d/krb5kdc
+%config(noreplace) /etc/logrotate.d/kadmind
+
+%dir %{_var}/kerberos
+%dir %{_var}/kerberos/krb5kdc
+%config(noreplace) %{_var}/kerberos/krb5kdc/kdc.conf
+%config(noreplace) %{_var}/kerberos/krb5kdc/kadm5.acl
+
+%dir %{_libdir}/krb5
+%dir %{_libdir}/krb5/plugins
+%dir %{_libdir}/krb5/plugins/kdb
+%dir %{_libdir}/krb5/plugins/preauth
+%dir %{_libdir}/krb5/plugins/authdata
+%{_libdir}/krb5/plugins/preauth/otp.so
+%{_libdir}/krb5/plugins/kdb/db2.so
+
+# KDC binaries and configuration.
+%{_mandir}/man5/kadm5.acl.5*
+%{_mandir}/man5/kdc.conf.5*
+%{_sbindir}/kadmin.local
+%{_mandir}/man8/kadmin.local.8*
+%{_sbindir}/kadmind
+%{_mandir}/man8/kadmind.8*
+%{_sbindir}/kdb5_util
+%{_mandir}/man8/kdb5_util.8*
+%{_sbindir}/kprop
+%{_mandir}/man8/kprop.8*
+%{_sbindir}/kpropd
+%{_mandir}/man8/kpropd.8*
+%{_sbindir}/kproplog
+%{_mandir}/man8/kproplog.8*
+%{_sbindir}/krb5kdc
+%{_mandir}/man8/krb5kdc.8*
+
+# This is here for people who want to test their server.  It was formerly also
+# included in -devel.
+%{_bindir}/sclient
+%{_mandir}/man1/sclient.1*
+%{_sbindir}/sserver
+%{_mandir}/man8/sserver.8*
+
+%files server-ldap
+%docdir %{_mandir}
+%doc src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif
+%doc src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema
+%doc 60kerberos.ldif
+%dir %{_libdir}/krb5
+%dir %{_libdir}/krb5/plugins
+%dir %{_libdir}/krb5/plugins/kdb
+%{_libdir}/krb5/plugins/kdb/kldap.so
+%{_libdir}/libkdb_ldap.so
+%{_libdir}/libkdb_ldap.so.*
+%{_mandir}/man8/kdb5_ldap_util.8.gz
+%{_sbindir}/kdb5_ldap_util
+
+%files libs -f %{gettext_domain}.lang
+%doc README NOTICE
+%{!?_licensedir:%global license %%doc}
+%license LICENSE
+%docdir %{_mandir}
+# These are hard-coded, not-dependent-on-the-configure-script paths.
+%dir /etc/gss
+%dir /etc/gss/mech.d
+%dir /etc/krb5.conf.d
+%config(noreplace) /etc/krb5.conf
+%config(noreplace) /etc/krb5.conf.d/crypto-policies
+/%{_mandir}/man5/.k5identity.5*
+/%{_mandir}/man5/.k5login.5*
+/%{_mandir}/man5/k5identity.5*
+/%{_mandir}/man5/k5login.5*
+/%{_mandir}/man5/krb5.conf.5*
+/%{_mandir}/man7/kerberos.7*
+%{_libdir}/libgssapi_krb5.so.*
+%{_libdir}/libgssrpc.so.*
+%{_libdir}/libk5crypto.so.*
+%{_libdir}/libkdb5.so.*
+%{_libdir}/libkrad.so.*
+%{_libdir}/libkrb5.so.*
+%{_libdir}/libkrb5support.so.*
+%dir %{_libdir}/krb5
+%dir %{_libdir}/krb5/plugins
+%dir %{_libdir}/krb5/plugins/*
+%{_libdir}/krb5/plugins/tls/k5tls.so
+%{_libdir}/krb5/plugins/preauth/spake.so
+%dir %{_var}/kerberos
+%dir %{_var}/kerberos/krb5
+%dir %{_var}/kerberos/krb5/user
+
+%files pkinit
+%dir %{_libdir}/krb5
+%dir %{_libdir}/krb5/plugins
+%dir %{_libdir}/krb5/plugins/preauth
+%{_libdir}/krb5/plugins/preauth/pkinit.so
+
+%files devel
+%docdir %{_mandir}
+%doc build-pdf/appdev.pdf build-pdf/plugindev.pdf
+
+%{_includedir}/*
+%{_libdir}/libgssapi_krb5.so
+%{_libdir}/libgssrpc.so
+%{_libdir}/libk5crypto.so
+%{_libdir}/libkdb5.so
+%{_libdir}/libkrad.so
+%{_libdir}/libkrb5.so
+%{_libdir}/libkrb5support.so
+%{_libdir}/pkgconfig/*
+
+%{_bindir}/krb5-config
+%{_mandir}/man1/krb5-config.1*
+
+# Protocol test clients.
+%{_bindir}/sim_client
+%{_bindir}/gss-client
+%{_bindir}/uuclient
+
+# Protocol test servers.
+%{_sbindir}/sim_server
+%{_sbindir}/gss-server
+%{_sbindir}/uuserver
+
+%files -n libkadm5
+%{_libdir}/libkadm5clnt.so
+%{_libdir}/libkadm5clnt_mit.so
+%{_libdir}/libkadm5srv.so
+%{_libdir}/libkadm5srv_mit.so
+%{_libdir}/libkadm5clnt_mit.so.*
+%{_libdir}/libkadm5srv_mit.so.*
+
+%changelog
+* Wed Feb 19 2020 Robbie Harwood <rharwood@redhat.com> - 1.17-18
+- Put KDB authdata first
+- Resolves: #1800575
+
+* Thu Nov 21 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-17
+- OpenSSL has an epoch, apparently
+- Resolves: #1754690
+
+* Wed Nov 20 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-16
+- Put openssl runtime requirement in the right place this time
+- Resolves: #1754690
+
+* Wed Nov 20 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-15
+- Restore accidentally dropped patch
+- Resolves: #1754690
+
+* Wed Nov 20 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-14
+- Fix krb5kdf support and add proper openssl version requirements
+- Resolves: #1754690
+
+* Tue Nov 19 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-13
+- Full FIPS compliance
+- Resolves: #1754690
+
+* Tue Oct 15 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-12
+- Backport soft-pkcs11 testing code
+- Resolves: #1734158
+
+* Tue Oct 15 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-11
+- Fix KCM client time offset propagation
+- Resolves: #1738553
+
+* Tue Oct 15 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-10
+- Fix source URLs in spec file
+- Resolves: #1755959
+
+* Tue Sep 17 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-9
+- Fix argument order on strlcpy() in enctype_name()
+- Resolves: #1754369
+
+* Wed Aug 07 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-8
+- Clean up etype display on KDC
+- Resolves: #1664157
+
+* Tue Jun 04 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-7
+- Fix pkinit_anchors path
+- Resolves: #1661339
+
+* Wed May 15 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-6
+- Re-provide krb5-kdb-version in -devel as well (IPA wants it)
+- Resolves: #1645594
+
+* Thu Apr 18 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-5
+- Move kdbversion info into -server for IPA (so we can rebase)
+- Resolves: #1645594
+
+* Mon Apr 01 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-4
+- FIPS: disable 3DES and ed25519
+- Resolves: #1616326
+
+* Tue Mar 19 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-3
+- Use openssl's PRNG in FIPS mode
+- Resolves: #1663571
+
+* Tue Mar 19 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-2
+- Address some optimized-out memset() calls
+- Resolves: #1663503
+
+* Mon Mar 18 2019 Robbie Harwood <rharwood@redhat.com> - 1.17-1
+- New upstream version (1.17)
+- Resolves: #1645594
+
+* Thu Feb 07 2019 Robbie Harwood <rharwood@redhat.com> - 1.16.1-22
+- Remove incorrect KDC assertion
+- Resolves: #1673016
+
+* Fri Feb 01 2019 Robbie Harwood <rharwood@redhat.com> - 1.16.1-21
+- Fix RC4 blocking in FIPS mode
+- Resolves: #1660222
+
+* Thu Dec 20 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-20
+- Gain FIPS awareness
+- Resolves: #1660222
+
+* Wed Aug 01 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-19
+- In FIPS mode, add plaintext fallback for RC4 usages and taint
+
+* Thu Jul 26 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-18
+- Fix k5test prompts for Python 3
+
+* Thu Jul 19 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-17
+- Remove outdated note in krb5kdc man page
+
+* Thu Jul 19 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-16
+- Make krb5kdc -p affect TCP ports
+
+* Thu Jul 19 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-15
+- Eliminate preprocessor-disabled dead code
+
+* Wed Jul 18 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-14
+- Fix some broken tests for Python 3
+
+* Mon Jul 16 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-13
+- Zap copy of secret in RC4 string-to-key
+
+* Thu Jul 12 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-12
+- Convert Python tests to Python 3
+
+* Wed Jul 11 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-11
+- Add build dependency on gcc
+
+* Tue Jul 10 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-10
+- Use SHA-256 instead of MD5 for audit ticket IDs
+
+* Fri Jul 06 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-9
+- Add BuildRequires on python2 so we can run tests at build-time
+
+* Fri Jul 06 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-8
+- Explicitly look for python2 in configure.in
+
+* Thu Jun 14 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-7
+- Add flag to disable encrypted timestamp on client
+
+* Thu Jun 14 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-6
+- Switch to python3-sphinx for docs
+- Resolves: #1590928
+
+* Thu Jun 14 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-5
+- Make docs build python3-compatible
+- Resolves: #1590928
+
+* Thu Jun 07 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-4
+- Update includedir processing to match upstream
+
+* Fri Jun 01 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-3
+- Log when non-root ksu authorization fails
+- Resolves: #1575771
+
+* Fri May 04 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-2
+- Remove "-nodes" option from make-certs scripts
+
+* Fri May 04 2018 Robbie Harwood <rharwood@redhat.com> - 1.16.1-1
+- New upstream release - 1.16.1
+
+* Thu May 03 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-27
+- Fix configuration of default ccache name to match file indentation
+
+* Mon Apr 30 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-26
+- Set error message on KCM get_princ failure
+
+* Mon Apr 30 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-25
+- Set error message on KCM get_princ failure
+
+* Tue Apr 24 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-24
+- Fix KDC null dereference on large TGS replies
+
+* Mon Apr 23 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-23
+- Explicitly use openssl rather than builtin crypto
+- Resolves: #1570910
+
+* Tue Apr 17 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-22
+- Merge duplicate subsections in profile library
+
+* Mon Apr 09 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-21
+- Restrict pre-authentication fallback cases
+
+* Tue Apr 03 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-20
+- Be more careful asking for AS key in SPAKE client
+
+* Mon Apr 02 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-19
+- Zap data when freeing krb5_spake_factor
+
+* Thu Mar 29 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-18
+- Continue after KRB5_CC_END in KCM cache iteration
+
+* Tue Mar 27 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-17
+- Fix SPAKE memory leak
+
+* Tue Mar 27 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-16
+- Fix gitignore problem with previous patchset
+
+* Tue Mar 27 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-15
+- Add SPAKE support
+- Improve protections on internal sensitive buffers
+- Improve internal hex encoding/decoding
+
+* Tue Mar 20 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-14
+- Fix problem with ccache_name logic in previous build
+
+* Tue Mar 20 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-13
+- Add pkinit_anchors default value to krb5.conf
+- Reindent krb5.conf to not be terrible
+
+* Tue Mar 20 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-12
+- Log preauth names in trace output
+- Misc bugfixes from upstream
+
+* Mon Mar 19 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-11
+- Add PKINIT KDC support for freshness token
+
+* Wed Mar 14 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-10
+- Exit with status 0 from kadmind
+
+* Tue Mar 13 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-9
+- Fix hex conversion of PKINIT certid strings
+
+* Wed Mar 07 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-8
+- Fix capaths "." values on client
+- Resolves: 1551099
+
+* Tue Feb 13 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-7
+- Fix flaws in LDAP DN checking
+- CVE-2018-5729, CVE-2018-5730
+
+* Mon Feb 12 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-6
+- Fix a leak in the previous commit
+- Restore dist macro that was accidentally removed
+- Resolves: #1540939
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.16-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Sat Feb 03 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.16-4
+- Switch to %%ldconfig_scriptlets
+
+* Mon Jan 29 2018 Robbie Harwood <rharwood@redhat.com> - 1.16-3
+- Process included directories in alphabetical order
+
+* Tue Dec 12 2017 Robbie Harwood <rharwood@redhat.com> - 1.16-2
+- Fix network service dependencies
+- Resolves: #1525230
+
+* Wed Dec 06 2017 Robbie Harwood <rharwood@redhat.com> - 1.16-1
+- New upstream release (1.16)
+- No changes from beta2
+
+* Mon Nov 27 2017 Robbie Harwood <rharwood@redhat.com> - 1.16-0.beta2.1
+- New upstream prerelease (1.16-beta2)
+
+* Tue Oct 24 2017 Robbie Harwood <rharwood@redhat.com> - 1.16-0.beta1.4
+- Fix CVE-2017-15088 (Buffer overflow in get_matching_data())
+
+* Mon Oct 23 2017 Robbie Harwood <rharwood@redhat.com> - 1.16-0.beta1.3
+- Drop dependency on python2-pyrad (dead upstream, broken with new python)
+
+* Mon Oct 09 2017 Robbie Harwood <rharwood@redhat.com> - 1.16-0.beta1.2
+- Actually bump kdbversion like I was supposed to
+
+* Thu Oct 05 2017 Robbie Harwood <rharwood@redhat.com> - 1.16-0.beta1.1
+- New upstream prerelease (1.16-beta1)
+
+* Thu Sep 28 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.2-2
+- Add German translation
+
+* Mon Sep 25 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.2-1
+- New upstream release - krb5-1.15.2
+- Adjust patches as appropriate
+
+* Wed Sep 06 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-28
+- Save other programs from worrying about CVE-2017-11462
+- Resolves: #1488873
+- Resolves: #1488874
+
+* Tue Sep 05 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-27
+- Add hostname-based ccselect module
+- Resolves: #1463665
+
+* Tue Sep 05 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-26
+- Backport upstream certauth EKU fixes
+
+* Fri Aug 25 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-25
+- Backport certauth eku security fix
+
+* Mon Aug 21 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-24
+- Backport kdc policy plugin, but this time with dependencies
+
+* Mon Aug 21 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-23
+- Backport kdcpolicy interface
+
+* Wed Aug 16 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-22
+
+* Mon Aug 07 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-21
+- Display an error message if ocsp pkinit is requested
+
+* Wed Aug 02 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-20
+- Disable dns_canonicalize_hostname.  This may break some setups.
+
+* Wed Aug 02 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-19
+- Re-enable test suite on ppc64le (no other changes)
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.15.1-18
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Thu Jul 20 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-17
+- Fix CVE-2017-11368 (remote triggerable assertion failure)
+
+* Wed Jul 19 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-16
+- Explicitly require python2 packages
+
+* Wed Jul 19 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-15
+- Add support to query the SSF of a context
+- Pick up rename of perl dependency
+
+* Thu Jul 06 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-14
+-  Fix leaks in gss_inquire_cred_by_oid()
+
+* Mon Jun 26 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-13
+- Fix arch name (ppc64le, not ppc64el)
+- Related-to: #1464381
+
+* Mon Jun 26 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-12
+- Skip test suite on ppc64el
+- Related-to: #1464381
+
+* Fri Jun 23 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-11
+- Include more test suite changes from upstream
+- Resolves: #1464381
+
+* Wed Jun 07 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-10
+- Fix custom build with -DDEBUG
+
+* Wed May 24 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-9
+- Use standard trigger logic for krb5 snippet
+
+* Fri Apr 28 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-8
+- Add kprop service env config file
+
+* Wed Apr 19 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-7
+- Update backports of certauth and corresponding test
+
+* Thu Apr 13 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-6
+- Include fixes for previous commit
+- Resolves: #1433083
+
+* Thu Apr 13 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-5
+- Automatically add includedir where not present
+- Try removing sleep statement to see if it is still needed
+- Resolves: #1433083
+
+* Fri Apr 07 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-4
+- Fix use of enterprise principals with forwarding
+
+* Wed Mar 22 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-3
+- Backport certauth plugin and related pkinit changes
+
+* Tue Mar 07 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-2
+- Remove duplication between subpackages
+- Resolves: #1250228
+
+* Fri Mar 03 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.1-1
+- New upstream release - 1.15.1
+
+* Wed Mar 01 2017 Robbie Harwood <rharwood@redhat.com> - 1.15-9
+- Patch build by disabling failing test; will fix properly soon
+
+* Fri Feb 17 2017 Robbie Harwood <rharwood@redhat.com> - 1.15-8
+- Hammer refresh around transient rawhide issue
+
+* Fri Feb 17 2017 Robbie Harwood <rharwood@redhat.com> - 1.15-7
+- Backport fix for GSSAPI fallback realm
+
+* Tue Feb 07 2017 Robbie Harwood <rharwood@redhat.com> - 1.15-6
+- Move krb5-kdb-version provides from -libs to -devel
+
+* Fri Jan 20 2017 Robbie Harwood <rharwood@redhat.com> - 1.15-5
+- Add free hook to KDB; increments KDB version
+- Add KDB version flag
+
+* Mon Dec 05 2016 Robbie Harwood <rharwood@redhat.com> - 1.15-4
+- New upstream release
+
+* Wed Nov 16 2016 Robbie Harwood <rharwood@redhat.com> - 1.15-beta2-3
+- New upstream release
+
+* Thu Nov 10 2016 Robbie Harwood <rharwood@redhat.com> - 1.15-beta1-2
+- Ensure we can build with the new CFLAGS
+- Remove the git versioning in patches
+
+* Thu Oct 20 2016 Robbie Harwood <rharwood@redhat.com> - 1.15-beta1-1
+- New upstream release
+- Update selinux with RHEL hygene
+- Resolves: #1314096
+
+* Tue Oct 11 2016 Tomáš Mráz <tmraz@redhat.com> - 1.14.4-6
+- rebuild with OpenSSL 1.1.0, added backported upstream patch
+
+* Fri Sep 30 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.4-5
+- Properly close krad sockets
+- Resolves: #1380836
+
+* Fri Sep 30 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.4-4
+- Fix backward check in kprop.service
+
+* Fri Sep 30 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.4-3
+- Switch to using autosetup macro.
+  - Patches come from git, so it is easiest to just make a git repo
+
+* Thu Sep 22 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.4-2
+- Backport getrandom() support
+- Remove patch numbering
+
+* Mon Sep 19 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.4-1
+- New upstream release
+- Update names and numbers to match external git
+
+* Mon Sep 19 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.3-9
+- Add krb5_db_register_keytab
+- Resolves: #1376812
+
+* Mon Aug 29 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.3-8
+- Use responder for non-preauth AS requests
+- Resolves: #1370622
+
+* Mon Aug 29 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.3-7
+- Guess Samba client mutual flag using ap_option
+- Resolves: #1370980
+
+* Thu Aug 25 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.3-6
+- Fix KDC return code and set prompt types for OTP client preauth
+- Resolves: #1370072
+
+* Mon Aug 15 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.3-5
+- Turn OFD locks back on with glibc workaround
+- Resolves: #1274922
+
+* Wed Aug 10 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.3-4
+- Fix use of KKDCPP with SNI
+- Resolves: #1365027
+
+* Fri Aug 05 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.3-3
+- Make krb5-devel depend on libkadm5
+- Resolves: #1364487
+
+* Wed Aug 03 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.3-2
+- Up-port a bunch of stuff from the el-7.3 cycle
+- Resolves: #1255450, #1314989
+
+* Mon Aug 01 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.3-1
+- New upstream version 1.14.3
+
+* Thu Jul 28 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.1-9
+- Fix CVE-2016-3120
+- Resolves: #1361051
+
+* Wed Jun 22 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.1-8
+- Fix incorrect recv() size calculation in libkrad
+
+* Thu Jun 16 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.1-7
+- Separate out the kadm5 libs
+
+* Fri May 27 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.1-6
+- Fix setting of AS key in OTP preauth failure
+
+* Tue Apr 05 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.1-5
+- Use the correct patches this time.
+- Resolves: #1321135
+
+* Mon Apr 04 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.1-4
+- Add send/receive sendto_kdc hooks and corresponding tests
+- Resolves: #1321135
+
+* Fri Mar 18 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.1-3
+- Fix CVE-2016-3119 (NULL deref in LDAP module)
+
+* Thu Mar 17 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.1-2
+- Backport OID mech fix
+- Resolves: #1317609
+
+* Mon Feb 29 2016 Robbie Harwood <rharwood@redhat.com> - 1.14.1-1
+- New rawhide, new upstream version
+- Drop CVE patches
+- Rename fix_interposer.patch to acquire_cred_interposer.patch
+- Update acquire_cred_interposer.patch to apply to new source
+
+* Mon Feb 22 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-23
+- Fix log file permissions patch with our selinux
+- Resolves: #1309421
+
+* Fri Feb 19 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-22
+- Backport my interposer fixes from upstream
+  - Supersedes krb5-mechglue_inqure_attrs.patch
+
+* Tue Feb 16 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-21
+- Adjust dependency on crypto-polices to be just the file we want
+- Patch courtesy of lslebodn
+- Resolves: #1308984
+
+* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.14-20
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Thu Jan 28 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-19
+- Replace _kadmin/_kprop with systemd macros
+- Remove traces of upstart from fedora package per policy
+- Resolves: #1290185
+
+* Wed Jan 27 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-18
+- Fix CVE-2015-8629, CVE-2015-8630, CVE-2015-8631
+
+* Thu Jan 21 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-17
+- Make krb5kdc.log not world-readable by default
+- Resolves: #1276484
+
+* Thu Jan 21 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-16
+- Allow verification of attributes on krb5.conf
+
+* Wed Jan 20 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-15
+- Use "new" systemd macros for service handling.  (Thanks vpavlin!)
+- Resolves: #850399
+
+* Wed Jan 20 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-14
+- Remove WITH_NSS macro (always false)
+- Remove WITH_SYSTEMD macro (always true)
+- Remove WITH_LDAP macro (always true)
+- Remove WITH_OPENSSL macro (always true)
+
+* Fri Jan 08 2016 Robbie Harwood <rharwood@redhat.com> - 1.14-13
+- Backport fix for chrome crash in spnego_gss_inquire_context
+- Resolves: #1295893
+
+* Wed Dec 16 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-12
+- Backport patch to fix mechglue for gss_inqure_attrs_for_mech()
+
+* Thu Dec 03 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-11
+- Backport interposer fix (#1284985)
+- Drop workaround pwsize initialization patch (gcc has been fixed)
+
+* Tue Nov 24 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-10
+- Fix FTBFS by no longer working around bug in nss_wrapper
+
+* Mon Nov 23 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-9
+- Upstream release.  No actual change from beta, just version bump
+- Clean up unused parts of spec file
+
+* Mon Nov 16 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-beta2-8
+- New upstream beta version
+
+* Wed Nov 04 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-beta1-7
+- Patch CVE-2015-2698
+
+* Tue Oct 27 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-beta1-6
+- Patch CVE-2015-2697, CVE-2015-2696, CVE-2015-2695
+
+* Thu Oct 22 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-beta1-5
+- Ensure pwsize is initialized in chpass_util.c
+
+* Thu Oct 22 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-beta1-4
+- Fix typo of crypto-policies file in previous version
+
+* Mon Oct 19 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-beta1-3
+- Start using crypto-policies
+
+* Mon Oct 19 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-beta1-2
+- TEMPORARILY disable usage of OFD locks as a workaround for x86
+
+* Thu Oct 15 2015 Robbie Harwood <rharwood@redhat.com> - 1.14-beta1-1
+- New upstream beta version
+
+* Thu Oct 08 2015 Robbie Harwood <rharwood@redhat.com> - 1.13.2-13
+- Work around KDC client prinicipal in referrals issue (#1259844)
+
+* Thu Oct 01 2015 Robbie Harwood <rharwood@redhat.com> - 1.13.2-12
+- Enable building with bad system /etc/krb5.conf
+
+* Wed Sep 23 2015 Robbie Harwood <rharwood@redhat.com> - 1.13.2-11
+- Drop dependency on pax, ksh
+- Remove support for fedora < 20
+
+* Wed Sep 23 2015 Robbie Harwood <rharwood@redhat.com> - 1.13.2-10
+- Nix /usr/share/krb5.conf.d to reduce complexity
+
+* Wed Sep 23 2015 Robbie Harwood <rharwood@redhat.com> - 1.13.2-9
+- Depend on crypto-policies which provides /etc/krb5.conf.d (#1225792)
+
+* Thu Sep 10 2015 Robbie Harwood <rharwood@redhat.com> - 1.13.2-8
+- Remove dependency on systemd-sysv which is no longer needed for fedora > 20
+  This also fixes a fail-to-build issue.
+- Miscalaneous spec cleanup fixes
+
+* Thu Sep 10 2015 Robbie Harwood <rharwood@redhat.com> - 1.13.2-7
+- Support config snippets in /etc/krb5.conf.d/ and /usr/share/krb5.conf.d/
+  (#1225792, #1146370, #1145808)
+
+* Thu Jun 25 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-6
+- Use system nss_wrapper and socket_wrapper for testing.
+  Patch by Andreas Schneider <asn@redhat.com>
+
+* Thu Jun 25 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-5
+- Remove Zanata test glue and related workarounds
+  - Bug #1234292 ("IPA server cannot be run in container due to incorrect /usr/sbin/_kadmind")
+  - Bug #1234326 ("krb5-server introduces new rpm dependency on ksh")
+
+* Thu Jun 18 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-4
+- Fix dependicy on binfmt.service
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.13.2-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Tue Jun 2 2015 Roland Mainz <rmainz@redhat.com> - 1.13.2-2
+- Add patch to fix Redhat Bug #1227542 ("[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-1
+- Add fix for RedHat Bug #1164304 ("Upstream unit tests loads
+  the installed shared libraries instead the ones from the build")
+
+* Thu May 14 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
+- Add script processing for upcoming Zanata l10n support
+- Minor spec cleanup
+
+* Mon May 4 2015 Roland Mainz <rmainz@redhat.com> - 1.13.1-4
+- fix for CVE-2015-2694 (#1216133) "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.
+
+* Wed Mar 25 2015 Roland Mainz <rmainz@redhat.com> - 1.13.1-3
+- Add temporay workaround for RH bug #1204646 ("krb5-config
+  returns wrong -specs path") which modifies krb5-config post
+  build so that development of krb5 dependicies gets unstuck.
+  This MUST be removed before rawhide becomes F23 ...
+
+* Thu Mar 19 2015 Roland Mainz <rmainz@redhat.com> - 1.13.1-2
+- fix for CVE-2014-5355 (#1193939) "krb5: unauthenticated
+  denial of service in recvauth_common() and others"  
+
+* Fri Feb 13 2015 Roland Mainz <rmainz@redhat.com> - 1.13.1-1
+- Update to 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 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
+- Minor spec cleanup
+
+* Wed Feb 4 2015 Roland Mainz <rmainz@redhat.com> - 1.13-8
+- fix for CVE-2014-5352 (#1179856) "gss_process_context_token()
+  incorrectly frees context (MITKRB5-SA-2015-001)"
+- fix for CVE-2014-9421 (#1179857) "kadmind doubly frees partial
+  deserialization results (MITKRB5-SA-2015-001)"
+- fix for CVE-2014-9422 (#1179861) "kadmind incorrectly
+  validates server principal name (MITKRB5-SA-2015-001)"
+- fix for CVE-2014-9423 (#1179863) "libgssrpc server applications
+  leak uninitialized bytes (MITKRB5-SA-2015-001)"
+
+* Wed Feb 4 2015 Roland Mainz <rmainz@redhat.com> - 1.13-7
+- Remove "python-sphinx-latex" and "tar" from the build requirements
+  to fix build failures on F22 machines.
+- Minor spec cleanup
+
+* Mon Feb 02 2015 Nathaniel McCallum <npmccallum@redhat.com> - 1.13-6
+- Support KDC_ERR_MORE_PREAUTH_DATA_REQUIRED (RT#8063)
+
+* Mon Jan 26 2015 Roland Mainz <rmainz@redhat.com> - 1.13-5
+- fix for kinit -C loops (#1184629, MIT/krb5 issue 243, "Do not
+  loop on principal unknown errors").
+- Added "python-sphinx-latex" to the build requirements
+  to fix build failures on F22 machines.
+
+* Thu Dec 18 2014 Roland Mainz <rmainz@redhat.com> - 1.13-4
+- fix for CVE-2014-5354 (#1174546) "krb5: NULL pointer
+  dereference when using keyless entries"  
+
+* Wed Dec 17 2014 Roland Mainz <rmainz@redhat.com> - 1.13-3
+- fix for CVE-2014-5353 (#1174543) "Fix LDAP misused policy
+  name crash"  
+
+* Wed Oct 29 2014 Roland Mainz <rmainz@redhat.com> - 1.13-2
+- Bump 1%%{?dist} to 2%%{?dist} to workaround RPM sort issue
+  which would lead yum updates to treat the last alpha as newer
+  than the final version.  
+
+* Wed Oct 29 2014 Roland Mainz <rmainz@redhat.com> - 1.13-1
+- Update from krb5-1.13-alpha1 to final krb5-1.13
+- Removed patch for CVE-2014-5351 (#1145425) "krb5: current
+  keys returned when randomizing the keys for a service principal" -
+  now part of upstream sources
+- Use patch for glibc |eventfd()| prototype mismatch (#1147887) only
+  for Fedora > 20
+
+* Tue Sep 30 2014 Roland Mainz <rmainz@redhat.com> - 1.13-0.alpha1.3
+- fix build failure caused by change of prototype for glibc
+  |eventfd()| (#1147887)
+
+* Mon Sep 29 2014 Roland Mainz <rmainz@redhat.com> - 1.13-0.alpha1.3
+- fix for CVE-2014-5351 (#1145425) "krb5: current keys returned when
+  randomizing the keys for a service principal"
+
+* Mon Sep  8 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.13-0.alpha1.3
+- fix the problem where the %%license file has been a dangling symlink
+
+* Tue Aug 26 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.13-0.alpha1.2
+- kpropd hasn't bothered with -S since 1.11; stop trying to use that flag
+  in the systemd unit file
+
+* Fri Aug 22 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.13-0.alpha1.1
+- update to 1.13 alpha1
+  - drop upstreamed and backported patches
+
+* Wed Aug 20 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.2-3
+- pull in upstream fix for an incorrect check on the value returned by a
+  strdup() call (#1132062)
+
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.12.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Fri Aug 15 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.2-1
+- update to 1.12.2
+  - drop patch for RT#7820, fixed in 1.12.2
+  - drop patch for #231147, fixed as RT#3277 in 1.12.2
+  - drop patch for RT#7818, fixed in 1.12.2
+  - drop patch for RT#7836, fixed in 1.12.2
+  - drop patch for RT#7858, fixed in 1.12.2
+  - drop patch for RT#7924, fixed in 1.12.2
+  - drop patch for RT#7926, fixed in 1.12.2
+  - drop patches for CVE-2014-4341/CVE-2014-4342, included in 1.12.2
+  - drop patch for CVE-2014-4343, included in 1.12.2
+  - drop patch for CVE-2014-4344, included in 1.12.2
+  - drop patch for CVE-2014-4345, included in 1.12.2
+- replace older proposed changes for ksu with backports of the changes
+  after review and merging upstream (#1015559, #1026099, #1118347)
+
+* Thu Aug  7 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-14
+- incorporate fix for MITKRB5-SA-2014-001 (CVE-2014-4345)
+
+* Mon Jul 21 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-13
+- gssapi: pull in upstream fix for a possible NULL dereference
+  in spnego (CVE-2014-4344)
+
+* Wed Jul 16 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-12
+- gssapi: pull in proposed fix for a double free in initiators (David
+  Woodhouse, CVE-2014-4343, #1117963)
+
+* Sat Jul 12 2014 Tom Callaway <spot@fedoraproject.org> - 1.12.1-11
+- fix license handling
+
+* Mon Jul  7 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-10
+- pull in fix for denial of service by injection of malformed GSSAPI tokens
+  (CVE-2014-4341, CVE-2014-4342, #1116181)
+
+* Tue Jun 24 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-9
+- pull in changes from upstream which add processing of the contents of
+  /etc/gss/mech.d/*.conf when loading GSS modules (#1102839)
+
+* Thu Jun 12 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-8
+- pull in fix for building against tcl 8.6 (#1107061)
+
+* Sun Jun 08 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.12.1-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Tue Mar 04 2014 Nathaniel McCallum <npmccallum@redhat.com> - 1.12.1-6
+- Backport fix for change password requests when using FAST (RT#7868)
+
+* Mon Feb 17 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-5
+- spnego: pull in patch from master to restore preserving the OID of the
+  mechanism the initiator requested when we have multiple OIDs for the same
+  mechanism, so that we reply using the same mechanism OID and the initiator
+  doesn't get confused (#1066000, RT#7858)
+
+* Fri Feb  7 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-4
+- pull in patch from master to move the default directory which the KDC uses
+  when computing the socket path for a local OTP daemon from the database
+  directory (/var/kerberos/krb5kdc) to the newly-added run directory
+  (/run/krb5kdc), in line with what we're expecting in 1.13 (RT#7859, more
+  of #1040056 as #1063905)
+- add a tmpfiles.d configuration file to have /run/krb5kdc created at
+  boot-time
+- own /var/run/krb5kdc
+
+* Fri Jan 31 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-3
+- refresh nss_wrapper and add socket_wrapper to the %%check environment
+
+* Fri Jan 31 2014 Nalin Dahyabhai <nalin@redhat.com>
+- add currently-proposed changes to teach ksu about credential cache
+  collections and the default_ccache_name setting (#1015559,#1026099)
+
+* Tue Jan 21 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-2
+- pull in multiple changes to allow replay caches to be added to a GSS
+  credential store as "rcache"-type credentials (RT#7818/#7819/#7836,
+  #1056078/#1056080)
+
+* Fri Jan 17 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12.1-1
+- update to 1.12.1
+  - drop patch for RT#7794, included now
+  - drop patch for RT#7797, included now
+  - drop patch for RT#7803, included now
+  - drop patch for RT#7805, included now
+  - drop patch for RT#7807, included now
+  - drop patch for RT#7045, included now
+  - drop patches for RT#7813 and RT#7815, included now
+  - add patch to always retrieve the KDC time offsets from keyring caches,
+    so that we don't mistakenly interpret creds as expired before their
+    time when our clock is ahead of the KDC's (RT#7820, #1030607)
+
+* Mon Jan 13 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12-11
+- update the PIC patch for iaesx86.s to not use ELF relocations to the version
+  that landed upstream (RT#7815, #1045699)
+
+* Thu Jan  9 2014 Nalin Dahyabhai <nalin@redhat.com>
+- pass -Wl,--warn-shared-textrel to the compiler when we're creating shared
+  libraries
+
+* Thu Jan  9 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12-10
+- amend the PIC patch for iaesx86.s to also save/restore ebx in the
+  functions where we modify it, because the ELF spec says we need to
+
+* Mon Jan  6 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12-9
+- grab a more-commented version of the most recent patch from upstream
+  master
+- make a guess at making the 32-bit AES-NI implementation sufficiently
+  position-independent to not require execmod permissions for libk5crypto
+  (more of #1045699)
+
+* Thu Jan  2 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12-8
+- add patch from Dhiru Kholia for the AES-NI implementations to allow
+  libk5crypto to be properly marked as not needing an executable stack
+  on arches where they're used (#1045699, and so many others)
+
+* Thu Jan  2 2014 Nalin Dahyabhai <nalin@redhat.com> - 1.12-7
+- revert that last change for a bit while sorting out execstack when we
+  use AES-NI (#1045699)
+
+* Thu Dec 19 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.12-6
+- add yasm as a build requirement for AES-NI support, on arches that have
+  yasm and AES-NI
+
+* Thu Dec 19 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.12-5
+- pull in fix from master to make reporting of errors encountered by
+  the SPNEGO mechanism work better (RT#7045, part of #1043962)
+
+* Thu Dec 19 2013 Nalin Dahyabhai <nalin@redhat.com>
+- update a test wrapper to properly handle things that the new libkrad does,
+  and add python-pyrad as a build requirement so that we can run its tests
+
+* Wed Dec 18 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.12-4
+- revise previous patch to initialize one more element
+
+* Wed Dec 18 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.12-3
+- backport fixes to krb5_copy_context (RT#7807, #1044735/#1044739)
+
+* Wed Dec 18 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.12-2
+- pull in fix from master to return a NULL pointer rather than allocating
+  zero bytes of memory if we read a zero-length input token (RT#7794, part of
+  #1043962)
+- pull in fix from master to ignore an empty token from an acceptor if
+  we've already finished authenticating (RT#7797, part of #1043962)
+- pull in fix from master to avoid a memory leak when a mechanism's
+  init_sec_context function fails (RT#7803, part of #1043962)
+- pull in fix from master to avoid a memory leak in a couple of error
+  cases which could occur while obtaining acceptor credentials (RT#7805, part
+  of #1043962)
+
+* Wed Dec 11 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.12-1
+- update to 1.12 final
+
+* Mon Dec  2 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.12-beta2.0
+- update to beta2
+  - drop obsolete backports for storing KDC time offsets and expiration times
+    in keyring credential caches
+
+* Tue Nov 19 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.12-beta1.0
+- rebase to master
+- update to beta1
+  - drop obsolete backport of fix for RT#7706
+
+* Mon Nov 18 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.4-2
+- pull in fix to store KDC time offsets in keyring credential caches (RT#7768,
+  #1030607)
+- pull in fix to set expiration times on credentials stored in keyring
+  credential caches (RT#7769, #1031724)
+
+* Tue Nov 12 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.4-1
+- update to 1.11.4
+  - drop patch for RT#7650, obsoleted
+  - drop patch for RT#7706, obsoleted as RT#7723
+  - drop patch for CVE-2013-1418/CVE-2013-6800, included in 1.11.4
+
+* Tue Nov 12 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-31
+- switch to the simplified version of the patch for #1029110 (RT#7764)
+
+* Mon Nov 11 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-30
+- check more thoroughly for errors when resolving KEYRING ccache names of type
+  "persistent", which should only have a numeric UID as the next part of the
+  name (#1029110)
+
+* Tue Nov  5 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-29
+- incorporate upstream patch for remote crash of KDCs which serve multiple
+  realms simultaneously (RT#7756, CVE-2013-1418/CVE-2013-6800,
+  #1026997/#1031501)
+
+* Mon Nov  4 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-28
+- drop patch to add additional access() checks to ksu - they add to breakage
+  when non-FILE: caches are in use (#1026099), shouldn't be resulting in any
+  benefit, and clash with proposed changes to fix its cache handling
+
+* Tue Oct 22 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-27
+- add some minimal description to the top of the wrapper scripts we use
+  when starting krb5kdc and kadmind to describe why they exist (tooling)
+
+* Thu Oct 17 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.12-alpha1.0
+- initial update to alpha1
+  - drop backport of persistent keyring support
+  - drop backport for RT#7689
+  - drop obsolete patch for fixing a use-before-init in a test program
+  - drop obsolete patch teaching config.guess/config.sub about aarch64-linux
+  - drop backport for RT#7598
+  - drop backport for RT#7172
+  - drop backport for RT#7642
+  - drop backport for RT#7643
+  - drop patches from master to not test GSSRPC-over-UDP and to not
+    depend on the portmapper, which are areas where our build systems
+    often give us trouble, too; obsolete
+  - drop backports for RT#7682
+  - drop backport for RT#7709
+  - drop backport for RT#7590 and partial backport for RT#7680
+  - drop OTP backport
+  - drop backports for RT#7656 and RT#7657
+- BuildRequires: libedit-devel to prefer it
+- BuildRequires: pkgconfig, since configure uses it
+
+* Wed Oct 16 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-26
+- create and own /etc/gss (#1019937)
+
+* Tue Oct 15 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-25
+- pull up fix for importing previously-exported credential caches in the
+  gssapi library (RT# 7706, #1019420)
+
+* Mon Oct 14 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-24
+- backport the callback to use the libkrb5 prompter when we can't load PEM
+  files for PKINIT (RT#7590, includes part of #965721/#1016690)
+- extract the rest of the fix #965721/#1016690 from the changes for RT#7680
+
+* Mon Oct 14 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-23
+- fix trigger scriptlet's invocation of sed (#1016945)
+
+* Fri Oct  4 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-22
+- rebuild with keyutils 1.5.8 (part of #1012043)
+
+* Wed Oct  2 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-21
+- switch to the version of persistent-keyring that was just merged to
+  master (RT#7711), along with related changes to kinit (RT#7689)
+- go back to setting default_ccache_name to a KEYRING type
+
+* Mon Sep 30 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-20
+- pull up fix for not calling a kdb plugin's check-transited-path
+  method before calling the library's default version, which only knows
+  how to read what's in the configuration file (RT#7709, #1013664)
+
+* Thu Sep 26 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-19
+- configure --without-krb5-config so that we don't pull in the old default
+  ccache name when we want to stop setting a default ccache name at configure-
+  time
+
+* Wed Sep 25 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-18
+- fix broken dependency on awk (should be gawk, rdieter)
+
+* Wed Sep 25 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-17
+- add missing dependency on newer keyutils-libs (#1012034)
+
+* Tue Sep 24 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-16
+- back out setting default_ccache_name to the new default for now, resetting
+  it to the old default while the kernel/keyutils bits get sorted (sgallagh)
+
+* Mon Sep 23 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-15
+- add explicit build-time dependency on a version of keyutils that's new
+  enough to include keyctl_get_persistent() (more of #991148)
+
+* Thu Sep 19 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-14
+- incorporate Simo's updated backport of his updated persistent-keyring changes
+  (more of #991148)
+
+* Fri Sep 13 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-13
+- don't break during %%check when the session keyring is revoked
+
+* Fri Sep 13 2013 Nalin Dahyabhai <nalin@redhat.com> - 1.11.3-12
+- pull the newer F21 defaults back to F20 (sgallagh)
+
+* Mon Sep  9 2013 Nalin Dahyabhai <nalin@redhat.com>
+- only apply the patch to autocreate /run/user/0 when we're hard-wiring the
+  default ccache location to be under it; otherwise it's unnecessary
+
+* Mon Sep  9 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-11
+- don't let comments intended for one scriptlet become part of the "script"
+  that gets passed to ldconfig as part of another one (Mattias Ellert, #1005675)
+
+* Fri Sep  6 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-10
+- incorporate Simo's backport of his persistent-keyring changes (#991148)
+- restore build-time default DEFCCNAME on Fedora 21 and later and EL, and
+  instead set default_ccache_name in the default krb5.conf's [libdefaults]
+  section (#991148)
+- on releases where we expect krb5.conf to be configured with a
+  default_ccache_name, add it whenever we upgrade from an older version of
+  the package that wouldn't have included it in its default configuration
+  file (#991148)
+
+* Fri Aug 23 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-9
+- take another stab at accounting for UnversionedDocdirs for the -libs
+  subpackage (spotted by ssorce)
+- switch to just the snapshot of nss_wrapper we were using, since we
+  no longer need to carry anything that isn't in the cwrap.org repository
+  (ssorce)
+
+* Thu Aug 15 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-8
+- drop a patch we weren't not applying (build tooling)
+- wrap kadmind and kpropd in scripts which check for the presence/absence
+  of files which dictate particular exit codes before exec'ing the actual
+  binaries, instead of trying to use ConditionPathExists in the unit files
+  to accomplish that, so that we exit with failure properly when what we
+  expect isn't actually in effect on the system (#800343)
+
+* Mon Jul 29 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-7
+- attempt to account for UnversionedDocdirs for the -libs subpackage
+
+* Fri Jul 26 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-6
+- tweak configuration files used during tests to try to reduce the number
+  of conflicts encountered when builds for multiple arches land on the same
+  builder
+
+* Mon Jul 22 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-5
+- pull up changes to allow GSSAPI modules to provide more functions
+  (RT#7682, #986564/#986565)
+
+* Fri Jul 19 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-4
+- use (a bundled, for now, copy of) nss_wrapper to let us run some of the
+  self-tests at build-time in more places than we could previously (#978756)
+- cover inconsistencies in whether or not there's a local caching nameserver
+  that's willing to answer when the build environment doesn't have a
+  resolver configuration, so that nss_wrapper's faking of the local
+  hostname can be complete
+
+* Mon Jul  1 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-3
+- specify dependencies on the same arch of krb5-libs by using the %%{?_isa}
+  suffix, to avoid dragging 32-bit libraries onto 64-bit systems (#980155)
+
+* Thu Jun 13 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-2
+- special-case /run/user/0, attempting to create it when resolving a
+  directory cache below it fails due to ENOENT and we find that it doesn't
+  already exist, either, before attempting to create the directory cache
+  (maybe helping, maybe just making things more confusing for #961235)
+
+* Tue Jun  4 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.3-1
+- update to 1.11.3
+  - drop patch for RT#7605, fixed in this release
+  - drop patch for CVE-2002-2443, fixed in this release
+  - drop patch for RT#7369, fixed in this release
+- pull upstream fix for breaking t_skew.py by adding the patch for #961221
+
+* Fri May 31 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-10
+- respin with updated version of patch for RT#7650 (#969331)
+
+* Thu May 30 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-9
+- don't forget to set the SELinux label when creating the directory for
+  a DIR: ccache
+- pull in proposed fix for attempts to get initial creds, which end up
+  following referrals, incorrectly trying to always use master KDCs if
+  they talked to a master at any point (should fix RT#7650)
+
+* Thu May 30 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-8
+- pull in patches from master to not test GSSRPC-over-UDP and to not
+  depend on the portmapper, which are areas where our build systems
+  often give us trouble, too
+
+* Tue May 28 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-7
+- backport fix for not being able to verify the list of transited realms
+  in GSS acceptors (RT#7639, #959685)
+- backport fix for not being able to pass an empty password to the
+  get-init-creds APIs and have them actually use it (RT#7642, #960001)
+- add backported proposed fix to use the unauthenticated server time
+  as the basis for computing the requested credential expiration times,
+  rather than the client's idea of the current time, which could be
+  significantly incorrect (#961221)
+
+* Tue May 21 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-6
+- pull in upstream fix to start treating a KRB5CCNAME value that begins
+  with DIR:: the same as it would a DIR: value with just one ccache file
+  in it (RT#7172, #965574)
+
+* Mon May 13 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-5
+- pull up fix for UDP ping-pong flaw in kpasswd service (CVE-2002-2443,
+  #962531,#962534)
+
+* Mon Apr 29 2013 Nathaniel McCallum <npmccallum@redhat.com> 1.11.2-4
+- Update otp patches
+- Merge otp patches into a single patch
+- Add keycheck patch
+
+* Tue Apr 23 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-3
+- pull the changing of the compiled-in default ccache location to
+  DIR:/run/user/%%{uid}/krb5cc back into F19, in line with SSSD and
+  the most recent pam_krb5 build
+
+* Wed Apr 17 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-2
+- correct some configuration file paths which the KDC_DIR patch missed
+
+* Mon Apr 15 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.2-1
+- update to 1.11.2
+  - drop pulled in patch for RT#7586, included in this release
+  - drop pulled in patch for RT#7592, included in this release
+- pull in fix for keeping track of the message type when parsing FAST requests
+  in the KDC (RT#7605, #951843) (also #951965)
+
+* Fri Apr 12 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.1-9
+- move the compiled-in default ccache location from the previous default of
+  FILE:/tmp/krb5cc_%%{uid} to DIR:/run/user/%%{uid}/krb5cc (part of #949588)
+
+* Tue Apr 09 2013 Nathaniel McCallum <npmccallum@redhat.com> - 1.11.1-8
+- Update otp backport patches (libk5radius => libkrad)
+
+* Wed Apr  3 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.1-7
+- when testing the RPC library, treat denials from the local portmapper the
+  same as a portmapper-not-running situation, to allow other library tests
+  to be run while building the package
+
+* Thu Mar 28 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.1-6
+- create and own /var/kerberos/krb5/user instead of /var/kerberos/kdc/user,
+  since that's what the libraries actually look for
+- add buildrequires on nss-myhostname, in an attempt to get more of the tests
+  to run properly during builds
+- pull in Simo's patch to recognize "client_keytab" as a key type which can
+  be passed in to gss_acquire_cred_from() (RT#7598)
+
+* Tue Mar 26 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.1-5
+- pull up Simo's patch to mark the correct mechanism on imported GSSAPI
+  contexts (RT#7592)
+- go back to using reconf to run autoconf and autoheader (part of #925640)
+- add temporary patch to use newer config.guess/config.sub (more of #925640)
+
+* Mon Mar 18 2013 Nalin Dahyabhai <nalin@redhat.com>
+- fix a version comparison to expect newer texlive build requirements when
+  %%{_rhel} > 6 rather than when it's > 7
+
+* Mon Mar 11 2013 Nathaniel McCallum <npmccallum@redhat.com> 1.11.1-4
+- Add libverto-devel requires for krb5-devel
+- Add otp support
+
+* Thu Feb 28 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.1-3
+- fix a memory leak when acquiring credentials using a keytab (RT#7586, #911110)
+
+* Wed Feb 27 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.1-2
+- prebuild PDF docs to reduce multilib differences (internal tooling, #884065)
+- drop the kerberos-iv portreserve file, and drop the rest on systemd systems
+- escape uses of macros in comments (more of #884065)
+
+* Mon Feb 25 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11.1-1
+- update to 1.11.1
+  - drop patch for noticing negative timeouts being passed to the poll()
+    wrapper in the client transmit functions
+
+* Fri Feb  8 2013 Nalin Dahyabhai <nalin@redhat.com> 1.11-2
+- set "rdns = false" in the default krb5.conf (#908323,#908324)
+
+* Tue Dec 18 2012 Nalin Dahyabhai <nalin@redhat.com> 1.11-1
+- update to 1.11 release
+
+* Thu Dec 13 2012 Nalin Dahyabhai <nalin@redhat.com> 1.11-0.beta2.0
+- update to 1.11 beta 2
+
+* Thu Dec 13 2012 Nalin Dahyabhai <nalin@redhat.com>
+- when building with our bundled copy of libverto, package it in with -libs
+  rather than with -server (#886049)
+
+* Wed Nov 21 2012 Nalin Dahyabhai <nalin@redhat.com> 1.11-0.beta1.0
+- update to 1.11 beta 1
+
+* Fri Nov 16 2012 Nalin Dahyabhai <nalin@redhat.com> 1.11-0.alpha1.1
+- handle releases where texlive packaging wasn't yet as complicated as it
+  is in Fedora 18
+- fix an uninitialized-variable error building one of the test programs
+
+* Fri Nov 16 2012 Nalin Dahyabhai <nalin@redhat.com> 1.11-0.alpha1.0
+- move the rather large pile of html and pdf docs to -workstation, so
+  that just having something that links to the libraries won't drag
+  them onto a system, and we avoid having to sort out hard-coded paths
+  that include %%{_libdir} showing up in docs in multilib packages
+- actually create %%{_var}/kerberos/kdc/user, so that it can be packaged
+- correct the list of packaged man pages
+- don't dummy up required tex stylesheets, require them
+- require pdflatex and makeindex
+
+* Thu Nov 15 2012 Nalin Dahyabhai <nalin@redhat.com>
+- update to 1.11 alpha 1
+  - drop backported patch for RT #7406
+  - drop backported patch for RT #7407
+  - drop backported patch for RT #7408
+  - the new docs system generates PDFs, so stop including them as sources
+  - drop backported patch to allow deltat.y to build with the usual
+    warning flags and the current gcc
+  - drop backported fix for disabling use of a replay cache when verifying
+    initial credentials
+  - drop backported fix for teaching PKINIT clients which trust the KDC's
+    certificate directly to verify signed-data messages that are signed with
+    the KDC's certificate, when the blobs don't include a copy of the KDC's
+    certificate
+  - drop backported patches to make keytab-based authentication attempts
+    work better when the client tells the KDC that it supports a particular
+    cipher, but doesn't have a key for it in the keytab
+  - drop backported fix for avoiding spurious clock skew when a TGT is
+    decrypted long after the KDC sent it to the client which decrypts it
+  - move the cross-referenced HTML docs into the -libs package to avoid
+    broken internal links
+  - drop patches to fixup paths in man pages, shouldn't be needed any more
+
+* Wed Oct 17 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.3-7
+- tag a couple of other patches which we still need to be applied during
+  %%{?_rawbuild} builds (zmraz)
+
+* Tue Sep 25 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.3-6
+- actually pull up the patch for RT#7063, and not some other ticket (#773496)
+
+* Mon Sep 10 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.3-5
+- add patch based on one from Filip Krska to not call poll() with a negative
+  timeout when the caller's intent is for us to just stop calling it (#838548)
+
+* Fri Sep  7 2012 Nalin Dahyabhai <nalin@redhat.com>
+- on EL6, conflict with libsmbclient before 3.5.10-124, which is when it
+  stopped linking with a symbol which we no longer export (#771687)
+- pull up patch for RT#7063, in which not noticing a prompt for a long
+  time throws the client library's idea of the time difference between it
+  and the KDC really far out of whack (#773496)
+- add a backport of more patches to set the client's list of supported enctypes
+  when using a keytab to be the list of types of keys in the keytab, plus the
+  list of other types the client supports but for which it doesn't have keys,
+  in that order, so that KDCs have a better chance of being able to issue
+  tickets with session keys of types that the client can use (#837855)
+
+* Thu Sep  6 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.3-4
+- cut down the number of times we load SELinux labeling configuration from
+  a minimum of two times to actually one (more of #845125)
+
+* Thu Aug 30 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.3-3
+- backport patch to disable replay detection in krb5_verify_init_creds()
+  while reading the AP-REQ that's generated in the same function (RT#7229)
+
+* Thu Aug 30 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.3-2
+- undo rename from krb5-pkinit-openssl to krb5-pkinit on EL6
+- version the Obsoletes: on the krb5-pkinit-openssl to krb5-pkinit rename
+- reintroduce the init scripts for non-systemd releases
+- forward-port %%{?_rawbuild} annotations from EL6 packaging
+
+* Thu Aug  9 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.3-1
+- update to 1.10.3, rolling in the fixes from MITKRB5-SA-2012-001
+
+* Thu Aug  2 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.2-7
+- selinux: hang on to the list of selinux contexts, freeing and reloading
+  it only when the file we read it from is modified, freeing it when the
+  shared library is being unloaded (#845125)
+
+* Thu Aug  2 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.2-6
+- go back to not messing with library file paths on Fedora 17: it breaks
+  file path dependencies in other packages, and since Fedora 17 is already
+  released, breaking that is our fault
+
+* Tue Jul 31 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.2-5
+- add upstream patch to fix freeing an uninitialized pointer and dereferencing
+  another uninitialized pointer in the KDC (MITKRB5-SA-2012-001, CVE-2012-1014
+  and CVE-2012-1015, #844779 and #844777)
+- fix a thinko in whether or not we mess around with devel .so symlinks on
+  systems without a separate /usr (sbose)
+
+* Fri Jul 27 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.10.2-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Fri Jun 22 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.2-3
+- backport a fix to allow a PKINIT client to handle SignedData from a KDC
+  that's signed with a certificate that isn't in the SignedData, but which
+  is available as an anchor or intermediate on the client (RT#7183)
+
+* Tue Jun  5 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.2-2
+- back out this labeling change (dwalsh):
+  - when building the new label for a file we're about to create, also mix
+    in the current range, in addition to the current user
+
+* Fri Jun  1 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.2-1
+- update to 1.10.2
+  - when building the new label for a file we're about to create, also mix
+    in the current range, in addition to the current user
+  - also package the PDF format admin, user, and install guides
+  - drop some PDFs that no longer get built right
+- add a backport of Stef's patch to set the client's list of supported
+  enctypes to match the types of keys that we have when we are using a
+  keytab to try to get initial credentials, so that a KDC won't send us
+  an AS reply that we can't encrypt (RT#2131, #748528)
+- don't shuffle around any shared libraries on releases with no-separate-/usr,
+  since /usr/lib is the same place as /lib
+- add explicit buildrequires: on 'hostname', for the tests, on systems where
+  it's in its own package, and require net-tools, which used to provide the
+  command, everywhere
+
+* Mon May  7 2012 Nalin Dahyabhai <nalin@redhat.com>
+- skip the setfscreatecon() if fopen() is passed "rb" as the open mode (part
+  of #819115)
+
+* Tue May  1 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.1-3
+- have -server require /usr/share/dict/words, which we set as the default
+  dict_file in kdc.conf (#817089)
+
+* Tue Mar 20 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.1-2
+- change back dns_lookup_kdc to the default setting (Stef Walter, #805318)
+- comment out example.com examples in default krb5.conf (Stef Walter, #805320)
+
+* Fri Mar  9 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10.1-1
+- update to 1.10.1
+  - drop the KDC crash fix
+  - drop the KDC lookaside cache fix
+  - drop the fix for kadmind RPC ACLs (CVE-2012-1012)
+
+* Wed Mar  7 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10-5
+- when removing -workstation, remove our files from the info index while
+  the file is still there, in %%preun, rather than %%postun, and use the
+  compressed file's name (#801035)
+
+* Tue Feb 21 2012 Nathaniel McCallum <nathaniel@natemccallum.com> - 1.10-4
+- Fix string RPC ACLs (RT#7093); CVE-2012-1012
+
+* Tue Jan 31 2012 Nathaniel McCallum <nathaniel@natemccallum.com> - 1.10-3
+- Add upstream lookaside cache behavior fix (RT#7082)
+
+* Mon Jan 30 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10-2
+- add patch to accept keytab entries with vno==0 as matches when we're
+  searching for an entry with a specific name/kvno (#230382/#782211,RT#3349)
+
+* Mon Jan 30 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10-1
+- update to 1.10 final
+
+* Thu Jan 26 2012 Nathaniel McCallum <nathaniel@natemccallum.com> - 1.10-0.beta1.2
+- Add upstream crashfix patch (RT#7081)
+
+* Thu Jan 12 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10-0.beta1.1
+- update to beta 1
+
+* Wed Jan 11 2012 Peter Robinson <pbrobinson@gmail.com>
+- mktemp was long obsoleted by coreutils
+
+* Wed Jan  4 2012 Nalin Dahyabhai <nalin@redhat.com> 1.10-0.alpha2.2
+- modify the deltat grammar to also tell gcc (4.7) to suppress
+  "maybe-uninitialized" warnings in addition to the "uninitialized" warnings
+  it's already being told to suppress (RT#7080)
+
+* Tue Dec 20 2011 Nalin Dahyabhai <nalin@redhat.com> 1.10-0.alpha2.1
+- update to alpha 2
+- drop a couple of patches which were integrated for alpha 2
+
+* Tue Dec 13 2011 Nalin Dahyabhai <nalin@redhat.com> 1.10-0.alpha1.3
+- pull in patch for RT#7046: tag a ccache containing credentials obtained via
+  S4U2Proxy with the principal name of the proxying principal (part of #761317)
+  so that the default principal name can be set to that of the client for which
+  it is proxying, which results in the ccache looking more normal to consumers
+  of the ccache that don't care that there's proxying going on
+- pull in patch for RT#7047: allow tickets obtained via S4U2Proxy to be cached
+  (more of #761317)
+- pull in patch for RT#7048: allow PAC verification to only bother trying to
+  verify the signature with keys that it's given (still more of #761317)
+
+* Tue Dec  6 2011 Nalin Dahyabhai <nalin@redhat.com> 1.10-0.alpha1.2
+- apply upstream patch to fix a null pointer dereference when processing
+  TGS requests (CVE-2011-1530, #753748)
+
+* Wed Nov 30 2011 Nalin Dahyabhai <nalin@redhat.com> 1.10-0.alpha1.1
+- correct a bug in the fix for #754001 so that the file creation context is
+  consistently reset
+
+* Tue Nov 15 2011 Nalin Dahyabhai <nalin@redhat.com> 1.10-0.alpha1.0
+- update to 1.10 alpha 1
+- on newer releases where we can assume NSS >= 3.13, configure PKINIT to build
+  using NSS
+- on newer releases where we build PKINIT using NSS, configure libk5crypto to
+  build using NSS
+- rename krb5-pkinit-openssl to krb5-pkinit on newer releases where we're
+  expecting to build PKINIT using NSS instead
+- during %%check, run check in the library and kdc subdirectories, which
+  should be able to run inside of the build system without issue
+
+* Wed Oct 26 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.9.1-19
+- Rebuilt for glibc bug#747377
+
+* Tue Oct 18 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-18
+- apply upstream patch to fix a null pointer dereference with the LDAP kdb
+  backend (CVE-2011-1527, #744125), an assertion failure with multiple kdb
+  backends (CVE-2011-1528), and a null pointer dereference with multiple kdb
+  backends (CVE-2011-1529) (#737711)
+
+* Thu Oct 13 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-17
+- pull in patch from trunk to rename krb5int_pac_sign() to krb5_pac_sign() and
+  make it public (#745533)
+
+* Fri Oct  7 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-16
+- kadmin.service: fix #723723 again
+- kadmin.service,krb5kdc.service: remove optional use of $KRB5REALM in command
+  lines, because systemd parsing doesn't handle alternate value shell variable
+  syntax
+- kprop.service: add missing Type=forking so that systemd doesn't assume simple
+- kprop.service: expect the ACL configuration to be there, not absent
+- handle a harder-to-trigger assertion failure that starts cropping up when we
+  exit the transmit loop on time (#739853)
+
+* Sun Oct  2 2011 Tom Callaway <spot@fedoraproject.org> 1.9.1-15
+- hardcode pid file as option in krb5kdc.service
+
+* Fri Sep 30 2011 Tom Callaway <spot@fedoraproject.org> 1.9.1-14
+- fix pid path in krb5kdc.service
+
+* Mon Sep 19 2011 Tom Callaway <spot@fedoraproject.org> 1.9.1-13
+- convert to systemd
+
+* Tue Sep  6 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-12
+- pull in upstream patch for RT#6952, confusion following referrals for
+  cross-realm auth (#734341)
+- pull in build-time deps for the tests
+
+* Thu Sep  1 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-11
+- switch to the upstream patch for #727829
+
+* Wed Aug 31 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-10
+- handle an assertion failure that starts cropping up when the patch for
+  using poll (#701446) meets servers that aren't running KDCs or against
+  which the connection fails for other reasons (#727829, #734172)
+
+* Mon Aug  8 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-9
+- override the default build rules to not delete temporary y.tab.c files,
+  so that they can be packaged, allowing debuginfo files which point to them
+  do so usefully (#729044)
+
+* Fri Jul 22 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-8
+- build shared libraries with partial RELRO support (#723995)
+- filter out potentially multiple instances of -Wl,-z,relro from krb5-config
+  output, now that it's in the buildroot's default LDFLAGS
+- pull in a patch to fix losing track of the replay cache FD, from SVN by
+  way of Kevin Coffman
+
+* Wed Jul 20 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-7
+- kadmind.init: drop the attempt to detect no-database-present errors (#723723),
+  which is too fragile in cases where the database has been manually moved or
+  is accessed through another kdb plugin
+
+* Tue Jul 19 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-6
+- backport fixes to teach libkrb5 to use descriptors higher than FD_SETSIZE
+  to talk to a KDC by using poll() if it's detected at compile-time (#701446,
+  RT#6905)
+
+* Thu Jun 23 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-5
+- pull a fix from SVN to try to avoid triggering a PTR lookup in getaddrinfo()
+  during krb5_sname_to_principal(), and to let getaddrinfo() decide whether or
+  not to ask for an IPv6 address based on the set of configured interfaces
+  (#717378, RT#6922)
+- pull a fix from SVN to use AI_ADDRCONFIG more often (RT#6923)
+
+* Mon Jun 20 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-4
+- apply upstream patch by way of Burt Holzman to fall back to a non-referral
+  method in cases where we might be derailed by a KDC that rejects the
+  canonicalize option (for example, those from the RHEL 2.1 or 3 era) (#715074)
+
+* Tue Jun 14 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-3
+- pull a fix from SVN to get libgssrpc clients (e.g. kadmin) authenticating
+  using the old protocol over IPv4 again (RT#6920)
+
+* Tue Jun 14 2011 Nalin Dahyabhai <nalin@redhat.com>
+- incorporate a fix to teach the file labeling bits about when replay caches
+  are expunged (#576093)
+
+* Thu May 26 2011 Nalin Dahyabhai <nalin@redhat.com>
+- switch to the upstream patch for #707145
+
+* Wed May 25 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-2
+- klist: don't trip over referral entries when invoked with -s (#707145,
+  RT#6915)
+
+* Fri May  6 2011 Nalin Dahyabhai <nalin@redhat.com>
+- fixup URL in a comment
+- when built with NSS, require 3.12.10 rather than 3.12.9
+
+* Thu May  5 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9.1-1
+- update to 1.9.1:
+  - drop no-longer-needed patches for CVE-2010-4022, CVE-2011-0281,
+    CVE-2011-0282, CVE-2011-0283, CVE-2011-0284, CVE-2011-0285
+
+* Wed Apr 13 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9-9
+- kadmind: add upstream patch to fix free() on an invalid pointer (#696343,
+  MITKRB5-SA-2011-004, CVE-2011-0285)
+
+* Mon Apr  4 2011 Nalin Dahyabhai <nalin@redhat.com>
+- don't discard the error code from an error message received in response
+  to a change-password request (#658871, RT#6893)
+
+* Fri Apr  1 2011 Nalin Dahyabhai <nalin@redhat.com>
+- override INSTALL_SETUID at build-time so that ksu is installed into
+  the buildroot with the right permissions (part of #225974)
+
+* Fri Mar 18 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9-8
+- backport change from SVN to fix a computed-value-not-used warning in
+  kpropd (#684065)
+
+* Tue Mar 15 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9-7
+- turn off NSS as the backend for libk5crypto for now to work around its
+  DES string2key not working (#679012)
+- add revised upstream patch to fix double-free in KDC while returning
+  typed-data with errors (MITKRB5-SA-2011-003, CVE-2011-0284, #674325)
+
+* Thu Feb 17 2011 Nalin Dahyabhai <nalin@redhat.com>
+- throw in a not-applied-by-default patch to try to make pkinit debugging
+  into a run-time boolean option named "pkinit_debug"
+
+* Wed Feb 16 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9-6
+- turn on NSS as the backend for libk5crypto, adding nss-devel as a build
+  dependency when that switch is flipped
+
+* Wed Feb  9 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9-5
+- krb5kdc init script: prototype some changes to do a quick spot-check
+  of the TGS and kadmind keys and warn if there aren't any non-weak keys
+  on file for them (to flush out parts of #651466)
+
+* Tue Feb  8 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9-4
+- add upstream patches to fix standalone kpropd exiting if the per-client
+  child process exits with an error (MITKRB5-SA-2011-001), a hang or crash
+  in the KDC when using the LDAP kdb backend, and an uninitialized pointer
+  use in the KDC (MITKRB5-SA-2011-002) (CVE-2010-4022, #664009,
+  CVE-2011-0281, #668719, CVE-2011-0282, #668726, CVE-2011-0283, #676126)
+
+* Mon Feb 07 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.9-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Mon Feb  7 2011 Nalin Dahyabhai <nalin@redhat.com>
+- fix a compile error in the SELinux labeling patch when -DDEBUG is used (Sumit
+  Bose)
+
+* Tue Feb  1 2011 Nalin Dahyabhai <nalin@redhat.com>
+- properly advertise that the kpropd init script now supports force-reload
+  (Zbysek Mraz, #630587)
+
+* Wed Jan 26 2011 Nalin Dahyabhai <nalin@redhat.com> 1.9-2
+- pkinit: when verifying signed data, use the CMS APIs for better
+  interoperability (#636985, RT#6851)
+
+* Wed Dec 22 2010 Nalin Dahyabhai <nalin@redhat.com> 1.9-1
+- update to 1.9 final
+
+* Mon Dec 20 2010 Nalin Dahyabhai <nalin@redhat.com> 1.9-0.beta3.1
+- fix link flags and permissions on shared libraries (ausil)
+
+* Thu Dec 16 2010 Nalin Dahyabhai <nalin@redhat.com> 1.9-0.beta3.0
+- update to 1.9 beta 3
+
+* Mon Dec  6 2010 Nalin Dahyabhai <nalin@redhat.com> 1.9-0.beta2.0
+- update to 1.9 beta 2
+
+* Tue Nov  9 2010 Nalin Dahyabhai <nalin@redhat.com> 1.9-0.beta1.1
+- drop not-needed-since-1.8 build dependency on rsh (ssorce)
+
+* Fri Nov  5 2010 Nalin Dahyabhai <nalin@redhat.com> 1.9-0.beta1.0
+- start moving to 1.9 with beta 1
+  - drop patches for RT#5755, RT#6762, RT#6774, RT#6775
+  - drop no-longer-needed backport patch for #539423
+  - drop no-longer-needed patch for CVE-2010-1322
+- if WITH_NSS is set, built with --with-crypto-impl=nss (requires NSS 3.12.9)
+
+* Tue Oct  5 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.3-8
+- incorporate upstream patch to fix uninitialized pointer crash in the KDC's
+  authorization data handling (CVE-2010-1322, #636335)
+
+* Mon Oct  4 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.3-7
+- rebuild
+
+* Mon Oct  4 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.3-6
+- pull down patches from trunk to implement k5login_authoritative and
+  k5login_directory settings for krb5.conf (#539423)
+
+* Wed Sep 29 2010 jkeating - 1.8.3-5
+- Rebuilt for gcc bug 634757
+
+* Wed Sep 15 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.3-4
+- fix reading of keyUsage extensions when attempting to select pkinit client
+  certs (part of #629022, RT#6775)
+- fix selection of pkinit client certs when one or more don't include a
+  subjectAltName extension (part of #629022, RT#6774)
+
+* Fri Sep  3 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.3-3
+- build with -fstack-protector-all instead of the default -fstack-protector,
+  so that we add checking to more functions (i.e., all of them) (#629950)
+- also link binaries with -Wl,-z,relro,-z,now (part of #629950)
+
+* Tue Aug 24 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.3-2
+- fix a logic bug in computing key expiration times (RT#6762, #627022)
+
+* Wed Aug  4 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.3-1
+- update to 1.8.3
+  - drop backports of fixes for gss context expiration and error table
+    registration/deregistration mismatch
+  - drop patch for upstream #6750
+
+* Wed Jul  7 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.2-3
+- tell krb5kdc and kadmind to create pid files, since they can
+- add logrotate configuration files for krb5kdc and kadmind (#462658)
+- fix parsing of the pidfile option in the KDC (upstream #6750)
+
+* Mon Jun 21 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.2-2
+- libgssapi: pull in patch from svn to stop returning context-expired errors
+  when the ticket which was used to set up the context expires (#605366,
+  upstream #6739)
+
+* Mon Jun 21 2010 Nalin Dahyabhai <nalin@redhat.com>
+- pull up fix for upstream #6745, in which the gssapi library would add the
+  wrong error table but subsequently attempt to unload the right one
+
+* Thu Jun 10 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.2-1
+- update to 1.8.2
+  - drop patches for CVE-2010-1320, CVE-2010-1321
+
+* Tue Jun  1 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.1-7
+- rebuild
+
+* Thu May 27 2010 Nalin Dahyabhai <nalin@redhat.com>
+- ksu: move session management calls to before we drop privileges, like
+  su does (#596887), and don't skip the PAM account check for root or the
+  same user (more of #540769)
+
+* Mon May 24 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.1-6
+- make krb5-server-ldap also depend on the same version-release of krb5-libs,
+  as the other subpackages do, if only to make it clearer than it is when we
+  just do it through krb5-server
+- drop explicit linking with libtinfo for applications that use libss, now
+  that readline itself links with libtinfo (as of readline-5.2-3, since
+  fedora 7 or so)
+- go back to building without strict aliasing (compiler warnings in gssrpc)
+
+* Tue May 18 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.1-5
+- add patch to correct GSSAPI library null pointer dereference which could be
+  triggered by malformed client requests (CVE-2010-1321, #582466)
+
+* Tue May  4 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.1-4
+- fix output of kprop's init script's "status" and "reload" commands (#588222)
+
+* Tue Apr 20 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.1-3
+- incorporate patch to fix double-free in the KDC (CVE-2010-1320, #581922)
+
+* Wed Apr 14 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.1-2
+- fix a typo in kerberos.ldif
+
+* Fri Apr  9 2010 Nalin Dahyabhai <nalin@redhat.com> 1.8.1-1
+- update to 1.8.1
+  - no longer need patches for #555875, #561174, #563431, RT#6661, CVE-2010-0628
+- replace buildrequires on tetex-latex with one on texlive-latex, which is
+  the package that provides it now
+
+* Thu Apr  8 2010 Nalin Dahyabhai <nalin@redhat.com>
+- kdc.conf: no more need to suggest a v4 mode, or listening on the v4 port
+
+* Thu Apr  8 2010 Nalin Dahyabhai <nalin@redhat.com>
+- drop patch to suppress key expiration warnings sent from the KDC in
+  the last-req field, as the KDC is expected to just be configured to either
+  send them or not as a particular key approaches expiration (#556495)
+
+* Tue Mar 23 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.8-5
+- add upstream fix for denial-of-service in SPNEGO (CVE-2010-0628, #576325)
+- kdc.conf: no more need to suggest keeping keys with v4-compatible salting
+
+* Fri Mar 19 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.8-4
+- remove the krb5-appl bits (the -workstation-clients and -workstation-servers
+  subpackages) now that krb5-appl is its own package
+- replace our patch for #563431 (kpasswd doesn't fall back to guessing your
+  principal name using your user name if you don't have a ccache) with the
+  one upstream uses
+
+* Fri Mar 12 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.8-3
+- add documentation for the ticket_lifetime option (#561174)
+
+* Mon Mar  8 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.8-2
+- pull up patch to get the client libraries to correctly perform password
+  changes over IPv6 (Sumit Bose, RT#6661)
+
+* Fri Mar  5 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.8-1
+- update to 1.8
+  - temporarily bundling the krb5-appl package (split upstream as of 1.8)
+    until its package review is complete
+  - profile.d scriptlets are now only needed by -workstation-clients
+  - adjust paths in init scripts
+  - drop upstreamed fix for KDC denial of service (CVE-2010-0283)
+  - drop patch to check the user's password correctly using crypt(), which
+    isn't a code path we hit when we're using PAM
+
+* Wed Mar  3 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7.1-6
+- fix a null pointer dereference and crash introduced in our PAM patch that
+  would happen if ftpd was given the name of a user who wasn't known to the
+  local system, limited to being triggerable by gssapi-authenticated clients by
+  the default xinetd config (Olivier Fourdan, #569472)
+
+* Tue Mar  2 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7.1-5
+- fix a regression (not labeling a kdb database lock file correctly, #569902)
+
+* Thu Feb 25 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7.1-4
+- move the package changelog to the end to match the usual style (jdennis)
+- scrub out references to $RPM_SOURCE_DIR (jdennis)
+- include a symlink to the readme with the name LICENSE so that people can
+  find it more easily (jdennis)
+
+* Wed Feb 17 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7.1-3
+- pull up the change to make kpasswd's behavior better match the docs
+  when there's no ccache (#563431)
+
+* Tue Feb 16 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7.1-2
+- apply patch from upstream to fix KDC denial of service (CVE-2010-0283,
+  #566002)
+
+* Wed Feb  3 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7.1-1
+- update to 1.7.1
+  - don't trip AD lockout on wrong password (#542687, #554351)
+  - incorporates fixes for CVE-2009-4212 and CVE-2009-3295
+  - fixes gss_krb5_copy_ccache() when SPNEGO is used
+- move sim_client/sim_server, gss-client/gss-server, uuclient/uuserver to
+  the devel subpackage, better lining up with the expected krb5/krb5-appl
+  split in 1.8
+- drop kvno,kadmin,k5srvutil,ktutil from -workstation-servers, as it already
+  depends on -workstation which also includes them
+
+* Mon Jan 25 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7-23
+- tighten up default permissions on kdc.conf and kadm5.acl (#558343)
+
+* Fri Jan 22 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7-22
+- use portreserve correctly -- portrelease takes the basename of the file
+  whose entries should be released, so we need three files, not one
+
+* Mon Jan 18 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7-21
+- suppress warnings of impending password expiration if expiration is more than
+  seven days away when the KDC reports it via the last-req field, just as we
+  already do when it reports expiration via the key-expiration field (#556495)
+- link with libtinfo rather than libncurses, when we can, in future RHEL
+
+* Fri Jan 15 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7-20
+- krb5_get_init_creds_password: check opte->flags instead of options->flags
+  when checking whether or not we get to use the prompter callback (#555875)
+
+* Thu Jan 14 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7-19
+- use portreserve to make sure the KDC can always bind to the kerberos-iv
+  port, kpropd can always bind to the krb5_prop port, and that kadmind can
+  always bind to the kerberos-adm port (#555279)
+- correct inadvertent use of macros in the changelog (rpmlint)
+
+* Tue Jan 12 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7-18
+- add upstream patch for integer underflow during AES and RC4 decryption
+  (CVE-2009-4212), via Tom Yu (#545015)
+
+* Wed Jan  6 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7-17
+- put the conditional back for the -devel subpackage
+- back down to the earlier version of the patch for #551764; the backported
+  alternate version was incomplete
+
+* Tue Jan  5 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7-16
+- use %%global instead of %%define
+- pull up proposed patch for creating previously-not-there lock files for
+  kdb databases when 'kdb5_util' is called to 'load' (#551764)
+
+* Mon Jan  4 2010 Dennis Gregorovic <dgregor@redhat.com>
+- fix conditional for future RHEL
+
+* Mon Jan  4 2010 Nalin Dahyabhai <nalin@redhat.com> - 1.7-15
+- add upstream patch for KDC crash during referral processing (CVE-2009-3295),
+  via Tom Yu (#545002)
+
+* Mon Dec 21 2009 Nalin Dahyabhai <nalin@redhat.com> - 1.7-14
+- refresh patch for #542868 from trunk
+
+* Thu Dec 10 2009 Nalin Dahyabhai <nalin@redhat.com>
+- move man pages that live in the -libs subpackage into the regular
+  %%{_mandir} tree where they'll still be found if that package is the
+  only one installed (#529319)
+
+* Wed Dec  9 2009 Nalin Dahyabhai <nalin@redhat.com> - 1.7-13
+- and put it back in
+
+* Tue Dec  8 2009 Nalin Dahyabhai <nalin@redhat.com>
+- back that last change out
+
+* Tue Dec  8 2009 Nalin Dahyabhai <nalin@redhat.com> - 1.7-12
+- try to make gss_krb5_copy_ccache() work correctly for spnego (#542868)
+
+* Fri Dec  4 2009 Nalin Dahyabhai <nalin@redhat.com>
+- make krb5-config suppress CFLAGS output when called with --libs (#544391)
+
+* Thu Dec  3 2009 Nalin Dahyabhai <nalin@redhat.com> - 1.7-11
+- ksu: move account management checks to before we drop privileges, like
+  su does (#540769)
+- selinux: set the user part of file creation contexts to match the current
+  context instead of what we looked up
+- configure with --enable-dns-for-realm instead of --enable-dns, which isn't
+  recognized any more
+
+* Fri Nov 20 2009 Nalin Dahyabhai <nalin@redhat.com> - 1.7-10
+- move /etc/pam.d/ksu from krb5-workstation-servers to krb5-workstation,
+  where it's actually needed (#538703)
+
+* Fri Oct 23 2009 Nalin Dahyabhai <nalin@redhat.com> - 1.7-9
+- add some conditional logic to simplify building on older Fedora releases
+
+* Tue Oct 13 2009 Nalin Dahyabhai <nalin@redhat.com>
+- don't forget the README
+
+* Mon Sep 14 2009 Nalin Dahyabhai <nalin@redhat.com> - 1.7-8
+- specify the location of the subsystem lock when using the status() function
+  in the kadmind and kpropd init scripts, so that we get the right error when
+  we're dead but have a lock file - requires initscripts 8.99 (#521772)
+
+* Tue Sep  8 2009 Nalin Dahyabhai <nalin@redhat.com>
+- if the init script fails to start krb5kdc/kadmind/kpropd because it's already
+  running (according to status()), return 0 (part of #521772)
+
+* Mon Aug 24 2009 Nalin Dahyabhai <nalin@redhat.com> - 1.7-7
+- work around a compile problem with new openssl
+
+* Fri Aug 21 2009 Tomas Mraz <tmraz@redhat.com> - 1.7-6
+- rebuilt with new openssl
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.7-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Tue Jul  7 2009 Nalin Dahyabhai <nalin@redhat.com> 1.7-5
+- rebuild to pick up the current forms of various patches
+
+* Mon Jul  6 2009 Nalin Dahyabhai <nalin@redhat.com>
+- simplify the man pages patch by only preprocessing the files we care about
+  and moving shared configure.in logic into a shared function
+- catch the case of ftpd printing file sizes using %%i, when they might be
+  bigger than an int now
+
+* Tue Jun 30 2009 Nalin Dahyabhai <nalin@redhat.com> 1.7-4
+- try to merge and clean up all the large file support for ftp and rcp
+  - ftpd no longer prints a negative length when sending a large file
+    from a 32-bit host
+
+* Tue Jun 30 2009 Nalin Dahyabhai <nalin@redhat.com>
+- pam_rhosts_auth.so's been gone, use pam_rhosts.so instead
+
+* Mon Jun 29 2009 Nalin Dahyabhai <nalin@redhat.com> 1.7-3
+- switch buildrequires: and requires: on e2fsprogs-devel into
+  buildrequires: and requires: on libss-devel, libcom_err-devel, per
+  sandeen on fedora-devel-list
+
+* Fri Jun 26 2009 Nalin Dahyabhai <nalin@redhat.com>
+- fix a type mismatch in krb5_copy_error_message()
+- ftp: fix some odd use of strlen()
+- selinux labeling: use selabel_open() family of functions rather than
+  matchpathcon(), bail on it if attempting to get the mutex lock fails
+
+* Tue Jun 16 2009 Nalin Dahyabhai <nalin@redhat.com>
+- compile with %%{?_smp_mflags} (Steve Grubb)
+- drop the bit where we munge part of the error table header, as it's not
+  needed any more
+
+* Fri Jun  5 2009 Nalin Dahyabhai <nalin@redhat.com> 1.7-2
+- add and own %%{_libdir}/krb5/plugins/authdata
+
+* Thu Jun  4 2009 Nalin Dahyabhai <nalin@redhat.com> 1.7-1
+- update to 1.7
+  - no need to work around build issues with ASN1BUF_OMIT_INLINE_FUNCS
+  - configure recognizes --enable/--disable-pkinit now
+  - configure can take --disable-rpath now
+  - no more libdes425, krb524d, krb425.info
+  - kadmin/k5srvutil/ktutil are user commands now
+  - new kproplog
+  - FAST encrypted-challenge plugin is new
+- drop static build logic
+- drop pam_krb5-specific configuration from the default krb5.conf
+- drop only-use-v5 flags being passed to various things started by xinetd
+- put %%{krb5prefix}/sbin in everyone's path, too (#504525)
+
+* Tue May 19 2009 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-106
+- add an auth stack to ksu's PAM configuration so that pam_setcred() calls
+  won't just fail
+
+* Mon May 11 2009 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-105
+- make PAM support for ksu also set PAM_RUSER
+
+* Thu Apr 23 2009 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-104
+- extend PAM support to ksu: perform account and session management for the
+  target user
+- pull up and merge James Leddy's changes to also set PAM_RHOST in PAM-aware
+  network-facing services
+
+* Tue Apr 21 2009 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-103
+- fix a typo in a ksu error message (Marek Mahut)
+- "rev" works the way the test suite expects now, so don't disable tests
+  that use it
+
+* Mon Apr 20 2009 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-102
+- add LSB-style init script info
+
+* Fri Apr 17 2009 Nalin Dahyabhai <nalin@redhat.com>
+- explicitly run the pdf generation script using sh (part of #225974)
+
+* Tue Apr  7 2009 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-101
+- add patches for read overflow and null pointer dereference in the
+  implementation of the SPNEGO mechanism (CVE-2009-0844, CVE-2009-0845)
+- add patch for attempt to free uninitialized pointer in libkrb5
+  (CVE-2009-0846)
+- add patch to fix length validation bug in libkrb5 (CVE-2009-0847)
+- put the krb5-user .info file into just -workstation and not also
+  -workstation-clients
+
+* Mon Apr  6 2009 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-100
+- turn off krb4 support (it won't be part of the 1.7 release, but do it now)
+- use triggeruns to properly shut down and disable krb524d when -server and
+  -workstation-servers gets upgraded, because it's gone now
+- move the libraries to /%%{_lib}, but leave --libdir alone so that plugins
+  get installed and are searched for in the same locations (#473333)
+- clean up buildprereq/prereqs, explicit mktemp requires, and add the
+  ldconfig for the -server-ldap subpackage (part of #225974)
+- escape possible macros in the changelog (part of #225974)
+- fixup summary texts (part of #225974)
+- take the execute bit off of the protocol docs (part of #225974)
+- unflag init scripts as configuration files (part of #225974)
+- make the kpropd init script treat 'reload' as 'restart' (part of #225974)
+
+* Tue Mar 17 2009 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-19
+- libgssapi_krb5: backport fix for some errors which can occur when
+  we fail to set up the server half of a context (CVE-2009-0845)
+
+* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.6.3-18
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Fri Jan 16 2009 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-17
+- rebuild
+
+* Thu Sep  4 2008 Nalin Dahyabhai <nalin@redhat.com>
+- if we successfully change the user's password during an attempt to get
+  initial credentials, but then fail to get initial creds from a non-master
+  using the new password, retry against the master (#432334)
+
+* Tue Aug  5 2008 Tom "spot" Callaway <tcallawa@redhat.com> 1.6.3-16
+- fix license tag
+
+* Wed Jul 16 2008 Nalin Dahyabhai <nalin@redhat.com>
+- clear fuzz out of patches, dropping a man page patch which is no longer
+  necessary
+- quote %%{__cc} where needed because it includes whitespace now
+- define ASN1BUF_OMIT_INLINE_FUNCS at compile-time (for now) to keep building
+
+* Fri Jul 11 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-15
+- build with -fno-strict-aliasing, which is needed because the library
+  triggers these warnings
+- don't forget to label principal database lock files
+- fix the labeling patch so that it doesn't break bootstrapping
+
+* Sat Jun 14 2008 Tom "spot" Callaway <tcallawa@redhat.com> 1.6.3-14
+- generate src/include/krb5/krb5.h before building
+- fix conditional for sparcv9
+
+* Wed Apr 16 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-13
+- ftp: use the correct local filename during mget when the 'case' option is
+  enabled (#442713)
+
+* Fri Apr  4 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-12
+- stop exporting kadmin keys to a keytab file when kadmind starts -- the
+  daemon's been able to use the database directly for a long long time now
+- belatedly add aes128,aes256 to the default set of supported key types
+
+* Tue Apr  1 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-11
+- libgssapi_krb5: properly export the acceptor subkey when creating a lucid
+  context (Kevin Coffman, via the nfs4 mailing list)
+
+* Tue Mar 18 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-10
+- add fixes from MITKRB5-SA-2008-001 for use of null or dangling pointer
+  when v4 compatibility is enabled on the KDC (CVE-2008-0062, CVE-2008-0063,
+  #432620, #432621)
+- add fixes from MITKRB5-SA-2008-002 for array out-of-bounds accesses when
+  high-numbered descriptors are used (CVE-2008-0947, #433596)
+- add backport bug fix for an attempt to free non-heap memory in
+  libgssapi_krb5 (CVE-2007-5901, #415321)
+- add backport bug fix for a double-free in out-of-memory situations in
+  libgssapi_krb5 (CVE-2007-5971, #415351)
+
+* Tue Mar 18 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-9
+- rework file labeling patch to not depend on fragile preprocessor trickery,
+  in another attempt at fixing #428355 and friends
+
+* Tue Feb 26 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-8
+- ftp: add patch to fix "runique on" case when globbing fixes applied
+- stop adding a redundant but harmless call to initialize the gssapi internals
+
+* Mon Feb 25 2008 Nalin Dahyabhai <nalin@redhat.com>
+- add patch to suppress double-processing of /etc/krb5.conf when we build
+  with --sysconfdir=/etc, thereby suppressing double-logging (#231147)
+
+* Mon Feb 25 2008 Nalin Dahyabhai <nalin@redhat.com>
+- remove a patch, to fix problems with interfaces which are "up" but which
+  have no address assigned, which conflicted with a different fix for the same
+  problem in 1.5 (#200979)
+
+* Mon Feb 25 2008 Nalin Dahyabhai <nalin@redhat.com>
+- ftp: don't lose track of a descriptor on passive get when the server fails to
+  open a file
+
+* Mon Feb 25 2008 Nalin Dahyabhai <nalin@redhat.com>
+- in login, allow PAM to interact with the user when they've been strongly
+  authenticated
+- in login, signal PAM when we're changing an expired password that it's an
+  expired password, so that when cracklib flags a password as being weak it's
+  treated as an error even if we're running as root
+
+* Mon Feb 18 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-7
+- drop netdb patch
+- kdb_ldap: add patch to treat 'nsAccountLock: true' as an indication that
+  the DISALLOW_ALL_TIX flag is set on an entry, for better interop with Fedora,
+  Netscape, Red Hat Directory Server (Simo Sorce)
+
+* Wed Feb 13 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-6
+- patch to avoid depending on <netdb.h> to define NI_MAXHOST and NI_MAXSERV
+
+* Tue Feb 12 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-5
+- enable patch for key-expiration reporting
+- enable patch to make kpasswd fall back to TCP if UDP fails (#251206)
+- enable patch to make kpasswd use the right sequence number on retransmit
+- enable patch to allow mech-specific creds delegated under spnego to be found
+  when searching for creds
+
+* Wed Jan  2 2008 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-4
+- some init script cleanups
+  - drop unquoted check and silent exit for "$NETWORKING" (#426852, #242502)
+  - krb524: don't barf on missing database if it looks like we're using kldap,
+    same as for kadmin
+  - return non-zero status for missing files which cause startup to
+    fail (#242502)
+
+* Tue Dec 18 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-3
+- allocate space for the nul-terminator in the local pathname when looking up
+  a file context, and properly free a previous context (Jose Plans, #426085)
+
+* Wed Dec  5 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-2
+- rebuild
+
+* Tue Oct 23 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.3-1
+- update to 1.6.3, dropping now-integrated patches for CVE-2007-3999
+  and CVE-2007-4000 (the new pkinit module is built conditionally and goes
+  into the -pkinit-openssl package, at least for now, to make a buildreq
+  loop with openssl avoidable)
+
+* Wed Oct 17 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-10
+- make proper use of pam_loginuid and pam_selinux in rshd and ftpd
+
+* Fri Oct 12 2007 Nalin Dahyabhai <nalin@redhat.com>
+- make krb5.conf %%verify(not md5 size mtime) in addition to
+  %%config(noreplace), like /etc/nsswitch.conf (#329811)
+
+* Mon Oct  1 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-9
+- apply the fix for CVE-2007-4000 instead of the experimental patch for
+  setting ok-as-delegate flags
+
+* Tue Sep 11 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-8
+- move the db2 kdb plugin from -server to -libs, because a multilib libkdb
+  might need it
+
+* Tue Sep 11 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-7
+- also perform PAM session and credential management when ftpd accepts a
+  client using strong authentication, missed earlier
+- also label kadmind log files and files created by the db2 plugin
+
+* Thu Sep  6 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-6
+- incorporate updated fix for CVE-2007-3999 (CVE-2007-4743)
+- fix incorrect call to "test" in the kadmin init script (#252322,#287291)
+
+* Tue Sep  4 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-5
+- incorporate fixes for MITKRB5-SA-2007-006 (CVE-2007-3999, CVE-2007-4000)
+
+* Sat Aug 25 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-4
+- cover more cases in labeling files on creation
+- add missing gawk build dependency
+
+* Thu Aug 23 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-3
+- rebuild
+
+* Thu Jul 26 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-2
+- kdc.conf: default to listening for TCP clients, too (#248415)
+
+* Thu Jul 19 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.2-1
+- update to 1.6.2
+- add "buildrequires: texinfo-tex" to get texi2pdf
+
+* Wed Jun 27 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.1-8
+- incorporate fixes for MITKRB5-SA-2007-004 (CVE-2007-2442,CVE-2007-2443)
+  and MITKRB5-SA-2007-005 (CVE-2007-2798)
+
+* Mon Jun 25 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.1-7
+- reintroduce missing %%postun for the non-split_workstation case
+
+* Mon Jun 25 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.1-6
+- rebuild
+
+* Mon Jun 25 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.1-5.1
+- rebuild
+
+* Sun Jun 24 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.1-5
+- add missing pam-devel build requirement, force selinux-or-fail build
+
+* Sun Jun 24 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.1-4
+- rebuild
+
+* Sun Jun 24 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.1-3
+- label all files at creation-time according to the SELinux policy (#228157)
+
+* Fri Jun 22 2007 Nalin Dahyabhai <nalin@redhat.com>
+- perform PAM account / session management in krshd (#182195,#195922)
+- perform PAM authentication and account / session management in ftpd
+- perform PAM authentication, account / session management, and password-
+  changing in login.krb5 (#182195,#195922)
+
+* Fri Jun 22 2007 Nalin Dahyabhai <nalin@redhat.com>
+- preprocess kerberos.ldif into a format FDS will like better, and include
+  that as a doc file as well
+
+* Fri Jun 22 2007 Nalin Dahyabhai <nalin@redhat.com>
+- switch man pages to being generated with the right paths in them
+- drop old, incomplete SELinux patch
+- add patch from Greg Hudson to make srvtab routines report missing-file errors
+  at same point that keytab routines do (#241805)
+
+* Thu May 24 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.1-2
+- pull patch from svn to undo unintentional chattiness in ftp
+- pull patch from svn to handle NULL krb5_get_init_creds_opt structures
+  better in a couple of places where they're expected
+
+* Wed May 23 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6.1-1
+- update to 1.6.1
+  - drop no-longer-needed patches for CVE-2007-0956,CVE-2007-0957,CVE-2007-1216
+  - drop patch for sendto bug in 1.6, fixed in 1.6.1
+
+* Fri May 18 2007 Nalin Dahyabhai <nalin@redhat.com>
+- kadmind.init: don't fail outright if the default principal database
+  isn't there if it looks like we might be using the kldap plugin
+- kadmind.init: attempt to extract the key for the host-specific kadmin
+  service when we try to create the keytab
+
+* Wed May 16 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6-6
+- omit dependent libraries from the krb5-config --libs output, as using
+  shared libraries (no more static libraries) makes them unnecessary and
+  they're not part of the libkrb5 interface (patch by Rex Dieter, #240220)
+  (strips out libkeyutils, libresolv, libdl)
+
+* Fri May  4 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6-5
+- pull in keyutils as a build requirement to get the "KEYRING:" ccache type,
+  because we've merged
+
+* Fri May  4 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6-4
+- fix an uninitialized length value which could cause a crash when parsing
+  key data coming from a directory server
+- correct a typo in the krb5.conf man page ("ldap_server"->"ldap_servers")
+
+* Fri Apr 13 2007 Nalin Dahyabhai <nalin@redhat.com>
+- move the default acl_file, dict_file, and admin_keytab settings to
+  the part of the default/example kdc.conf where they'll actually have
+  an effect (#236417)
+
+* Thu Apr  5 2007 Nalin Dahyabhai <nalin@redhat.com> 1.5-24
+- merge security fixes from RHSA-2007:0095
+
+* Tue Apr  3 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6-3
+- add patch to correct unauthorized access via krb5-aware telnet
+  daemon (#229782, CVE-2007-0956)
+- add patch to fix buffer overflow in krb5kdc and kadmind
+  (#231528, CVE-2007-0957)
+- add patch to fix double-free in kadmind (#231537, CVE-2007-1216)
+
+* Thu Mar 22 2007 Nalin Dahyabhai <nalin@redhat.com>
+- back out buildrequires: keyutils-libs-devel for now
+
+* Thu Mar 22 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6-2
+- add buildrequires: on keyutils-libs-devel to enable use of keyring ccaches,
+  dragging keyutils-libs in as a dependency
+
+* Mon Mar 19 2007 Nalin Dahyabhai <nalin@redhat.com> 1.5-23
+- fix bug ID in changelog
+
+* Thu Mar 15 2007 Nalin Dahyabhai <nalin@redhat.com> 1.5-22
+
+* Thu Mar 15 2007 Nalin Dahyabhai <nalin@redhat.com> 1.5-21
+- add preliminary patch to fix buffer overflow in krb5kdc and kadmind
+  (#231528, CVE-2007-0957)
+- add preliminary patch to fix double-free in kadmind (#231537, CVE-2007-1216)
+
+* Wed Feb 28 2007 Nalin Dahyabhai <nalin@redhat.com>
+- add patch to build semi-useful static libraries, but don't apply it unless
+  we need them
+
+* Tue Feb 27 2007 Nalin Dahyabhai <nalin@redhat.com> - 1.5-20
+- temporarily back out %%post changes, fix for #143289 for security update
+- add preliminary patch to correct unauthorized access via krb5-aware telnet
+
+* Mon Feb 19 2007 Nalin Dahyabhai <nalin@redhat.com>
+- make profile.d scriptlets mode 644 instead of 755 (part of #225974)
+
+* Tue Jan 30 2007 Nalin Dahyabhai <nalin@redhat.com> 1.6-1
+- clean up quoting of command-line arguments passed to the krsh/krlogin
+  wrapper scripts
+
+* Mon Jan 22 2007 Nalin Dahyabhai <nalin@redhat.com>
+- initial update to 1.6, pre-package-reorg
+- move workstation daemons to a new subpackage (#81836, #216356, #217301), and
+  make the new subpackage require xinetd (#211885)
+
+* Mon Jan 22 2007 Nalin Dahyabhai <nalin@redhat.com> - 1.5-18
+- make use of install-info more failsafe (Ville Skyttä, #223704)
+- preserve timestamps on shell scriptlets at %%install-time
+
+* Tue Jan 16 2007 Nalin Dahyabhai <nalin@redhat.com> - 1.5-17
+- move to using pregenerated PDF docs to cure multilib conflicts (#222721)
+
+* Fri Jan 12 2007 Nalin Dahyabhai <nalin@redhat.com> - 1.5-16
+- update backport of the preauth module interface (part of #194654)
+
+* Tue Jan  9 2007 Nalin Dahyabhai <nalin@redhat.com> - 1.5-14
+- apply fixes from Tom Yu for MITKRB5-SA-2006-002 (CVE-2006-6143) (#218456)
+- apply fixes from Tom Yu for MITKRB5-SA-2006-003 (CVE-2006-6144) (#218456)
+
+* Wed Dec 20 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-12
+- update backport of the preauth module interface
+
+* Mon Oct 30 2006 Nalin Dahyabhai <nalin@redhat.com>
+- update backport of the preauth module interface
+- add proposed patches 4566, 4567
+- add proposed edata reporting interface for KDC
+- add temporary placeholder for module global context fixes
+
+* Mon Oct 23 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-11
+- don't bail from the KDC init script if there's no database, it may be in
+  a different location than the default (fenlason)
+- remove the [kdc] section from the default krb5.conf -- doesn't seem to have
+  been applicable for a while
+
+* Wed Oct 18 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-10
+- rename krb5.sh and krb5.csh so that they don't overlap (#210623)
+- way-late application of added error info in kadmind.init (#65853)
+
+* Wed Oct 18 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-9.pal_18695
+- add backport of in-development preauth module interface (#208643)
+
+* Mon Oct  9 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-9
+- provide docs in PDF format instead of as tex source (Enrico Scholz, #209943)
+
+* Wed Oct  4 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-8
+- add missing shebang headers to krsh and krlogin wrapper scripts (#209238)
+
+* Wed Sep  6 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-7
+- set SS_LIB at configure-time so that libss-using apps get working readline
+  support (#197044)
+
+* Fri Aug 18 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-6
+- switch to the updated patch for MITKRB-SA-2006-001
+
+* Tue Aug  8 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-5
+- apply patch to address MITKRB-SA-2006-001 (CVE-2006-3084)
+
+* Mon Aug  7 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-4
+- ensure that the gssapi library's been initialized before walking the
+  internal mechanism list in gss_release_oid(), needed if called from
+  gss_release_name() right after a gss_import_name() (#198092)
+
+* Tue Jul 25 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-3
+- rebuild
+
+* Tue Jul 25 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-2
+- pull up latest revision of patch to reduce lockups in rsh/rshd
+
+* Mon Jul 17 2006 Nalin Dahyabhai <nalin@redhat.com> - 1.5-1.2
+- rebuild
+
+* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 1.5-1.1
+- rebuild
+
+* Thu Jul  6 2006 Nalin Dahyabhai <nalin@redhat.com> 1.5-1
+- build
+
+* Wed Jul  5 2006 Nalin Dahyabhai <nalin@redhat.com> 1.5-0
+- update to 1.5
+
+* Fri Jun 23 2006 Nalin Dahyabhai <nalin@redhat.com> 1.4.3-9
+- mark profile.d config files noreplace (Laurent Rineau, #196447)
+
+* Thu Jun  8 2006 Nalin Dahyabhai <nalin@redhat.com> 1.4.3-8
+- add buildprereq for autoconf
+
+* Mon May 22 2006 Nalin Dahyabhai <nalin@redhat.com> 1.4.3-7
+- further munge krb5-config so that 'libdir=/usr/lib' is given even on 64-bit
+  architectures, to avoid multilib conflicts; other changes will conspire to
+  strip out the -L flag which uses this, so it should be harmless (#192692)
+
+* Fri Apr 28 2006 Nalin Dahyabhai <nalin@redhat.com> 1.4.3-6
+- adjust the patch which removes the use of rpath to also produce a
+  krb5-config which is okay in multilib environments (#190118)
+- make the name-of-the-tempfile comment which compile_et adds to error code
+  headers always list the same file to avoid conflicts on multilib installations
+- strip SIZEOF_LONG out of krb5.h so that it doesn't conflict on multilib boxes
+- strip GSS_SIZEOF_LONG out of gssapi.h so that it doesn't conflict on mulitlib
+  boxes
+
+* Fri Apr 14 2006 Stepan Kasal <skasal@redhat.com> 1.4.3-5
+- Fix formatting typo in kinit.1 (krb5-kinit-man-typo.patch)
+
+* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> 1.4.3-4.1
+- bump again for double-long bug on ppc(64)
+
+* Mon Feb  6 2006 Nalin Dahyabhai <nalin@redhat.com> 1.4.3-4
+- give a little bit more information to the user when kinit gets the catch-all
+  I/O error (#180175)
+
+* Thu Jan 19 2006 Nalin Dahyabhai <nalin@redhat.com> 1.4.3-3
+- rebuild properly when pthread_mutexattr_setrobust_np() is defined but not
+  declared, such as with recent glibc when _GNU_SOURCE isn't being used
+
+* Thu Jan 19 2006 Matthias Clasen <mclasen@redhat.com> 1.4.3-2
+- Use full paths in krb5.sh to avoid path lookups
+
+* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
+- rebuilt
+
+* Thu Dec  1 2005 Nalin Dahyabhai <nalin@redhat.com>
+- login: don't truncate passwords before passing them into crypt(), in
+  case they're significant (#149476)
+
+* Thu Nov 17 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.3-1
+- update to 1.4.3
+- make ksu setuid again (#137934, others)
+
+* Tue Sep 13 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.2-4
+- mark %%{krb5prefix}/man so that files which are packaged within it are
+  flagged as %%doc (#168163)
+
+* Tue Sep  6 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.2-3
+- add an xinetd configuration file for encryption-only telnetd, parallelling
+  the kshell/ekshell pair (#167535)
+
+* Wed Aug 31 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.2-2
+- change the default configured encryption type for KDC databases to the
+  compiled-in default of des3-hmac-sha1 (#57847)
+
+* Thu Aug 11 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.2-1
+- update to 1.4.2, incorporating the fixes for MIT-KRB5-SA-2005-002 and
+  MIT-KRB5-SA-2005-003
+
+* Wed Jun 29 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.1-6
+- rebuild
+
+* Wed Jun 29 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.1-5
+- fix telnet client environment variable disclosure the same way NetKit's
+  telnet client did (CAN-2005-0488) (#159305)
+- keep apps which call krb5_principal_compare() or krb5_realm_compare() with
+  malformed or NULL principal structures from crashing outright (Thomas Biege)
+  (#161475)
+
+* Tue Jun 28 2005 Nalin Dahyabhai <nalin@redhat.com>
+- apply fixes from draft of MIT-KRB5-SA-2005-002 (CAN-2005-1174,CAN-2005-1175)
+  (#157104)
+- apply fixes from draft of MIT-KRB5-SA-2005-003 (CAN-2005-1689) (#159755)
+
+* Fri Jun 24 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.1-4
+- fix double-close in keytab handling
+- add port of fixes for CAN-2004-0175 to krb5-aware rcp (#151612)
+
+* Fri May 13 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.1-3
+- prevent spurious EBADF in krshd when stdin is closed by the client while
+  the command is running (#151111)
+
+* Fri May 13 2005 Martin Stransky <stransky@redhat.com> 1.4.1-2
+- add deadlock patch, removed old patch
+
+* Fri May  6 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4.1-1
+- update to 1.4.1, incorporating fixes for CAN-2005-0468 and CAN-2005-0469
+- when starting the KDC or kadmind, if KRB5REALM is set via the /etc/sysconfig
+  file for the service, pass it as an argument for the -r flag
+
+* Wed Mar 23 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4-3
+- drop krshd patch for now
+
+* Thu Mar 17 2005 Nalin Dahyabhai <nalin@redhat.com>
+- add draft fix from Tom Yu for slc_add_reply() buffer overflow (CAN-2005-0469)
+- add draft fix from Tom Yu for env_opt_add() buffer overflow (CAN-2005-0468)
+
+* Wed Mar 16 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4-2
+- don't include <term.h> into the telnet client when we're not using curses
+
+* Thu Feb 24 2005 Nalin Dahyabhai <nalin@redhat.com> 1.4-1
+- update to 1.4
+  - v1.4 kadmin client requires a v1.4 kadmind on the server, or use the "-O"
+    flag to specify that it should communicate with the server using the older
+    protocol
+  - new libkrb5support library
+  - v5passwdd and kadmind4 are gone
+  - versioned symbols
+- pick up $KRB5KDC_ARGS from /etc/sysconfig/krb5kdc, if it exists, and pass
+  it on to krb5kdc
+- pick up $KADMIND_ARGS from /etc/sysconfig/kadmin, if it exists, and pass
+  it on to kadmind
+- pick up $KRB524D_ARGS from /etc/sysconfig/krb524, if it exists, and pass
+  it on to krb524d *instead of* "-m"
+- set "forwardable" in [libdefaults] in the default krb5.conf to match the
+  default setting which we supply for pam_krb5
+- set a default of 24h for "ticket_lifetime" in [libdefaults], reflecting the
+  compiled-in default
+
+* Mon Dec 20 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.6-3
+- rebuild
+
+* Mon Dec 20 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.6-2
+- rebuild
+
+* Mon Dec 20 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.6-1
+- update to 1.3.6, which includes the previous fix
+
+* Mon Dec 20 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.5-8
+- apply fix from Tom Yu for MITKRB5-SA-2004-004 (CAN-2004-1189)
+
+* Fri Dec 17 2004 Martin Stransky <stransky@redhat.com> 1.3.5-7
+- fix deadlock during file transfer via rsync/krsh
+- thanks goes to James Antill for hint
+
+* Fri Nov 26 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.5-6
+- rebuild
+
+* Mon Nov 22 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.5-3
+- fix predictable-tempfile-name bug in krb5-send-pr (CAN-2004-0971, #140036)
+
+* Tue Nov 16 2004 Nalin Dahyabhai <nalin@redhat.com>
+- silence compiler warning in kprop by using an in-memory ccache with a fixed
+  name instead of an on-disk ccache with a name generated by tmpnam()
+
+* Tue Nov 16 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.5-2
+- fix globbing patch port mode (#139075)
+
+* Mon Nov  1 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.5-1
+- fix segfault in telnet due to incorrect checking of gethostbyname_r result
+  codes (#129059)
+
+* Fri Oct 15 2004 Nalin Dahyabhai <nalin@redhat.com>
+- remove rc4-hmac:norealm and rc4-hmac:onlyrealm from the default list of
+  supported keytypes in kdc.conf -- they produce exactly the same keys as
+  rc4-hmac:normal because rc4 string-to-key ignores salts
+- nuke kdcrotate -- there are better ways to balance the load on KDCs, and
+  the SELinux policy for it would have been scary-looking
+- update to 1.3.5, mainly to include MITKRB5SA 2004-002 and 2004-003
+
+* Tue Aug 31 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.4-7
+- rebuild
+
+* Tue Aug 24 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.4-6
+- rebuild
+
+* Tue Aug 24 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.4-5
+- incorporate revised fixes from Tom Yu for CAN-2004-0642, CAN-2004-0644,
+  CAN-2004-0772
+
+* Mon Aug 23 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.4-4
+- rebuild
+
+* Mon Aug 23 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.4-3
+- incorporate fixes from Tom Yu for CAN-2004-0642, CAN-2004-0772
+  (MITKRB5-SA-2004-002, #130732)
+- incorporate fixes from Tom Yu for CAN-2004-0644 (MITKRB5-SA-2004-003, #130732)
+
+* Tue Jul 27 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.4-2
+- fix indexing error in server sorting patch (#127336)
+
+* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Mon Jun 14 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.4-0.1
+- update to 1.3.4 final
+
+* Mon Jun  7 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.4-0
+- update to 1.3.4 beta1
+- remove MITKRB5-SA-2004-001, included in 1.3.4
+
+* Mon Jun  7 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.3-8
+- rebuild
+
+* Fri Jun  4 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.3-7
+- rebuild
+
+* Fri Jun  4 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.3-6
+- apply updated patch from MITKRB5-SA-2004-001 (revision 2004-06-02)
+
+* Tue Jun  1 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.3-5
+- rebuild
+
+* Tue Jun  1 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.3-4
+- apply patch from MITKRB5-SA-2004-001 (#125001)
+
+* Wed May 12 2004 Thomas Woerner <twoerner@redhat.com> 1.3.3-3
+- removed rpath
+
+* Thu Apr 15 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.3-2
+- re-enable large file support, fell out in 1.3-1
+- patch rcp to use long long and %%lld format specifiers when reporting file
+  sizes on large files
+
+* Tue Apr 13 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.3-1
+- update to 1.3.3
+
+* Wed Mar 10 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.2-1
+- update to 1.3.2
+
+* Mon Mar  8 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-12
+- rebuild
+
+* Tue Mar 02 2004 Elliot Lee <sopwith@redhat.com> 1.3.1-11.1
+- rebuilt
+
+* Fri Feb 13 2004 Elliot Lee <sopwith@redhat.com> 1.3.1-11
+- rebuilt
+
+* Mon Feb  9 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-10
+- catch krb4 send_to_kdc cases in kdc preference patch
+
+* Mon Feb  2 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-9
+- remove patch to set TERM in klogind which, combined with the upstream fix in
+  1.3.1, actually produces the bug now (#114762)
+
+* Mon Jan 19 2004 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-8
+- when iterating over lists of interfaces which are "up" from getifaddrs(),
+  skip over those which have no address (#113347)
+
+* Mon Jan 12 2004 Nalin Dahyabhai <nalin@redhat.com>
+- prefer the kdc which last replied to a request when sending requests to kdcs
+
+* Mon Nov 24 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-7
+- fix combination of --with-netlib and --enable-dns (#82176)
+
+* Tue Nov 18 2003 Nalin Dahyabhai <nalin@redhat.com>
+- remove libdefault ticket_lifetime option from the default krb5.conf, it is
+  ignored by libkrb5
+
+* Thu Sep 25 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-6
+- fix bug in patch to make rlogind start login with a clean environment a la
+  netkit rlogin, spotted and fixed by Scott McClung
+
+* Tue Sep 23 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-5
+- include profile.d scriptlets in krb5-devel so that krb5-config will be in
+  the path if krb5-workstation isn't installed, reported by Kir Kolyshkin
+
+* Mon Sep  8 2003 Nalin Dahyabhai <nalin@redhat.com>
+- add more etypes (arcfour) to the default enctype list in kdc.conf
+- don't apply previous patch, refused upstream
+
+* Fri Sep  5 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-4
+- fix 32/64-bit bug storing and retrieving the issue_date in v4 credentials
+
+* Wed Sep 3 2003 Dan Walsh <dwalsh@redhat.com> 1.3.1-3
+- Don't check for write access on /etc/krb5.conf if SELinux
+
+* Tue Aug 26 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-2
+- fixup some int/pointer varargs wackiness
+
+* Tue Aug  5 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-1
+- rebuild
+
+* Mon Aug  4 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3.1-0
+- update to 1.3.1
+
+* Thu Jul 24 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3-2
+- pull fix for non-compliant encoding of salt field in etype-info2 preauth
+  data from 1.3.1 beta 1, until 1.3.1 is released.
+
+* Mon Jul 21 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3-1
+- update to 1.3
+
+* Mon Jul  7 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.8-4
+- correctly use stdargs
+
+* Wed Jun 18 2003 Nalin Dahyabhai <nalin@redhat.com> 1.3-0.beta.4
+- test update to 1.3 beta 4
+- ditch statglue build option
+- krb5-devel requires e2fsprogs-devel, which now provides libss and libcom_err
+
+* Wed Jun 04 2003 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Wed May 21 2003 Jeremy Katz <katzj@redhat.com> 1.2.8-2
+- gcc 3.3 doesn't implement varargs.h, include stdarg.h instead
+
+* Wed Apr  9 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.8-1
+- update to 1.2.8
+
+* Mon Mar 31 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-14
+- fix double-free of enc_part2 in krb524d
+
+* Fri Mar 21 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-13
+- update to latest patch kit for MITKRB5-SA-2003-004
+
+* Wed Mar 19 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-12
+- add patch included in MITKRB5-SA-2003-003 (CAN-2003-0028)
+
+* Mon Mar 17 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-11
+- add patches from patchkit from MITKRB5-SA-2003-004 (CAN-2003-0138 and
+  CAN-2003-0139)
+
+* Thu Mar  6 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-10
+- rebuild
+
+* Thu Mar  6 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-9
+- fix buffer underrun in unparsing certain principals (CAN-2003-0082)
+
+* Tue Feb  4 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-8
+- add patch to document the reject-bad-transited option in kdc.conf
+
+* Mon Feb  3 2003 Nalin Dahyabhai <nalin@redhat.com>
+- add patch to fix server-side crashes when principals have no
+  components (CAN-2003-0072)
+
+* Thu Jan 23 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-7
+- add patch from Mark Cox for exploitable bugs in ftp client
+
+* Wed Jan 22 2003 Tim Powers <timp@redhat.com>
+- rebuilt
+
+* Wed Jan 15 2003 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-5
+- use PICFLAGS when building code from the ktany patch
+
+* Thu Jan  9 2003 Bill Nottingham <notting@redhat.com> 1.2.7-4
+- debloat
+
+* Tue Jan  7 2003 Jeremy Katz <katzj@redhat.com> 1.2.7-3
+- include .so.* symlinks as well as .so.*.*
+
+* Mon Dec  9 2002 Jakub Jelinek <jakub@redhat.com> 1.2.7-2
+- always #include <errno.h> to access errno, never do it directly
+- enable LFS on a bunch of other 32-bit arches
+
+* Wed Dec  4 2002 Nalin Dahyabhai <nalin@redhat.com>
+- increase the maximum name length allowed by kuserok() to the higher value
+  used in development versions
+
+* Mon Dec  2 2002 Nalin Dahyabhai <nalin@redhat.com>
+- install src/krb524/README as README.krb524 in the -servers package,
+  includes information about converting for AFS principals
+
+* Fri Nov 15 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.7-1
+- update to 1.2.7
+- disable use of tcl
+
+* Mon Nov 11 2002 Nalin Dahyabhai <nalin@redhat.com>
+- update to 1.2.7-beta2 (internal only, not for release), dropping dnsparse
+  and kadmind4 fixes
+
+* Wed Oct 23 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.6-5
+- add patch for buffer overflow in kadmind4 (not used by default)
+
+* Fri Oct 11 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.6-4
+- drop a hunk from the dnsparse patch which is actually redundant (thanks to
+  Tom Yu)
+
+* Wed Oct  9 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.6-3
+- patch to handle truncated dns responses
+
+* Mon Oct  7 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.6-2
+- remove hashless key types from the default kdc.conf, they're not supposed to
+  be there, noted by Sam Hartman on krbdev
+
+* Fri Sep 27 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.6-1
+- update to 1.2.6
+
+* Fri Sep 13 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.5-7
+- use %%{_lib} for the sake of multilib systems
+
+* Fri Aug  2 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.5-6
+- add patch from Tom Yu for exploitable bugs in rpc code used in kadmind
+
+* Tue Jul 23 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.5-5
+- fix bug in krb5.csh which would cause the path check to always succeed
+
+* Fri Jul 19 2002 Jakub Jelinek <jakub@redhat.com> 1.2.5-4
+- build even libdb.a with -fPIC and $RPM_OPT_FLAGS.
+
+* Fri Jun 21 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Sun May 26 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Wed May  1 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.5-1
+- update to 1.2.5
+- disable statglue
+
+* Fri Mar  1 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.4-1
+- update to 1.2.4
+
+* Wed Feb 20 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.3-5
+- rebuild in new environment
+- reenable statglue
+
+* Sat Jan 26 2002 Florian La Roche <Florian.LaRoche@redhat.de>
+- prereq chkconfig for the server subpackage
+
+* Wed Jan 16 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.3-3
+- build without -g3, which gives us large static libraries in -devel
+
+* Tue Jan 15 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.3-2
+- reintroduce ld.so.conf munging in the -libs %%post
+
+* Thu Jan 10 2002 Nalin Dahyabhai <nalin@redhat.com> 1.2.3-1
+- rename the krb5 package back to krb5-libs; the previous rename caused
+  something of an uproar
+- update to 1.2.3, which includes the FTP and telnetd fixes
+- configure without --enable-dns-for-kdc --enable-dns-for-realm, which now set
+  the default behavior instead of enabling the feature (the feature is enabled
+  by --enable-dns, which we still use)
+- reenable optimizations on Alpha
+- support more encryption types in the default kdc.conf (heads-up from post
+  to comp.protocols.kerberos by Jason Heiss)
+
+* Fri Aug  3 2001 Nalin Dahyabhai <nalin@redhat.com> 1.2.2-14
+- rename the krb5-libs package to krb5 (naming a subpackage -libs when there
+  is no main package is silly)
+- move defaults for PAM to the appdefaults section of krb5.conf -- this is
+  the area where the krb5_appdefault_* functions look for settings)
+- disable statglue (warning: breaks binary compatibility with previous
+  packages, but has to be broken at some point to work correctly with
+  unpatched versions built with newer versions of glibc)
+
+* Fri Aug  3 2001 Nalin Dahyabhai <nalin@redhat.com> 1.2.2-13
+- bump release number and rebuild
+
+* Wed Aug  1 2001 Nalin Dahyabhai <nalin@redhat.com>
+- add patch to fix telnetd vulnerability
+
+* Fri Jul 20 2001 Nalin Dahyabhai <nalin@redhat.com>
+- tweak statglue.c to fix stat/stat64 aliasing problems
+- be cleaner in use of gcc to build shlibs
+
+* Wed Jul 11 2001 Nalin Dahyabhai <nalin@redhat.com>
+- use gcc to build shared libraries
+
+* Wed Jun 27 2001 Nalin Dahyabhai <nalin@redhat.com>
+- add patch to support "ANY" keytab type (i.e.,
+  "default_keytab_name = ANY:FILE:/etc/krb5.keytab,SRVTAB:/etc/srvtab"
+  patch from Gerald Britton, #42551)
+- build with -D_FILE_OFFSET_BITS=64 to get large file I/O in ftpd (#30697)
+- patch ftpd to use long long and %%lld format specifiers to support the SIZE
+  command on large files (also #30697)
+- don't use LOG_AUTH as an option value when calling openlog() in ksu (#45965)
+- implement reload in krb5kdc and kadmind init scripts (#41911)
+- lose the krb5server init script (not using it any more)
+
+* Sun Jun 24 2001 Elliot Lee <sopwith@redhat.com>
+- Bump release + rebuild.
+
+* Tue May 29 2001 Nalin Dahyabhai <nalin@redhat.com>
+- pass some structures by address instead of on the stack in krb5kdc
+
+* Tue May 22 2001 Nalin Dahyabhai <nalin@redhat.com>
+- rebuild in new environment
+
+* Thu Apr 26 2001 Nalin Dahyabhai <nalin@redhat.com>
+- add patch from Tom Yu to fix ftpd overflows (#37731)
+
+* Wed Apr 18 2001 Than Ngo <than@redhat.com>
+- disable optimizations on the alpha again
+
+* Fri Mar 30 2001 Nalin Dahyabhai <nalin@redhat.com>
+- add in glue code to make sure that libkrb5 continues to provide a
+  weak copy of stat()
+
+* Thu Mar 15 2001 Nalin Dahyabhai <nalin@redhat.com>
+- build alpha with -O0 for now
+
+* Thu Mar  8 2001 Nalin Dahyabhai <nalin@redhat.com>
+- fix the kpropd init script
+
+* Mon Mar  5 2001 Nalin Dahyabhai <nalin@redhat.com>
+- update to 1.2.2, which fixes some bugs relating to empty ETYPE-INFO
+- re-enable optimization on Alpha
+
+* Thu Feb  8 2001 Nalin Dahyabhai <nalin@redhat.com>
+- build alpha with -O0 for now
+- own %%{_var}/kerberos
+
+* Tue Feb  6 2001 Nalin Dahyabhai <nalin@redhat.com>
+- own the directories which are created for each package (#26342)
+
+* Tue Jan 23 2001 Nalin Dahyabhai <nalin@redhat.com>
+- gettextize init scripts
+
+* Fri Jan 19 2001 Nalin Dahyabhai <nalin@redhat.com>
+- add some comments to the ksu patches for the curious
+- re-enable optimization on alphas
+
+* Mon Jan 15 2001 Nalin Dahyabhai <nalin@redhat.com>
+- fix krb5-send-pr (#18932) and move it from -server to -workstation
+- buildprereq libtermcap-devel
+- temporariliy disable optimization on alphas
+- gettextize init scripts
+
+* Tue Dec  5 2000 Nalin Dahyabhai <nalin@redhat.com>
+- force -fPIC
+
+* Fri Dec  1 2000 Nalin Dahyabhai <nalin@redhat.com>
+- rebuild in new environment
+
+* Tue Oct 31 2000 Nalin Dahyabhai <nalin@redhat.com>
+- add bison as a BuildPrereq (#20091)
+
+* Mon Oct 30 2000 Nalin Dahyabhai <nalin@redhat.com>
+- change /usr/dict/words to /usr/share/dict/words in default kdc.conf (#20000)
+
+* Thu Oct  5 2000 Nalin Dahyabhai <nalin@redhat.com>
+- apply kpasswd bug fixes from David Wragg
+
+* Wed Oct  4 2000 Nalin Dahyabhai <nalin@redhat.com>
+- make krb5-libs obsolete the old krb5-configs package (#18351)
+- don't quit from the kpropd init script if there's no principal database so
+  that you can propagate the first time without running kpropd manually
+- don't complain if /etc/ld.so.conf doesn't exist in the -libs %%post
+
+* Tue Sep 12 2000 Nalin Dahyabhai <nalin@redhat.com>
+- fix credential forwarding problem in klogind (goof in KRB5CCNAME handling)
+  (#11588)
+- fix heap corruption bug in FTP client (#14301)
+
+* Wed Aug 16 2000 Nalin Dahyabhai <nalin@redhat.com>
+- fix summaries and descriptions
+- switched the default transfer protocol from PORT to PASV as proposed on
+  bugzilla (#16134), and to match the regular ftp package's behavior
+
+* Wed Jul 19 2000 Jeff Johnson <jbj@redhat.com>
+- rebuild to compress man pages.
+
+* Sat Jul 15 2000 Bill Nottingham <notting@redhat.com>
+- move initscript back
+
+* Fri Jul 14 2000 Nalin Dahyabhai <nalin@redhat.com>
+- disable servers by default to keep linuxconf from thinking they need to be
+  started when they don't
+
+* Thu Jul 13 2000 Prospector <bugzilla@redhat.com>
+- automatic rebuild
+
+* Mon Jul 10 2000 Nalin Dahyabhai <nalin@redhat.com>
+- change cleanup code in post to not tickle chkconfig
+- add grep as a Prereq: for -libs
+
+* Thu Jul  6 2000 Nalin Dahyabhai <nalin@redhat.com>
+- move condrestarts to postun
+- make xinetd configs noreplace
+- add descriptions to xinetd configs
+- add /etc/init.d as a prereq for the -server package
+- patch to properly truncate $TERM in krlogind
+
+* Fri Jun 30 2000 Nalin Dahyabhai <nalin@redhat.com>
+- update to 1.2.1
+- back out Tom Yu's patch, which is a big chunk of the 1.2 -> 1.2.1 update
+- start using the official source tarball instead of its contents
+
+* Thu Jun 29 2000 Nalin Dahyabhai <nalin@redhat.com>
+- Tom Yu's patch to fix compatibility between 1.2 kadmin and 1.1.1 kadmind
+- pull out 6.2 options in the spec file (sonames changing in 1.2 means it's not
+  compatible with other stuff in 6.2, so no need)
+
+* Wed Jun 28 2000 Nalin Dahyabhai <nalin@redhat.com>
+- tweak graceful start/stop logic in post and preun
+
+* Mon Jun 26 2000 Nalin Dahyabhai <nalin@redhat.com>
+- update to the 1.2 release
+- ditch a lot of our patches which went upstream
+- enable use of DNS to look up things at build-time
+- disable use of DNS to look up things at run-time in default krb5.conf
+- change ownership of the convert-config-files script to root.root
+- compress PS docs
+- fix some typos in the kinit man page
+- run condrestart in server post, and shut down in preun
+
+* Mon Jun 19 2000 Nalin Dahyabhai <nalin@redhat.com>
+- only remove old krb5server init script links if the init script is there
+
+* Sat Jun 17 2000 Nalin Dahyabhai <nalin@redhat.com>
+- disable kshell and eklogin by default
+
+* Thu Jun 15 2000 Nalin Dahyabhai <nalin@redhat.com>
+- patch mkdir/rmdir problem in ftpcmd.y
+- add condrestart option to init script
+- split the server init script into three pieces and add one for kpropd
+
+* Wed Jun 14 2000 Nalin Dahyabhai <nalin@redhat.com>
+- make sure workstation servers are all disabled by default
+- clean up krb5server init script
+
+* Fri Jun  9 2000 Nalin Dahyabhai <nalin@redhat.com>
+- apply second set of buffer overflow fixes from Tom Yu
+- fix from Dirk Husung for a bug in buffer cleanups in the test suite
+- work around possibly broken rev binary in running test suite
+- move default realm configs from /var/kerberos to %%{_var}/kerberos
+
+* Tue Jun  6 2000 Nalin Dahyabhai <nalin@redhat.com>
+- make ksu and v4rcp owned by root
+
+* Sat Jun  3 2000 Nalin Dahyabhai <nalin@redhat.com>
+- use %%{_infodir} to better comply with FHS
+- move .so files to -devel subpackage
+- tweak xinetd config files (bugs #11833, #11835, #11836, #11840)
+- fix package descriptions again
+
+* Wed May 24 2000 Nalin Dahyabhai <nalin@redhat.com>
+- change a LINE_MAX to 1024, fix from Ken Raeburn
+- add fix for login vulnerability in case anyone rebuilds without krb4 compat
+- add tweaks for byte-swapping macros in krb.h, also from Ken
+- add xinetd config files
+- make rsh and rlogin quieter
+- build with debug to fix credential forwarding
+- add rsh as a build-time req because the configure scripts look for it to
+  determine paths
+
+* Wed May 17 2000 Nalin Dahyabhai <nalin@redhat.com>
+- fix config_subpackage logic
+
+* Tue May 16 2000 Nalin Dahyabhai <nalin@redhat.com>
+- remove setuid bit on v4rcp and ksu in case the checks previously added
+  don't close all of the problems in ksu
+- apply patches from Jeffrey Schiller to fix overruns Chris Evans found
+- reintroduce configs subpackage for use in the errata
+- add PreReq: sh-utils
+
+* Mon May 15 2000 Nalin Dahyabhai <nalin@redhat.com>
+- fix double-free in the kdc (patch merged into MIT tree)
+- include convert-config-files script as a documentation file
+
+* Wed May 03 2000 Nalin Dahyabhai <nalin@redhat.com>
+- patch ksu man page because the -C option never works
+- add access() checks and disable debug mode in ksu
+- modify default ksu build arguments to specify more directories in CMD_PATH
+  and to use getusershell()
+
+* Wed May 03 2000 Bill Nottingham <notting@redhat.com>
+- fix configure stuff for ia64
+
+* Mon Apr 10 2000 Nalin Dahyabhai <nalin@redhat.com>
+- add LDCOMBINE=-lc to configure invocation to use libc versioning (bug #10653)
+- change Requires: for/in subpackages to include %%{version}
+
+* Wed Apr 05 2000 Nalin Dahyabhai <nalin@redhat.com>
+- add man pages for kerberos(1), kvno(1), .k5login(5)
+- add kvno to -workstation
+
+* Mon Apr 03 2000 Nalin Dahyabhai <nalin@redhat.com>
+- Merge krb5-configs back into krb5-libs.  The krb5.conf file is marked as
+  a %%config file anyway.
+- Make krb5.conf a noreplace config file.
+
+* Thu Mar 30 2000 Nalin Dahyabhai <nalin@redhat.com>
+- Make klogind pass a clean environment to children, like NetKit's rlogind does.
+
+* Wed Mar 08 2000 Nalin Dahyabhai <nalin@redhat.com>
+- Don't enable the server by default.
+- Compress info pages.
+- Add defaults for the PAM module to krb5.conf
+
+* Mon Mar 06 2000 Nalin Dahyabhai <nalin@redhat.com>
+- Correct copyright: it's exportable now, provided the proper paperwork is
+  filed with the government.
+
+* Fri Mar 03 2000 Nalin Dahyabhai <nalin@redhat.com>
+- apply Mike Friedman's patch to fix format string problems
+- don't strip off argv[0] when invoking regular rsh/rlogin
+
+* Thu Mar 02 2000 Nalin Dahyabhai <nalin@redhat.com>
+- run kadmin.local correctly at startup
+
+* Mon Feb 28 2000 Nalin Dahyabhai <nalin@redhat.com>
+- pass absolute path to kadm5.keytab if/when extracting keys at startup
+
+* Sat Feb 19 2000 Nalin Dahyabhai <nalin@redhat.com>
+- fix info page insertions
+
+* Wed Feb  9 2000 Nalin Dahyabhai <nalin@redhat.com>
+- tweak server init script to automatically extract kadm5 keys if
+  /var/kerberos/krb5kdc/kadm5.keytab doesn't exist yet
+- adjust package descriptions
+
+* Thu Feb  3 2000 Nalin Dahyabhai <nalin@redhat.com>
+- fix for potentially gzipped man pages
+
+* Fri Jan 21 2000 Nalin Dahyabhai <nalin@redhat.com>
+- fix comments in krb5-configs
+
+* Fri Jan  7 2000 Nalin Dahyabhai <nalin@redhat.com>
+- move /usr/kerberos/bin to end of PATH
+
+* Tue Dec 28 1999 Nalin Dahyabhai <nalin@redhat.com>
+- install kadmin header files
+
+* Tue Dec 21 1999 Nalin Dahyabhai <nalin@redhat.com>
+- patch around TIOCGTLC defined on alpha and remove warnings from libpty.h
+- add installation of info docs
+- remove krb4 compat patch because it doesn't fix workstation-side servers
+
+* Mon Dec 20 1999 Nalin Dahyabhai <nalin@redhat.com>
+- remove hesiod dependency at build-time
+
+* Sun Dec 19 1999 Nalin Dahyabhai <nsdahya1@eos.ncsu.edu>
+- rebuild on 1.1.1
+
+* Thu Oct  7 1999 Nalin Dahyabhai <nsdahya1@eos.ncsu.edu>
+- clean up init script for server, verify that it works [jlkatz]
+- clean up rotation script so that rc likes it better
+- add clean stanza
+
+* Mon Oct  4 1999 Nalin Dahyabhai <nsdahya1@eos.ncsu.edu>
+- backed out ncurses and makeshlib patches
+- update for krb5-1.1
+- add KDC rotation to rc.boot, based on ideas from Michael's C version
+
+* Mon Sep 27 1999 Nalin Dahyabhai <nsdahya1@eos.ncsu.edu>
+- added -lncurses to telnet and telnetd makefiles
+
+* Mon Jul  5 1999 Nalin Dahyabhai <nsdahya1@eos.ncsu.edu>
+- added krb5.csh and krb5.sh to /etc/profile.d
+
+* Tue Jun 22 1999 Nalin Dahyabhai <nsdahya1@eos.ncsu.edu>
+- broke out configuration files
+
+* Mon Jun 14 1999 Nalin Dahyabhai <nsdahya1@eos.ncsu.edu>
+- fixed server package so that it works now
+
+* Sat May 15 1999 Nalin Dahyabhai <nsdahya1@eos.ncsu.edu>
+- started changelog (previous package from zedz.net)
+- updated existing 1.0.5 RPM from Eos Linux to krb5 1.0.6
+- added --force to makeinfo commands to skip errors during build