From bd95eeadf1b97a783a5169935e0c2093f705c2c8 Mon Sep 17 00:00:00 2001 From: basebuilder_pel7ppc64bebuilder0 Date: Tue, 5 Jun 2018 19:03:59 +0200 Subject: [PATCH] krb5 package update Signed-off-by: basebuilder_pel7ppc64bebuilder0 --- .../Add-KDC-policy-pluggable-interface.patch | 994 +++++ .../Add-PKINIT-UPN-tests-to-t_pkinit.py.patch | 100 + .../Add-certauth-pluggable-interface.patch | 1146 ++++++ ...d-k5test-expected_msg-expected_trace.patch | 94 + ...rt-to-query-the-SSF-of-a-GSS-context.patch | 419 ++ ...est-cert-generation-to-make-certs.sh.patch | 90 + .../Add-test-cert-with-no-extensions.patch | 34 + ...-the-client_name-kdcpreauth-callback.patch | 58 + SOURCES/Add-timestamp-helper-functions.patch | 80 + SOURCES/Add-timestamp-tests.patch | 599 +++ SOURCES/Add-y2038-documentation.patch | 59 + ...-clock-skew-in-krb5-gss_context_time.patch | 36 + ...me-pkiDebug-messages-to-TRACE-macros.patch | 423 ++ ...t-error-handling-bug-in-prior-commit.patch | 32 + .../Deindent-crypto_retrieve_X509_sans.patch | 264 ++ ...-errors-in-pkinit_server_plugin_init.patch | 73 + SOURCES/Fix-bugs-in-kdcpolicy-commit.patch | 130 + ...Fix-certauth-built-in-module-returns.patch | 124 + ...ck_skew-and-use-it-in-AS-client-code.patch | 58 + .../Fix-make-certs.sh-for-OpenSSL-1.1.patch | 70 + ...ix-more-time-manipulations-for-y2038.patch | 83 + SOURCES/Improve-PKINIT-UPN-SAN-matching.patch | 151 + ...it-ticket-lifetime-to-2-31-1-seconds.patch | 203 + ...e-timestamp-manipulations-y2038-safe.patch | 1844 +++++++++ ...-KDC-unset-status-assertion-failures.patch | 108 + ...emove-incomplete-PKINIT-OCSP-support.patch | 134 + ...Use-krb5_timestamp-where-appropriate.patch | 327 ++ ...onical-client-principal-name-for-OTP.patch | 29 + SOURCES/_kadmind | 14 + SOURCES/_kpropd | 14 + SOURCES/kadm5.acl | 1 + SOURCES/kadmin.service | 13 + SOURCES/kadmin.sysconfig | 1 + SOURCES/kadmind.init | 108 + SOURCES/kadmind.logrotate | 9 + SOURCES/kdc.conf | 12 + SOURCES/kerberos-adm.portreserve | 1 + SOURCES/kprop.service | 11 + SOURCES/kprop.sysconfig | 1 + SOURCES/kpropd.init | 92 + SOURCES/krb5-1.11-kpasswdtest.patch | 20 + SOURCES/krb5-1.11-run_user_0.patch | 41 + SOURCES/krb5-1.12-api.patch | 34 + SOURCES/krb5-1.12-ksu-path.patch | 21 + SOURCES/krb5-1.12-ktany.patch | 363 ++ SOURCES/krb5-1.12.1-pam.patch | 757 ++++ SOURCES/krb5-1.13-dirsrv-accountlock.patch | 73 + SOURCES/krb5-1.15-beta1-buildconf.patch | 65 + SOURCES/krb5-1.15-beta1-selinux-label.patch | 1033 +++++ SOURCES/krb5-1.3.1-dns.patch | 21 + SOURCES/krb5-1.9-debuginfo.patch | 36 + SOURCES/krb5-krb5kdc.conf | 1 + SOURCES/krb5-kvno-230379.patch | 53 + SOURCES/krb5.conf | 25 + SOURCES/krb5_prop.portreserve | 1 + SOURCES/krb5kdc.init | 102 + SOURCES/krb5kdc.logrotate | 9 + SOURCES/krb5kdc.service | 13 + SOURCES/krb5kdc.sysconfig | 1 + SOURCES/ksu.pamd | 4 + SOURCES/noport.c | 111 + SPECS/krb5.spec | 3569 +++++++++++++++++ 62 files changed, 14392 insertions(+) create mode 100644 SOURCES/Add-KDC-policy-pluggable-interface.patch create mode 100644 SOURCES/Add-PKINIT-UPN-tests-to-t_pkinit.py.patch create mode 100644 SOURCES/Add-certauth-pluggable-interface.patch create mode 100644 SOURCES/Add-k5test-expected_msg-expected_trace.patch create mode 100644 SOURCES/Add-support-to-query-the-SSF-of-a-GSS-context.patch create mode 100644 SOURCES/Add-test-cert-generation-to-make-certs.sh.patch create mode 100644 SOURCES/Add-test-cert-with-no-extensions.patch create mode 100644 SOURCES/Add-the-client_name-kdcpreauth-callback.patch create mode 100644 SOURCES/Add-timestamp-helper-functions.patch create mode 100644 SOURCES/Add-timestamp-tests.patch create mode 100644 SOURCES/Add-y2038-documentation.patch create mode 100644 SOURCES/Allow-clock-skew-in-krb5-gss_context_time.patch create mode 100644 SOURCES/Convert-some-pkiDebug-messages-to-TRACE-macros.patch create mode 100644 SOURCES/Correct-error-handling-bug-in-prior-commit.patch create mode 100644 SOURCES/Deindent-crypto_retrieve_X509_sans.patch create mode 100644 SOURCES/Expose-context-errors-in-pkinit_server_plugin_init.patch create mode 100644 SOURCES/Fix-bugs-in-kdcpolicy-commit.patch create mode 100644 SOURCES/Fix-certauth-built-in-module-returns.patch create mode 100644 SOURCES/Fix-in_clock_skew-and-use-it-in-AS-client-code.patch create mode 100644 SOURCES/Fix-make-certs.sh-for-OpenSSL-1.1.patch create mode 100644 SOURCES/Fix-more-time-manipulations-for-y2038.patch create mode 100644 SOURCES/Improve-PKINIT-UPN-SAN-matching.patch create mode 100644 SOURCES/Limit-ticket-lifetime-to-2-31-1-seconds.patch create mode 100644 SOURCES/Make-timestamp-manipulations-y2038-safe.patch create mode 100644 SOURCES/Prevent-KDC-unset-status-assertion-failures.patch create mode 100644 SOURCES/Remove-incomplete-PKINIT-OCSP-support.patch create mode 100644 SOURCES/Use-krb5_timestamp-where-appropriate.patch create mode 100644 SOURCES/Use-the-canonical-client-principal-name-for-OTP.patch create mode 100644 SOURCES/_kadmind create mode 100644 SOURCES/_kpropd create mode 100644 SOURCES/kadm5.acl create mode 100644 SOURCES/kadmin.service create mode 100644 SOURCES/kadmin.sysconfig create mode 100755 SOURCES/kadmind.init create mode 100644 SOURCES/kadmind.logrotate create mode 100644 SOURCES/kdc.conf create mode 100644 SOURCES/kerberos-adm.portreserve create mode 100644 SOURCES/kprop.service create mode 100644 SOURCES/kprop.sysconfig create mode 100755 SOURCES/kpropd.init create mode 100644 SOURCES/krb5-1.11-kpasswdtest.patch create mode 100644 SOURCES/krb5-1.11-run_user_0.patch create mode 100644 SOURCES/krb5-1.12-api.patch create mode 100644 SOURCES/krb5-1.12-ksu-path.patch create mode 100644 SOURCES/krb5-1.12-ktany.patch create mode 100644 SOURCES/krb5-1.12.1-pam.patch create mode 100644 SOURCES/krb5-1.13-dirsrv-accountlock.patch create mode 100644 SOURCES/krb5-1.15-beta1-buildconf.patch create mode 100644 SOURCES/krb5-1.15-beta1-selinux-label.patch create mode 100644 SOURCES/krb5-1.3.1-dns.patch create mode 100644 SOURCES/krb5-1.9-debuginfo.patch create mode 100644 SOURCES/krb5-krb5kdc.conf create mode 100644 SOURCES/krb5-kvno-230379.patch create mode 100644 SOURCES/krb5.conf create mode 100644 SOURCES/krb5_prop.portreserve create mode 100755 SOURCES/krb5kdc.init create mode 100644 SOURCES/krb5kdc.logrotate create mode 100644 SOURCES/krb5kdc.service create mode 100644 SOURCES/krb5kdc.sysconfig create mode 100644 SOURCES/ksu.pamd create mode 100644 SOURCES/noport.c create mode 100644 SPECS/krb5.spec diff --git a/SOURCES/Add-KDC-policy-pluggable-interface.patch b/SOURCES/Add-KDC-policy-pluggable-interface.patch new file mode 100644 index 00000000..60b51a55 --- /dev/null +++ b/SOURCES/Add-KDC-policy-pluggable-interface.patch @@ -0,0 +1,994 @@ +From f12b57979012f93b339982ba335093d7c0d364f7 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 27 Jun 2017 17:15:39 -0400 +Subject: [PATCH] Add KDC policy pluggable interface + +Add the header include/krb5/kdcpolicy_plugin.h, defining a pluggable +interface for modules to deny AS and TGS requests and set maximum +ticket lifetimes. This interface replaces the policy.c stub functions. + +Add check_kdcpolicy_as() and check_kdcpolicy_tgs() as entry functions. +Call them after auth indicators and ticket lifetimes have been +determined. + +Add a test module and a test script with basic kdcpolicy tests. Add +plugin interface documentation in doc/plugindev/policy.rst. + +Also authored by Matt Rogers . + +ticket: 8606 (new) +(cherry picked from commit d0969f6a8170344031ef58fd2a161190f1edfb96) +[rharwood@redhat.com: mention but do not use kadm_auth] +--- + doc/plugindev/index.rst | 1 + + doc/plugindev/kdcpolicy.rst | 24 +++ + src/Makefile.in | 1 + + src/configure.in | 1 + + src/include/Makefile.in | 1 + + src/include/k5-int.h | 4 +- + src/include/k5-trace.h | 5 + + src/include/krb5/kdcpolicy_plugin.h | 128 ++++++++++++ + src/kdc/do_as_req.c | 7 + + src/kdc/do_tgs_req.c | 6 + + src/kdc/kdc_util.c | 7 - + src/kdc/kdc_util.h | 11 - + src/kdc/main.c | 8 + + src/kdc/policy.c | 267 +++++++++++++++++++++---- + src/kdc/policy.h | 19 +- + src/kdc/tgs_policy.c | 6 - + src/lib/krb5/krb/plugin.c | 4 +- + src/plugins/kdcpolicy/test/Makefile.in | 20 ++ + src/plugins/kdcpolicy/test/deps | 0 + src/plugins/kdcpolicy/test/main.c | 111 ++++++++++ + src/plugins/kdcpolicy/test/policy_test.exports | 1 + + src/tests/Makefile.in | 1 + + src/tests/t_kdcpolicy.py | 57 ++++++ + 23 files changed, 616 insertions(+), 74 deletions(-) + create mode 100644 doc/plugindev/kdcpolicy.rst + create mode 100644 src/include/krb5/kdcpolicy_plugin.h + create mode 100644 src/plugins/kdcpolicy/test/Makefile.in + create mode 100644 src/plugins/kdcpolicy/test/deps + create mode 100644 src/plugins/kdcpolicy/test/main.c + create mode 100644 src/plugins/kdcpolicy/test/policy_test.exports + create mode 100644 src/tests/t_kdcpolicy.py + +diff --git a/doc/plugindev/index.rst b/doc/plugindev/index.rst +index 67dbc2790..0a012b82b 100644 +--- a/doc/plugindev/index.rst ++++ b/doc/plugindev/index.rst +@@ -32,5 +32,6 @@ Contents + gssapi.rst + internal.rst + certauth.rst ++ kdcpolicy.rst + + .. TODO: GSSAPI mechanism plugins +diff --git a/doc/plugindev/kdcpolicy.rst b/doc/plugindev/kdcpolicy.rst +new file mode 100644 +index 000000000..74f21f08f +--- /dev/null ++++ b/doc/plugindev/kdcpolicy.rst +@@ -0,0 +1,24 @@ ++.. _kdcpolicy_plugin: ++ ++KDC policy interface (kdcpolicy) ++================================ ++ ++The kdcpolicy interface was first introduced in release 1.16. It ++allows modules to veto otherwise valid AS and TGS requests or restrict ++the lifetime and renew time of the resulting ticket. For a detailed ++description of the kdcpolicy interface, see the header file ++````. ++ ++The optional **check_as** and **check_tgs** functions allow the module ++to perform access control. Additionally, a module can create and ++destroy module data with the **init** and **fini** methods. Module ++data objects last for the lifetime of the KDC process, and are ++provided to all other methods. The data has the type ++krb5_kdcpolicy_moddata, which should be cast to the appropriate ++internal type. ++ ++kdcpolicy modules can optionally inspect principal entries. To do ++this, the module must also include ```` to gain access to the ++principal entry structure definition. As the KDB interface is ++explicitly not as stable as other public interfaces, modules which do ++this may not retain compatibility across releases. +diff --git a/src/Makefile.in b/src/Makefile.in +index ad8565056..e47bddcb1 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -21,6 +21,7 @@ SUBDIRS=util include lib \ + plugins/kdb/db2 \ + @ldap_plugin_dir@ \ + plugins/kdb/test \ ++ plugins/kdcpolicy/test \ + plugins/preauth/otp \ + plugins/preauth/pkinit \ + plugins/preauth/test \ +diff --git a/src/configure.in b/src/configure.in +index 4ae2c07d5..ee1983043 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1470,6 +1470,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test + plugins/kdb/db2/libdb2/recno + plugins/kdb/db2/libdb2/test + plugins/kdb/test ++ plugins/kdcpolicy/test + plugins/preauth/otp + plugins/preauth/test + plugins/authdata/greet_client +diff --git a/src/include/Makefile.in b/src/include/Makefile.in +index 0239338a1..6a3fa8242 100644 +--- a/src/include/Makefile.in ++++ b/src/include/Makefile.in +@@ -144,6 +144,7 @@ install-headers-unix install: krb5/krb5.h profile.h + $(INSTALL_DATA) $(srcdir)/krb5/ccselect_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)ccselect_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/clpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)clpreauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/hostrealm_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)hostrealm_plugin.h ++ $(INSTALL_DATA) $(srcdir)/krb5/kdcpolicy_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpolicy_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/kdcpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpreauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/localauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)localauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/locate_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)locate_plugin.h +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index ed9c7bf75..39ffb9568 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -1157,7 +1157,9 @@ struct plugin_interface { + #define PLUGIN_INTERFACE_TLS 8 + #define PLUGIN_INTERFACE_KDCAUTHDATA 9 + #define PLUGIN_INTERFACE_CERTAUTH 10 +-#define PLUGIN_NUM_INTERFACES 11 ++#define PLUGIN_INTERFACE_KADM5_AUTH 11 ++#define PLUGIN_INTERFACE_KDCPOLICY 12 ++#define PLUGIN_NUM_INTERFACES 13 + + /* Retrieve the plugin module of type interface_id and name modname, + * storing the result into module. */ +diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h +index c75e264e0..2885408a2 100644 +--- a/src/include/k5-trace.h ++++ b/src/include/k5-trace.h +@@ -454,4 +454,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); + #define TRACE_GET_CRED_VIA_TKT_EXT_RETURN(c, ret) \ + TRACE(c, "Got cred; {kerr}", ret) + ++#define TRACE_KDCPOLICY_VTINIT_FAIL(c, ret) \ ++ TRACE(c, "KDC policy module failed to init vtable: {kerr}", ret) ++#define TRACE_KDCPOLICY_INIT_SKIP(c, name) \ ++ TRACE(c, "kadm5_auth module {str} declined to initialize", name) ++ + #endif /* K5_TRACE_H */ +diff --git a/src/include/krb5/kdcpolicy_plugin.h b/src/include/krb5/kdcpolicy_plugin.h +new file mode 100644 +index 000000000..c7592c5db +--- /dev/null ++++ b/src/include/krb5/kdcpolicy_plugin.h +@@ -0,0 +1,128 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/krb5/kdcpolicy_plugin.h - KDC policy plugin interface */ ++/* ++ * Copyright (C) 2017 by 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. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * Declarations for kdcpolicy plugin module implementors. ++ * ++ * The kdcpolicy pluggable interface currently has only one supported major ++ * version, which is 1. Major version 1 has a current minor version number of ++ * 1. ++ * ++ * kdcpolicy plugin modules should define a function named ++ * kdcpolicy__initvt, matching the signature: ++ * ++ * krb5_error_code ++ * kdcpolicy_modname_initvt(krb5_context context, int maj_ver, int min_ver, ++ * krb5_plugin_vtable vtable); ++ * ++ * The initvt function should: ++ * ++ * - Check that the supplied maj_ver number is supported by the module, or ++ * return KRB5_PLUGIN_VER_NOTSUPP if it is not. ++ * ++ * - Cast the vtable pointer as appropriate for maj_ver: ++ * maj_ver == 1: Cast to krb5_kdcpolicy_vtable ++ * ++ * - Initialize the methods of the vtable, stopping as appropriate for the ++ * supplied min_ver. Optional methods may be left uninitialized. ++ * ++ * Memory for the vtable is allocated by the caller, not by the module. ++ */ ++ ++#ifndef KRB5_POLICY_PLUGIN_H ++#define KRB5_POLICY_PLUGIN_H ++ ++#include ++ ++/* Abstract module datatype. */ ++typedef struct krb5_kdcpolicy_moddata_st *krb5_kdcpolicy_moddata; ++ ++/* A module can optionally include kdb.h to inspect principal entries when ++ * authorizing requests. */ ++struct _krb5_db_entry_new; ++ ++/* ++ * Optional: Initialize module data. Return 0 on success, ++ * KRB5_PLUGIN_NO_HANDLE if the module is inoperable (due to configuration, for ++ * example), and any other error code to abort KDC startup. Optionally set ++ * *data_out to a module data object to be passed to future calls. ++ */ ++typedef krb5_error_code ++(*krb5_kdcpolicy_init_fn)(krb5_context context, ++ krb5_kdcpolicy_moddata *data_out); ++ ++/* Optional: Clean up module data. */ ++typedef krb5_error_code ++(*krb5_kdcpolicy_fini_fn)(krb5_context context, ++ krb5_kdcpolicy_moddata moddata); ++ ++/* ++ * Optional: return an error code and set status to an appropriate string ++ * literal to deny an AS request; otherwise return 0. lifetime_out, if set, ++ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the ++ * ticket renewable lifetime. ++ */ ++typedef krb5_error_code ++(*krb5_kdcpolicy_check_as_fn)(krb5_context context, ++ krb5_kdcpolicy_moddata moddata, ++ const krb5_kdc_req *request, ++ const struct _krb5_db_entry_new *client, ++ const struct _krb5_db_entry_new *server, ++ const char *const *auth_indicators, ++ const char **status, krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out); ++ ++/* ++ * Optional: return an error code and set status to an appropriate string ++ * literal to deny a TGS request; otherwise return 0. lifetime_out, if set, ++ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the ++ * ticket renewable lifetime. ++ */ ++typedef krb5_error_code ++(*krb5_kdcpolicy_check_tgs_fn)(krb5_context context, ++ krb5_kdcpolicy_moddata moddata, ++ const krb5_kdc_req *request, ++ const struct _krb5_db_entry_new *server, ++ const krb5_ticket *ticket, ++ const char *const *auth_indicators, ++ const char **status, krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out); ++ ++typedef struct krb5_kdcpolicy_vtable_st { ++ const char *name; ++ krb5_kdcpolicy_init_fn init; ++ krb5_kdcpolicy_fini_fn fini; ++ krb5_kdcpolicy_check_as_fn check_as; ++ krb5_kdcpolicy_check_tgs_fn check_tgs; ++} *krb5_kdcpolicy_vtable; ++ ++#endif /* KRB5_POLICY_PLUGIN_H */ +diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c +index 59a39cd30..241b05b40 100644 +--- a/src/kdc/do_as_req.c ++++ b/src/kdc/do_as_req.c +@@ -207,6 +207,13 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode) + + state->ticket_reply.enc_part2 = &state->enc_tkt_reply; + ++ errcode = check_kdcpolicy_as(kdc_context, state->request, state->client, ++ state->server, state->auth_indicators, ++ state->kdc_time, &state->enc_tkt_reply.times, ++ &state->status); ++ if (errcode) ++ goto egress; ++ + /* + * Find the server key + */ +diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c +index aacd2f20d..4c722a4a3 100644 +--- a/src/kdc/do_tgs_req.c ++++ b/src/kdc/do_tgs_req.c +@@ -518,6 +518,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt, + kdc_get_ticket_renewtime(kdc_active_realm, request, header_enc_tkt, client, + server, &enc_tkt_reply); + ++ errcode = check_kdcpolicy_tgs(kdc_context, request, server, header_ticket, ++ auth_indicators, kdc_time, ++ &enc_tkt_reply.times, &status); ++ if (errcode) ++ goto cleanup; ++ + /* + * Set authtime to be the same as header or evidence ticket's + */ +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index 778a629e5..8cbdf2c5b 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -642,7 +642,6 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + krb5_db_entry server, krb5_timestamp kdc_time, + const char **status, krb5_pa_data ***e_data) + { +- int errcode; + krb5_error_code ret; + + /* +@@ -750,12 +749,6 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP) + return errcode_to_protocol(ret); + +- /* Check against local policy. */ +- errcode = against_local_policy_as(request, client, server, +- kdc_time, status, e_data); +- if (errcode) +- return errcode; +- + return 0; + } + +diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h +index 672f94380..dcedfd538 100644 +--- a/src/kdc/kdc_util.h ++++ b/src/kdc/kdc_util.h +@@ -166,17 +166,6 @@ kdc_err(krb5_context call_context, errcode_t code, const char *fmt, ...) + #endif + ; + +-/* policy.c */ +-int +-against_local_policy_as (krb5_kdc_req *, krb5_db_entry, +- krb5_db_entry, krb5_timestamp, +- const char **, krb5_pa_data ***); +- +-int +-against_local_policy_tgs (krb5_kdc_req *, krb5_db_entry, +- krb5_ticket *, const char **, +- krb5_pa_data ***); +- + /* kdc_preauth.c */ + krb5_boolean + enctype_requires_etype_info_2(krb5_enctype enctype); +diff --git a/src/kdc/main.c b/src/kdc/main.c +index a4dffb29a..ccac3a759 100644 +--- a/src/kdc/main.c ++++ b/src/kdc/main.c +@@ -31,6 +31,7 @@ + #include "kdc_util.h" + #include "kdc_audit.h" + #include "extern.h" ++#include "policy.h" + #include "kdc5_err.h" + #include "kdb_kt.h" + #include "net-server.h" +@@ -986,6 +987,12 @@ int main(int argc, char **argv) + + load_preauth_plugins(&shandle, kcontext, ctx); + load_authdata_plugins(kcontext); ++ retval = load_kdcpolicy_plugins(kcontext); ++ if (retval) { ++ kdc_err(kcontext, retval, _("while loading KDC policy plugin")); ++ finish_realms(); ++ return 1; ++ } + + retval = setup_sam(); + if (retval) { +@@ -1068,6 +1075,7 @@ int main(int argc, char **argv) + krb5_klog_syslog(LOG_INFO, _("shutting down")); + unload_preauth_plugins(kcontext); + unload_authdata_plugins(kcontext); ++ unload_kdcpolicy_plugins(kcontext); + unload_audit_modules(kcontext); + krb5_klog_close(kcontext); + finish_realms(); +diff --git a/src/kdc/policy.c b/src/kdc/policy.c +index 6cba4303f..e49644e06 100644 +--- a/src/kdc/policy.c ++++ b/src/kdc/policy.c +@@ -1,67 +1,246 @@ + /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ + /* kdc/policy.c - Policy decision routines for KDC */ + /* +- * Copyright 1990 by the Massachusetts Institute of Technology. ++ * Copyright (C) 2017 by Red Hat, Inc. ++ * 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. ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: + * +- * 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. Furthermore if you modify this software you must label +- * your software as modified software and not distribute it in such a +- * fashion that it might be confused with the original M.I.T. software. +- * 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. ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #include "k5-int.h" + #include "kdc_util.h" + #include "extern.h" ++#include "policy.h" ++#include "adm_proto.h" ++#include ++#include + +-int +-against_local_policy_as(register krb5_kdc_req *request, krb5_db_entry client, +- krb5_db_entry server, krb5_timestamp kdc_time, +- const char **status, krb5_pa_data ***e_data) ++typedef struct kdcpolicy_handle_st { ++ struct krb5_kdcpolicy_vtable_st vt; ++ krb5_kdcpolicy_moddata moddata; ++} *kdcpolicy_handle; ++ ++static kdcpolicy_handle *handles; ++ ++static void ++free_indicators(char **ais) + { +-#if 0 +- /* An AS request must include the addresses field */ +- if (request->addresses == 0) { +- *status = "NO ADDRESS"; +- return KRB5KDC_ERR_POLICY; +- } +-#endif ++ size_t i; + +- return 0; /* not against policy */ ++ if (ais == NULL) ++ return; ++ for (i = 0; ais[i] != NULL; i++) ++ free(ais[i]); ++ free(ais); ++} ++ ++/* Convert inds to a null-terminated list of C strings. */ ++static krb5_error_code ++authind_strings(krb5_data *const *inds, char ***strs_out) ++{ ++ krb5_error_code ret; ++ char **list = NULL; ++ size_t i, count; ++ ++ *strs_out = NULL; ++ ++ for (count = 0; inds != NULL && inds[count] != NULL; count++); ++ list = k5calloc(count + 1, sizeof(*list), &ret); ++ if (list == NULL) ++ goto error; ++ ++ for (i = 0; i < count; i++) { ++ list[i] = k5memdup0(inds[i]->data, inds[i]->length, &ret); ++ if (list[i] == NULL) ++ goto error; ++ } ++ ++ *strs_out = list; ++ return 0; ++ ++error: ++ free_indicators(list); ++ return ret; ++} ++ ++/* Constrain times->endtime to life and times->renew_till to rlife, relative to ++ * now. */ ++static void ++update_ticket_times(krb5_ticket_times *times, krb5_timestamp now, ++ krb5_deltat life, krb5_deltat rlife) ++{ ++ if (life) ++ times->endtime = ts_min(ts_incr(now, life), times->endtime); ++ if (rlife) ++ times->renew_till = ts_min(ts_incr(now, rlife), times->renew_till); ++} ++ ++/* Check an AS request against kdcpolicy modules, updating times with any ++ * module endtime constraints. Set an appropriate status string on error. */ ++krb5_error_code ++check_kdcpolicy_as(krb5_context context, const krb5_kdc_req *request, ++ const krb5_db_entry *client, const krb5_db_entry *server, ++ krb5_data *const *auth_indicators, krb5_timestamp kdc_time, ++ krb5_ticket_times *times, const char **status) ++{ ++ krb5_deltat life, rlife; ++ krb5_error_code ret; ++ kdcpolicy_handle *hp, h; ++ char **ais = NULL; ++ ++ *status = NULL; ++ ++ ret = authind_strings(auth_indicators, &ais); ++ if (ret) ++ goto done; ++ ++ for (hp = handles; *hp != NULL; hp++) { ++ h = *hp; ++ if (h->vt.check_as == NULL) ++ continue; ++ ++ ret = h->vt.check_as(context, h->moddata, request, client, server, ++ (const char **)ais, status, &life, &rlife); ++ if (ret) ++ goto done; ++ ++ update_ticket_times(times, kdc_time, life, rlife); ++ } ++ ++done: ++ free_indicators(ais); ++ return ret; + } + + /* +- * This is where local policy restrictions for the TGS should placed. ++ * Check the TGS request against the local TGS policy. Accepts an ++ * authentication indicator for the module policy decisions. Returns 0 and a ++ * NULL status string on success. + */ + krb5_error_code +-against_local_policy_tgs(register krb5_kdc_req *request, krb5_db_entry server, +- krb5_ticket *ticket, const char **status, +- krb5_pa_data ***e_data) ++check_kdcpolicy_tgs(krb5_context context, const krb5_kdc_req *request, ++ const krb5_db_entry *server, const krb5_ticket *ticket, ++ krb5_data *const *auth_indicators, krb5_timestamp kdc_time, ++ krb5_ticket_times *times, const char **status) + { +-#if 0 +- /* +- * For example, if your site wants to disallow ticket forwarding, +- * you might do something like this: +- */ ++ krb5_deltat life, rlife; ++ krb5_error_code ret; ++ kdcpolicy_handle *hp, h; ++ char **ais = NULL; + +- if (isflagset(request->kdc_options, KDC_OPT_FORWARDED)) { +- *status = "FORWARD POLICY"; +- return KRB5KDC_ERR_POLICY; ++ *status = NULL; ++ ++ ret = authind_strings(auth_indicators, &ais); ++ if (ret) ++ goto done; ++ ++ for (hp = handles; *hp != NULL; hp++) { ++ h = *hp; ++ if (h->vt.check_tgs == NULL) ++ continue; ++ ++ ret = h->vt.check_tgs(context, h->moddata, request, server, ticket, ++ (const char **)ais, status, &life, &rlife); ++ if (ret) ++ goto done; ++ ++ update_ticket_times(times, kdc_time, life, rlife); + } +-#endif + +- return 0; /* not against policy */ ++done: ++ free_indicators(ais); ++ return ret; ++} ++ ++void ++unload_kdcpolicy_plugins(krb5_context context) ++{ ++ kdcpolicy_handle *hp, h; ++ ++ for (hp = handles; *hp != NULL; hp++) { ++ h = *hp; ++ if (h->vt.fini != NULL) ++ h->vt.fini(context, h->moddata); ++ free(h); ++ } ++ free(handles); ++ handles = NULL; ++} ++ ++krb5_error_code ++load_kdcpolicy_plugins(krb5_context context) ++{ ++ krb5_error_code ret; ++ krb5_plugin_initvt_fn *modules = NULL, *mod; ++ kdcpolicy_handle h; ++ size_t count; ++ ++ ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_KDCPOLICY, &modules); ++ if (ret) ++ goto cleanup; ++ ++ for (count = 0; modules[count] != NULL; count++); ++ handles = k5calloc(count + 1, sizeof(*handles), &ret); ++ if (handles == NULL) ++ goto cleanup; ++ ++ count = 0; ++ for (mod = modules; *mod != NULL; mod++) { ++ h = k5calloc(1, sizeof(*h), &ret); ++ if (h == NULL) ++ goto cleanup; ++ ++ ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&h->vt); ++ if (ret) { /* Version mismatch. */ ++ TRACE_KDCPOLICY_VTINIT_FAIL(context, ret); ++ free(h); ++ continue; ++ } ++ if (h->vt.init != NULL) { ++ ret = h->vt.init(context, &h->moddata); ++ if (ret == KRB5_PLUGIN_NO_HANDLE) { ++ TRACE_KADM5_AUTH_INIT_SKIP(context, h->vt.name); ++ free(h); ++ continue; ++ } ++ if (ret) { ++ kdc_err(context, ret, _("while loading policy module %s"), ++ h->vt.name); ++ free(h); ++ goto cleanup; ++ } ++ } ++ handles[count++] = h; ++ } ++ ++ ret = 0; ++ ++cleanup: ++ if (ret) ++ unload_kdcpolicy_plugins(context); ++ k5_plugin_free_modules(context, modules); ++ return ret; + } +diff --git a/src/kdc/policy.h b/src/kdc/policy.h +index 6b000dc90..2a57b0a01 100644 +--- a/src/kdc/policy.h ++++ b/src/kdc/policy.h +@@ -26,11 +26,22 @@ + #ifndef __KRB5_KDC_POLICY__ + #define __KRB5_KDC_POLICY__ + +-extern int against_postdate_policy (krb5_timestamp); ++krb5_error_code ++load_kdcpolicy_plugins(krb5_context context); + +-extern int against_flag_policy_as (const krb5_kdc_req *); ++void ++unload_kdcpolicy_plugins(krb5_context context); + +-extern int against_flag_policy_tgs (const krb5_kdc_req *, +- const krb5_ticket *); ++krb5_error_code ++check_kdcpolicy_as(krb5_context context, const krb5_kdc_req *request, ++ const krb5_db_entry *client, const krb5_db_entry *server, ++ krb5_data *const *auth_indicators, krb5_timestamp kdc_time, ++ krb5_ticket_times *times, const char **status); ++ ++krb5_error_code ++check_kdcpolicy_tgs(krb5_context context, const krb5_kdc_req *request, ++ const krb5_db_entry *server, const krb5_ticket *ticket, ++ krb5_data *const *auth_indicators, krb5_timestamp kdc_time, ++ krb5_ticket_times *times, const char **status); + + #endif /* __KRB5_KDC_POLICY__ */ +diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c +index d0f25d1b7..33cfbcd81 100644 +--- a/src/kdc/tgs_policy.c ++++ b/src/kdc/tgs_policy.c +@@ -375,11 +375,5 @@ validate_tgs_request(kdc_realm_t *kdc_active_realm, + if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP) + return errcode_to_protocol(ret); + +- /* Check local policy. */ +- errcode = against_local_policy_tgs(request, server, ticket, +- status, e_data); +- if (errcode) +- return errcode; +- + return 0; + } +diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c +index 17dd6bd30..31aaf661d 100644 +--- a/src/lib/krb5/krb/plugin.c ++++ b/src/lib/krb5/krb/plugin.c +@@ -58,7 +58,9 @@ const char *interface_names[] = { + "audit", + "tls", + "kdcauthdata", +- "certauth" ++ "certauth", ++ "kadm5_auth", ++ "kdcpolicy", + }; + + /* Return the context's interface structure for id, or NULL if invalid. */ +diff --git a/src/plugins/kdcpolicy/test/Makefile.in b/src/plugins/kdcpolicy/test/Makefile.in +new file mode 100644 +index 000000000..b81f1a7ce +--- /dev/null ++++ b/src/plugins/kdcpolicy/test/Makefile.in +@@ -0,0 +1,20 @@ ++mydir=plugins$(S)policy$(S)test ++BUILDTOP=$(REL)..$(S)..$(S).. ++ ++LIBBASE=policy_test ++LIBMAJOR=0 ++LIBMINOR=0 ++RELDIR=../plugins/kdcpolicy/test ++SHLIB_EXPDEPS=$(KRB5_BASE_DEPLIBS) ++SHLIB_EXPLIBS=$(KRB5_BASE_LIBS) ++ ++STLIBOBJS=main.o ++ ++SRCS=$(srcdir)/main.c ++ ++all-unix: all-libs ++install-unix: ++clean-unix:: clean-libs clean-libobjs ++ ++@libnover_frag@ ++@libobj_frag@ +diff --git a/src/plugins/kdcpolicy/test/deps b/src/plugins/kdcpolicy/test/deps +new file mode 100644 +index 000000000..e69de29bb +diff --git a/src/plugins/kdcpolicy/test/main.c b/src/plugins/kdcpolicy/test/main.c +new file mode 100644 +index 000000000..eb8fde053 +--- /dev/null ++++ b/src/plugins/kdcpolicy/test/main.c +@@ -0,0 +1,111 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/krb5/kdcpolicy_plugin.h - KDC policy plugin interface */ ++/* ++ * Copyright (C) 2017 by 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. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "k5-int.h" ++#include "kdb.h" ++#include ++ ++static krb5_error_code ++output_from_indicator(const char *const *auth_indicators, ++ krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out, ++ const char **status) ++{ ++ if (auth_indicators[0] == NULL) { ++ *status = NULL; ++ return 0; ++ } ++ ++ if (strcmp(auth_indicators[0], "ONE_HOUR") == 0) { ++ *lifetime_out = 3600; ++ *renew_lifetime_out = *lifetime_out * 2; ++ return 0; ++ } else if (strcmp(auth_indicators[0], "SEVEN_HOURS") == 0) { ++ *lifetime_out = 7 * 3600; ++ *renew_lifetime_out = *lifetime_out * 2; ++ return 0; ++ } ++ ++ *status = "LOCAL_POLICY"; ++ return KRB5KDC_ERR_POLICY; ++} ++ ++static krb5_error_code ++test_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata, ++ const krb5_kdc_req *request, const krb5_db_entry *client, ++ const krb5_db_entry *server, const char *const *auth_indicators, ++ const char **status, krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out) ++{ ++ if (request->client != NULL && request->client->length >= 1 && ++ data_eq_string(request->client->data[0], "fail")) { ++ *status = "LOCAL_POLICY"; ++ return KRB5KDC_ERR_POLICY; ++ } ++ return output_from_indicator(auth_indicators, lifetime_out, ++ renew_lifetime_out, status); ++} ++ ++static krb5_error_code ++test_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata, ++ const krb5_kdc_req *request, const krb5_db_entry *server, ++ const krb5_ticket *ticket, const char *const *auth_indicators, ++ const char **status, krb5_deltat *lifetime_out, ++ krb5_deltat *renew_lifetime_out) ++{ ++ if (request->server != NULL && request->server->length >= 1 && ++ data_eq_string(request->server->data[0], "fail")) { ++ *status = "LOCAL_POLICY"; ++ return KRB5KDC_ERR_POLICY; ++ } ++ return output_from_indicator(auth_indicators, lifetime_out, ++ renew_lifetime_out, status); ++} ++ ++krb5_error_code ++kdcpolicy_test_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable); ++krb5_error_code ++kdcpolicy_test_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_kdcpolicy_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ ++ vt = (krb5_kdcpolicy_vtable)vtable; ++ vt->name = "test"; ++ vt->check_as = test_check_as; ++ vt->check_tgs = test_check_tgs; ++ return 0; ++} +diff --git a/src/plugins/kdcpolicy/test/policy_test.exports b/src/plugins/kdcpolicy/test/policy_test.exports +new file mode 100644 +index 000000000..9682ec74f +--- /dev/null ++++ b/src/plugins/kdcpolicy/test/policy_test.exports +@@ -0,0 +1 @@ ++kdcpolicy_test_initvt +diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in +index 2b3112537..a2093108b 100644 +--- a/src/tests/Makefile.in ++++ b/src/tests/Makefile.in +@@ -169,6 +169,7 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter + $(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_y2038.py $(PYTESTFLAGS) ++ $(RUNPYTEST) $(srcdir)/t_kdcpolicy.py $(PYTESTFLAGS) + + clean: + $(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest +diff --git a/src/tests/t_kdcpolicy.py b/src/tests/t_kdcpolicy.py +new file mode 100644 +index 000000000..6a745b959 +--- /dev/null ++++ b/src/tests/t_kdcpolicy.py +@@ -0,0 +1,57 @@ ++#!/usr/bin/python ++from k5test import * ++from datetime import datetime ++import re ++ ++testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so') ++testpolicy = os.path.join(buildtop, 'plugins', 'kdcpolicy', 'test', ++ 'policy_test.so') ++krb5_conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth}, ++ 'clpreauth': {'module': 'test:' + testpreauth}, ++ 'kdcpolicy': {'module': 'test:' + testpolicy}}} ++kdc_conf = {'realms': {'$realm': {'default_principal_flags': '+preauth', ++ 'max_renewable_life': '1d'}}} ++realm = K5Realm(krb5_conf=krb5_conf, kdc_conf=kdc_conf) ++ ++realm.run([kadminl, 'addprinc', '-pw', password('fail'), 'fail']) ++ ++def verify_time(out, target_time): ++ times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out) ++ times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times] ++ while len(times) > 0: ++ starttime = times.pop(0) ++ endtime = times.pop(0) ++ renewtime = times.pop(0) ++ ++ if str(endtime - starttime) != target_time: ++ fail('unexpected lifetime value') ++ if str(renewtime - endtime) != target_time: ++ fail('unexpected renewable value') ++ ++rflags = ['-r', '1d', '-l', '12h'] ++ ++# Test AS+TGS success path. ++realm.kinit(realm.user_princ, password('user'), ++ rflags + ['-X', 'indicators=SEVEN_HOURS']) ++realm.run([kvno, realm.host_princ]) ++realm.run(['./adata', realm.host_princ], expected_msg='+97: [SEVEN_HOURS]') ++out = realm.run([klist, realm.ccache, '-e']) ++verify_time(out, '7:00:00') ++ ++# Test AS+TGS success path with different values. ++realm.kinit(realm.user_princ, password('user'), ++ rflags + ['-X', 'indicators=ONE_HOUR']) ++realm.run([kvno, realm.host_princ]) ++realm.run(['./adata', realm.host_princ], expected_msg='+97: [ONE_HOUR]') ++out = realm.run([klist, realm.ccache, '-e']) ++verify_time(out, '1:00:00') ++ ++# Test TGS failure path (using previous creds). ++realm.run([kvno, 'fail@%s' % realm.realm], expected_code=1, ++ expected_msg='KDC policy rejects request') ++ ++# Test AS failure path. ++realm.kinit('fail@%s' % realm.realm, password('fail'), ++ expected_code=1, expected_msg='KDC policy rejects request') ++ ++success('kdcpolicy tests') diff --git a/SOURCES/Add-PKINIT-UPN-tests-to-t_pkinit.py.patch b/SOURCES/Add-PKINIT-UPN-tests-to-t_pkinit.py.patch new file mode 100644 index 00000000..4bb9bb09 --- /dev/null +++ b/SOURCES/Add-PKINIT-UPN-tests-to-t_pkinit.py.patch @@ -0,0 +1,100 @@ +From f726fe232a16a51ca277b660c61aa9cfc2f512f1 Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Fri, 9 Dec 2016 11:43:27 -0500 +Subject: [PATCH] Add PKINIT UPN tests to t_pkinit.py + +[ghudson@mit.edu: simplify and explain tests; add test for +id-pkinit-san match against canonicalized client principal] + +ticket: 8528 +(cherry picked from commit d520fd3f032121b61b22681838af96ee505fe44d) +--- + src/tests/t_pkinit.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 57 insertions(+) + +diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py +index 526473b42..ac4d326b6 100755 +--- a/src/tests/t_pkinit.py ++++ b/src/tests/t_pkinit.py +@@ -23,6 +23,9 @@ privkey_pem = os.path.join(certs, 'privkey.pem') + privkey_enc_pem = os.path.join(certs, 'privkey-enc.pem') + user_p12 = os.path.join(certs, 'user.p12') + user_enc_p12 = os.path.join(certs, 'user-enc.p12') ++user_upn_p12 = os.path.join(certs, 'user-upn.p12') ++user_upn2_p12 = os.path.join(certs, 'user-upn2.p12') ++user_upn3_p12 = os.path.join(certs, 'user-upn3.p12') + path = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs') + path_enc = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs-enc') + +@@ -36,6 +39,20 @@ pkinit_kdc_conf = {'realms': {'$realm': { + restrictive_kdc_conf = {'realms': {'$realm': { + 'restrict_anonymous_to_tgt': 'true' }}} + ++testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'}, ++ 'user': {'keys': 'aes128-cts', 'flags': '+preauth'}, ++ 'user2': {'keys': 'aes128-cts', 'flags': '+preauth'}} ++alias_kdc_conf = {'realms': {'$realm': { ++ 'default_principal_flags': '+preauth', ++ 'pkinit_eku_checking': 'none', ++ 'pkinit_allow_upn': 'true', ++ 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem), ++ 'database_module': 'test'}}, ++ 'dbmodules': {'test': { ++ 'db_library': 'test', ++ 'alias': {'user@krbtest.com': 'user'}, ++ 'princs': testprincs}}} ++ + file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem) + file_enc_identity = 'FILE:%s,%s' % (user_pem, privkey_enc_pem) + dir_identity = 'DIR:%s' % path +@@ -45,11 +62,51 @@ dir_file_identity = 'FILE:%s,%s' % (os.path.join(path, 'user.crt'), + dir_file_enc_identity = 'FILE:%s,%s' % (os.path.join(path_enc, 'user.crt'), + os.path.join(path_enc, 'user.key')) + p12_identity = 'PKCS12:%s' % user_p12 ++p12_upn_identity = 'PKCS12:%s' % user_upn_p12 ++p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12 ++p12_upn3_identity = 'PKCS12:%s' % user_upn3_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)') + ++# 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, ++ create_kdb=False) ++realm.start_kdc() ++ ++# Compatibility check: cert contains UPN "user", which matches the ++# request principal user@KRBTEST.COM if parsed as a normal principal. ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_upn2_identity]) ++ ++# Compatibility check: cert contains UPN "user@KRBTEST.COM", which matches ++# the request principal user@KRBTEST.COM if parsed as a normal principal. ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_upn3_identity]) ++ ++# Cert contains UPN "user@krbtest.com" which is aliased to the request ++# principal. ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % p12_upn_identity]) ++ ++# Test an id-pkinit-san match to a post-canonical principal. ++realm.kinit('user@krbtest.com', ++ flags=['-E', '-X', 'X509_user_identity=%s' % p12_identity]) ++ ++# Test a UPN match to a post-canonical principal. (This only works ++# for the cert with the UPN containing just "user", as we don't allow ++# UPN reparsing when comparing to the canonicalized client principal.) ++realm.kinit('user@krbtest.com', ++ flags=['-E', '-X', 'X509_user_identity=%s' % p12_upn2_identity]) ++ ++# Test a mismatch. ++out = realm.run([kinit, '-X', 'X509_user_identity=%s' % p12_upn2_identity, ++ 'user2'], expected_code=1) ++if 'kinit: Client name mismatch while getting initial credentials' not in out: ++ fail('Wrong error for UPN SAN mismatch') ++realm.stop() ++ + realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf, + get_creds=False) diff --git a/SOURCES/Add-certauth-pluggable-interface.patch b/SOURCES/Add-certauth-pluggable-interface.patch new file mode 100644 index 00000000..27847ecd --- /dev/null +++ b/SOURCES/Add-certauth-pluggable-interface.patch @@ -0,0 +1,1146 @@ +From 5a0b9b43a070c273ae4ee39ee460fa759ff9d934 Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Tue, 28 Feb 2017 15:55:24 -0500 +Subject: [PATCH] Add certauth pluggable interface + +Add the header include/krb5/certauth_plugin.h, defining a pluggable +interface to control authorization of PKINIT client certificates. + +Add the "pkinit_san" and "pkinit_eku" builtin certauth modules and +related PKINIT crypto X.509 helper functions. Add authorize_cert() as +the entry function for certauth plugin module checks called in +pkinit_server_verify_padata(). Modify kdcpreauth_moddata to hold the +list of certauth module handles, and load the modules when the PKINIT +kdcpreauth server plugin is initialized. Change +crypto_retrieve_X509_sans() to return ENOENT when no SAN is found. + +Add test modules in plugins/certauth/test. Create t_certauth.py with +basic certauth tests. Add plugin interface documentation in +doc/plugindev/certauth.rst and doc/admin/krb5_conf.rst. + +[ghudson@mit.edu: simplified code, edited docs] + +ticket: 8561 (new) +(cherry picked from commit b619ce84470519bea65470be3263cd85fba94f57) +--- + doc/admin/conf_files/krb5_conf.rst | 21 ++ + doc/plugindev/certauth.rst | 27 ++ + doc/plugindev/index.rst | 1 + + src/Makefile.in | 1 + + src/configure.in | 1 + + src/include/Makefile.in | 1 + + src/include/k5-int.h | 3 +- + src/include/krb5/certauth_plugin.h | 103 +++++++ + src/lib/krb5/krb/plugin.c | 3 +- + src/plugins/certauth/test/Makefile.in | 20 ++ + src/plugins/certauth/test/certauth_test.exports | 2 + + src/plugins/certauth/test/deps | 14 + + src/plugins/certauth/test/main.c | 209 +++++++++++++ + src/plugins/preauth/pkinit/pkinit_crypto.h | 4 + + src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 30 ++ + src/plugins/preauth/pkinit/pkinit_srv.c | 335 ++++++++++++++++++--- + src/plugins/preauth/pkinit/pkinit_trace.h | 5 + + src/tests/Makefile.in | 1 + + src/tests/t_certauth.py | 47 +++ + 19 files changed, 786 insertions(+), 42 deletions(-) + create mode 100644 doc/plugindev/certauth.rst + create mode 100644 src/include/krb5/certauth_plugin.h + create mode 100644 src/plugins/certauth/test/Makefile.in + create mode 100644 src/plugins/certauth/test/certauth_test.exports + create mode 100644 src/plugins/certauth/test/deps + create mode 100644 src/plugins/certauth/test/main.c + create mode 100644 src/tests/t_certauth.py + +diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst +index 653aad613..c0e4349c0 100644 +--- a/doc/admin/conf_files/krb5_conf.rst ++++ b/doc/admin/conf_files/krb5_conf.rst +@@ -858,6 +858,27 @@ built-in modules exist for this interface: + This module authorizes a principal to a local account if the + principal name maps to the local account name. + ++.. _certauth: ++ ++certauth interface ++################## ++ ++The certauth section (introduced in release 1.16) controls modules for ++the certificate authorization interface, which determines whether a ++certificate is allowed to preauthenticate a user via PKINIT. The ++following built-in modules exist for this interface: ++ ++**pkinit_san** ++ This module authorizes the certificate if it contains a PKINIT ++ Subject Alternative Name for the requested client principal, or a ++ Microsoft UPN SAN matching the principal if **pkinit_allow_upn** ++ is set to true for the realm. ++ ++**pkinit_eku** ++ This module rejects the certificate if it does not contain an ++ Extended Key Usage attribute consistent with the ++ **pkinit_eku_checking** value for the realm. ++ + + PKINIT options + -------------- +diff --git a/doc/plugindev/certauth.rst b/doc/plugindev/certauth.rst +new file mode 100644 +index 000000000..8a7f7c5eb +--- /dev/null ++++ b/doc/plugindev/certauth.rst +@@ -0,0 +1,27 @@ ++.. _certauth_plugin: ++ ++PKINIT certificate authorization interface (certauth) ++===================================================== ++ ++The certauth interface was first introduced in release 1.16. It ++allows customization of the X.509 certificate attribute requirements ++placed on certificates used by PKINIT enabled clients. For a detailed ++description of the certauth interface, see the header file ++```` ++ ++A certauth module implements the **authorize** method to determine ++whether a client's certificate is authorized to authenticate a client ++principal. **authorize** receives the DER-encoded certificate, the ++requested client principal, and a pointer to the client's ++krb5_db_entry (for modules that link against libkdb5). It returns the ++authorization status and optionally outputs a list of authentication ++indicator strings to be added to the ticket. A module must use its ++own internal or library-provided ASN.1 certificate decoder. ++ ++A module can optionally create and destroy module data with the ++**init** and **fini** methods. Module data objects last for the ++lifetime of the KDC process. ++ ++If a module allocates and returns a list of authentication indicators ++from **authorize**, it must also implement the **free_ind** method ++to free the list. +diff --git a/doc/plugindev/index.rst b/doc/plugindev/index.rst +index 3fb921778..67dbc2790 100644 +--- a/doc/plugindev/index.rst ++++ b/doc/plugindev/index.rst +@@ -31,5 +31,6 @@ Contents + profile.rst + gssapi.rst + internal.rst ++ certauth.rst + + .. TODO: GSSAPI mechanism plugins +diff --git a/src/Makefile.in b/src/Makefile.in +index 2ebf2fb4d..b0249778c 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -17,6 +17,7 @@ SUBDIRS=util include lib \ + plugins/pwqual/test \ + plugins/authdata/greet_server \ + plugins/authdata/greet_client \ ++ plugins/certauth/test \ + plugins/kdb/db2 \ + @ldap_plugin_dir@ \ + plugins/kdb/test \ +diff --git a/src/configure.in b/src/configure.in +index acf3a458b..24f653f0d 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1451,6 +1451,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test + + kdc slave config-files build-tools man doc include + ++ plugins/certauth/test + plugins/hostrealm/test + plugins/localauth/test + plugins/kadm5_hook/test +diff --git a/src/include/Makefile.in b/src/include/Makefile.in +index f5b921833..0239338a1 100644 +--- a/src/include/Makefile.in ++++ b/src/include/Makefile.in +@@ -140,6 +140,7 @@ install-headers-unix install: krb5/krb5.h profile.h + $(INSTALL_DATA) $(srcdir)/krb5.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5.h + $(INSTALL_DATA) $(srcdir)/kdb.h $(DESTDIR)$(KRB5_INCDIR)$(S)kdb.h + $(INSTALL_DATA) krb5/krb5.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)krb5.h ++ $(INSTALL_DATA) $(srcdir)/krb5/certauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)certauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/ccselect_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)ccselect_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/clpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)clpreauth_plugin.h + $(INSTALL_DATA) $(srcdir)/krb5/hostrealm_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)hostrealm_plugin.h +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 173cb0264..cea644d0a 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -1156,7 +1156,8 @@ struct plugin_interface { + #define PLUGIN_INTERFACE_AUDIT 7 + #define PLUGIN_INTERFACE_TLS 8 + #define PLUGIN_INTERFACE_KDCAUTHDATA 9 +-#define PLUGIN_NUM_INTERFACES 10 ++#define PLUGIN_INTERFACE_CERTAUTH 10 ++#define PLUGIN_NUM_INTERFACES 11 + + /* Retrieve the plugin module of type interface_id and name modname, + * storing the result into module. */ +diff --git a/src/include/krb5/certauth_plugin.h b/src/include/krb5/certauth_plugin.h +new file mode 100644 +index 000000000..f22fc1e84 +--- /dev/null ++++ b/src/include/krb5/certauth_plugin.h +@@ -0,0 +1,103 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* include/krb5/certauth_plugin.h - certauth plugin header. */ ++/* ++ * Copyright (C) 2017 by 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. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * Certificate authorization plugin interface. The PKINIT server module uses ++ * this interface to check client certificate attributes after the certificate ++ * signature has been verified. ++ */ ++#ifndef KRB5_CERTAUTH_PLUGIN_H ++#define KRB5_CERTAUTH_PLUGIN_H ++ ++#include ++#include ++ ++/* Abstract module data type. */ ++typedef struct krb5_certauth_moddata_st *krb5_certauth_moddata; ++ ++typedef struct _krb5_db_entry_new krb5_db_entry; ++ ++/* ++ * Optional: Initialize module data. ++ */ ++typedef krb5_error_code ++(*krb5_certauth_init_fn)(krb5_context context, ++ krb5_certauth_moddata *moddata_out); ++ ++/* ++ * Optional: Clean up the module data. ++ */ ++typedef void ++(*krb5_certauth_fini_fn)(krb5_context context, krb5_certauth_moddata moddata); ++ ++/* ++ * Mandatory: ++ * Return 0 if the DER-encoded cert is authorized for PKINIT authentication by ++ * princ; otherwise return one of the following error codes: ++ * - KRB5KDC_ERR_CLIENT_NAME_MISMATCH - incorrect SAN value ++ * - KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE - incorrect EKU ++ * - KRB5KDC_ERR_CERTIFICATE_MISMATCH - other extension error ++ * - KRB5_PLUGIN_NO_HANDLE - the module has no opinion about cert ++ * ++ * - opts is used by built-in modules to receive internal data, and must be ++ * ignored by other modules. ++ * - db_entry receives the client principal database entry, and can be ignored ++ * by modules that do not link with libkdb5. ++ * - *authinds_out optionally returns a null-terminated list of authentication ++ * indicator strings upon KRB5_PLUGIN_NO_HANDLE or accepted authorization. ++ */ ++typedef krb5_error_code ++(*krb5_certauth_authorize_fn)(krb5_context context, ++ krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, ++ char ***authinds_out); ++ ++/* ++ * Free indicators allocated by a module. Mandatory if authorize returns ++ * authentication indicators. ++ */ ++typedef void ++(*krb5_certauth_free_indicator_fn)(krb5_context context, ++ krb5_certauth_moddata moddata, ++ char **authinds); ++ ++typedef struct krb5_certauth_vtable_st { ++ char *name; ++ krb5_certauth_init_fn init; ++ krb5_certauth_fini_fn fini; ++ krb5_certauth_authorize_fn authorize; ++ krb5_certauth_free_indicator_fn free_ind; ++} *krb5_certauth_vtable; ++ ++#endif /* KRB5_CERTAUTH_PLUGIN_H */ +diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c +index 7d64b7c7e..17dd6bd30 100644 +--- a/src/lib/krb5/krb/plugin.c ++++ b/src/lib/krb5/krb/plugin.c +@@ -57,7 +57,8 @@ const char *interface_names[] = { + "hostrealm", + "audit", + "tls", +- "kdcauthdata" ++ "kdcauthdata", ++ "certauth" + }; + + /* Return the context's interface structure for id, or NULL if invalid. */ +diff --git a/src/plugins/certauth/test/Makefile.in b/src/plugins/certauth/test/Makefile.in +new file mode 100644 +index 000000000..d3524084c +--- /dev/null ++++ b/src/plugins/certauth/test/Makefile.in +@@ -0,0 +1,20 @@ ++mydir=plugins$(S)certauth$(S)test ++BUILDTOP=$(REL)..$(S)..$(S).. ++ ++LIBBASE=certauth_test ++LIBMAJOR=0 ++LIBMINOR=0 ++RELDIR=../plugins/certauth/test ++SHLIB_EXPDEPS=$(KRB5_BASE_DEPLIBS) ++SHLIB_EXPLIBS=$(KRB5_BASE_LIBS) ++ ++STLIBOBJS=main.o ++ ++SRCS=$(srcdir)/main.c ++ ++all-unix: all-libs ++install-unix: ++clean-unix:: clean-libs clean-libobjs ++ ++@libnover_frag@ ++@libobj_frag@ +diff --git a/src/plugins/certauth/test/certauth_test.exports b/src/plugins/certauth/test/certauth_test.exports +new file mode 100644 +index 000000000..1c8cd24e2 +--- /dev/null ++++ b/src/plugins/certauth/test/certauth_test.exports +@@ -0,0 +1,2 @@ ++certauth_test1_initvt ++certauth_test2_initvt +diff --git a/src/plugins/certauth/test/deps b/src/plugins/certauth/test/deps +new file mode 100644 +index 000000000..2974b3b57 +--- /dev/null ++++ b/src/plugins/certauth/test/deps +@@ -0,0 +1,14 @@ ++# ++# Generated makefile dependencies follow. ++# ++main.so main.po $(OUTPRE)main.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ ++ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ ++ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ ++ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ ++ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ ++ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ ++ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ ++ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ ++ $(top_srcdir)/include/krb5/certauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \ ++ $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ ++ main.c +diff --git a/src/plugins/certauth/test/main.c b/src/plugins/certauth/test/main.c +new file mode 100644 +index 000000000..7ef7377fb +--- /dev/null ++++ b/src/plugins/certauth/test/main.c +@@ -0,0 +1,209 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* plugins/certauth/main.c - certauth plugin test modules. */ ++/* ++ * Copyright (C) 2017 by 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. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include "krb5/certauth_plugin.h" ++ ++struct krb5_certauth_moddata_st { ++ int initialized; ++}; ++ ++/* Test module 1 returns OK with an indicator. */ ++static krb5_error_code ++test1_authorize(krb5_context context, krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, char ***authinds_out) ++{ ++ char **ais = NULL; ++ ++ ais = calloc(2, sizeof(*ais)); ++ assert(ais != NULL); ++ ais[0] = strdup("test1"); ++ assert(ais[0] != NULL); ++ *authinds_out = ais; ++ return KRB5_PLUGIN_NO_HANDLE; ++} ++ ++static void ++test_free_ind(krb5_context context, krb5_certauth_moddata moddata, ++ char **authinds) ++{ ++ size_t i; ++ ++ if (authinds == NULL) ++ return; ++ for (i = 0; authinds[i] != NULL; i++) ++ free(authinds[i]); ++ free(authinds); ++} ++ ++/* A basic moddata test. */ ++static krb5_error_code ++test2_init(krb5_context context, krb5_certauth_moddata *moddata_out) ++{ ++ krb5_certauth_moddata mod; ++ ++ mod = calloc(1, sizeof(*mod)); ++ assert(mod != NULL); ++ mod->initialized = 1; ++ *moddata_out = mod; ++ return 0; ++} ++ ++static void ++test2_fini(krb5_context context, krb5_certauth_moddata moddata) ++{ ++ free(moddata); ++} ++ ++/* Return true if cert appears to contain the CN name, based on a search of the ++ * DER encoding. */ ++static krb5_boolean ++has_cn(krb5_context context, const uint8_t *cert, size_t cert_len, ++ const char *name) ++{ ++ krb5_boolean match = FALSE; ++ uint8_t name_len, cntag[5] = "\x06\x03\x55\x04\x03"; ++ const uint8_t *c; ++ struct k5buf buf; ++ size_t c_left; ++ ++ /* Construct a DER search string of the CN AttributeType encoding followed ++ * by a UTF8String encoding containing name as the AttributeValue. */ ++ k5_buf_init_dynamic(&buf); ++ k5_buf_add_len(&buf, cntag, sizeof(cntag)); ++ k5_buf_add(&buf, "\x0C"); ++ assert(strlen(name) < 128); ++ name_len = strlen(name); ++ k5_buf_add_len(&buf, &name_len, 1); ++ k5_buf_add_len(&buf, name, name_len); ++ assert(k5_buf_status(&buf) == 0); ++ ++ /* Check for the CN needle in the certificate haystack. */ ++ c_left = cert_len; ++ c = memchr(cert, *cntag, c_left); ++ while (c != NULL) { ++ c_left = cert_len - (c - cert); ++ if (buf.len > c_left) ++ break; ++ if (memcmp(c, buf.data, buf.len) == 0) { ++ match = TRUE; ++ break; ++ } ++ assert(c_left >= 1); ++ c = memchr(c + 1, *cntag, c_left - 1); ++ } ++ ++ k5_buf_free(&buf); ++ return match; ++} ++ ++/* ++ * Test module 2 returns OK if princ matches the CN part of the subject name, ++ * and returns indicators of the module name and princ. ++ */ ++static krb5_error_code ++test2_authorize(krb5_context context, krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, char ***authinds_out) ++{ ++ krb5_error_code ret; ++ char *name = NULL, **ais = NULL; ++ ++ *authinds_out = NULL; ++ ++ assert(moddata != NULL && moddata->initialized); ++ ++ ret = krb5_unparse_name_flags(context, princ, ++ KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name); ++ if (ret) ++ goto cleanup; ++ ++ if (!has_cn(context, cert, cert_len, name)) { ++ ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH; ++ goto cleanup; ++ } ++ ++ /* Create an indicator list with the module name and CN. */ ++ ais = calloc(3, sizeof(*ais)); ++ assert(ais != NULL); ++ ais[0] = strdup("test2"); ++ ais[1] = strdup(name); ++ assert(ais[0] != NULL && ais[1] != NULL); ++ *authinds_out = ais; ++ ++ ais = NULL; ++ ++cleanup: ++ krb5_free_unparsed_name(context, name); ++ return ret; ++} ++ ++krb5_error_code ++certauth_test1_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable); ++krb5_error_code ++certauth_test1_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_certauth_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ vt = (krb5_certauth_vtable)vtable; ++ vt->name = "test1"; ++ vt->authorize = test1_authorize; ++ vt->free_ind = test_free_ind; ++ return 0; ++} ++ ++krb5_error_code ++certauth_test2_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable); ++krb5_error_code ++certauth_test2_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_certauth_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ vt = (krb5_certauth_vtable)vtable; ++ vt->name = "test2"; ++ vt->authorize = test2_authorize; ++ vt->init = test2_init; ++ vt->fini = test2_fini; ++ vt->free_ind = test_free_ind; ++ return 0; ++} +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h +index b483affed..49b96b8ee 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto.h ++++ b/src/plugins/preauth/pkinit/pkinit_crypto.h +@@ -664,4 +664,8 @@ extern const size_t krb5_pkinit_sha512_oid_len; + */ + extern krb5_data const * const supported_kdf_alg_ids[]; + ++krb5_error_code ++crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, ++ uint8_t **der_out, size_t *der_len); ++ + #endif /* _PKINIT_CRYPTO_H */ +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 8def8c542..a5b010b26 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2137,6 +2137,7 @@ crypto_retrieve_X509_sans(krb5_context context, + + if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) { + pkiDebug("%s: found no subject alt name extensions\n", __FUNCTION__); ++ retval = ENOENT; + goto cleanup; + } + num_sans = sk_GENERAL_NAME_num(ialt); +@@ -6176,3 +6177,32 @@ crypto_get_deferred_ids(krb5_context context, + ret = (const pkinit_deferred_id *)deferred; + return ret; + } ++ ++/* Return the received certificate as DER-encoded data. */ ++krb5_error_code ++crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, ++ uint8_t **der_out, size_t *der_len) ++{ ++ int len; ++ unsigned char *der, *p; ++ ++ *der_out = NULL; ++ *der_len = 0; ++ ++ if (reqctx->received_cert == NULL) ++ return EINVAL; ++ p = NULL; ++ len = i2d_X509(reqctx->received_cert, NULL); ++ if (len <= 0) ++ return EINVAL; ++ p = der = malloc(len); ++ if (p == NULL) ++ return ENOMEM; ++ if (i2d_X509(reqctx->received_cert, &p) <= 0) { ++ free(p); ++ return EINVAL; ++ } ++ *der_out = der; ++ *der_len = len; ++ return 0; ++} +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index b5638a367..731d14eb8 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -31,6 +31,25 @@ + + #include + #include "pkinit.h" ++#include "krb5/certauth_plugin.h" ++ ++/* Aliases used by the built-in certauth modules */ ++struct certauth_req_opts { ++ krb5_kdcpreauth_callbacks cb; ++ krb5_kdcpreauth_rock rock; ++ pkinit_kdc_context plgctx; ++ pkinit_kdc_req_context reqctx; ++}; ++ ++typedef struct certauth_module_handle_st { ++ struct krb5_certauth_vtable_st vt; ++ krb5_certauth_moddata moddata; ++} *certauth_handle; ++ ++struct krb5_kdcpreauth_moddata_st { ++ pkinit_kdc_context *realm_contexts; ++ certauth_handle *certauth_modules; ++}; + + static krb5_error_code + pkinit_init_kdc_req_context(krb5_context, pkinit_kdc_req_context *blob); +@@ -51,6 +70,34 @@ pkinit_find_realm_context(krb5_context context, + krb5_kdcpreauth_moddata moddata, + krb5_principal princ); + ++static void ++free_realm_contexts(krb5_context context, pkinit_kdc_context *realm_contexts) ++{ ++ int i; ++ ++ if (realm_contexts == NULL) ++ return; ++ for (i = 0; realm_contexts[i] != NULL; i++) ++ pkinit_server_plugin_fini_realm(context, realm_contexts[i]); ++ pkiDebug("%s: freeing context at %p\n", __FUNCTION__, realm_contexts); ++ free(realm_contexts); ++} ++ ++static void ++free_certauth_handles(krb5_context context, certauth_handle *list) ++{ ++ int i; ++ ++ if (list == NULL) ++ return; ++ for (i = 0; list[i] != NULL; i++) { ++ if (list[i]->vt.fini != NULL) ++ list[i]->vt.fini(context, list[i]->moddata); ++ free(list[i]); ++ } ++ free(list); ++} ++ + static krb5_error_code + pkinit_create_edata(krb5_context context, + pkinit_plg_crypto_context plg_cryptoctx, +@@ -123,7 +170,7 @@ verify_client_san(krb5_context context, + pkinit_kdc_req_context reqctx, + krb5_kdcpreauth_callbacks cb, + krb5_kdcpreauth_rock rock, +- krb5_principal client, ++ krb5_const_principal client, + int *valid_san) + { + krb5_error_code retval; +@@ -134,12 +181,15 @@ verify_client_san(krb5_context context, + char *client_string = NULL, *san_string; + #endif + ++ *valid_san = 0; + retval = crypto_retrieve_cert_sans(context, plgctx->cryptoctx, + reqctx->cryptoctx, plgctx->idctx, + &princs, + plgctx->opts->allow_upn ? &upns : NULL, + NULL); +- if (retval) { ++ if (retval == ENOENT) { ++ goto out; ++ } else if (retval) { + pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__); + retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH; + goto out; +@@ -273,6 +323,73 @@ out: + return retval; + } + ++ ++/* Run the received, verified certificate through certauth modules, to verify ++ * that it is authorized to authenticate as client. */ ++static krb5_error_code ++authorize_cert(krb5_context context, certauth_handle *certauth_modules, ++ pkinit_kdc_context plgctx, pkinit_kdc_req_context reqctx, ++ krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock, ++ krb5_principal client) ++{ ++ krb5_error_code ret; ++ certauth_handle h; ++ struct certauth_req_opts opts; ++ krb5_boolean accepted = FALSE; ++ uint8_t *cert; ++ size_t i, cert_len; ++ void *db_ent = NULL; ++ char **ais = NULL, **ai = NULL; ++ ++ /* Re-encode the received certificate into DER, which is extra work, but ++ * avoids creating an X.509 library dependency in the interface. */ ++ ret = crypto_encode_der_cert(context, reqctx->cryptoctx, &cert, &cert_len); ++ if (ret) ++ goto cleanup; ++ ++ /* Set options for the builtin module. */ ++ opts.plgctx = plgctx; ++ opts.reqctx = reqctx; ++ opts.cb = cb; ++ opts.rock = rock; ++ ++ db_ent = cb->client_entry(context, rock); ++ ++ /* ++ * Check the certificate against each certauth module. For the certificate ++ * to be authorized at least one module must return 0, and no module can an ++ * error code other than KRB5_PLUGIN_NO_HANDLE (pass). Add indicators from ++ * modules that return 0 or pass. ++ */ ++ ret = KRB5_PLUGIN_NO_HANDLE; ++ for (i = 0; certauth_modules != NULL && certauth_modules[i] != NULL; i++) { ++ h = certauth_modules[i]; ++ ret = h->vt.authorize(context, h->moddata, cert, cert_len, client, ++ &opts, db_ent, &ais); ++ if (ret == 0) ++ accepted = TRUE; ++ else if (ret != KRB5_PLUGIN_NO_HANDLE) ++ goto cleanup; ++ ++ if (ais != NULL) { ++ /* Assert authentication indicators from the module. */ ++ for (ai = ais; *ai != NULL; ai++) { ++ ret = cb->add_auth_indicator(context, rock, *ai); ++ if (ret) ++ goto cleanup; ++ } ++ h->vt.free_ind(context, h->moddata, ais); ++ ais = NULL; ++ } ++ } ++ ++ ret = accepted ? 0 : KRB5KDC_ERR_CLIENT_NAME_MISMATCH; ++ ++cleanup: ++ free(cert); ++ return ret; ++} ++ + static void + pkinit_server_verify_padata(krb5_context context, + krb5_data *req_pkt, +@@ -295,7 +412,6 @@ pkinit_server_verify_padata(krb5_context context, + pkinit_kdc_req_context reqctx = NULL; + krb5_checksum cksum = {0, 0, 0, NULL}; + krb5_data *der_req = NULL; +- int valid_eku = 0, valid_san = 0; + krb5_data k5data; + int is_signed = 1; + krb5_pa_data **e_data = NULL; +@@ -388,27 +504,11 @@ pkinit_server_verify_padata(krb5_context context, + goto cleanup; + } + if (is_signed) { +- +- retval = verify_client_san(context, plgctx, reqctx, cb, rock, +- request->client, &valid_san); +- if (retval) +- goto cleanup; +- if (!valid_san) { +- pkiDebug("%s: did not find an acceptable SAN in user " +- "certificate\n", __FUNCTION__); +- retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH; +- goto cleanup; +- } +- retval = verify_client_eku(context, plgctx, reqctx, &valid_eku); ++ retval = authorize_cert(context, moddata->certauth_modules, plgctx, ++ reqctx, cb, rock, request->client); + if (retval) + goto cleanup; + +- if (!valid_eku) { +- pkiDebug("%s: did not find an acceptable EKU in user " +- "certificate\n", __FUNCTION__); +- retval = KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE; +- goto cleanup; +- } + } else { /* !is_signed */ + if (!krb5_principal_compare(context, request->client, + krb5_anonymous_principal())) { +@@ -1245,11 +1345,15 @@ pkinit_find_realm_context(krb5_context context, + krb5_principal princ) + { + int i; +- pkinit_kdc_context *realm_contexts = (pkinit_kdc_context *)moddata; ++ pkinit_kdc_context *realm_contexts; + + if (moddata == NULL) + return NULL; + ++ realm_contexts = moddata->realm_contexts; ++ if (realm_contexts == NULL) ++ return NULL; ++ + for (i = 0; realm_contexts[i] != NULL; i++) { + pkinit_kdc_context p = realm_contexts[i]; + +@@ -1331,6 +1435,155 @@ errout: + return retval; + } + ++static krb5_error_code ++pkinit_san_authorize(krb5_context context, krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, char ***authinds_out) ++{ ++ krb5_error_code ret; ++ int valid_san; ++ const struct certauth_req_opts *req_opts = opts; ++ ++ *authinds_out = NULL; ++ ++ ret = verify_client_san(context, req_opts->plgctx, req_opts->reqctx, ++ req_opts->cb, req_opts->rock, princ, &valid_san); ++ if (ret == ENOENT) ++ return KRB5_PLUGIN_NO_HANDLE; ++ else if (ret) ++ return ret; ++ ++ if (!valid_san) { ++ pkiDebug("%s: did not find an acceptable SAN in user certificate\n", ++ __FUNCTION__); ++ return KRB5KDC_ERR_CLIENT_NAME_MISMATCH; ++ } ++ ++ return 0; ++} ++ ++static krb5_error_code ++pkinit_eku_authorize(krb5_context context, krb5_certauth_moddata moddata, ++ const uint8_t *cert, size_t cert_len, ++ krb5_const_principal princ, const void *opts, ++ const krb5_db_entry *db_entry, char ***authinds_out) ++{ ++ krb5_error_code ret; ++ int valid_eku; ++ const struct certauth_req_opts *req_opts = opts; ++ ++ *authinds_out = NULL; ++ ++ /* Verify the client EKU. */ ++ ret = verify_client_eku(context, req_opts->plgctx, req_opts->reqctx, ++ &valid_eku); ++ if (ret) ++ return ret; ++ ++ if (!valid_eku) { ++ pkiDebug("%s: did not find an acceptable EKU in user certificate\n", ++ __FUNCTION__); ++ return KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE; ++ } ++ ++ return 0; ++} ++ ++static krb5_error_code ++certauth_pkinit_san_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_certauth_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ vt = (krb5_certauth_vtable)vtable; ++ vt->name = "pkinit_san"; ++ vt->authorize = pkinit_san_authorize; ++ return 0; ++} ++ ++static krb5_error_code ++certauth_pkinit_eku_initvt(krb5_context context, int maj_ver, int min_ver, ++ krb5_plugin_vtable vtable) ++{ ++ krb5_certauth_vtable vt; ++ ++ if (maj_ver != 1) ++ return KRB5_PLUGIN_VER_NOTSUPP; ++ vt = (krb5_certauth_vtable)vtable; ++ vt->name = "pkinit_eku"; ++ vt->authorize = pkinit_eku_authorize; ++ return 0; ++} ++ ++static krb5_error_code ++load_certauth_plugins(krb5_context context, certauth_handle **handle_out) ++{ ++ krb5_error_code ret; ++ krb5_plugin_initvt_fn *modules = NULL, *mod; ++ certauth_handle *list = NULL, h; ++ size_t count; ++ ++ /* Register the builtin modules. */ ++ ret = k5_plugin_register(context, PLUGIN_INTERFACE_CERTAUTH, ++ "pkinit_san", certauth_pkinit_san_initvt); ++ if (ret) ++ goto cleanup; ++ ++ ret = k5_plugin_register(context, PLUGIN_INTERFACE_CERTAUTH, ++ "pkinit_eku", certauth_pkinit_eku_initvt); ++ if (ret) ++ goto cleanup; ++ ++ ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_CERTAUTH, &modules); ++ if (ret) ++ goto cleanup; ++ ++ /* Allocate handle list. */ ++ for (count = 0; modules[count]; count++); ++ list = k5calloc(count + 1, sizeof(*list), &ret); ++ if (list == NULL) ++ goto cleanup; ++ ++ /* Initialize each module, ignoring ones that fail. */ ++ count = 0; ++ for (mod = modules; *mod != NULL; mod++) { ++ h = k5calloc(1, sizeof(*h), &ret); ++ if (h == NULL) ++ goto cleanup; ++ ++ ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&h->vt); ++ if (ret) { ++ TRACE_CERTAUTH_VTINIT_FAIL(context, ret); ++ free(h); ++ continue; ++ } ++ h->moddata = NULL; ++ if (h->vt.init != NULL) { ++ ret = h->vt.init(context, &h->moddata); ++ if (ret) { ++ TRACE_CERTAUTH_INIT_FAIL(context, h->vt.name, ret); ++ free(h); ++ continue; ++ } ++ } ++ list[count++] = h; ++ list[count] = NULL; ++ } ++ list[count] = NULL; ++ ++ ret = 0; ++ *handle_out = list; ++ list = NULL; ++ ++cleanup: ++ k5_plugin_free_modules(context, modules); ++ free_certauth_handles(context, list); ++ return ret; ++} ++ + static int + pkinit_server_plugin_init(krb5_context context, + krb5_kdcpreauth_moddata *moddata_out, +@@ -1338,6 +1591,8 @@ pkinit_server_plugin_init(krb5_context context, + { + krb5_error_code retval = ENOMEM; + pkinit_kdc_context plgctx, *realm_contexts = NULL; ++ certauth_handle *certauth_modules = NULL; ++ krb5_kdcpreauth_moddata moddata; + size_t i, j; + size_t numrealms; + +@@ -1368,16 +1623,22 @@ pkinit_server_plugin_init(krb5_context context, + goto errout; + } + +- *moddata_out = (krb5_kdcpreauth_moddata)realm_contexts; +- retval = 0; +- pkiDebug("%s: returning context at %p\n", __FUNCTION__, realm_contexts); ++ retval = load_certauth_plugins(context, &certauth_modules); ++ if (retval) ++ goto errout; ++ ++ moddata = k5calloc(1, sizeof(*moddata), &retval); ++ if (moddata == NULL) ++ goto errout; ++ moddata->realm_contexts = realm_contexts; ++ moddata->certauth_modules = certauth_modules; ++ *moddata_out = moddata; ++ pkiDebug("%s: returning context at %p\n", __FUNCTION__, moddata); ++ return 0; + + errout: +- if (retval) { +- pkinit_server_plugin_fini(context, +- (krb5_kdcpreauth_moddata)realm_contexts); +- } +- ++ free_realm_contexts(context, realm_contexts); ++ free_certauth_handles(context, certauth_modules); + return retval; + } + +@@ -1405,17 +1666,11 @@ static void + pkinit_server_plugin_fini(krb5_context context, + krb5_kdcpreauth_moddata moddata) + { +- pkinit_kdc_context *realm_contexts = (pkinit_kdc_context *)moddata; +- int i; +- +- if (realm_contexts == NULL) ++ if (moddata == NULL) + return; +- +- for (i = 0; realm_contexts[i] != NULL; i++) { +- pkinit_server_plugin_fini_realm(context, realm_contexts[i]); +- } +- pkiDebug("%s: freeing context at %p\n", __FUNCTION__, realm_contexts); +- free(realm_contexts); ++ free_realm_contexts(context, moddata->realm_contexts); ++ free_certauth_handles(context, moddata->certauth_modules); ++ free(moddata); + } + + static krb5_error_code +diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h +index b3f5cbb20..458d0961e 100644 +--- a/src/plugins/preauth/pkinit/pkinit_trace.h ++++ b/src/plugins/preauth/pkinit/pkinit_trace.h +@@ -91,4 +91,9 @@ + #define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \ + TRACE(c, "PKINIT OpenSSL error: {str}", msg) + ++#define TRACE_CERTAUTH_VTINIT_FAIL(c, ret) \ ++ TRACE(c, "certauth module failed to init vtable: {kerr}", ret) ++#define TRACE_CERTAUTH_INIT_FAIL(c, name, ret) \ ++ TRACE(c, "certauth module {str} failed to init: {kerr}", name, ret) ++ + #endif /* PKINIT_TRACE_H */ +diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in +index b55469146..0e93d6b59 100644 +--- a/src/tests/Makefile.in ++++ b/src/tests/Makefile.in +@@ -167,6 +167,7 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter + $(RUNPYTEST) $(srcdir)/t_preauth.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_princflags.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS) ++ $(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS) + + clean: + $(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest +diff --git a/src/tests/t_certauth.py b/src/tests/t_certauth.py +new file mode 100644 +index 000000000..e64a57b0d +--- /dev/null ++++ b/src/tests/t_certauth.py +@@ -0,0 +1,47 @@ ++#!/usr/bin/python ++from k5test import * ++ ++# Skip this test if pkinit wasn't built. ++if not os.path.exists(os.path.join(plugins, 'preauth', 'pkinit.so')): ++ skip_rest('certauth tests', 'PKINIT module not built') ++ ++certs = os.path.join(srctop, 'tests', 'dejagnu', 'pkinit-certs') ++ca_pem = os.path.join(certs, 'ca.pem') ++kdc_pem = os.path.join(certs, 'kdc.pem') ++privkey_pem = os.path.join(certs, 'privkey.pem') ++user_pem = os.path.join(certs, 'user.pem') ++ ++modpath = os.path.join(buildtop, 'plugins', 'certauth', 'test', ++ 'certauth_test.so') ++pkinit_krb5_conf = {'realms': {'$realm': { ++ 'pkinit_anchors': 'FILE:%s' % ca_pem}}, ++ 'plugins': {'certauth': {'module': ['test1:' + modpath, ++ 'test2:' + modpath], ++ 'enable_only': ['test1', 'test2']}}} ++pkinit_kdc_conf = {'realms': {'$realm': { ++ 'default_principal_flags': '+preauth', ++ 'pkinit_eku_checking': 'none', ++ 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem), ++ 'pkinit_indicator': ['indpkinit1', 'indpkinit2']}}} ++ ++file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem) ++ ++realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf, ++ get_creds=False) ++ ++# Let the test module match user to CN=user, with indicators. ++realm.kinit(realm.user_princ, ++ flags=['-X', 'X509_user_identity=%s' % file_identity]) ++realm.klist(realm.user_princ) ++realm.run([kvno, realm.host_princ]) ++realm.run(['./adata', realm.host_princ], ++ expected_msg='+97: [test1, test2, user, indpkinit1, indpkinit2]') ++ ++# Let the test module mismatch with user2 to CN=user. ++realm.addprinc("user2@KRBTEST.COM") ++out = realm.kinit("user2@KRBTEST.COM", ++ flags=['-X', 'X509_user_identity=%s' % file_identity], ++ expected_code=1, ++ expected_msg='kinit: Certificate mismatch') ++ ++success("certauth tests") diff --git a/SOURCES/Add-k5test-expected_msg-expected_trace.patch b/SOURCES/Add-k5test-expected_msg-expected_trace.patch new file mode 100644 index 00000000..9aa378e4 --- /dev/null +++ b/SOURCES/Add-k5test-expected_msg-expected_trace.patch @@ -0,0 +1,94 @@ +From c099e896f28d8c5ccacc9df086a8f4297c6b484e Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 17 Jan 2017 11:24:41 -0500 +Subject: [PATCH] Add k5test expected_msg, expected_trace + +In k5test.py, add the optional keyword argument "expected_msg" to +methods that run commands, to make it easier to look for substrings in +the command output. Add the optional keyword "expected_trace" to run +the command with KRB5_TRACE enabled and look for an ordered series of +substrings in the trace output. + +(cherry picked from commit 8bb5fce69a4aa6c3082fa7def66a93974e10e17a) +[rharwood@redhat.com: back out .gitignore] +--- + src/config/post.in | 2 +- + src/util/k5test.py | 37 ++++++++++++++++++++++++++++++++++--- + 2 files changed, 35 insertions(+), 4 deletions(-) + +diff --git a/src/config/post.in b/src/config/post.in +index 77a9bffdf..aecac9d3b 100644 +--- a/src/config/post.in ++++ b/src/config/post.in +@@ -156,7 +156,7 @@ clean: clean-$(WHAT) + + clean-unix:: + $(RM) $(OBJS) $(DEPTARGETS_CLEAN) $(EXTRA_FILES) +- $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog ++ $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog testtrace + -$(RM) -r testdir + + clean-windows:: +diff --git a/src/util/k5test.py b/src/util/k5test.py +index c3d026377..4d30baf40 100644 +--- a/src/util/k5test.py ++++ b/src/util/k5test.py +@@ -223,8 +223,11 @@ Scripts may use the following realm methods and attributes: + command-line debugging options. Fail if the command does not return + 0. Log the command output appropriately, and return it as a single + multi-line string. Keyword arguments can contain input='string' to +- send an input string to the command, and expected_code=N to expect a +- return code other than 0. ++ send an input string to the command, expected_code=N to expect a ++ return code other than 0, expected_msg=MSG to expect a substring in ++ the command output, and expected_trace=('a', 'b', ...) to expect an ++ ordered series of line substrings in the command's KRB5_TRACE ++ output. + + * realm.kprop_port(): Returns a port number based on realm.portbase + intended for use by kprop and kpropd. +@@ -647,10 +650,31 @@ def _stop_or_shell(stop, shell, env, ind): + subprocess.call(os.getenv('SHELL'), env=env) + + +-def _run_cmd(args, env, input=None, expected_code=0): ++# Read tracefile and look for the expected strings in successive lines. ++def _check_trace(tracefile, expected): ++ output('*** Trace output for previous command:\n') ++ i = 0 ++ with open(tracefile, 'r') as f: ++ for line in f: ++ output(line) ++ if i < len(expected) and expected[i] in line: ++ i += 1 ++ if i < len(expected): ++ fail('Expected string not found in trace output: ' + expected[i]) ++ ++ ++def _run_cmd(args, env, input=None, expected_code=0, expected_msg=None, ++ expected_trace=None): + global null_input, _cmd_index, _last_cmd, _last_cmd_output, _debug + global _stop_before, _stop_after, _shell_before, _shell_after + ++ if expected_trace is not None: ++ tracefile = 'testtrace' ++ if os.path.exists(tracefile): ++ os.remove(tracefile) ++ env = env.copy() ++ env['KRB5_TRACE'] = tracefile ++ + if (_match_cmdnum(_debug, _cmd_index)): + return _debug_cmd(args, env, input) + +@@ -679,6 +703,13 @@ def _run_cmd(args, env, input=None, expected_code=0): + # Check the return code and return the output. + if code != expected_code: + fail('%s failed with code %d.' % (args[0], code)) ++ ++ if expected_msg is not None and expected_msg not in outdata: ++ fail('Expected string not found in command output: ' + expected_msg) ++ ++ if expected_trace is not None: ++ _check_trace(tracefile, expected_trace) ++ + return outdata diff --git a/SOURCES/Add-support-to-query-the-SSF-of-a-GSS-context.patch b/SOURCES/Add-support-to-query-the-SSF-of-a-GSS-context.patch new file mode 100644 index 00000000..017e4761 --- /dev/null +++ b/SOURCES/Add-support-to-query-the-SSF-of-a-GSS-context.patch @@ -0,0 +1,419 @@ +From 1f7d42707585e552842455857070fff8957fcb7c Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 30 Mar 2017 11:27:09 -0400 +Subject: [PATCH] Add support to query the SSF of a GSS context + +Cyrus SASL provides a Security Strength Factor number to assess the +relative "strength" of the negotiated mechanism, and applications +sometimes make access control decisions based on it. + +Add a call that allows us to query the mechanism that established the +GSS security context to ask what is the current SSF, based on the +enctype of the session key. + +ticket: 8569 (new) +(cherry picked from commit 7feb7da54c0321b5a3eeb6c3797846a3cf7eda28) +[rharwood@redhat.com: stub out GSS_KRB5_GET_CRED_IMPERSONATOR] +--- + src/include/k5-int.h | 1 + + src/lib/crypto/krb/crypto_int.h | 1 + + src/lib/crypto/krb/enctype_util.c | 16 ++++++++++++++++ + src/lib/crypto/krb/etypes.c | 33 ++++++++++++++++++--------------- + src/lib/crypto/libk5crypto.exports | 1 + + src/lib/gssapi/generic/gssapi_ext.h | 11 +++++++++++ + src/lib/gssapi/generic/gssapi_generic.c | 9 +++++++++ + src/lib/gssapi/krb5/gssapiP_krb5.h | 6 ++++++ + src/lib/gssapi/krb5/gssapi_krb5.c | 4 ++++ + src/lib/gssapi/krb5/inq_context.c | 27 +++++++++++++++++++++++++++ + src/lib/gssapi/libgssapi_krb5.exports | 1 + + src/lib/gssapi32.def | 3 +++ + src/lib/krb5_32.def | 3 +++ + src/tests/gssapi/t_enctypes.c | 14 ++++++++++++++ + 14 files changed, 115 insertions(+), 15 deletions(-) + +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index cea644d0a..06ca2b66d 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -2114,6 +2114,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_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 *, + krb5_const_pointer, krb5_kdc_rep *); +diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h +index d75b49c69..e5099291e 100644 +--- a/src/lib/crypto/krb/crypto_int.h ++++ b/src/lib/crypto/krb/crypto_int.h +@@ -111,6 +111,7 @@ struct krb5_keytypes { + prf_func prf; + krb5_cksumtype required_ctype; + krb5_flags flags; ++ unsigned int ssf; + }; + + #define ETYPE_WEAK 1 +diff --git a/src/lib/crypto/krb/enctype_util.c b/src/lib/crypto/krb/enctype_util.c +index 0ed74bd6e..b1b40e7ec 100644 +--- a/src/lib/crypto/krb/enctype_util.c ++++ b/src/lib/crypto/krb/enctype_util.c +@@ -131,3 +131,19 @@ krb5_enctype_to_name(krb5_enctype enctype, krb5_boolean shortest, + return ENOMEM; + return 0; + } ++ ++/* The security of a mechanism cannot be summarized with a simple integer ++ * value, but we provide a per-enctype value for Cyrus SASL's SSF. */ ++krb5_error_code ++k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out) ++{ ++ const struct krb5_keytypes *ktp; ++ ++ *ssf_out = 0; ++ ++ ktp = find_enctype(enctype); ++ if (ktp == NULL) ++ return EINVAL; ++ *ssf_out = ktp->ssf; ++ return 0; ++} +diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c +index 0e5e977d4..53d4a5c79 100644 +--- a/src/lib/crypto/krb/etypes.c ++++ b/src/lib/crypto/krb/etypes.c +@@ -42,7 +42,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 }, ++ ETYPE_WEAK, 56 }, + { ENCTYPE_DES_CBC_MD4, + "des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4", + &krb5int_enc_des, &krb5int_hash_md4, +@@ -51,7 +51,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 }, ++ ETYPE_WEAK, 56 }, + { ENCTYPE_DES_CBC_MD5, + "des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5", + &krb5int_enc_des, &krb5int_hash_md5, +@@ -60,7 +60,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 }, ++ ETYPE_WEAK, 56 }, + { ENCTYPE_DES_CBC_RAW, + "des-cbc-raw", { 0 }, "DES cbc mode raw", + &krb5int_enc_des, NULL, +@@ -69,7 +69,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_des_string_to_key, k5_rand2key_des, + krb5int_des_prf, + 0, +- ETYPE_WEAK }, ++ ETYPE_WEAK, 56 }, + { ENCTYPE_DES3_CBC_RAW, + "des3-cbc-raw", { 0 }, "Triple DES cbc mode raw", + &krb5int_enc_des3, NULL, +@@ -78,7 +78,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_dk_string_to_key, k5_rand2key_des3, + NULL, /*PRF*/ + 0, +- ETYPE_WEAK }, ++ ETYPE_WEAK, 112 }, + + { ENCTYPE_DES3_CBC_SHA1, + "des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" }, +@@ -89,7 +89,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*/ }, ++ 0 /*flags*/, 112 }, + + { ENCTYPE_DES_HMAC_SHA1, + "des-hmac-sha1", { 0 }, "DES with HMAC/sha1", +@@ -99,7 +99,10 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_dk_string_to_key, k5_rand2key_des, + NULL, /*PRF*/ + 0, +- ETYPE_WEAK }, ++ ETYPE_WEAK, 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. */ + { ENCTYPE_ARCFOUR_HMAC, + "arcfour-hmac", { "rc4-hmac", "arcfour-hmac-md5" }, + "ArcFour with HMAC/md5", +@@ -110,7 +113,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*/ }, ++ 0 /*flags*/, 64 }, + { ENCTYPE_ARCFOUR_HMAC_EXP, + "arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" }, + "Exportable ArcFour with HMAC/md5", +@@ -121,7 +124,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 ++ ETYPE_WEAK, 40 + }, + + { ENCTYPE_AES128_CTS_HMAC_SHA1_96, +@@ -133,7 +136,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_aes_string_to_key, k5_rand2key_direct, + krb5int_dk_prf, + CKSUMTYPE_HMAC_SHA1_96_AES128, +- 0 /*flags*/ }, ++ 0 /*flags*/, 128 }, + { ENCTYPE_AES256_CTS_HMAC_SHA1_96, + "aes256-cts-hmac-sha1-96", { "aes256-cts", "aes256-sha1" }, + "AES-256 CTS mode with 96-bit SHA-1 HMAC", +@@ -143,7 +146,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_aes_string_to_key, k5_rand2key_direct, + krb5int_dk_prf, + CKSUMTYPE_HMAC_SHA1_96_AES256, +- 0 /*flags*/ }, ++ 0 /*flags*/, 256 }, + + { ENCTYPE_CAMELLIA128_CTS_CMAC, + "camellia128-cts-cmac", { "camellia128-cts" }, +@@ -155,7 +158,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_camellia_string_to_key, k5_rand2key_direct, + krb5int_dk_cmac_prf, + CKSUMTYPE_CMAC_CAMELLIA128, +- 0 /*flags*/ }, ++ 0 /*flags*/, 128 }, + { ENCTYPE_CAMELLIA256_CTS_CMAC, + "camellia256-cts-cmac", { "camellia256-cts" }, + "Camellia-256 CTS mode with CMAC", +@@ -166,7 +169,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_camellia_string_to_key, k5_rand2key_direct, + krb5int_dk_cmac_prf, + CKSUMTYPE_CMAC_CAMELLIA256, +- 0 /*flags */ }, ++ 0 /*flags */, 256 }, + + { ENCTYPE_AES128_CTS_HMAC_SHA256_128, + "aes128-cts-hmac-sha256-128", { "aes128-sha2" }, +@@ -177,7 +180,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_aes2_string_to_key, k5_rand2key_direct, + krb5int_aes2_prf, + CKSUMTYPE_HMAC_SHA256_128_AES128, +- 0 /*flags*/ }, ++ 0 /*flags*/, 128 }, + { ENCTYPE_AES256_CTS_HMAC_SHA384_192, + "aes256-cts-hmac-sha384-192", { "aes256-sha2" }, + "AES-256 CTS mode with 192-bit SHA-384 HMAC", +@@ -187,7 +190,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = { + krb5int_aes2_string_to_key, k5_rand2key_direct, + krb5int_aes2_prf, + CKSUMTYPE_HMAC_SHA384_192_AES256, +- 0 /*flags*/ }, ++ 0 /*flags*/, 256 }, + }; + + const int krb5int_enctypes_length = +diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports +index 447e45644..82eb5f30c 100644 +--- a/src/lib/crypto/libk5crypto.exports ++++ b/src/lib/crypto/libk5crypto.exports +@@ -108,3 +108,4 @@ krb5int_nfold + k5_allow_weak_pbkdf2iter + krb5_c_prfplus + krb5_c_derive_prfplus ++k5_enctype_to_ssf +diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h +index 9ad44216d..9d3a7e736 100644 +--- a/src/lib/gssapi/generic/gssapi_ext.h ++++ b/src/lib/gssapi/generic/gssapi_ext.h +@@ -575,4 +575,15 @@ gss_import_cred( + } + #endif + ++/* ++ * When used with gss_inquire_sec_context_by_oid(), return a buffer set with ++ * the first member containing an unsigned 32-bit integer in network byte ++ * order. This is the Security Strength Factor (SSF) associated with the ++ * secure channel established by the security context. NOTE: This value is ++ * made available solely as an indication for use by APIs like Cyrus SASL that ++ * classify the strength of a secure channel via this number. The strength of ++ * a channel cannot necessarily be represented by a simple number. ++ */ ++GSS_DLLIMP extern gss_OID GSS_C_SEC_CONTEXT_SASL_SSF; ++ + #endif /* GSSAPI_EXT_H_ */ +diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c +index 5496aa335..fa144c2bf 100644 +--- a/src/lib/gssapi/generic/gssapi_generic.c ++++ b/src/lib/gssapi/generic/gssapi_generic.c +@@ -157,6 +157,13 @@ static const gss_OID_desc const_oids[] = { + {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x19"}, + {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1a"}, + {7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1b"}, ++ ++ /* ++ * GSS_SEC_CONTEXT_SASL_SSF_OID 1.2.840.113554.1.2.2.5.15 ++ * iso(1) member-body(2) United States(840) mit(113554) ++ * infosys(1) gssapi(2) krb5(2) krb5-gssapi-ext(5) sasl-ssf(15) ++ */ ++ {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f"}, + }; + + /* Here are the constants which point to the static structure above. +@@ -218,6 +225,8 @@ GSS_DLLIMP gss_const_OID GSS_C_MA_PFS = oids+33; + GSS_DLLIMP gss_const_OID GSS_C_MA_COMPRESS = oids+34; + GSS_DLLIMP gss_const_OID GSS_C_MA_CTX_TRANS = oids+35; + ++GSS_DLLIMP gss_OID GSS_C_SEC_CONTEXT_SASL_SSF = oids+36; ++ + static gss_OID_set_desc gss_ma_known_attrs_desc = { 27, oids+9 }; + gss_OID_set gss_ma_known_attrs = &gss_ma_known_attrs_desc; + +diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h +index d7bdef7e2..ef030707e 100644 +--- a/src/lib/gssapi/krb5/gssapiP_krb5.h ++++ b/src/lib/gssapi/krb5/gssapiP_krb5.h +@@ -1144,6 +1144,12 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *, + const gss_OID, + gss_buffer_set_t *); + ++#define GET_SEC_CONTEXT_SASL_SSF_OID_LENGTH 11 ++#define GET_SEC_CONTEXT_SASL_SSF_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f" ++OM_uint32 ++gss_krb5int_sec_context_sasl_ssf(OM_uint32 *, const gss_ctx_id_t, ++ const gss_OID, gss_buffer_set_t *); ++ + #define GSS_KRB5_IMPORT_CRED_OID_LENGTH 11 + #define GSS_KRB5_IMPORT_CRED_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0d" + +diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c +index 99092ccab..de4131980 100644 +--- a/src/lib/gssapi/krb5/gssapi_krb5.c ++++ b/src/lib/gssapi/krb5/gssapi_krb5.c +@@ -352,6 +352,10 @@ static struct { + { + {GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID}, + gss_krb5int_extract_authtime_from_sec_context ++ }, ++ { ++ {GET_SEC_CONTEXT_SASL_SSF_OID_LENGTH, GET_SEC_CONTEXT_SASL_SSF_OID}, ++ gss_krb5int_sec_context_sasl_ssf + } + }; + +diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c +index 9024b3c7e..d2e466e60 100644 +--- a/src/lib/gssapi/krb5/inq_context.c ++++ b/src/lib/gssapi/krb5/inq_context.c +@@ -310,3 +310,30 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *minor_status, + + return generic_gss_add_buffer_set_member(minor_status, &rep, data_set); + } ++ ++OM_uint32 ++gss_krb5int_sec_context_sasl_ssf(OM_uint32 *minor_status, ++ const gss_ctx_id_t context_handle, ++ const gss_OID desired_object, ++ gss_buffer_set_t *data_set) ++{ ++ krb5_gss_ctx_id_rec *ctx; ++ krb5_key key; ++ krb5_error_code code; ++ gss_buffer_desc ssfbuf; ++ unsigned int ssf; ++ uint8_t buf[4]; ++ ++ ctx = (krb5_gss_ctx_id_rec *)context_handle; ++ key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey; ++ ++ code = k5_enctype_to_ssf(key->keyblock.enctype, &ssf); ++ if (code) ++ return GSS_S_FAILURE; ++ ++ store_32_be(ssf, buf); ++ ssfbuf.value = buf; ++ ssfbuf.length = sizeof(buf); ++ ++ return generic_gss_add_buffer_set_member(minor_status, &ssfbuf, data_set); ++} +diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports +index 9facb3f42..936540e41 100644 +--- a/src/lib/gssapi/libgssapi_krb5.exports ++++ b/src/lib/gssapi/libgssapi_krb5.exports +@@ -37,6 +37,7 @@ GSS_C_MA_CBINDINGS + GSS_C_MA_PFS + GSS_C_MA_COMPRESS + GSS_C_MA_CTX_TRANS ++GSS_C_SEC_CONTEXT_SASL_SSF + gss_accept_sec_context + gss_acquire_cred + gss_acquire_cred_with_password +diff --git a/src/lib/gssapi32.def b/src/lib/gssapi32.def +index 362b9bce8..dff057754 100644 +--- a/src/lib/gssapi32.def ++++ b/src/lib/gssapi32.def +@@ -182,3 +182,6 @@ EXPORTS + gss_verify_mic_iov @146 + ; Added in 1.14 + GSS_KRB5_CRED_NO_CI_FLAGS_X @147 DATA ++; Added in 1.16 ++; GSS_KRB5_GET_CRED_IMPERSONATOR @148 DATA ++ GSS_C_SEC_CONTEXT_SASL_SSF @149 DATA +diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def +index e5b560dfc..f7b428e16 100644 +--- a/src/lib/krb5_32.def ++++ b/src/lib/krb5_32.def +@@ -470,3 +470,6 @@ EXPORTS + krb5_get_init_creds_opt_set_pac_request @435 + krb5int_trace @436 ; PRIVATE GSSAPI + krb5_expand_hostname @437 ++ ++; new in 1.16 ++ k5_enctype_to_ssf @438 ; PRIVATE GSSAPI +diff --git a/src/tests/gssapi/t_enctypes.c b/src/tests/gssapi/t_enctypes.c +index a2ad18f47..3fd31e2f8 100644 +--- a/src/tests/gssapi/t_enctypes.c ++++ b/src/tests/gssapi/t_enctypes.c +@@ -32,6 +32,7 @@ + + #include "k5-int.h" + #include "common.h" ++#include "gssapi_ext.h" + + /* + * This test program establishes contexts with the krb5 mech, the default +@@ -86,6 +87,9 @@ main(int argc, char *argv[]) + gss_krb5_lucid_context_v1_t *ilucid, *alucid; + gss_krb5_rfc1964_keydata_t *i1964, *a1964; + gss_krb5_cfx_keydata_t *icfx, *acfx; ++ gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET; ++ gss_OID ssf_oid = GSS_C_SEC_CONTEXT_SASL_SSF; ++ unsigned int ssf; + size_t count; + void *lptr; + int c; +@@ -139,6 +143,16 @@ main(int argc, char *argv[]) + establish_contexts(&mech_krb5, icred, acred, tname, flags, &ictx, &actx, + NULL, NULL, NULL); + ++ /* Query the SSF value and range-check the result. */ ++ major = gss_inquire_sec_context_by_oid(&minor, ictx, ssf_oid, &bufset); ++ check_gsserr("gss_inquire_sec_context_by_oid(ssf)", major, minor); ++ if (bufset->elements[0].length != 4) ++ errout("SSF buffer has unexpected length"); ++ ssf = load_32_be(bufset->elements[0].value); ++ if (ssf < 56 || ssf > 256) ++ errout("SSF value not within acceptable range (56-256)"); ++ (void)gss_release_buffer_set(&minor, &bufset); ++ + /* Export to lucid contexts. */ + major = gss_krb5_export_lucid_sec_context(&minor, &ictx, 1, &lptr); + check_gsserr("gss_export_lucid_sec_context(initiator)", major, minor); diff --git a/SOURCES/Add-test-cert-generation-to-make-certs.sh.patch b/SOURCES/Add-test-cert-generation-to-make-certs.sh.patch new file mode 100644 index 00000000..2f3bec71 --- /dev/null +++ b/SOURCES/Add-test-cert-generation-to-make-certs.sh.patch @@ -0,0 +1,90 @@ +From fd8ce9e1ed7a8d6cf5ac7d27d6acf40b0453c45e Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Tue, 5 Sep 2017 15:54:31 -0400 +Subject: [PATCH] Add test cert generation to make-certs.sh + +Based on commit 5a1d0388ba2e4ec510ed715ce5fbc7f748941425 but missing +everything but the make-certs change since infrastructure cannot patch +binaries. Plan to run make-certs during build, but this will only +work with openssl < 1.1. +--- + src/tests/dejagnu/pkinit-certs/make-certs.sh | 53 +++++++++++++++++++++++++++- + 1 file changed, 52 insertions(+), 1 deletion(-) + +diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh +index b82ef6f83..0f07709b0 100755 +--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh ++++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh +@@ -4,7 +4,9 @@ NAMETYPE=1 + KEYSIZE=2048 + DAYS=4000 + REALM=KRBTEST.COM ++LOWREALM=krbtest.com + KRB5_PRINCIPAL_SAN=1.3.6.1.5.2.2 ++KRB5_UPN_SAN=1.3.6.1.4.1.311.20.2.3 + PKINIT_KDC_EKU=1.3.6.1.5.2.3.5 + PKINIT_CLIENT_EKU=1.3.6.1.5.2.3.4 + TLS_SERVER_EKU=1.3.6.1.5.5.7.3.1 +@@ -85,6 +87,30 @@ keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement + basicConstraints = critical,CA:FALSE + subjectAltName = otherName:$KRB5_PRINCIPAL_SAN;SEQUENCE:krb5princ_client + extendedKeyUsage = $CLIENT_EKU_LIST ++ ++[exts_upn_client] ++subjectKeyIdentifier = hash ++authorityKeyIdentifier = keyid:always,issuer:always ++keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement ++basicConstraints = critical,CA:FALSE ++subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$LOWREALM ++extendedKeyUsage = $CLIENT_EKU_LIST ++ ++[exts_upn2_client] ++subjectKeyIdentifier = hash ++authorityKeyIdentifier = keyid:always,issuer:always ++keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement ++basicConstraints = critical,CA:FALSE ++subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user ++extendedKeyUsage = $CLIENT_EKU_LIST ++ ++[exts_upn3_client] ++subjectKeyIdentifier = hash ++authorityKeyIdentifier = keyid:always,issuer:always ++keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement ++basicConstraints = critical,CA:FALSE ++subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$REALM ++extendedKeyUsage = $CLIENT_EKU_LIST + EOF + + # Generate a private key. +@@ -113,5 +139,30 @@ openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user.p12 \ + openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user-enc.p12 \ + -passout pass:encrypted + ++# Generate a client certificate and PKCS#12 bundles with a UPN SAN. ++SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ ++ -key privkey.pem -out user-upn.csr ++SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn_client \ ++ -set_serial 4 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ ++ -out user-upn.pem -in user-upn.csr ++openssl pkcs12 -export -in user-upn.pem -inkey privkey.pem -out user-upn.p12 \ ++ -passout pass: ++ ++SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ ++ -key privkey.pem -out user-upn2.csr ++SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn2_client \ ++ -set_serial 5 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ ++ -out user-upn2.pem -in user-upn2.csr ++openssl pkcs12 -export -in user-upn2.pem -inkey privkey.pem \ ++ -out user-upn2.p12 -passout pass: ++ ++SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ ++ -key privkey.pem -out user-upn3.csr ++SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn3_client \ ++ -set_serial 6 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ ++ -out user-upn3.pem -in user-upn3.csr ++openssl pkcs12 -export -in user-upn3.pem -inkey privkey.pem \ ++ -out user-upn3.p12 -passout pass: ++ + # Clean up. +-rm -f openssl.cnf kdc.csr user.csr ++rm -f openssl.cnf kdc.csr user.csr user-upn.csr user-upn2.csr user-upn3.csr diff --git a/SOURCES/Add-test-cert-with-no-extensions.patch b/SOURCES/Add-test-cert-with-no-extensions.patch new file mode 100644 index 00000000..40b80365 --- /dev/null +++ b/SOURCES/Add-test-cert-with-no-extensions.patch @@ -0,0 +1,34 @@ +From dd189f46b9e43392b842c4309c95dc7e71963261 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 5 Oct 2017 12:54:13 -0400 +Subject: [PATCH] Add test cert with no extensions + +Add commands to make-certs.sh to generate a test client certificate +with no certificate extensions. Re-run make-certs.sh. + +ticket: 8562 +(cherry-picked from commit 0d23835660ab131d244d395e4568969b5c0dc678) +[rharwood@redhat.com: only backport the make-certs.sh changes] +--- + src/tests/dejagnu/pkinit-certs/make-certs.sh | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh +index 0d8c2019a..23426af8a 100755 +--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh ++++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh +@@ -163,5 +163,14 @@ SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn3_client \ + openssl pkcs12 -export -in user-upn3.pem -inkey privkey.pem \ + -out user-upn3.p12 -passout pass: + ++# Generate a client certificate and PKCS#12 bundle with no PKINIT extensions. ++SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ ++ -key privkey.pem -out generic.csr ++SUBJECT=user openssl x509 -set_serial 7 -days $DAYS -req -CA ca.pem \ ++ -CAkey privkey.pem -out generic.pem -in generic.csr ++openssl pkcs12 -export -in generic.pem -inkey privkey.pem -out generic.p12 \ ++ -passout pass: ++ + # Clean up. + rm -f openssl.cnf kdc.csr user.csr user-upn.csr user-upn2.csr user-upn3.csr ++rm -f generic.csr diff --git a/SOURCES/Add-the-client_name-kdcpreauth-callback.patch b/SOURCES/Add-the-client_name-kdcpreauth-callback.patch new file mode 100644 index 00000000..7cbb80bf --- /dev/null +++ b/SOURCES/Add-the-client_name-kdcpreauth-callback.patch @@ -0,0 +1,58 @@ +From aa153bb60c4fdc05adbc88cca578612fce6c8ce0 Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Tue, 4 Apr 2017 16:54:56 -0400 +Subject: [PATCH] Add the client_name() kdcpreauth callback + +Add a kdcpreauth callback to returns the canonicalized client principal. + +ticket: 8570 (new) +(cherry picked from commit a84f39ec30f3deeda7836da6e8b3d8dcf7a045b1) +--- + src/include/krb5/kdcpreauth_plugin.h | 6 ++++++ + src/kdc/kdc_preauth.c | 9 ++++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/src/include/krb5/kdcpreauth_plugin.h b/src/include/krb5/kdcpreauth_plugin.h +index 92aa5a5a5..fa4436b83 100644 +--- a/src/include/krb5/kdcpreauth_plugin.h ++++ b/src/include/krb5/kdcpreauth_plugin.h +@@ -232,6 +232,12 @@ typedef struct krb5_kdcpreauth_callbacks_st { + krb5_kdcpreauth_rock rock, + krb5_principal princ); + ++ /* ++ * Get an alias to the client DB entry principal (possibly canonicalized). ++ */ ++ krb5_principal (*client_name)(krb5_context context, ++ krb5_kdcpreauth_rock rock); ++ + /* End of version 4 kdcpreauth callbacks. */ + + } *krb5_kdcpreauth_callbacks; +diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c +index 0ce79c667..81d0b8cff 100644 +--- a/src/kdc/kdc_preauth.c ++++ b/src/kdc/kdc_preauth.c +@@ -591,6 +591,12 @@ match_client(krb5_context context, krb5_kdcpreauth_rock rock, + return match; + } + ++static krb5_principal ++client_name(krb5_context context, krb5_kdcpreauth_rock rock) ++{ ++ return rock->client->princ; ++} ++ + static struct krb5_kdcpreauth_callbacks_st callbacks = { + 4, + max_time_skew, +@@ -607,7 +613,8 @@ static struct krb5_kdcpreauth_callbacks_st callbacks = { + add_auth_indicator, + get_cookie, + set_cookie, +- match_client ++ match_client, ++ client_name + }; + + static krb5_error_code diff --git a/SOURCES/Add-timestamp-helper-functions.patch b/SOURCES/Add-timestamp-helper-functions.patch new file mode 100644 index 00000000..ae45ecb2 --- /dev/null +++ b/SOURCES/Add-timestamp-helper-functions.patch @@ -0,0 +1,80 @@ +From 6437685130b68670888db1d0551f5464d56c4cec Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 22 Apr 2017 09:49:12 -0400 +Subject: [PATCH] Add timestamp helper functions + +Add k5-int.h helper functions to manipulate krb5_timestamp values, +avoiding undefined behavior and treating negative timestamp values as +times between 2038 and 2106. Add a doxygen comment for krb5_timestamp +indicating how third-party code should use it safely. + +ticket: 8352 +(cherry picked from commit 58e9155060cd93b1a7557e37fbc9b077b76465c2) +--- + src/include/k5-int.h | 31 +++++++++++++++++++++++++++++++ + src/include/krb5/krb5.hin | 9 +++++++++ + 2 files changed, 40 insertions(+) + +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 06ca2b66d..82ee20760 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -2353,6 +2353,37 @@ k5memdup0(const void *in, size_t len, krb5_error_code *code) + return ptr; + } + ++/* Convert a krb5_timestamp to a time_t value, treating the negative range of ++ * krb5_timestamp as times between 2038 and 2106 (if time_t is 64-bit). */ ++static inline time_t ++ts2tt(krb5_timestamp timestamp) ++{ ++ return (time_t)(uint32_t)timestamp; ++} ++ ++/* Return the delta between two timestamps (a - b) as a signed 32-bit value, ++ * without relying on undefined behavior. */ ++static inline krb5_deltat ++ts_delta(krb5_timestamp a, krb5_timestamp b) ++{ ++ return (krb5_deltat)((uint32_t)a - (uint32_t)b); ++} ++ ++/* Increment a timestamp by a signed 32-bit interval, without relying on ++ * undefined behavior. */ ++static inline krb5_timestamp ++ts_incr(krb5_timestamp ts, krb5_deltat delta) ++{ ++ return (krb5_timestamp)((uint32_t)ts + (uint32_t)delta); ++} ++ ++/* Return true if a comes after b. */ ++static inline krb5_boolean ++ts_after(krb5_timestamp a, krb5_timestamp b) ++{ ++ return (uint32_t)a > (uint32_t)b; ++} ++ + krb5_error_code KRB5_CALLCONV + krb5_get_credentials_for_user(krb5_context context, krb5_flags options, + krb5_ccache ccache, +diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin +index cf60d6c41..53ad85384 100644 +--- a/src/include/krb5/krb5.hin ++++ b/src/include/krb5/krb5.hin +@@ -187,7 +187,16 @@ typedef krb5_int32 krb5_cryptotype; + + typedef krb5_int32 krb5_preauthtype; /* This may change, later on */ + typedef krb5_int32 krb5_flags; ++ ++/** ++ * Represents a timestamp in seconds since the POSIX epoch. This legacy type ++ * is used frequently in the ABI, but cannot represent timestamps after 2038 as ++ * a positive number. Code which uses this type should cast values of it to ++ * uint32_t so that negative values are treated as timestamps between 2038 and ++ * 2106 on platforms with 64-bit time_t. ++ */ + typedef krb5_int32 krb5_timestamp; ++ + typedef krb5_int32 krb5_deltat; + + /** diff --git a/SOURCES/Add-timestamp-tests.patch b/SOURCES/Add-timestamp-tests.patch new file mode 100644 index 00000000..8b485bae --- /dev/null +++ b/SOURCES/Add-timestamp-tests.patch @@ -0,0 +1,599 @@ +From 47999bb8735f653f06e0eb46e7eced600210b9da Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 29 Apr 2017 17:30:36 -0400 +Subject: [PATCH] Add timestamp tests + +Add a test program for krb5int_validate_times() covering cases before +and across the y2038 boundary. Add a GSSAPI test program to exercise +lifetime queries, and tests using it in t_gssapi.py for ticket end +times after y2038. Add a new test script t_y2038.py which only runs +on platforms with 64-bit time_t to exercise end-user operations across +and after y2038. Add an LDAP test case to test storage of post-y2038 +timestamps. + +ticket: 8352 +(cherry picked from commit 8ca62e54e89e2fbd6a089e8ab20b4e374a486003) +[rharwood@redhat.com: prune gitignore] +--- + src/Makefile.in | 1 + + src/config/pre.in | 2 + + src/configure.in | 3 + + src/lib/krb5/krb/Makefile.in | 14 ++-- + src/lib/krb5/krb/t_valid_times.c | 109 ++++++++++++++++++++++++++++++ + src/tests/Makefile.in | 1 + + src/tests/gssapi/Makefile.in | 27 ++++---- + src/tests/gssapi/t_gssapi.py | 32 +++++++++ + src/tests/gssapi/t_lifetime.c | 140 +++++++++++++++++++++++++++++++++++++++ + src/tests/t_kdb.py | 7 ++ + src/tests/t_y2038.py | 75 +++++++++++++++++++++ + 11 files changed, 395 insertions(+), 16 deletions(-) + create mode 100644 src/lib/krb5/krb/t_valid_times.c + create mode 100644 src/tests/gssapi/t_lifetime.c + create mode 100644 src/tests/t_y2038.py + +diff --git a/src/Makefile.in b/src/Makefile.in +index b0249778c..ad8565056 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -521,6 +521,7 @@ pyrunenv.vals: Makefile + done > $@ + echo "tls_impl = '$(TLS_IMPL)'" >> $@ + echo "have_sasl = '$(HAVE_SASL)'" >> $@ ++ echo "sizeof_time_t = $(SIZEOF_TIME_T)" >> $@ + + runenv.py: pyrunenv.vals + echo 'env = {}' > $@ +diff --git a/src/config/pre.in b/src/config/pre.in +index d961b5621..f23c07d9d 100644 +--- a/src/config/pre.in ++++ b/src/config/pre.in +@@ -452,6 +452,8 @@ HAVE_SASL = @HAVE_SASL@ + # Whether we have libresolv 1.1.5 for URI discovery tests + HAVE_RESOLV_WRAPPER = @HAVE_RESOLV_WRAPPER@ + ++SIZEOF_TIME_T = @SIZEOF_TIME_T@ ++ + # error table rules + # + ### /* these are invoked as $(...) foo.et, which works, but could be better */ +diff --git a/src/configure.in b/src/configure.in +index 24f653f0d..4ae2c07d5 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -744,6 +744,9 @@ fi + + AC_HEADER_TIME + AC_CHECK_TYPE(time_t, long) ++AC_CHECK_SIZEOF(time_t) ++SIZEOF_TIME_T=$ac_cv_sizeof_time_t ++AC_SUBST(SIZEOF_TIME_T) + + # Determine where to put the replay cache. + +diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in +index 0fe02a95d..55f82b147 100644 +--- a/src/lib/krb5/krb/Makefile.in ++++ b/src/lib/krb5/krb/Makefile.in +@@ -364,6 +364,7 @@ SRCS= $(srcdir)/addr_comp.c \ + $(srcdir)/t_in_ccache.c \ + $(srcdir)/t_response_items.c \ + $(srcdir)/t_sname_match.c \ ++ $(srcdir)/t_valid_times.c \ + $(srcdir)/t_vfy_increds.c + + # Someday, when we have a "maintainer mode", do this right: +@@ -457,9 +458,12 @@ t_response_items: t_response_items.o response_items.o $(KRB5_BASE_DEPLIBS) + t_sname_match: t_sname_match.o sname_match.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o $@ t_sname_match.o sname_match.o $(KRB5_BASE_LIBS) + ++t_valid_times: t_valid_times.o valid_times.o $(KRB5_BASE_DEPLIBS) ++ $(CC_LINK) -o $@ t_valid_times.o valid_times.o $(KRB5_BASE_LIBS) ++ + TEST_PROGS= t_walk_rtree t_kerb t_ser t_deltat t_expand t_authdata t_pac \ +- t_in_ccache t_cc_config t_copy_context \ +- t_princ t_etypes t_vfy_increds t_response_items t_sname_match ++ t_in_ccache t_cc_config t_copy_context t_princ t_etypes t_vfy_increds \ ++ t_response_items t_sname_match t_valid_times + + check-unix: $(TEST_PROGS) + $(RUN_TEST_LOCAL_CONF) ./t_kerb \ +@@ -496,6 +500,7 @@ check-unix: $(TEST_PROGS) + $(RUN_TEST) ./t_response_items + $(RUN_TEST) ./t_copy_context + $(RUN_TEST) ./t_sname_match ++ $(RUN_TEST) ./t_valid_times + + check-pytests: t_expire_warn t_vfy_increds + $(RUNPYTEST) $(srcdir)/t_expire_warn.py $(PYTESTFLAGS) +@@ -522,8 +527,9 @@ clean: + $(OUTPRE)t_ad_fx_armor$(EXEEXT) $(OUTPRE)t_ad_fx_armor.$(OBJEXT) \ + $(OUTPRE)t_vfy_increds$(EXEEXT) $(OUTPRE)t_vfy_increds.$(OBJEXT) \ + $(OUTPRE)t_response_items$(EXEEXT) \ +- $(OUTPRE)t_response_items.$(OBJEXT) $(OUTPRE)t_sname_match$(EXEEXT) \ +- $(OUTPRE)t_sname_match.$(OBJEXT) \ ++ $(OUTPRE)t_response_items.$(OBJEXT) \ ++ $(OUTPRE)t_sname_match$(EXEEXT) $(OUTPRE)t_sname_match.$(OBJEXT) \ ++ $(OUTPRE)t_valid_times$(EXEEXT) $(OUTPRE)t_valid_times.$(OBJECT) \ + $(OUTPRE)t_parse_host_string$(EXEEXT) \ + $(OUTPRE)t_parse_host_string.$(OBJEXT) + +diff --git a/src/lib/krb5/krb/t_valid_times.c b/src/lib/krb5/krb/t_valid_times.c +new file mode 100644 +index 000000000..1b469ffc2 +--- /dev/null ++++ b/src/lib/krb5/krb/t_valid_times.c +@@ -0,0 +1,109 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* lib/krb5/krb/t_valid_times.c - test program for krb5int_validate_times() */ ++/* ++ * Copyright (C) 2017 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "k5-int.h" ++#include "int-proto.h" ++ ++#define BOUNDARY (uint32_t)INT32_MIN ++ ++int ++main() ++{ ++ krb5_error_code ret; ++ krb5_context context; ++ krb5_ticket_times times = { 0, 0, 0, 0 }; ++ ++ ret = krb5_init_context(&context); ++ assert(!ret); ++ ++ /* Current time is within authtime and end time. */ ++ ret = krb5_set_debugging_time(context, 1000, 0); ++ times.authtime = 500; ++ times.endtime = 1500; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is before starttime, but within clock skew. */ ++ times.starttime = 1100; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is before starttime by more than clock skew. */ ++ times.starttime = 1400; ++ ret = krb5int_validate_times(context, ×); ++ assert(ret == KRB5KRB_AP_ERR_TKT_NYV); ++ ++ /* Current time is after end time, but within clock skew. */ ++ times.starttime = 500; ++ times.endtime = 800; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is after end time by more than clock skew. */ ++ times.endtime = 600; ++ ret = krb5int_validate_times(context, ×); ++ assert(ret == KRB5KRB_AP_ERR_TKT_EXPIRED); ++ ++ /* Current time is within starttime and endtime; current time and ++ * endtime are across y2038 boundary. */ ++ ret = krb5_set_debugging_time(context, BOUNDARY - 100, 0); ++ assert(!ret); ++ times.starttime = BOUNDARY - 200; ++ times.endtime = BOUNDARY + 500; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is before starttime, but by less than clock skew. */ ++ times.starttime = BOUNDARY + 100; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is before starttime by more than clock skew. */ ++ times.starttime = BOUNDARY + 250; ++ ret = krb5int_validate_times(context, ×); ++ assert(ret == KRB5KRB_AP_ERR_TKT_NYV); ++ ++ /* Current time is after endtime, but by less than clock skew. */ ++ ret = krb5_set_debugging_time(context, BOUNDARY + 100, 0); ++ assert(!ret); ++ times.starttime = BOUNDARY - 1000; ++ times.endtime = BOUNDARY - 100; ++ ret = krb5int_validate_times(context, ×); ++ assert(!ret); ++ ++ /* Current time is after endtime by more than clock skew. */ ++ times.endtime = BOUNDARY - 300; ++ ret = krb5int_validate_times(context, ×); ++ assert(ret == KRB5KRB_AP_ERR_TKT_EXPIRED); ++ ++ return 0; ++} +diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in +index 0e93d6b59..2b3112537 100644 +--- a/src/tests/Makefile.in ++++ b/src/tests/Makefile.in +@@ -168,6 +168,7 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter + $(RUNPYTEST) $(srcdir)/t_princflags.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS) ++ $(RUNPYTEST) $(srcdir)/t_y2038.py $(PYTESTFLAGS) + + clean: + $(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest +diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in +index 6c1464297..604f926de 100644 +--- a/src/tests/gssapi/Makefile.in ++++ b/src/tests/gssapi/Makefile.in +@@ -15,15 +15,16 @@ SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \ + $(srcdir)/t_gssexts.c $(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c \ + $(srcdir)/t_invalid.c $(srcdir)/t_inq_cred.c $(srcdir)/t_inq_ctx.c \ + $(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \ +- $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c $(srcdir)/t_pcontok.c \ +- $(srcdir)/t_prf.c $(srcdir)/t_s4u.c $(srcdir)/t_s4u2proxy_krb5.c \ +- $(srcdir)/t_saslname.c $(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c ++ $(srcdir)/t_lifetime.c $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c \ ++ $(srcdir)/t_pcontok.c $(srcdir)/t_prf.c $(srcdir)/t_s4u.c \ ++ $(srcdir)/t_s4u2proxy_krb5.c $(srcdir)/t_saslname.c \ ++ $(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c + + OBJS= ccinit.o ccrefresh.o common.o t_accname.o t_ccselect.o t_ciflags.o \ + t_credstore.o t_enctypes.o t_err.o t_export_cred.o t_export_name.o \ + t_gssexts.o t_imp_cred.o t_imp_name.o t_invalid.o t_inq_cred.o \ +- t_inq_ctx.o t_inq_mechs_name.o t_iov.o t_namingexts.o t_oid.o \ +- t_pcontok.o t_prf.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \ ++ t_inq_ctx.o t_inq_mechs_name.o t_iov.o t_lifetime.o t_namingexts.o \ ++ t_oid.o t_pcontok.o t_prf.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \ + t_spnego.o t_srcattrs.o + + COMMON_DEPS= common.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS) +@@ -31,9 +32,9 @@ COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS) + + all: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore t_enctypes \ + t_err t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name \ +- t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_namingexts \ +- t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname t_spnego \ +- t_srcattrs ++ t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime \ ++ t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname \ ++ t_spnego t_srcattrs + + check-unix: t_oid + $(RUN_TEST) ./t_invalid +@@ -42,8 +43,8 @@ check-unix: t_oid + + check-pytests: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore \ + t_enctypes t_err t_export_cred t_export_name t_imp_cred t_inq_cred \ +- t_inq_ctx t_inq_mechs_name t_iov t_pcontok t_s4u t_s4u2proxy_krb5 \ +- t_spnego t_srcattrs ++ t_inq_ctx t_inq_mechs_name t_iov t_lifetime t_pcontok t_s4u \ ++ t_s4u2proxy_krb5 t_spnego t_srcattrs + $(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS) + $(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS) +@@ -88,6 +89,8 @@ t_inq_mechs_name: t_inq_mechs_name.o $(COMMON_DEPS) + $(CC_LINK) -o $@ t_inq_mechs_name.o $(COMMON_LIBS) + t_iov: t_iov.o $(COMMON_DEPS) + $(CC_LINK) -o $@ t_iov.o $(COMMON_LIBS) ++t_lifetime: t_lifetime.o $(COMMON_DEPS) ++ $(CC_LINK) -o $@ t_lifetime.o $(COMMON_LIBS) + t_namingexts: t_namingexts.o $(COMMON_DEPS) + $(CC_LINK) -o $@ t_namingexts.o $(COMMON_LIBS) + t_pcontok: t_pcontok.o $(COMMON_DEPS) +@@ -111,5 +114,5 @@ clean: + $(RM) ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore + $(RM) t_enctypes t_err t_export_cred t_export_name t_gssexts t_imp_cred + $(RM) t_imp_name t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov +- $(RM) t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 +- $(RM) t_saslname t_spnego t_srcattrs ++ $(RM) t_lifetime t_namingexts t_oid t_pcontok t_prf t_s4u ++ $(RM) t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs +diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py +index e23c936d7..fa214242f 100755 +--- a/src/tests/gssapi/t_gssapi.py ++++ b/src/tests/gssapi/t_gssapi.py +@@ -220,4 +220,36 @@ realm.run(['./t_ciflags', 'p:' + realm.host_princ]) + # contexts. + realm.run(['./t_inq_ctx', 'user', password('user'), 'p:%s' % realm.host_princ]) + ++# Test lifetime results, using a realm with a large maximum lifetime ++# so that we can test ticket end dates after y2038. There are no ++# time_t conversions involved, so we can run these tests on platforms ++# with 32-bit time_t. ++realm.stop() ++conf = {'realms': {'$realm': {'max_life': '9000d'}}} ++realm = K5Realm(kdc_conf=conf, get_creds=False) ++ ++# Check a lifetime string result against an expected number value (or None). ++# Allow some variance due to time elapsed during the tests. ++def check_lifetime(msg, val, expected): ++ if expected is None and val != 'indefinite': ++ fail('%s: expected indefinite, got %s' % (msg, val)) ++ if expected is not None and val == 'indefinite': ++ fail('%s: expected %d, got indefinite' % (msg, expected)) ++ if expected is not None and abs(int(val) - expected) > 100: ++ fail('%s: expected %d, got %s' % (msg, expected, val)) ++ ++realm.kinit(realm.user_princ, password('user'), flags=['-l', '8500d']) ++out = realm.run(['./t_lifetime', 'p:' + realm.host_princ, str(8000 * 86400)]) ++ln = out.split('\n') ++check_lifetime('icred gss_acquire_cred', ln[0], 8500 * 86400) ++check_lifetime('icred gss_inquire_cred', ln[1], 8500 * 86400) ++check_lifetime('acred gss_acquire_cred', ln[2], None) ++check_lifetime('acred gss_inquire_cred', ln[3], None) ++check_lifetime('ictx gss_init_sec_context', ln[4], 8000 * 86400) ++check_lifetime('ictx gss_inquire_context', ln[5], 8000 * 86400) ++check_lifetime('ictx gss_context_time', ln[6], 8000 * 86400) ++check_lifetime('actx gss_accept_sec_context', ln[7], 8000 * 86400 + 300) ++check_lifetime('actx gss_inquire_context', ln[8], 8000 * 86400 + 300) ++check_lifetime('actx gss_context_time', ln[9], 8000 * 86400 + 300) ++ + success('GSSAPI tests') +diff --git a/src/tests/gssapi/t_lifetime.c b/src/tests/gssapi/t_lifetime.c +new file mode 100644 +index 000000000..8dcf18621 +--- /dev/null ++++ b/src/tests/gssapi/t_lifetime.c +@@ -0,0 +1,140 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* tests/gssapi/t_lifetime.c - display cred and context lifetimes */ ++/* ++ * Copyright (C) 2017 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include ++#include "common.h" ++ ++/* ++ * Using the default credential, exercise the GSS functions which accept or ++ * produce lifetimes. Display the following results, one per line, as ASCII ++ * integers or the string "indefinite": ++ * ++ * initiator cred lifetime according to gss_acquire_cred() ++ * initiator cred lifetime according to gss_inquire_cred() ++ * acceptor cred lifetime according to gss_acquire_cred() ++ * acceptor cred lifetime according to gss_inquire_cred() ++ * initiator context lifetime according to gss_init_sec_context() ++ * initiator context lifetime according to gss_inquire_context() ++ * initiator context lifetime according to gss_context_time() ++ * acceptor context lifetime according to gss_init_sec_context() ++ * acceptor context lifetime according to gss_inquire_context() ++ * acceptor context lifetime according to gss_context_time() ++ */ ++ ++static void ++display_time(OM_uint32 tval) ++{ ++ if (tval == GSS_C_INDEFINITE) ++ puts("indefinite"); ++ else ++ printf("%u\n", (unsigned int)tval); ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++ OM_uint32 minor, major; ++ gss_cred_id_t icred, acred; ++ gss_name_t tname; ++ gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; ++ gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER; ++ OM_uint32 time_req = GSS_C_INDEFINITE, time_rec; ++ ++ if (argc < 2 || argc > 3) { ++ fprintf(stderr, "Usage: %s targetname [time_req]\n", argv[0]); ++ return 1; ++ } ++ tname = import_name(argv[1]); ++ if (argc >= 3) ++ time_req = atoll(argv[2]); ++ ++ /* Get initiator cred and display its lifetime according to ++ * gss_acquire_cred and gss_inquire_cred. */ ++ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5, ++ GSS_C_INITIATE, &icred, NULL, &time_rec); ++ check_gsserr("gss_acquire_cred(initiate)", major, minor); ++ display_time(time_rec); ++ major = gss_inquire_cred(&minor, icred, NULL, &time_rec, NULL, NULL); ++ check_gsserr("gss_inquire_cred(initiate)", major, minor); ++ display_time(time_rec); ++ ++ /* Get acceptor cred and display its lifetime according to gss_acquire_cred ++ * and gss_inquire_cred. */ ++ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5, ++ GSS_C_ACCEPT, &acred, NULL, &time_rec); ++ check_gsserr("gss_acquire_cred(accept)", major, minor); ++ display_time(time_rec); ++ major = gss_inquire_cred(&minor, acred, NULL, &time_rec, NULL, NULL); ++ check_gsserr("gss_inquire_cred(accept)", major, minor); ++ display_time(time_rec); ++ ++ /* Make an initiator context and display its lifetime according to ++ * gss_init_sec_context, gss_inquire_context, and gss_context_time. */ ++ major = gss_init_sec_context(&minor, icred, &ictx, tname, &mech_krb5, 0, ++ time_req, GSS_C_NO_CHANNEL_BINDINGS, &atok, ++ NULL, &itok, NULL, &time_rec); ++ check_gsserr("gss_init_sec_context", major, minor); ++ assert(major == GSS_S_COMPLETE); ++ display_time(time_rec); ++ major = gss_inquire_context(&minor, ictx, NULL, NULL, &time_rec, NULL, ++ NULL, NULL, NULL); ++ check_gsserr("gss_inquire_context(initiate)", major, minor); ++ display_time(time_rec); ++ major = gss_context_time(&minor, ictx, &time_rec); ++ check_gsserr("gss_context_time(initiate)", major, minor); ++ display_time(time_rec); ++ ++ major = gss_accept_sec_context(&minor, &actx, acred, &itok, ++ GSS_C_NO_CHANNEL_BINDINGS, NULL, ++ NULL, &atok, NULL, &time_rec, NULL); ++ check_gsserr("gss_accept_sec_context", major, minor); ++ assert(major == GSS_S_COMPLETE); ++ display_time(time_rec); ++ major = gss_inquire_context(&minor, actx, NULL, NULL, &time_rec, NULL, ++ NULL, NULL, NULL); ++ check_gsserr("gss_inquire_context(accept)", major, minor); ++ display_time(time_rec); ++ major = gss_context_time(&minor, actx, &time_rec); ++ check_gsserr("gss_context_time(accept)", major, minor); ++ display_time(time_rec); ++ ++ (void)gss_release_buffer(&minor, &itok); ++ (void)gss_release_buffer(&minor, &atok); ++ (void)gss_release_name(&minor, &tname); ++ (void)gss_release_cred(&minor, &icred); ++ (void)gss_release_cred(&minor, &acred); ++ (void)gss_delete_sec_context(&minor, &ictx, NULL); ++ (void)gss_delete_sec_context(&minor, &actx, NULL); ++ return 0; ++} +diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py +index 185225afa..c0eeb0118 100755 +--- a/src/tests/t_kdb.py ++++ b/src/tests/t_kdb.py +@@ -446,6 +446,13 @@ realm.run([kadminl, 'addprinc', '-policy', 'keepoldpasspol', '-pw', 'aaaa', + for p in ('bbbb', 'cccc', 'aaaa'): + realm.run([kadminl, 'cpw', '-keepold', '-pw', p, 'keepoldpassprinc']) + ++if runenv.sizeof_time_t <= 4: ++ skipped('y2038 LDAP test', 'platform has 32-bit time_t') ++else: ++ # Test storage of timestamps after y2038. ++ realm.run([kadminl, 'modprinc', '-pwexpire', '2040-02-03', 'user']) ++ realm.run([kadminl, 'getprinc', 'user'], expected_msg=' 2040\n') ++ + realm.stop() + + # Briefly test dump and load. +diff --git a/src/tests/t_y2038.py b/src/tests/t_y2038.py +new file mode 100644 +index 000000000..02e946df4 +--- /dev/null ++++ b/src/tests/t_y2038.py +@@ -0,0 +1,75 @@ ++#!/usr/bin/python ++from k5test import * ++ ++# These tests will become much less important after the y2038 boundary ++# has elapsed, and may start exhibiting problems around the year 2075. ++ ++if runenv.sizeof_time_t <= 4: ++ skip_rest('y2038 timestamp tests', 'platform has 32-bit time_t') ++ ++# Start a KDC running roughly 21 years in the future, after the y2038 ++# boundary. Set long maximum lifetimes for later tests. ++conf = {'realms': {'$realm': {'max_life': '9000d', ++ 'max_renewable_life': '9000d'}}} ++realm = K5Realm(start_kdc=False, kdc_conf=conf) ++realm.start_kdc(['-T', '662256000']) ++ ++# kinit without preauth should succeed with clock skew correction, but ++# will result in an expired ticket, because we sent an absolute end ++# time and didn't get a chance to correct it.. ++realm.kinit(realm.user_princ, password('user')) ++realm.run([kvno, realm.host_princ], expected_code=1, ++ expected_msg='Ticket expired') ++ ++# kinit with preauth should succeed and result in a valid ticket, as ++# we get a chance to correct the end time based on the KDC time. Try ++# with encrypted timestamp and encrypted challenge. ++realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) ++realm.kinit(realm.user_princ, password('user')) ++realm.run([kvno, realm.host_princ]) ++realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache]) ++realm.run([kvno, realm.host_princ]) ++ ++# Test that expiration warning works after y2038, by setting a ++# password expiration time ten minutes after the KDC time. ++realm.run([kadminl, 'modprinc', '-pwexpire', '662256600 seconds', 'user']) ++out = realm.kinit(realm.user_princ, password('user')) ++if 'will expire in less than one hour' not in out: ++ fail('password expiration message') ++year = int(out.split()[-1]) ++if year < 2038 or year > 9999: ++ fail('password expiration year') ++ ++realm.stop_kdc() ++realm.start_kdc() ++realm.start_kadmind() ++realm.prep_kadmin() ++ ++# Test getdate parsing of absolute timestamps after 2038 and ++# marshalling over the kadmin protocol. The local time zone will ++# affect the display time by a little bit, so just look for the year. ++realm.run_kadmin(['modprinc', '-pwexpire', '2040-02-03', realm.host_princ]) ++realm.run_kadmin(['getprinc', realm.host_princ], expected_msg=' 2040\n') ++ ++# Get a ticket whose lifetime crosses the y2038 boundary and ++# range-check the expiration year as reported by klist. ++realm.kinit(realm.user_princ, password('user'), ++ flags=['-l', '8000d', '-r', '8500d']) ++realm.run([kvno, realm.host_princ]) ++out = realm.run([klist]) ++if int(out.split('\n')[4].split()[2].split('/')[2]) < 39: ++ fail('unexpected tgt expiration year') ++if int(out.split('\n')[5].split()[2].split('/')[2]) < 40: ++ fail('unexpected tgt rtill year') ++if int(out.split('\n')[6].split()[2].split('/')[2]) < 39: ++ fail('unexpected service ticket expiration year') ++if int(out.split('\n')[7].split()[2].split('/')[2]) < 40: ++ fail('unexpected service ticket rtill year') ++realm.kinit(realm.user_princ, None, ['-R']) ++out = realm.run([klist]) ++if int(out.split('\n')[4].split()[2].split('/')[2]) < 39: ++ fail('unexpected renewed tgt expiration year') ++if int(out.split('\n')[5].split()[2].split('/')[2]) < 40: ++ fail('unexpected renewed tgt rtill year') ++ ++success('y2038 tests') diff --git a/SOURCES/Add-y2038-documentation.patch b/SOURCES/Add-y2038-documentation.patch new file mode 100644 index 00000000..d6a1af09 --- /dev/null +++ b/SOURCES/Add-y2038-documentation.patch @@ -0,0 +1,59 @@ +From f9702eabc568679f48ea5d0bc7be073582cc52ad Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 4 May 2017 17:03:35 -0400 +Subject: [PATCH] Add y2038 documentation + +ticket: 8352 +(cherry picked from commit 85d64c43dbf7a7faa56a1999494cdfa49e8bd2c9) +--- + doc/appdev/index.rst | 1 + + doc/appdev/y2038.rst | 28 ++++++++++++++++++++++++++++ + 2 files changed, 29 insertions(+) + create mode 100644 doc/appdev/y2038.rst + +diff --git a/doc/appdev/index.rst b/doc/appdev/index.rst +index 3d62045ca..961bb1e9e 100644 +--- a/doc/appdev/index.rst ++++ b/doc/appdev/index.rst +@@ -5,6 +5,7 @@ For application developers + :maxdepth: 1 + + gssapi.rst ++ y2038.rst + h5l_mit_apidiff.rst + init_creds.rst + princ_handle.rst +diff --git a/doc/appdev/y2038.rst b/doc/appdev/y2038.rst +new file mode 100644 +index 000000000..bc4122dad +--- /dev/null ++++ b/doc/appdev/y2038.rst +@@ -0,0 +1,28 @@ ++Year 2038 considerations for uses of krb5_timestamp ++=================================================== ++ ++POSIX time values, which measure the number of seconds since January 1 ++1970, will exceed the maximum value representable in a signed 32-bit ++integer in January 2038. This documentation describes considerations ++for consumers of the MIT krb5 libraries. ++ ++Applications or libraries which use libkrb5 and consume the timestamps ++included in credentials or other structures make use of the ++:c:type:`krb5_timestamp` type. For historical reasons, krb5_timestamp ++is a signed 32-bit integer, even on platforms where a larger type is ++natively used to represent time values. To behave properly for time ++values after January 2038, calling code should cast krb5_timestamp ++values to uint32_t, and then to time_t:: ++ ++ (time_t)(uint32_t)timestamp ++ ++Used in this way, krb5_timestamp values can represent time values up ++until February 2106, provided that the platform uses a 64-bit or ++larger time_t type. This usage will also remain safe if a later ++version of MIT krb5 changes krb5_timestamp to an unsigned 32-bit ++integer. ++ ++The GSSAPI only uses representations of time intervals, not absolute ++times. Callers of the GSSAPI should require no changes to behave ++correctly after January 2038, provided that they use MIT krb5 release ++1.16 or later. diff --git a/SOURCES/Allow-clock-skew-in-krb5-gss_context_time.patch b/SOURCES/Allow-clock-skew-in-krb5-gss_context_time.patch new file mode 100644 index 00000000..410dc559 --- /dev/null +++ b/SOURCES/Allow-clock-skew-in-krb5-gss_context_time.patch @@ -0,0 +1,36 @@ +From 498b43b1a58795773834c1c5bb2b61dd801b9a03 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 22 Apr 2017 16:51:23 -0400 +Subject: [PATCH] Allow clock skew in krb5 gss_context_time() + +Commit b496ce4095133536e0ace36b74130e4b9ecb5e11 (ticket #8268) adds +the clock skew to krb5 acceptor context lifetimes for +gss_accept_sec_context() and gss_inquire_context(), but not for +gss_context_time(). Add the clock skew in gss_context_time() as well. + +ticket: 8581 (new) +target_version: 1.14-next +target_version: 1.15-next +tags: pullup + +(cherry picked from commit b0a072e6431261734e7350996a363801f180e8ea) +--- + src/lib/gssapi/krb5/context_time.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c +index a18cfb05b..450593288 100644 +--- a/src/lib/gssapi/krb5/context_time.c ++++ b/src/lib/gssapi/krb5/context_time.c +@@ -51,7 +51,10 @@ krb5_gss_context_time(minor_status, context_handle, time_rec) + return(GSS_S_FAILURE); + } + +- if ((lifetime = ctx->krb_times.endtime - now) <= 0) { ++ lifetime = ctx->krb_times.endtime - now; ++ if (!ctx->initiate) ++ lifetime += ctx->k5_context->clockskew; ++ if (lifetime <= 0) { + *time_rec = 0; + *minor_status = 0; + return(GSS_S_CONTEXT_EXPIRED); diff --git a/SOURCES/Convert-some-pkiDebug-messages-to-TRACE-macros.patch b/SOURCES/Convert-some-pkiDebug-messages-to-TRACE-macros.patch new file mode 100644 index 00000000..ed25ad01 --- /dev/null +++ b/SOURCES/Convert-some-pkiDebug-messages-to-TRACE-macros.patch @@ -0,0 +1,423 @@ +From b4c2212ae7412e21f4965acdb8c10e4a60b65b9b Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Wed, 29 Mar 2017 10:35:13 -0400 +Subject: [PATCH] Convert some pkiDebug messages to TRACE macros + +ticket: 8568 (new) +(cherry picked from commit 9852862a83952a94300adfafa3e333f43396ec33) +(cherry picked from commit 686fa6476eb759532d566794fa8d430774d44cf7) +--- + src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 46 ++++++--------- + src/plugins/preauth/pkinit/pkinit_identity.c | 3 - + src/plugins/preauth/pkinit/pkinit_matching.c | 1 + + src/plugins/preauth/pkinit/pkinit_srv.c | 24 ++++---- + src/plugins/preauth/pkinit/pkinit_trace.h | 68 +++++++++++++++++++++- + 5 files changed, 97 insertions(+), 45 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 90c30dbf5..70e230ec2 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2320,7 +2320,6 @@ crypto_check_cert_eku(krb5_context context, + + X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert), + buf, sizeof(buf)); +- pkiDebug("%s: looking for EKUs in cert = %s\n", __FUNCTION__, buf); + + if ((i = X509_get_ext_by_NID(reqctx->received_cert, + NID_ext_key_usage, -1)) >= 0) { +@@ -2354,7 +2353,6 @@ crypto_check_cert_eku(krb5_context context, + + if (found_eku) { + ASN1_BIT_STRING *usage = NULL; +- pkiDebug("%s: found acceptable EKU, checking for digitalSignature\n", __FUNCTION__); + + /* check that digitalSignature KeyUsage is present */ + X509_check_ca(reqctx->received_cert); +@@ -2363,12 +2361,10 @@ crypto_check_cert_eku(krb5_context context, + + if (!ku_reject(reqctx->received_cert, + X509v3_KU_DIGITAL_SIGNATURE)) { +- pkiDebug("%s: found digitalSignature KU\n", +- __FUNCTION__); ++ TRACE_PKINIT_EKU(context); + *valid_eku = 1; + } else +- pkiDebug("%s: didn't find digitalSignature KU\n", +- __FUNCTION__); ++ TRACE_PKINIT_EKU_NO_KU(context); + } + ASN1_BIT_STRING_free(usage); + } +@@ -4317,8 +4313,7 @@ pkinit_get_certs_pkcs12(krb5_context context, + + fp = fopen(idopts->cert_filename, "rb"); + if (fp == NULL) { +- pkiDebug("Failed to open PKCS12 file '%s', error %d\n", +- idopts->cert_filename, errno); ++ TRACE_PKINIT_PKCS_OPEN_FAIL(context, idopts->cert_filename, errno); + goto cleanup; + } + set_cloexec_file(fp); +@@ -4326,8 +4321,7 @@ pkinit_get_certs_pkcs12(krb5_context context, + p12 = d2i_PKCS12_fp(fp, NULL); + fclose(fp); + if (p12 == NULL) { +- pkiDebug("Failed to decode PKCS12 file '%s' contents\n", +- idopts->cert_filename); ++ TRACE_PKINIT_PKCS_DECODE_FAIL(context, idopts->cert_filename); + goto cleanup; + } + /* +@@ -4345,7 +4339,7 @@ pkinit_get_certs_pkcs12(krb5_context context, + char *p12name = reassemble_pkcs12_name(idopts->cert_filename); + const char *tmp; + +- pkiDebug("Initial PKCS12_parse with no password failed\n"); ++ TRACE_PKINIT_PKCS_PARSE_FAIL_FIRST(context); + + if (id_cryptoctx->defer_id_prompt) { + /* Supply the identity name to be passed to the responder. */ +@@ -4386,14 +4380,14 @@ pkinit_get_certs_pkcs12(krb5_context context, + NULL, NULL, 1, &kprompt); + k5int_set_prompt_types(context, 0); + if (r) { +- pkiDebug("Failed to prompt for PKCS12 password"); ++ TRACE_PKINIT_PKCS_PROMPT_FAIL(context); + goto cleanup; + } + } + + ret = PKCS12_parse(p12, rdat.data, &y, &x, NULL); + if (ret == 0) { +- pkiDebug("Second PKCS12_parse with password failed\n"); ++ TRACE_PKINIT_PKCS_PARSE_FAIL_SECOND(context); + goto cleanup; + } + } +@@ -4516,8 +4510,7 @@ pkinit_get_certs_fs(krb5_context context, + } + + if (idopts->key_filename == NULL) { +- pkiDebug("%s: failed to get user's private key location\n", +- __FUNCTION__); ++ TRACE_PKINIT_NO_PRIVKEY(context); + goto cleanup; + } + +@@ -4545,8 +4538,7 @@ pkinit_get_certs_dir(krb5_context context, + char *dirname, *suf; + + if (idopts->cert_filename == NULL) { +- pkiDebug("%s: failed to get user's certificate directory location\n", +- __FUNCTION__); ++ TRACE_PKINIT_NO_CERT(context); + return ENOENT; + } + +@@ -4590,8 +4582,7 @@ pkinit_get_certs_dir(krb5_context context, + retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx, + certname, keyname, i); + if (retval == 0) { +- pkiDebug("%s: Successfully loaded cert (and key) for %s\n", +- __FUNCTION__, dentry->d_name); ++ TRACE_PKINIT_LOADED_CERT(context, dentry->d_name); + i++; + } + else +@@ -4599,8 +4590,7 @@ pkinit_get_certs_dir(krb5_context context, + } + + if (!id_cryptoctx->defer_id_prompt && i == 0) { +- pkiDebug("%s: No cert/key pairs found in directory '%s'\n", +- __FUNCTION__, idopts->cert_filename); ++ TRACE_PKINIT_NO_CERT_AND_KEY(context, idopts->cert_filename); + retval = ENOENT; + goto cleanup; + } +@@ -5370,9 +5360,7 @@ crypto_cert_select_default(krb5_context context, + goto errout; + } + if (cert_count != 1) { +- pkiDebug("%s: ERROR: There are %d certs to choose from, " +- "but there must be exactly one.\n", +- __FUNCTION__, cert_count); ++ TRACE_PKINIT_NO_DEFAULT_CERT(context, cert_count); + retval = EINVAL; + goto errout; + } +@@ -5520,7 +5508,7 @@ load_cas_and_crls(krb5_context context, + switch(catype) { + case CATYPE_ANCHORS: + if (sk_X509_num(ca_certs) == 0) { +- pkiDebug("no anchors in file, %s\n", filename); ++ TRACE_PKINIT_NO_CA_ANCHOR(context, filename); + if (id_cryptoctx->trustedCAs == NULL) + sk_X509_free(ca_certs); + } else { +@@ -5530,7 +5518,7 @@ load_cas_and_crls(krb5_context context, + break; + case CATYPE_INTERMEDIATES: + if (sk_X509_num(ca_certs) == 0) { +- pkiDebug("no intermediates in file, %s\n", filename); ++ TRACE_PKINIT_NO_CA_INTERMEDIATE(context, filename); + if (id_cryptoctx->intermediateCAs == NULL) + sk_X509_free(ca_certs); + } else { +@@ -5540,7 +5528,7 @@ load_cas_and_crls(krb5_context context, + break; + case CATYPE_CRLS: + if (sk_X509_CRL_num(ca_crls) == 0) { +- pkiDebug("no crls in file, %s\n", filename); ++ TRACE_PKINIT_NO_CRL(context, filename); + if (id_cryptoctx->revoked == NULL) + sk_X509_CRL_free(ca_crls); + } else { +@@ -5626,14 +5614,14 @@ crypto_load_cas_and_crls(krb5_context context, + int catype, + char *id) + { +- pkiDebug("%s: called with idtype %s and catype %s\n", +- __FUNCTION__, idtype2string(idtype), catype2string(catype)); + switch (idtype) { + case IDTYPE_FILE: ++ TRACE_PKINIT_LOAD_FROM_FILE(context); + return load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx, + id_cryptoctx, catype, id); + break; + case IDTYPE_DIR: ++ TRACE_PKINIT_LOAD_FROM_DIR(context); + return load_cas_and_crls_dir(context, plg_cryptoctx, req_cryptoctx, + id_cryptoctx, catype, id); + break; +diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c +index a897efa25..737552e85 100644 +--- a/src/plugins/preauth/pkinit/pkinit_identity.c ++++ b/src/plugins/preauth/pkinit/pkinit_identity.c +@@ -608,7 +608,6 @@ pkinit_identity_prompt(krb5_context context, + retval = pkinit_cert_matching(context, plg_cryptoctx, + req_cryptoctx, id_cryptoctx, princ); + if (retval) { +- pkiDebug("%s: No matching certificate found\n", __FUNCTION__); + crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx, + id_cryptoctx); + goto errout; +@@ -621,8 +620,6 @@ pkinit_identity_prompt(krb5_context context, + retval = crypto_cert_select_default(context, plg_cryptoctx, + req_cryptoctx, id_cryptoctx); + if (retval) { +- pkiDebug("%s: Failed while selecting default certificate\n", +- __FUNCTION__); + crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx, + id_cryptoctx); + goto errout; +diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c +index a50c50c8d..cad4c2b9a 100644 +--- a/src/plugins/preauth/pkinit/pkinit_matching.c ++++ b/src/plugins/preauth/pkinit/pkinit_matching.c +@@ -812,6 +812,7 @@ pkinit_cert_matching(krb5_context context, + goto cleanup; + } + } else { ++ TRACE_PKINIT_NO_MATCHING_CERT(context); + retval = ENOENT; /* XXX */ + goto cleanup; + } +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 32ca122f2..9c6e96c9e 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -188,6 +188,7 @@ verify_client_san(krb5_context context, + plgctx->opts->allow_upn ? &upns : NULL, + NULL); + if (retval == ENOENT) { ++ TRACE_PKINIT_SERVER_NO_SAN(context); + goto out; + } else if (retval) { + pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__); +@@ -224,7 +225,7 @@ verify_client_san(krb5_context context, + krb5_free_unparsed_name(context, san_string); + #endif + if (cb->match_client(context, rock, princs[i])) { +- pkiDebug("%s: pkinit san match found\n", __FUNCTION__); ++ TRACE_PKINIT_SERVER_MATCHING_SAN_FOUND(context); + *valid_san = 1; + retval = 0; + goto out; +@@ -252,7 +253,7 @@ verify_client_san(krb5_context context, + krb5_free_unparsed_name(context, san_string); + #endif + if (cb->match_client(context, rock, upns[i])) { +- pkiDebug("%s: upn san match found\n", __FUNCTION__); ++ TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(context); + *valid_san = 1; + retval = 0; + goto out; +@@ -300,7 +301,7 @@ verify_client_eku(krb5_context context, + *eku_accepted = 0; + + if (plgctx->opts->require_eku == 0) { +- pkiDebug("%s: configuration requests no EKU checking\n", __FUNCTION__); ++ TRACE_PKINIT_SERVER_EKU_SKIP(context); + *eku_accepted = 1; + retval = 0; + goto out; +@@ -364,6 +365,7 @@ authorize_cert(krb5_context context, certauth_handle *certauth_modules, + ret = KRB5_PLUGIN_NO_HANDLE; + for (i = 0; certauth_modules != NULL && certauth_modules[i] != NULL; i++) { + h = certauth_modules[i]; ++ TRACE_PKINIT_SERVER_CERT_AUTH(context, h->vt.name); + ret = h->vt.authorize(context, h->moddata, cert, cert_len, client, + &opts, db_ent, &ais); + if (ret == 0) +@@ -449,7 +451,7 @@ pkinit_server_verify_padata(krb5_context context, + + switch ((int)data->pa_type) { + case KRB5_PADATA_PK_AS_REQ: +- pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n"); ++ TRACE_PKINIT_SERVER_PADATA_VERIFY(context); + retval = k5int_decode_krb5_pa_pk_as_req(&k5data, &reqp); + if (retval) { + pkiDebug("decode_krb5_pa_pk_as_req failed\n"); +@@ -472,7 +474,7 @@ pkinit_server_verify_padata(krb5_context context, + break; + case KRB5_PADATA_PK_AS_REP_OLD: + case KRB5_PADATA_PK_AS_REQ_OLD: +- pkiDebug("processing KRB5_PADATA_PK_AS_REQ_OLD\n"); ++ TRACE_PKINIT_SERVER_PADATA_VERIFY_OLD(context); + retval = k5int_decode_krb5_pa_pk_as_req_draft9(&k5data, &reqp9); + if (retval) { + pkiDebug("decode_krb5_pa_pk_as_req_draft9 failed\n"); +@@ -500,7 +502,7 @@ pkinit_server_verify_padata(krb5_context context, + goto cleanup; + } + if (retval) { +- pkiDebug("pkcs7_signeddata_verify failed\n"); ++ TRACE_PKINIT_SERVER_PADATA_VERIFY_FAIL(context); + goto cleanup; + } + if (is_signed) { +@@ -830,7 +832,7 @@ pkinit_server_return_padata(krb5_context context, + return ENOENT; + } + +- pkiDebug("pkinit_return_padata: entered!\n"); ++ TRACE_PKINIT_SERVER_RETURN_PADATA(context); + reqctx = (pkinit_kdc_req_context)modreq; + + if (encrypting_key->contents) { +@@ -1463,8 +1465,7 @@ pkinit_san_authorize(krb5_context context, krb5_certauth_moddata moddata, + return ret; + + if (!valid_san) { +- pkiDebug("%s: did not find an acceptable SAN in user certificate\n", +- __FUNCTION__); ++ TRACE_PKINIT_SERVER_SAN_REJECT(context); + return KRB5KDC_ERR_CLIENT_NAME_MISMATCH; + } + +@@ -1490,8 +1491,7 @@ pkinit_eku_authorize(krb5_context context, krb5_certauth_moddata moddata, + return ret; + + if (!valid_eku) { +- pkiDebug("%s: did not find an acceptable EKU in user certificate\n", +- __FUNCTION__); ++ TRACE_PKINIT_SERVER_EKU_REJECT(context); + return KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE; + } + +@@ -1617,7 +1617,7 @@ pkinit_server_plugin_init(krb5_context context, + return ENOMEM; + + for (i = 0, j = 0; i < numrealms; i++) { +- pkiDebug("%s: processing realm '%s'\n", __FUNCTION__, realmnames[i]); ++ TRACE_PKINIT_SERVER_INIT_REALM(context, realmnames[i]); + retval = pkinit_server_plugin_init_realm(context, realmnames[i], &plgctx); + if (retval == 0 && plgctx != NULL) + realm_contexts[j++] = plgctx; +diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h +index 458d0961e..6abe28c0c 100644 +--- a/src/plugins/preauth/pkinit/pkinit_trace.h ++++ b/src/plugins/preauth/pkinit/pkinit_trace.h +@@ -52,7 +52,7 @@ + #define TRACE_PKINIT_CLIENT_REP_CHECKSUM_FAIL(c, expected, received) \ + TRACE(c, "PKINIT client checksum mismatch: expected {cksum}, " \ + "received {cksum}", expected, received) +-#define TRACE_PKINIT_CLIENT_REP_DH(c) \ ++#define TRACE_PKINIT_CLIENT_REP_DH(c) \ + TRACE(c, "PKINIT client verified DH reply") + #define TRACE_PKINIT_CLIENT_REP_DH_FAIL(c) \ + TRACE(c, "PKINIT client could not verify DH reply") +@@ -91,6 +91,72 @@ + #define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \ + TRACE(c, "PKINIT OpenSSL error: {str}", msg) + ++#define TRACE_PKINIT_SERVER_CERT_AUTH(c, modname) \ ++ TRACE(c, "PKINIT server authorizing cert with module {str}", \ ++ modname) ++#define TRACE_PKINIT_SERVER_EKU_REJECT(c) \ ++ TRACE(c, "PKINIT server found no acceptable EKU in client cert") ++#define TRACE_PKINIT_SERVER_EKU_SKIP(c) \ ++ TRACE(c, "PKINIT server skipping EKU check due to configuration") ++#define TRACE_PKINIT_SERVER_INIT_REALM(c, realm) \ ++ TRACE(c, "PKINIT server initializing realm {str}", realm) ++#define TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(c) \ ++ TRACE(c, "PKINIT server found a matching UPN SAN in client cert") ++#define TRACE_PKINIT_SERVER_MATCHING_SAN_FOUND(c) \ ++ TRACE(c, "PKINIT server found a matching SAN in client cert") ++#define TRACE_PKINIT_SERVER_NO_SAN(c) \ ++ TRACE(c, "PKINIT server found no SAN in client cert") ++#define TRACE_PKINIT_SERVER_PADATA_VERIFY(c) \ ++ TRACE(c, "PKINIT server verifying KRB5_PADATA_PK_AS_REQ") ++#define TRACE_PKINIT_SERVER_PADATA_VERIFY_OLD(c) \ ++ TRACE(c, "PKINIT server verifying KRB5_PADATA_PK_AS_REQ_OLD") ++#define TRACE_PKINIT_SERVER_PADATA_VERIFY_FAIL(c) \ ++ TRACE(c, "PKINIT server failed to verify PA data") ++#define TRACE_PKINIT_SERVER_RETURN_PADATA(c) \ ++ TRACE(c, "PKINIT server returning PA data") ++#define TRACE_PKINIT_SERVER_SAN_REJECT(c) \ ++ TRACE(c, "PKINIT server found no acceptable SAN in client cert") ++ ++#define TRACE_PKINIT_EKU(c) \ ++ TRACE(c, "PKINIT found acceptable EKU and digitalSignature KU") ++#define TRACE_PKINIT_EKU_NO_KU(c) \ ++ TRACE(c, "PKINIT found acceptable EKU but no digitalSignature KU") ++#define TRACE_PKINIT_LOADED_CERT(c, name) \ ++ TRACE(c, "PKINIT loaded cert and key for {str}", name) ++#define TRACE_PKINIT_LOAD_FROM_FILE(c) \ ++ TRACE(c, "PKINIT loading CA certs and CRLs from FILE") ++#define TRACE_PKINIT_LOAD_FROM_DIR(c) \ ++ TRACE(c, "PKINIT loading CA certs and CRLs from DIR") ++#define TRACE_PKINIT_NO_CA_ANCHOR(c, file) \ ++ TRACE(c, "PKINIT no anchor CA in file {str}", file) ++#define TRACE_PKINIT_NO_CA_INTERMEDIATE(c, file) \ ++ TRACE(c, "PKINIT no intermediate CA in file {str}", file) ++#define TRACE_PKINIT_NO_CERT(c) \ ++ TRACE(c, "PKINIT no certificate provided") ++#define TRACE_PKINIT_NO_CERT_AND_KEY(c, dirname) \ ++ TRACE(c, "PKINIT no cert and key pair found in directory {str}", \ ++ dirname) ++#define TRACE_PKINIT_NO_CRL(c, file) \ ++ TRACE(c, "PKINIT no CRL in file {str}", file) ++#define TRACE_PKINIT_NO_DEFAULT_CERT(c, count) \ ++ TRACE(c, "PKINIT error: There are {int} certs, but there must " \ ++ "be exactly one.", count) ++#define TRACE_PKINIT_NO_MATCHING_CERT(c) \ ++ TRACE(c, "PKINIT no matching certificate found") ++#define TRACE_PKINIT_NO_PRIVKEY(c) \ ++ TRACE(c, "PKINIT no private key provided") ++#define TRACE_PKINIT_PKCS_DECODE_FAIL(c, name) \ ++ TRACE(c, "PKINIT failed to decode PKCS12 file {str} contents", name) ++#define TRACE_PKINIT_PKCS_OPEN_FAIL(c, name, err) \ ++ TRACE(c, "PKINIT failed to open PKCS12 file {str}: err {errno}", \ ++ name, err) ++#define TRACE_PKINIT_PKCS_PARSE_FAIL_FIRST(c) \ ++ TRACE(c, "PKINIT initial PKCS12_parse with no password failed") ++#define TRACE_PKINIT_PKCS_PARSE_FAIL_SECOND(c) \ ++ TRACE(c, "PKINIT second PKCS12_parse with password failed") ++#define TRACE_PKINIT_PKCS_PROMPT_FAIL(c) \ ++ TRACE(c, "PKINIT failed to prompt for PKCS12 password") ++ + #define TRACE_CERTAUTH_VTINIT_FAIL(c, ret) \ + TRACE(c, "certauth module failed to init vtable: {kerr}", ret) + #define TRACE_CERTAUTH_INIT_FAIL(c, name, ret) \ diff --git a/SOURCES/Correct-error-handling-bug-in-prior-commit.patch b/SOURCES/Correct-error-handling-bug-in-prior-commit.patch new file mode 100644 index 00000000..5039df14 --- /dev/null +++ b/SOURCES/Correct-error-handling-bug-in-prior-commit.patch @@ -0,0 +1,32 @@ +From ca3e61600f1400974c63b2abb30b44f0c94d550b Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 23 Mar 2017 13:42:55 -0400 +Subject: [PATCH] Correct error handling bug in prior commit + +In crypto_encode_der_cert(), if the second i2d_X509() invocation +fails, make sure to free the allocated pointer and not the +possibly-modified alias. + +ticket: 8561 +(cherry picked from commit 7fdaef7c3280c86b5df25ae061fb04cc56d8620c) +--- + src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index a5b010b26..90c30dbf5 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -6196,10 +6196,10 @@ crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx, + if (len <= 0) + return EINVAL; + p = der = malloc(len); +- if (p == NULL) ++ if (der == NULL) + return ENOMEM; + if (i2d_X509(reqctx->received_cert, &p) <= 0) { +- free(p); ++ free(der); + return EINVAL; + } + *der_out = der; diff --git a/SOURCES/Deindent-crypto_retrieve_X509_sans.patch b/SOURCES/Deindent-crypto_retrieve_X509_sans.patch new file mode 100644 index 00000000..f4086c25 --- /dev/null +++ b/SOURCES/Deindent-crypto_retrieve_X509_sans.patch @@ -0,0 +1,264 @@ +From 54c5bec8deb2d4e972795e37273ad17a0b1e2f4f Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 4 Jan 2017 11:33:57 -0500 +Subject: [PATCH] Deindent crypto_retrieve_X509_sans() + +Fix some long lines in crypto_retrieve_X509_sans() by returning early +if X509_get_ext_by_NID() returns a negative result. Also ensure that +return parameters are always initialized. + +(cherry picked from commit c6b772523db9d7791ee1c56eb512c4626556a4e7) +(cherry picked from commit 23086ac768a32db1e40a9b63684dbcfd76aba033) +--- + src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 224 +++++++++++---------- + 1 file changed, 114 insertions(+), 110 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index bc6e7662e..8def8c542 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2101,11 +2101,21 @@ crypto_retrieve_X509_sans(krb5_context context, + { + krb5_error_code retval = EINVAL; + char buf[DN_BUF_LEN]; +- int p = 0, u = 0, d = 0, l; ++ int p = 0, u = 0, d = 0, ret = 0, l; + krb5_principal *princs = NULL; + krb5_principal *upns = NULL; + unsigned char **dnss = NULL; +- unsigned int i, num_found = 0; ++ unsigned int i, num_found = 0, num_sans = 0; ++ X509_EXTENSION *ext = NULL; ++ GENERAL_NAMES *ialt = NULL; ++ GENERAL_NAME *gen = NULL; ++ ++ if (princs_ret != NULL) ++ *princs_ret = NULL; ++ if (upn_ret != NULL) ++ *upn_ret = NULL; ++ if (dns_ret != NULL) ++ *dns_ret = NULL; + + if (princs_ret == NULL && upn_ret == NULL && dns_ret == NULL) { + pkiDebug("%s: nowhere to return any values!\n", __FUNCTION__); +@@ -2121,118 +2131,112 @@ crypto_retrieve_X509_sans(krb5_context context, + buf, sizeof(buf)); + pkiDebug("%s: looking for SANs in cert = %s\n", __FUNCTION__, buf); + +- if ((l = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0) { +- X509_EXTENSION *ext = NULL; +- GENERAL_NAMES *ialt = NULL; +- GENERAL_NAME *gen = NULL; +- int ret = 0; +- unsigned int num_sans = 0; ++ l = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); ++ if (l < 0) ++ return 0; + +- if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) { +- pkiDebug("%s: found no subject alt name extensions\n", +- __FUNCTION__); ++ if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) { ++ pkiDebug("%s: found no subject alt name extensions\n", __FUNCTION__); ++ goto cleanup; ++ } ++ num_sans = sk_GENERAL_NAME_num(ialt); ++ ++ pkiDebug("%s: found %d subject alt name extension(s)\n", __FUNCTION__, ++ num_sans); ++ ++ /* OK, we're likely returning something. Allocate return values */ ++ if (princs_ret != NULL) { ++ princs = calloc(num_sans + 1, sizeof(krb5_principal)); ++ if (princs == NULL) { ++ retval = ENOMEM; + goto cleanup; + } +- num_sans = sk_GENERAL_NAME_num(ialt); +- +- pkiDebug("%s: found %d subject alt name extension(s)\n", +- __FUNCTION__, num_sans); +- +- /* OK, we're likely returning something. Allocate return values */ +- if (princs_ret != NULL) { +- princs = calloc(num_sans + 1, sizeof(krb5_principal)); +- if (princs == NULL) { +- retval = ENOMEM; +- goto cleanup; +- } +- } +- if (upn_ret != NULL) { +- upns = calloc(num_sans + 1, sizeof(krb5_principal)); +- if (upns == NULL) { +- retval = ENOMEM; +- goto cleanup; +- } +- } +- if (dns_ret != NULL) { +- dnss = calloc(num_sans + 1, sizeof(*dnss)); +- if (dnss == NULL) { +- retval = ENOMEM; +- goto cleanup; +- } +- } +- +- for (i = 0; i < num_sans; i++) { +- krb5_data name = { 0, 0, NULL }; +- +- gen = sk_GENERAL_NAME_value(ialt, i); +- switch (gen->type) { +- case GEN_OTHERNAME: +- name.length = gen->d.otherName->value->value.sequence->length; +- name.data = (char *)gen->d.otherName->value->value.sequence->data; +- if (princs != NULL +- && OBJ_cmp(plgctx->id_pkinit_san, +- gen->d.otherName->type_id) == 0) { +-#ifdef DEBUG_ASN1 +- print_buffer_bin((unsigned char *)name.data, name.length, +- "/tmp/pkinit_san"); +-#endif +- ret = k5int_decode_krb5_principal_name(&name, &princs[p]); +- if (ret) { +- pkiDebug("%s: failed decoding pkinit san value\n", +- __FUNCTION__); +- } else { +- p++; +- num_found++; +- } +- } else if (upns != NULL +- && OBJ_cmp(plgctx->id_ms_san_upn, +- gen->d.otherName->type_id) == 0) { +- /* Prevent abuse of embedded null characters. */ +- if (memchr(name.data, '\0', name.length)) +- break; +- ret = krb5_parse_name_flags(context, name.data, +- KRB5_PRINCIPAL_PARSE_ENTERPRISE, +- &upns[u]); +- if (ret) { +- pkiDebug("%s: failed parsing ms-upn san value\n", +- __FUNCTION__); +- } else { +- u++; +- num_found++; +- } +- } else { +- pkiDebug("%s: unrecognized othername oid in SAN\n", +- __FUNCTION__); +- continue; +- } +- +- break; +- case GEN_DNS: +- if (dnss != NULL) { +- /* Prevent abuse of embedded null characters. */ +- if (memchr(gen->d.dNSName->data, '\0', +- gen->d.dNSName->length)) +- break; +- pkiDebug("%s: found dns name = %s\n", +- __FUNCTION__, gen->d.dNSName->data); +- dnss[d] = (unsigned char *) +- strdup((char *)gen->d.dNSName->data); +- if (dnss[d] == NULL) { +- pkiDebug("%s: failed to duplicate dns name\n", +- __FUNCTION__); +- } else { +- d++; +- num_found++; +- } +- } +- break; +- default: +- pkiDebug("%s: SAN type = %d expecting %d\n", +- __FUNCTION__, gen->type, GEN_OTHERNAME); +- } +- } +- sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); + } ++ if (upn_ret != NULL) { ++ upns = calloc(num_sans + 1, sizeof(krb5_principal)); ++ if (upns == NULL) { ++ retval = ENOMEM; ++ goto cleanup; ++ } ++ } ++ if (dns_ret != NULL) { ++ dnss = calloc(num_sans + 1, sizeof(*dnss)); ++ if (dnss == NULL) { ++ retval = ENOMEM; ++ goto cleanup; ++ } ++ } ++ ++ for (i = 0; i < num_sans; i++) { ++ krb5_data name = { 0, 0, NULL }; ++ ++ gen = sk_GENERAL_NAME_value(ialt, i); ++ switch (gen->type) { ++ case GEN_OTHERNAME: ++ name.length = gen->d.otherName->value->value.sequence->length; ++ name.data = (char *)gen->d.otherName->value->value.sequence->data; ++ if (princs != NULL && ++ OBJ_cmp(plgctx->id_pkinit_san, ++ gen->d.otherName->type_id) == 0) { ++#ifdef DEBUG_ASN1 ++ print_buffer_bin((unsigned char *)name.data, name.length, ++ "/tmp/pkinit_san"); ++#endif ++ ret = k5int_decode_krb5_principal_name(&name, &princs[p]); ++ if (ret) { ++ pkiDebug("%s: failed decoding pkinit san value\n", ++ __FUNCTION__); ++ } else { ++ p++; ++ num_found++; ++ } ++ } else if (upns != NULL && ++ OBJ_cmp(plgctx->id_ms_san_upn, ++ gen->d.otherName->type_id) == 0) { ++ /* Prevent abuse of embedded null characters. */ ++ if (memchr(name.data, '\0', name.length)) ++ break; ++ ret = krb5_parse_name_flags(context, name.data, ++ KRB5_PRINCIPAL_PARSE_ENTERPRISE, ++ &upns[u]); ++ if (ret) { ++ pkiDebug("%s: failed parsing ms-upn san value\n", ++ __FUNCTION__); ++ } else { ++ u++; ++ num_found++; ++ } ++ } else { ++ pkiDebug("%s: unrecognized othername oid in SAN\n", ++ __FUNCTION__); ++ continue; ++ } ++ ++ break; ++ case GEN_DNS: ++ if (dnss != NULL) { ++ /* Prevent abuse of embedded null characters. */ ++ if (memchr(gen->d.dNSName->data, '\0', gen->d.dNSName->length)) ++ break; ++ pkiDebug("%s: found dns name = %s\n", __FUNCTION__, ++ gen->d.dNSName->data); ++ dnss[d] = (unsigned char *) ++ strdup((char *)gen->d.dNSName->data); ++ if (dnss[d] == NULL) { ++ pkiDebug("%s: failed to duplicate dns name\n", ++ __FUNCTION__); ++ } else { ++ d++; ++ num_found++; ++ } ++ } ++ break; ++ default: ++ pkiDebug("%s: SAN type = %d expecting %d\n", __FUNCTION__, ++ gen->type, GEN_OTHERNAME); ++ } ++ } ++ sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); + + retval = 0; + if (princs) diff --git a/SOURCES/Expose-context-errors-in-pkinit_server_plugin_init.patch b/SOURCES/Expose-context-errors-in-pkinit_server_plugin_init.patch new file mode 100644 index 00000000..ecfe9fe7 --- /dev/null +++ b/SOURCES/Expose-context-errors-in-pkinit_server_plugin_init.patch @@ -0,0 +1,73 @@ +From 9c0a06f38189d255575acdae5efb22b76b4c33b3 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 13 Nov 2017 13:32:37 -0500 +Subject: [PATCH] Expose context errors in pkinit_server_plugin_init + +Commit 3ff426b9048a8024e5c175256c63cd0ad0572320 attempted to display +an error when OCSP support was requested, but this error message was +suppressed in pkinit_server_plugin_init(). Add a trace log for each +realm initialization error, and pass through the realm initialization +error when the KDC serves only one realm. Other error messages from +pkinit_init_kdc_profile(), such as missing pkinit_identity or +pkinit_anchors, are also now exposted. + +[ghudson@mit.edu: clarified commit message] + +ticket: 8621 (new) +target_version: 1.16 +tags: pullup + +(cherry picked from commit 225aab3540c13c6289b22022d5e110f6fc26151d) +--- + src/plugins/preauth/pkinit/pkinit_srv.c | 19 +++++++++++++------ + src/plugins/preauth/pkinit/pkinit_trace.h | 3 +++ + 2 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 8e77606f8..143d331a2 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -1622,16 +1622,23 @@ pkinit_server_plugin_init(krb5_context context, + + for (i = 0, j = 0; i < numrealms; i++) { + TRACE_PKINIT_SERVER_INIT_REALM(context, realmnames[i]); +- retval = pkinit_server_plugin_init_realm(context, realmnames[i], &plgctx); +- if (retval == 0 && plgctx != NULL) ++ krb5_clear_error_message(context); ++ retval = pkinit_server_plugin_init_realm(context, realmnames[i], ++ &plgctx); ++ if (retval) ++ TRACE_PKINIT_SERVER_INIT_FAIL(context, realmnames[i], retval); ++ else + realm_contexts[j++] = plgctx; + } + + if (j == 0) { +- retval = EINVAL; +- krb5_set_error_message(context, retval, +- _("No realms configured correctly for pkinit " +- "support")); ++ if (numrealms == 1) { ++ k5_prependmsg(context, retval, "PKINIT initialization failed"); ++ } else { ++ retval = EINVAL; ++ k5_setmsg(context, retval, ++ _("No realms configured correctly for pkinit support")); ++ } + goto errout; + } + +diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h +index 6abe28c0c..8d489469f 100644 +--- a/src/plugins/preauth/pkinit/pkinit_trace.h ++++ b/src/plugins/preauth/pkinit/pkinit_trace.h +@@ -100,6 +100,9 @@ + TRACE(c, "PKINIT server skipping EKU check due to configuration") + #define TRACE_PKINIT_SERVER_INIT_REALM(c, realm) \ + TRACE(c, "PKINIT server initializing realm {str}", realm) ++#define TRACE_PKINIT_SERVER_INIT_FAIL(c, realm, retval) \ ++ TRACE(c, "PKINIT server initialization failed for realm {str}: {kerr}", \ ++ realm, retval) + #define TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(c) \ + TRACE(c, "PKINIT server found a matching UPN SAN in client cert") + #define TRACE_PKINIT_SERVER_MATCHING_SAN_FOUND(c) \ diff --git a/SOURCES/Fix-bugs-in-kdcpolicy-commit.patch b/SOURCES/Fix-bugs-in-kdcpolicy-commit.patch new file mode 100644 index 00000000..418aa24d --- /dev/null +++ b/SOURCES/Fix-bugs-in-kdcpolicy-commit.patch @@ -0,0 +1,130 @@ +From d59b00fd1fdcc473739f3033c0f67eb402f20d9c Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 19 Aug 2017 19:09:24 -0400 +Subject: [PATCH] Fix bugs in kdcpolicy commit + +Commit d0969f6a8170344031ef58fd2a161190f1edfb96 added tests using +"klist ccachname -e", which does not work with a POSIX-conformant +getopt() implementation such as the one in Solaris. Fix +t_kdcpolicy.py to use "klist -e ccachename" instead. + +The tests could fail if the clock second rolled over between kinit and +kvno. Divide service ticket maximum lifetimes by 2 in the test module +to correctly exercise TGS policy restrictions and ensure that service +tickets are not constrained by the TGT end time. + +Also use the correct trace macro when a kdcpolicy module declines to +initialize (my mistake when revising the commit, noted by rharwood). + +ticket: 8606 +(cherry picked from commit 09acbd91efc6df54e1572285ffc94c6acb3a9113) +--- + src/kdc/policy.c | 2 +- + src/plugins/kdcpolicy/test/main.c | 10 +++++----- + src/tests/t_kdcpolicy.py | 13 +++++++++---- + 3 files changed, 15 insertions(+), 10 deletions(-) + +diff --git a/src/kdc/policy.c b/src/kdc/policy.c +index e49644e06..26c16f97c 100644 +--- a/src/kdc/policy.c ++++ b/src/kdc/policy.c +@@ -222,7 +222,7 @@ load_kdcpolicy_plugins(krb5_context context) + if (h->vt.init != NULL) { + ret = h->vt.init(context, &h->moddata); + if (ret == KRB5_PLUGIN_NO_HANDLE) { +- TRACE_KADM5_AUTH_INIT_SKIP(context, h->vt.name); ++ TRACE_KDCPOLICY_INIT_SKIP(context, h->vt.name); + free(h); + continue; + } +diff --git a/src/plugins/kdcpolicy/test/main.c b/src/plugins/kdcpolicy/test/main.c +index eb8fde053..86c808958 100644 +--- a/src/plugins/kdcpolicy/test/main.c ++++ b/src/plugins/kdcpolicy/test/main.c +@@ -35,7 +35,7 @@ + #include + + static krb5_error_code +-output_from_indicator(const char *const *auth_indicators, ++output_from_indicator(const char *const *auth_indicators, int divisor, + krb5_deltat *lifetime_out, + krb5_deltat *renew_lifetime_out, + const char **status) +@@ -46,11 +46,11 @@ output_from_indicator(const char *const *auth_indicators, + } + + if (strcmp(auth_indicators[0], "ONE_HOUR") == 0) { +- *lifetime_out = 3600; ++ *lifetime_out = 3600 / divisor; + *renew_lifetime_out = *lifetime_out * 2; + return 0; + } else if (strcmp(auth_indicators[0], "SEVEN_HOURS") == 0) { +- *lifetime_out = 7 * 3600; ++ *lifetime_out = 7 * 3600 / divisor; + *renew_lifetime_out = *lifetime_out * 2; + return 0; + } +@@ -71,7 +71,7 @@ test_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata, + *status = "LOCAL_POLICY"; + return KRB5KDC_ERR_POLICY; + } +- return output_from_indicator(auth_indicators, lifetime_out, ++ return output_from_indicator(auth_indicators, 1, lifetime_out, + renew_lifetime_out, status); + } + +@@ -87,7 +87,7 @@ test_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata, + *status = "LOCAL_POLICY"; + return KRB5KDC_ERR_POLICY; + } +- return output_from_indicator(auth_indicators, lifetime_out, ++ return output_from_indicator(auth_indicators, 2, lifetime_out, + renew_lifetime_out, status); + } + +diff --git a/src/tests/t_kdcpolicy.py b/src/tests/t_kdcpolicy.py +index 6a745b959..b5d308461 100644 +--- a/src/tests/t_kdcpolicy.py ++++ b/src/tests/t_kdcpolicy.py +@@ -18,16 +18,21 @@ realm.run([kadminl, 'addprinc', '-pw', password('fail'), 'fail']) + def verify_time(out, target_time): + times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out) + times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times] ++ divisor = 1 + while len(times) > 0: + starttime = times.pop(0) + endtime = times.pop(0) + renewtime = times.pop(0) + +- if str(endtime - starttime) != target_time: ++ if str((endtime - starttime) * divisor) != target_time: + fail('unexpected lifetime value') +- if str(renewtime - endtime) != target_time: ++ if str((renewtime - endtime) * divisor) != target_time: + fail('unexpected renewable value') + ++ # Service tickets should have half the lifetime of initial ++ # tickets. ++ divisor = 2 ++ + rflags = ['-r', '1d', '-l', '12h'] + + # Test AS+TGS success path. +@@ -35,7 +40,7 @@ realm.kinit(realm.user_princ, password('user'), + rflags + ['-X', 'indicators=SEVEN_HOURS']) + realm.run([kvno, realm.host_princ]) + realm.run(['./adata', realm.host_princ], expected_msg='+97: [SEVEN_HOURS]') +-out = realm.run([klist, realm.ccache, '-e']) ++out = realm.run([klist, '-e', realm.ccache]) + verify_time(out, '7:00:00') + + # Test AS+TGS success path with different values. +@@ -43,7 +48,7 @@ realm.kinit(realm.user_princ, password('user'), + rflags + ['-X', 'indicators=ONE_HOUR']) + realm.run([kvno, realm.host_princ]) + realm.run(['./adata', realm.host_princ], expected_msg='+97: [ONE_HOUR]') +-out = realm.run([klist, realm.ccache, '-e']) ++out = realm.run([klist, '-e', realm.ccache]) + verify_time(out, '1:00:00') + + # Test TGS failure path (using previous creds). diff --git a/SOURCES/Fix-certauth-built-in-module-returns.patch b/SOURCES/Fix-certauth-built-in-module-returns.patch new file mode 100644 index 00000000..209775ed --- /dev/null +++ b/SOURCES/Fix-certauth-built-in-module-returns.patch @@ -0,0 +1,124 @@ +From 41b9111b48e53bf7864ed1f134e0433b070fa900 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 24 Aug 2017 11:11:46 -0400 +Subject: [PATCH] Fix certauth built-in module returns + +The PKINIT certauth eku module should never authoritatively authorize +a certificate, because an extended key usage does not establish a +relationship between the certificate and any specific user; it only +establishes that the certificate was created for PKINIT client +authentication. Therefore, pkinit_eku_authorize() should return +KRB5_PLUGIN_NO_HANDLE on success, not 0. + +The certauth san module should pass if it does not find any SANs of +the types it can match against; the presence of other types of SANs +should not cause it to explicitly deny a certificate. Check for an +empty result from crypto_retrieve_cert_sans() in verify_client_san(), +instead of returning ENOENT from crypto_retrieve_cert_sans() when +there are no SANs at all. + +ticket: 8561 +(cherry picked from commit 07243f85a760fb37f0622d7ff0177db3f19ab025) +--- + src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 39 ++++++++++------------ + src/plugins/preauth/pkinit/pkinit_srv.c | 14 +++++--- + 2 files changed, 27 insertions(+), 26 deletions(-) + +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 70e230ec2..7fa2efd21 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2137,7 +2137,6 @@ crypto_retrieve_X509_sans(krb5_context context, + + if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) { + pkiDebug("%s: found no subject alt name extensions\n", __FUNCTION__); +- retval = ENOENT; + goto cleanup; + } + num_sans = sk_GENERAL_NAME_num(ialt); +@@ -2240,31 +2239,29 @@ crypto_retrieve_X509_sans(krb5_context context, + sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free); + + retval = 0; +- if (princs) ++ if (princs != NULL && *princs != NULL) { + *princs_ret = princs; +- if (upns) ++ princs = NULL; ++ } ++ if (upns != NULL && *upns != NULL) { + *upn_ret = upns; +- if (dnss) ++ upns = NULL; ++ } ++ if (dnss != NULL && *dnss != NULL) { + *dns_ret = dnss; ++ dnss = NULL; ++ } + + cleanup: +- if (retval) { +- if (princs != NULL) { +- for (i = 0; princs[i] != NULL; i++) +- krb5_free_principal(context, princs[i]); +- free(princs); +- } +- if (upns != NULL) { +- for (i = 0; upns[i] != NULL; i++) +- krb5_free_principal(context, upns[i]); +- free(upns); +- } +- if (dnss != NULL) { +- for (i = 0; dnss[i] != NULL; i++) +- free(dnss[i]); +- free(dnss); +- } +- } ++ for (i = 0; princs != NULL && princs[i] != NULL; i++) ++ krb5_free_principal(context, princs[i]); ++ free(princs); ++ for (i = 0; upns != NULL && upns[i] != NULL; i++) ++ krb5_free_principal(context, upns[i]); ++ free(upns); ++ for (i = 0; dnss != NULL && dnss[i] != NULL; i++) ++ free(dnss[i]); ++ free(dnss); + return retval; + } + +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 9c6e96c9e..8e77606f8 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -187,14 +187,18 @@ verify_client_san(krb5_context context, + &princs, + plgctx->opts->allow_upn ? &upns : NULL, + NULL); +- if (retval == ENOENT) { +- TRACE_PKINIT_SERVER_NO_SAN(context); +- goto out; +- } else if (retval) { ++ if (retval) { + pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__); + retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH; + goto out; + } ++ ++ if (princs == NULL && upns == NULL) { ++ TRACE_PKINIT_SERVER_NO_SAN(context); ++ retval = ENOENT; ++ goto out; ++ } ++ + /* XXX Verify this is consistent with client side XXX */ + #if 0 + retval = call_san_checking_plugins(context, plgctx, reqctx, princs, +@@ -1495,7 +1499,7 @@ pkinit_eku_authorize(krb5_context context, krb5_certauth_moddata moddata, + return KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE; + } + +- return 0; ++ return KRB5_PLUGIN_NO_HANDLE; + } + + static krb5_error_code diff --git a/SOURCES/Fix-in_clock_skew-and-use-it-in-AS-client-code.patch b/SOURCES/Fix-in_clock_skew-and-use-it-in-AS-client-code.patch new file mode 100644 index 00000000..7e9e2d39 --- /dev/null +++ b/SOURCES/Fix-in_clock_skew-and-use-it-in-AS-client-code.patch @@ -0,0 +1,58 @@ +From 7e914206a676fb8f972c8021e97fab86a155488b Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Mon, 24 Apr 2017 02:02:36 -0400 +Subject: [PATCH] Fix in_clock_skew() and use it in AS client code + +Add a context parameter to the in_clock_skew() macro so that it isn't +implicitly relying on a local variable. Use it in +get_in_tkt.c:verify_as_reply(). + +(cherry picked from commit 28a07a6461bb443b7fa75cc5cb859ad0db4cbb5a) +--- + src/lib/krb5/krb/gc_via_tkt.c | 2 +- + src/lib/krb5/krb/get_in_tkt.c | 4 ++-- + src/lib/krb5/krb/int-proto.h | 3 ++- + 3 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c +index 4c0a1a461..c85d8b8d8 100644 +--- a/src/lib/krb5/krb/gc_via_tkt.c ++++ b/src/lib/krb5/krb/gc_via_tkt.c +@@ -305,7 +305,7 @@ krb5int_process_tgs_reply(krb5_context context, + goto cleanup; + + if (!in_cred->times.starttime && +- !in_clock_skew(dec_rep->enc_part2->times.starttime, ++ !in_clock_skew(context, dec_rep->enc_part2->times.starttime, + timestamp)) { + retval = KRB5_KDCREP_SKEW; + goto cleanup; +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 54badbbc3..a058f5bd7 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -287,8 +287,8 @@ verify_as_reply(krb5_context context, + return retval; + } else { + if ((request->from == 0) && +- (labs(as_reply->enc_part2->times.starttime - time_now) +- > context->clockskew)) ++ !in_clock_skew(context, as_reply->enc_part2->times.starttime, ++ time_now)) + return (KRB5_KDCREP_SKEW); + } + return 0; +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index 6da74858e..44eca359f 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -83,7 +83,8 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options, + krb5_creds *in_creds, krb5_creds *mcreds, + krb5_flags *fields); + +-#define in_clock_skew(date, now) (labs((date)-(now)) < context->clockskew) ++#define in_clock_skew(context, date, now) \ ++ (labs((date) - (now)) < (context)->clockskew) + + #define IS_TGS_PRINC(p) ((p)->length == 2 && \ + data_eq_string((p)->data[0], KRB5_TGS_NAME)) diff --git a/SOURCES/Fix-make-certs.sh-for-OpenSSL-1.1.patch b/SOURCES/Fix-make-certs.sh-for-OpenSSL-1.1.patch new file mode 100644 index 00000000..ba6b0efb --- /dev/null +++ b/SOURCES/Fix-make-certs.sh-for-OpenSSL-1.1.patch @@ -0,0 +1,70 @@ +From 7221a9f695016d3e4873bb799f06665ec74387f8 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 6 Sep 2017 12:56:37 -0400 +Subject: [PATCH] Fix make-certs.sh for OpenSSL 1.1 + +The openssl req commands in make-certs.sh contain -subj options which +were ignored in favor of the config file prior to OpenSSL 1.1. When +they are used, they remove elements of the subject which are now +required by t_pkinit.py. + +(cherry picked from commit b0473da67d72e43b9f03b703869069348e872efc) +[rharwood@redhat.com: remove newer sections in make-certs.sh] +--- + src/tests/dejagnu/pkinit-certs/make-certs.sh | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh +index 0f07709b0..0d8c2019a 100755 +--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh ++++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh +@@ -122,15 +122,14 @@ SUBJECT=ca openssl req -config openssl.cnf -new -x509 -extensions exts_ca \ + -set_serial 1 -days $DAYS -key privkey.pem -out ca.pem + + # Generate a KDC certificate. +-SUBJECT=kdc openssl req -config openssl.cnf -new -subj /CN=kdc \ +- -key privkey.pem -out kdc.csr ++SUBJECT=kdc openssl req -config openssl.cnf -new -key privkey.pem -out kdc.csr + SUBJECT=kdc openssl x509 -extfile openssl.cnf -extensions exts_kdc \ + -set_serial 2 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out kdc.pem -in kdc.csr + + # Generate a client certificate and PKCS#12 bundles. +-SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ +- -key privkey.pem -out user.csr ++SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ ++ -out user.csr + SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_client \ + -set_serial 3 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out user.pem -in user.csr +@@ -140,24 +139,24 @@ openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user-enc.p12 \ + -passout pass:encrypted + + # Generate a client certificate and PKCS#12 bundles with a UPN SAN. +-SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ +- -key privkey.pem -out user-upn.csr ++SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ ++ -out user-upn.csr + SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn_client \ + -set_serial 4 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out user-upn.pem -in user-upn.csr + openssl pkcs12 -export -in user-upn.pem -inkey privkey.pem -out user-upn.p12 \ + -passout pass: + +-SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ +- -key privkey.pem -out user-upn2.csr ++SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ ++ -out user-upn2.csr + SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn2_client \ + -set_serial 5 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out user-upn2.pem -in user-upn2.csr + openssl pkcs12 -export -in user-upn2.pem -inkey privkey.pem \ + -out user-upn2.p12 -passout pass: + +-SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ +- -key privkey.pem -out user-upn3.csr ++SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ ++ -out user-upn3.csr + SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn3_client \ + -set_serial 6 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ + -out user-upn3.pem -in user-upn3.csr diff --git a/SOURCES/Fix-more-time-manipulations-for-y2038.patch b/SOURCES/Fix-more-time-manipulations-for-y2038.patch new file mode 100644 index 00000000..ed6bcad7 --- /dev/null +++ b/SOURCES/Fix-more-time-manipulations-for-y2038.patch @@ -0,0 +1,83 @@ +From 006c68f6ed266d5ea7a24512349a931f45160cc6 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 17 May 2017 14:52:09 -0400 +Subject: [PATCH] Fix more time manipulations for y2038 + +Use timestamp helper functions to ensure that more operations are safe +after y2038, and display the current timestamp as unsigned in +krb5int_trace(). + +ticket: 8352 +(cherry picked from commit a60db180211a383bd382afe729e9309acb8dcf53) +--- + src/kadmin/server/misc.c | 2 +- + src/kdc/dispatch.c | 2 +- + src/lib/krb5/os/c_ustime.c | 8 ++++---- + src/lib/krb5/os/trace.c | 2 +- + 4 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/kadmin/server/misc.c b/src/kadmin/server/misc.c +index 27a6376af..a75b65a26 100644 +--- a/src/kadmin/server/misc.c ++++ b/src/kadmin/server/misc.c +@@ -184,7 +184,7 @@ check_min_life(void *server_handle, krb5_principal principal, + (void) kadm5_free_principal_ent(handle->lhandle, &princ); + return (ret == KADM5_UNK_POLICY) ? 0 : ret; + } +- if((now - princ.last_pwd_change) < pol.pw_min_life && ++ if(ts_delta(now, princ.last_pwd_change) < pol.pw_min_life && + !(princ.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) { + if (msg_ret != NULL) { + time_t until; +diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c +index 3a169ebc7..16a35d2be 100644 +--- a/src/kdc/dispatch.c ++++ b/src/kdc/dispatch.c +@@ -104,7 +104,7 @@ reseed_random(krb5_context kdc_err_context) + if (last_os_random == 0) + last_os_random = now; + /* Grab random data from OS every hour*/ +- if (now-last_os_random >= 60 * 60) { ++ if (ts_delta(now, last_os_random) >= 60 * 60) { + krb5_c_random_os_entropy(kdc_err_context, 0, NULL); + last_os_random = now; + } +diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c +index 871d72183..68fb381f4 100644 +--- a/src/lib/krb5/os/c_ustime.c ++++ b/src/lib/krb5/os/c_ustime.c +@@ -102,17 +102,17 @@ krb5_crypto_us_timeofday(krb5_int32 *seconds, krb5_int32 *microseconds) + putting now.sec in the past. But don't just use '<' because we + need to properly handle the case where the administrator intentionally + adjusted time backwards. */ +- if ((now.sec == last_time.sec-1) || +- ((now.sec == last_time.sec) && (now.usec <= last_time.usec))) { ++ if (now.sec == ts_incr(last_time.sec, -1) || ++ (now.sec == last_time.sec && !ts_after(last_time.usec, now.usec))) { + /* Correct 'now' to be exactly one microsecond later than 'last_time'. + Note that _because_ we perform this hack, 'now' may be _earlier_ + than 'last_time', even though the system time is monotonically + increasing. */ + + now.sec = last_time.sec; +- now.usec = ++last_time.usec; ++ now.usec = ts_incr(last_time.usec, 1); + if (now.usec >= 1000000) { +- ++now.sec; ++ now.sec = ts_incr(now.sec, 1); + now.usec = 0; + } + } +diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c +index a19246128..74c315c90 100644 +--- a/src/lib/krb5/os/trace.c ++++ b/src/lib/krb5/os/trace.c +@@ -350,7 +350,7 @@ krb5int_trace(krb5_context context, const char *fmt, ...) + goto cleanup; + if (krb5_crypto_us_timeofday(&sec, &usec) != 0) + goto cleanup; +- if (asprintf(&msg, "[%d] %d.%d: %s\n", (int) getpid(), (int) sec, ++ if (asprintf(&msg, "[%d] %u.%d: %s\n", (int) getpid(), (unsigned int) sec, + (int) usec, str) < 0) + goto cleanup; + info.message = msg; diff --git a/SOURCES/Improve-PKINIT-UPN-SAN-matching.patch b/SOURCES/Improve-PKINIT-UPN-SAN-matching.patch new file mode 100644 index 00000000..dd0eb587 --- /dev/null +++ b/SOURCES/Improve-PKINIT-UPN-SAN-matching.patch @@ -0,0 +1,151 @@ +From 802cf0263965eef725208f00eccb62df0b082319 Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Mon, 5 Dec 2016 12:17:59 -0500 +Subject: [PATCH] Improve PKINIT UPN SAN matching + +Add the match_client() kdcpreauth callback and use it in +verify_client_san(). match_client() preserves the direct UPN to +request principal comparison and adds a direct comparison to the +client principal, falling back to an alias DB search and comparison +against the client principal. Change crypto_retreive_X509_sans() to +parse UPN values as enterprise principals. + +[ghudson@mit.edu: use match_client for both kinds of SANs] + +ticket: 8528 (new) +(cherry picked from commit 46ff765e1fb8cbec2bb602b43311269e695dbedc) +--- + src/include/krb5/kdcpreauth_plugin.h | 13 ++++++++++ + src/kdc/kdc_preauth.c | 28 ++++++++++++++++++++-- + src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 4 +++- + src/plugins/preauth/pkinit/pkinit_srv.c | 10 ++++---- + 4 files changed, 48 insertions(+), 7 deletions(-) + +diff --git a/src/include/krb5/kdcpreauth_plugin.h b/src/include/krb5/kdcpreauth_plugin.h +index f455effae..92aa5a5a5 100644 +--- a/src/include/krb5/kdcpreauth_plugin.h ++++ b/src/include/krb5/kdcpreauth_plugin.h +@@ -221,6 +221,19 @@ typedef struct krb5_kdcpreauth_callbacks_st { + + /* End of version 3 kdcpreauth callbacks. */ + ++ /* ++ * Return true if princ matches the principal named in the request or the ++ * client principal (possibly canonicalized). If princ does not match, ++ * attempt a database lookup of princ with aliases allowed and compare the ++ * result to the client principal, returning true if it matches. ++ * Otherwise, return false. ++ */ ++ krb5_boolean (*match_client)(krb5_context context, ++ krb5_kdcpreauth_rock rock, ++ krb5_principal princ); ++ ++ /* End of version 4 kdcpreauth callbacks. */ ++ + } *krb5_kdcpreauth_callbacks; + + /* Optional: preauth plugin initialization function. */ +diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c +index 605fcb7ad..0ce79c667 100644 +--- a/src/kdc/kdc_preauth.c ++++ b/src/kdc/kdc_preauth.c +@@ -568,8 +568,31 @@ set_cookie(krb5_context context, krb5_kdcpreauth_rock rock, + return kdc_fast_set_cookie(rock->rstate, pa_type, data); + } + ++static krb5_boolean ++match_client(krb5_context context, krb5_kdcpreauth_rock rock, ++ krb5_principal princ) ++{ ++ krb5_db_entry *ent; ++ krb5_boolean match = FALSE; ++ krb5_principal req_client = rock->request->client; ++ krb5_principal client = rock->client->princ; ++ ++ /* Check for a direct match against the request principal or ++ * the post-canon client principal. */ ++ if (krb5_principal_compare_flags(context, princ, req_client, ++ KRB5_PRINCIPAL_COMPARE_ENTERPRISE) || ++ krb5_principal_compare(context, princ, client)) ++ return TRUE; ++ ++ if (krb5_db_get_principal(context, princ, KRB5_KDB_FLAG_ALIAS_OK, &ent)) ++ return FALSE; ++ match = krb5_principal_compare(context, ent->princ, client); ++ krb5_db_free_principal(context, ent); ++ return match; ++} ++ + static struct krb5_kdcpreauth_callbacks_st callbacks = { +- 3, ++ 4, + max_time_skew, + client_keys, + free_keys, +@@ -583,7 +606,8 @@ static struct krb5_kdcpreauth_callbacks_st callbacks = { + client_keyblock, + add_auth_indicator, + get_cookie, +- set_cookie ++ set_cookie, ++ match_client + }; + + static krb5_error_code +diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +index 74fffbf32..bc6e7662e 100644 +--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c ++++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +@@ -2190,7 +2190,9 @@ crypto_retrieve_X509_sans(krb5_context context, + /* Prevent abuse of embedded null characters. */ + if (memchr(name.data, '\0', name.length)) + break; +- ret = krb5_parse_name(context, name.data, &upns[u]); ++ ret = krb5_parse_name_flags(context, name.data, ++ KRB5_PRINCIPAL_PARSE_ENTERPRISE, ++ &upns[u]); + if (ret) { + pkiDebug("%s: failed parsing ms-upn san value\n", + __FUNCTION__); +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 295be25e1..b5638a367 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -121,6 +121,8 @@ static krb5_error_code + verify_client_san(krb5_context context, + pkinit_kdc_context plgctx, + pkinit_kdc_req_context reqctx, ++ krb5_kdcpreauth_callbacks cb, ++ krb5_kdcpreauth_rock rock, + krb5_principal client, + int *valid_san) + { +@@ -171,7 +173,7 @@ verify_client_san(krb5_context context, + __FUNCTION__, client_string, san_string); + krb5_free_unparsed_name(context, san_string); + #endif +- if (krb5_principal_compare(context, princs[i], client)) { ++ if (cb->match_client(context, rock, princs[i])) { + pkiDebug("%s: pkinit san match found\n", __FUNCTION__); + *valid_san = 1; + retval = 0; +@@ -199,7 +201,7 @@ verify_client_san(krb5_context context, + __FUNCTION__, client_string, san_string); + krb5_free_unparsed_name(context, san_string); + #endif +- if (krb5_principal_compare(context, upns[i], client)) { ++ if (cb->match_client(context, rock, upns[i])) { + pkiDebug("%s: upn san match found\n", __FUNCTION__); + *valid_san = 1; + retval = 0; +@@ -387,8 +389,8 @@ pkinit_server_verify_padata(krb5_context context, + } + if (is_signed) { + +- retval = verify_client_san(context, plgctx, reqctx, request->client, +- &valid_san); ++ retval = verify_client_san(context, plgctx, reqctx, cb, rock, ++ request->client, &valid_san); + if (retval) + goto cleanup; + if (!valid_san) { diff --git a/SOURCES/Limit-ticket-lifetime-to-2-31-1-seconds.patch b/SOURCES/Limit-ticket-lifetime-to-2-31-1-seconds.patch new file mode 100644 index 00000000..48bfd00a --- /dev/null +++ b/SOURCES/Limit-ticket-lifetime-to-2-31-1-seconds.patch @@ -0,0 +1,203 @@ +From 31d5c854198ed91fc2bd0b9fb87ed0dcd5a40eb6 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 24 Aug 2017 16:00:33 -0400 +Subject: [PATCH] Limit ticket lifetime to 2^31-1 seconds + +Although timestamps above 2^31-1 are now valid, intervals exceeding +2^31-1 seconds may be treated incorrectly by comparison operations. + +The initially computed interval in kdc_get_ticket_endtime() could be +negative if the requested end time is far in the future, causing the +function to yield an incorrect result. (With the new larger value of +kdc_infinity, this could specifically happen if a KDC-REQ contains a +zero till field.) Cap the interval at the maximum valid value. +Reported by Weijun Wang. + +Avoid delta comparisons in favor of timestamp comparions in +krb5int_validate_times(), ksu's krb5_check_exp(), and clockskew +checks. + +Also use a y2038-safe timestamp comparison in set_request_times() when +comparing the requested renewable end time to the requested ticket end +time. + +ticket: 8352 +(cherry picked from commit 54e58755368b58ba5894a14c1d02626da42d8003) +--- + src/clients/ksu/ccache.c | 2 +- + src/include/k5-int.h | 7 +++++++ + src/kdc/kdc_util.c | 7 ++++++- + src/kdc/replay.c | 2 +- + src/kdc/t_replay.c | 2 +- + src/lib/krb5/krb/gc_via_tkt.c | 4 ++-- + src/lib/krb5/krb/get_in_tkt.c | 6 +++--- + src/lib/krb5/krb/int-proto.h | 3 --- + src/lib/krb5/krb/valid_times.c | 4 ++-- + src/lib/krb5/os/timeofday.c | 2 +- + 10 files changed, 24 insertions(+), 15 deletions(-) + +diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c +index 236313b7b..2a99521d4 100644 +--- a/src/clients/ksu/ccache.c ++++ b/src/clients/ksu/ccache.c +@@ -282,7 +282,7 @@ krb5_error_code krb5_check_exp(context, tkt_time) + + } + +- if (ts_delta(currenttime, tkt_time.endtime) > context->clockskew) { ++ if (ts_after(currenttime, ts_incr(tkt_time.endtime, context->clockskew))) { + retval = KRB5KRB_AP_ERR_TKT_EXPIRED ; + return retval; + } +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 39ffb9568..e31004a7c 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -2386,6 +2386,13 @@ ts_after(krb5_timestamp a, krb5_timestamp b) + return (uint32_t)a > (uint32_t)b; + } + ++/* Return true if a and b are within d seconds. */ ++static inline krb5_boolean ++ts_within(krb5_timestamp a, krb5_timestamp b, krb5_deltat d) ++{ ++ return !ts_after(a, ts_incr(b, d)) && !ts_after(b, ts_incr(a, d)); ++} ++ + krb5_error_code KRB5_CALLCONV + krb5_get_credentials_for_user(krb5_context context, krb5_flags options, + krb5_ccache ccache, +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index 5455e2a67..770163b94 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -1759,14 +1759,19 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm, + krb5_db_entry *server, + krb5_timestamp *out_endtime) + { +- krb5_timestamp until, life; ++ krb5_timestamp until; ++ krb5_deltat life; + + if (till == 0) + till = kdc_infinity; + + until = ts_min(till, endtime); + ++ /* Determine the requested lifetime, capped at the maximum valid time ++ * interval. */ + life = ts_delta(until, starttime); ++ if (ts_after(until, starttime) && life < 0) ++ life = INT32_MAX; + + if (client != NULL && client->max_life != 0) + life = min(life, client->max_life); +diff --git a/src/kdc/replay.c b/src/kdc/replay.c +index fab39cf88..caca783bf 100644 +--- a/src/kdc/replay.c ++++ b/src/kdc/replay.c +@@ -61,7 +61,7 @@ static size_t total_size = 0; + static krb5_ui_4 seed; + + #define STALE_TIME (2*60) /* two minutes */ +-#define STALE(ptr, now) (labs(ts_delta((ptr)->timein, now)) >= STALE_TIME) ++#define STALE(ptr, now) (ts_after(now, ts_incr((ptr)->timein, STALE_TIME))) + + /* Return x rotated to the left by r bits. */ + static inline krb5_ui_4 +diff --git a/src/kdc/t_replay.c b/src/kdc/t_replay.c +index 1442e0e8c..bb7e2faff 100644 +--- a/src/kdc/t_replay.c ++++ b/src/kdc/t_replay.c +@@ -903,7 +903,7 @@ test_kdc_insert_lookaside_cache_expire(void **state) + assert_non_null(e); + e->num_hits = 5; + +- time_return(STALE_TIME, 0); ++ time_return(STALE_TIME + 1, 0); + kdc_insert_lookaside(context, &req2, NULL); + + assert_null(K5_LIST_FIRST(&hash_table[req_hash1])); +diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c +index cf1ea361f..5b9bb9573 100644 +--- a/src/lib/krb5/krb/gc_via_tkt.c ++++ b/src/lib/krb5/krb/gc_via_tkt.c +@@ -306,8 +306,8 @@ krb5int_process_tgs_reply(krb5_context context, + goto cleanup; + + if (!in_cred->times.starttime && +- !in_clock_skew(context, dec_rep->enc_part2->times.starttime, +- timestamp)) { ++ !ts_within(dec_rep->enc_part2->times.starttime, timestamp, ++ context->clockskew)) { + retval = KRB5_KDCREP_SKEW; + goto cleanup; + } +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 7178bd87b..ed15550f0 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -269,8 +269,8 @@ verify_as_reply(krb5_context context, + return retval; + } else { + if ((request->from == 0) && +- !in_clock_skew(context, as_reply->enc_part2->times.starttime, +- time_now)) ++ !ts_within(as_reply->enc_part2->times.starttime, time_now, ++ context->clockskew)) + return (KRB5_KDCREP_SKEW); + } + return 0; +@@ -781,7 +781,7 @@ set_request_times(krb5_context context, krb5_init_creds_context ctx) + if (ctx->renew_life > 0) { + /* Don't ask for a smaller renewable time than the lifetime. */ + ctx->request->rtime = ts_incr(from, ctx->renew_life); +- if (ctx->request->rtime < ctx->request->till) ++ if (ts_after(ctx->request->till, ctx->request->rtime)) + ctx->request->rtime = ctx->request->till; + ctx->request->kdc_options &= ~KDC_OPT_RENEWABLE_OK; + } else { +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index 48bd9f8f7..9c746d05b 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -83,9 +83,6 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options, + krb5_creds *in_creds, krb5_creds *mcreds, + krb5_flags *fields); + +-#define in_clock_skew(context, date, now) \ +- (labs(ts_delta(date, now)) < (context)->clockskew) +- + #define IS_TGS_PRINC(p) ((p)->length == 2 && \ + data_eq_string((p)->data[0], KRB5_TGS_NAME)) + +diff --git a/src/lib/krb5/krb/valid_times.c b/src/lib/krb5/krb/valid_times.c +index 9e509b2dd..294761a88 100644 +--- a/src/lib/krb5/krb/valid_times.c ++++ b/src/lib/krb5/krb/valid_times.c +@@ -47,10 +47,10 @@ krb5int_validate_times(krb5_context context, krb5_ticket_times *times) + else + starttime = times->authtime; + +- if (ts_delta(starttime, currenttime) > context->clockskew) ++ if (ts_after(starttime, ts_incr(currenttime, context->clockskew))) + return KRB5KRB_AP_ERR_TKT_NYV; /* ticket not yet valid */ + +- if (ts_delta(currenttime, times->endtime) > context->clockskew) ++ if (ts_after(currenttime, ts_incr(times->endtime, context->clockskew))) + return KRB5KRB_AP_ERR_TKT_EXPIRED; /* ticket expired */ + + return 0; +diff --git a/src/lib/krb5/os/timeofday.c b/src/lib/krb5/os/timeofday.c +index 887f24c22..d4e36b1c7 100644 +--- a/src/lib/krb5/os/timeofday.c ++++ b/src/lib/krb5/os/timeofday.c +@@ -60,7 +60,7 @@ krb5_check_clockskew(krb5_context context, krb5_timestamp date) + retval = krb5_timeofday(context, ¤ttime); + if (retval) + return retval; +- if (labs(ts_delta(date, currenttime)) >= context->clockskew) ++ if (!ts_within(date, currenttime, context->clockskew)) + return KRB5KRB_AP_ERR_SKEW; + + return 0; diff --git a/SOURCES/Make-timestamp-manipulations-y2038-safe.patch b/SOURCES/Make-timestamp-manipulations-y2038-safe.patch new file mode 100644 index 00000000..8d09a1bc --- /dev/null +++ b/SOURCES/Make-timestamp-manipulations-y2038-safe.patch @@ -0,0 +1,1844 @@ +From 7c671a869d1fc21b5154c035d568d5b5fd940783 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Sat, 22 Apr 2017 12:52:17 -0400 +Subject: [PATCH] Make timestamp manipulations y2038-safe + +Wherever we manipulate krb5_timestamp values using arithmetic, +comparison operations, or conversion to time_t, use the new helper +functions in k5-int.h to ensure that the operations work after y2038 +and do not exhibit undefined behavior. (Relying on +implementation-defined conversion to signed values is okay as we test +that in configure.in.) + +In printf format strings, use %u instead of signed types. When +exporting creds with k5_json_array_fmt(), use a long long so that +timestamps after y2038 aren't marshalled as negative numbers. When +parsing timestamps in test programs, use atoll() instead of atol() so +that positive timestamps after y2038 can be used as input. + +In ksu and klist, make printtime() take a krb5_timestamp parameter to +avoid an unnecessary conversion to time_t and back. + +As Leash does not use k5-int.h, use time_t values internally and +safely convert from libkrb5 timestamp values. + +ticket: 8352 +(cherry picked from commit a9cbbf0899f270fbb14f63ffbed1b6d542333641) +--- + src/clients/kinit/kinit.c | 2 +- + src/clients/klist/klist.c | 20 ++++------- + src/clients/ksu/ccache.c | 20 +++-------- + src/clients/ksu/ksu.h | 2 +- + src/kadmin/cli/getdate.y | 2 +- + src/kadmin/cli/kadmin.c | 5 ++- + src/kadmin/dbutil/dump.c | 27 ++++++++------- + src/kadmin/dbutil/kdb5_mkey.c | 6 ++-- + src/kadmin/dbutil/tabdump.c | 2 +- + src/kadmin/testing/util/tcl_kadm5.c | 12 +++---- + src/kdc/do_as_req.c | 2 +- + src/kdc/do_tgs_req.c | 6 ++-- + src/kdc/extern.c | 4 ++- + src/kdc/fast_util.c | 4 +-- + src/kdc/kdc_log.c | 14 ++++---- + src/kdc/kdc_util.c | 20 +++++------ + src/kdc/kdc_util.h | 2 ++ + src/kdc/replay.c | 2 +- + src/kdc/tgs_policy.c | 7 ++-- + src/lib/gssapi/krb5/accept_sec_context.c | 8 +++-- + src/lib/gssapi/krb5/acquire_cred.c | 13 ++++--- + src/lib/gssapi/krb5/context_time.c | 2 +- + src/lib/gssapi/krb5/export_cred.c | 5 +-- + src/lib/gssapi/krb5/iakerb.c | 4 +-- + src/lib/gssapi/krb5/init_sec_context.c | 9 ++--- + src/lib/gssapi/krb5/inq_context.c | 2 +- + src/lib/gssapi/krb5/inq_cred.c | 5 +-- + src/lib/gssapi/krb5/s4u_gss_glue.c | 2 +- + src/lib/kadm5/chpass_util.c | 8 ++--- + src/lib/kadm5/srv/server_acl.c | 5 +-- + src/lib/kadm5/srv/svr_principal.c | 12 +++---- + src/lib/kdb/kdb5.c | 2 +- + src/lib/krb5/asn.1/asn1_k_encode.c | 3 +- + src/lib/krb5/ccache/cc_keyring.c | 14 ++++---- + src/lib/krb5/ccache/cc_memory.c | 4 +-- + src/lib/krb5/ccache/cc_retr.c | 4 +-- + src/lib/krb5/ccache/ccapi/stdcc_util.c | 40 +++++++++++----------- + src/lib/krb5/ccache/cccursor.c | 2 +- + src/lib/krb5/keytab/kt_file.c | 6 ++-- + src/lib/krb5/krb/gc_via_tkt.c | 7 ++-- + src/lib/krb5/krb/get_creds.c | 2 +- + src/lib/krb5/krb/get_in_tkt.c | 38 ++++++-------------- + src/lib/krb5/krb/gic_pwd.c | 4 +-- + src/lib/krb5/krb/int-proto.h | 2 +- + src/lib/krb5/krb/pac.c | 2 +- + src/lib/krb5/krb/str_conv.c | 4 +-- + src/lib/krb5/krb/t_kerb.c | 12 ++----- + src/lib/krb5/krb/valid_times.c | 4 +-- + src/lib/krb5/krb/vfy_increds.c | 2 +- + src/lib/krb5/os/timeofday.c | 2 +- + src/lib/krb5/os/toffset.c | 2 +- + src/lib/krb5/os/ustime.c | 6 ++-- + src/lib/krb5/rcache/rc_dfl.c | 3 +- + src/lib/krb5/rcache/t_replay.c | 8 ++--- + src/plugins/kdb/db2/lockout.c | 8 ++--- + src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c | 2 +- + src/plugins/kdb/ldap/libkdb_ldap/lockout.c | 8 ++--- + src/windows/cns/tktlist.c | 10 +++--- + src/windows/include/leashwin.h | 12 +++---- + src/windows/leash/KrbListTickets.cpp | 12 +++---- + src/windows/leash/LeashView.cpp | 22 ++++++------ + src/windows/leashdll/lshfunc.c | 2 +- + src/windows/ms2mit/ms2mit.c | 2 +- + 63 files changed, 230 insertions(+), 255 deletions(-) + +diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c +index f1cd1b73d..50065e32e 100644 +--- a/src/clients/kinit/kinit.c ++++ b/src/clients/kinit/kinit.c +@@ -318,7 +318,7 @@ parse_options(argc, argv, opts) + fprintf(stderr, _("Bad start time value %s\n"), optarg); + errflg++; + } else { +- opts->starttime = abs_starttime - time(0); ++ opts->starttime = ts_delta(abs_starttime, time(NULL)); + } + } + break; +diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c +index ba19788a2..ffeecc394 100644 +--- a/src/clients/klist/klist.c ++++ b/src/clients/klist/klist.c +@@ -72,7 +72,7 @@ void do_ccache_name (char *); + int show_ccache (krb5_ccache); + int check_ccache (krb5_ccache); + void do_keytab (char *); +-void printtime (time_t); ++void printtime (krb5_timestamp); + void one_addr (krb5_address *); + void fillit (FILE *, unsigned int, int); + +@@ -538,10 +538,10 @@ check_ccache(krb5_ccache cache) + while (!(ret = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) { + if (is_local_tgt(creds.server, &princ->realm)) { + found_tgt = TRUE; +- if (creds.times.endtime > now) ++ if (ts_after(creds.times.endtime, now)) + found_current_tgt = TRUE; + } else if (!krb5_is_config_principal(kcontext, creds.server) && +- creds.times.endtime > now) { ++ ts_after(creds.times.endtime, now)) { + found_current_cred = TRUE; + } + krb5_free_cred_contents(kcontext, &creds); +@@ -623,19 +623,13 @@ flags_string(cred) + } + + void +-printtime(tv) +- time_t tv; ++printtime(krb5_timestamp ts) + { +- char timestring[BUFSIZ]; +- char fill; ++ char timestring[BUFSIZ], fill = ' '; + +- fill = ' '; +- if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv, +- timestring, +- timestamp_width+1, +- &fill)) { ++ if (!krb5_timestamp_to_sfstring(ts, timestring, timestamp_width + 1, ++ &fill)) + printf("%s", timestring); +- } + } + + static void +diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c +index a0736f2da..236313b7b 100644 +--- a/src/clients/ksu/ccache.c ++++ b/src/clients/ksu/ccache.c +@@ -278,11 +278,11 @@ krb5_error_code krb5_check_exp(context, tkt_time) + context->clockskew); + + fprintf(stderr,"krb5_check_exp: currenttime - endtime %d \n", +- (currenttime - tkt_time.endtime )); ++ ts_delta(currenttime, tkt_time.endtime)); + + } + +- if (currenttime - tkt_time.endtime > context->clockskew){ ++ if (ts_delta(currenttime, tkt_time.endtime) > context->clockskew) { + retval = KRB5KRB_AP_ERR_TKT_EXPIRED ; + return retval; + } +@@ -323,21 +323,11 @@ char *flags_string(cred) + return(buf); + } + +-void printtime(tv) +- time_t tv; ++void printtime(krb5_timestamp ts) + { +- char fmtbuf[18]; +- char fill; +- krb5_timestamp tstamp; ++ char fmtbuf[18], fill = ' '; + +- /* XXXX ASSUMES sizeof(krb5_timestamp) >= sizeof(time_t) */ +- (void) localtime((time_t *)&tv); +- tstamp = tv; +- fill = ' '; +- if (!krb5_timestamp_to_sfstring(tstamp, +- fmtbuf, +- sizeof(fmtbuf), +- &fill)) ++ if (!krb5_timestamp_to_sfstring(ts, fmtbuf, sizeof(fmtbuf), &fill)) + printf("%s", fmtbuf); + } + +diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h +index ee8e9d6a0..3bf0bd438 100644 +--- a/src/clients/ksu/ksu.h ++++ b/src/clients/ksu/ksu.h +@@ -150,7 +150,7 @@ extern krb5_boolean krb5_find_princ_in_cred_list + extern krb5_error_code krb5_find_princ_in_cache + (krb5_context, krb5_ccache, krb5_principal, krb5_boolean *); + +-extern void printtime (time_t); ++extern void printtime (krb5_timestamp); + + /* authorization.c */ + extern krb5_boolean fowner (FILE *, uid_t); +diff --git a/src/kadmin/cli/getdate.y b/src/kadmin/cli/getdate.y +index 4f0c56f7e..0a19c5648 100644 +--- a/src/kadmin/cli/getdate.y ++++ b/src/kadmin/cli/getdate.y +@@ -118,7 +118,7 @@ static int getdate_yyerror (char *); + + + #define EPOCH 1970 +-#define EPOCH_END 2038 /* assumes 32 bits */ ++#define EPOCH_END 2106 /* assumes unsigned 32-bit range */ + #define HOUR(x) ((time_t)(x) * 60) + #define SECSPERDAY (24L * 60L * 60L) + +diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c +index c53c677a8..aee5c83b9 100644 +--- a/src/kadmin/cli/kadmin.c ++++ b/src/kadmin/cli/kadmin.c +@@ -31,8 +31,7 @@ + * library */ + + /* for "_" macro */ +-#include "k5-platform.h" +-#include ++#include "k5-int.h" + #include + #include + #include +@@ -144,8 +143,8 @@ strdate(krb5_timestamp when) + { + struct tm *tm; + static char out[40]; ++ time_t lcltim = ts2tt(when); + +- time_t lcltim = when; + tm = localtime(&lcltim); + strftime(out, sizeof(out), "%a %b %d %H:%M:%S %Z %Y", tm); + return out; +diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c +index cad53cfbf..a6fc4ea77 100644 +--- a/src/kadmin/dbutil/dump.c ++++ b/src/kadmin/dbutil/dump.c +@@ -379,11 +379,12 @@ k5beta7_common(krb5_context context, krb5_db_entry *entry, + fprintf(fp, "princ\t%d\t%lu\t%d\t%d\t%d\t%s\t", (int)entry->len, + (unsigned long)strlen(name), counter, (int)entry->n_key_data, + (int)entry->e_length, name); +- fprintf(fp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d", entry->attributes, +- entry->max_life, entry->max_renewable_life, entry->expiration, +- entry->pw_expiration, +- omit_nra ? 0 : entry->last_success, +- omit_nra ? 0 : entry->last_failed, ++ fprintf(fp, "%d\t%d\t%d\t%u\t%u\t%u\t%u\t%d", entry->attributes, ++ entry->max_life, entry->max_renewable_life, ++ (unsigned int)entry->expiration, ++ (unsigned int)entry->pw_expiration, ++ (unsigned int)(omit_nra ? 0 : entry->last_success), ++ (unsigned int)(omit_nra ? 0 : entry->last_failed), + omit_nra ? 0 : entry->fail_auth_count); + + /* Write out tagged data. */ +@@ -717,7 +718,7 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep, + { + int retval, nread, i, j; + krb5_db_entry *dbentry; +- int t1, t2, t3, t4, t5, t6, t7; ++ int t1, t2, t3, t4; + unsigned int u1, u2, u3, u4, u5; + char *name = NULL; + krb5_key_data *kp = NULL, *kd; +@@ -773,8 +774,8 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep, + } + + /* Get the fixed principal attributes */ +- nread = fscanf(filep, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t", +- &t1, &t2, &t3, &t4, &t5, &t6, &t7, &u1); ++ nread = fscanf(filep, "%d\t%d\t%d\t%u\t%u\t%d\t%d\t%d\t", ++ &t1, &t2, &t3, &u1, &u2, &u3, &u4, &u5); + if (nread != 8) { + load_err(fname, *linenop, _("cannot read principal attributes")); + goto fail; +@@ -782,11 +783,11 @@ process_k5beta7_princ(krb5_context context, const char *fname, FILE *filep, + dbentry->attributes = t1; + dbentry->max_life = t2; + dbentry->max_renewable_life = t3; +- dbentry->expiration = t4; +- dbentry->pw_expiration = t5; +- dbentry->last_success = t6; +- dbentry->last_failed = t7; +- dbentry->fail_auth_count = u1; ++ dbentry->expiration = u1; ++ dbentry->pw_expiration = u2; ++ dbentry->last_success = u3; ++ dbentry->last_failed = u4; ++ dbentry->fail_auth_count = u5; + dbentry->mask = KADM5_LOAD | KADM5_PRINCIPAL | KADM5_ATTRIBUTES | + KADM5_MAX_LIFE | KADM5_MAX_RLIFE | + KADM5_PRINC_EXPIRE_TIME | KADM5_LAST_SUCCESS | +diff --git a/src/kadmin/dbutil/kdb5_mkey.c b/src/kadmin/dbutil/kdb5_mkey.c +index 7df8cbc83..2efe3176e 100644 +--- a/src/kadmin/dbutil/kdb5_mkey.c ++++ b/src/kadmin/dbutil/kdb5_mkey.c +@@ -44,8 +44,8 @@ static char *strdate(krb5_timestamp when) + { + struct tm *tm; + static char out[40]; ++ time_t lcltim = ts2tt(when); + +- time_t lcltim = when; + tm = localtime(&lcltim); + strftime(out, sizeof(out), "%a %b %d %H:%M:%S %Z %Y", tm); + return out; +@@ -481,7 +481,7 @@ kdb5_use_mkey(int argc, char *argv[]) + cur_actkvno != NULL; + prev_actkvno = cur_actkvno, cur_actkvno = cur_actkvno->next) { + +- if (new_actkvno->act_time < cur_actkvno->act_time) { ++ if (ts_after(cur_actkvno->act_time, new_actkvno->act_time)) { + if (prev_actkvno) { + prev_actkvno->next = new_actkvno; + new_actkvno->next = cur_actkvno; +@@ -499,7 +499,7 @@ kdb5_use_mkey(int argc, char *argv[]) + } + } + +- if (actkvno_list->act_time > now) { ++ if (ts_after(actkvno_list->act_time, now)) { + com_err(progname, EINVAL, + _("there must be one master key currently active")); + exit_status++; +diff --git a/src/kadmin/dbutil/tabdump.c b/src/kadmin/dbutil/tabdump.c +index 69a3482ec..fb36b060a 100644 +--- a/src/kadmin/dbutil/tabdump.c ++++ b/src/kadmin/dbutil/tabdump.c +@@ -148,7 +148,7 @@ write_date_iso(struct rec_args *args, krb5_timestamp when) + struct tm *tm = NULL; + struct rechandle *h = args->rh; + +- t = when; ++ t = ts2tt(when); + tm = gmtime(&t); + if (tm == NULL) { + errno = EINVAL; +diff --git a/src/kadmin/testing/util/tcl_kadm5.c b/src/kadmin/testing/util/tcl_kadm5.c +index a4997c60c..9dde579ef 100644 +--- a/src/kadmin/testing/util/tcl_kadm5.c ++++ b/src/kadmin/testing/util/tcl_kadm5.c +@@ -697,13 +697,13 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ, + } else + Tcl_DStringAppendElement(str, "null"); + +- sprintf(buf, "%d", princ->princ_expire_time); ++ sprintf(buf, "%u", (unsigned int)princ->princ_expire_time); + Tcl_DStringAppendElement(str, buf); + +- sprintf(buf, "%d", princ->last_pwd_change); ++ sprintf(buf, "%u", (unsigned int)princ->last_pwd_change); + Tcl_DStringAppendElement(str, buf); + +- sprintf(buf, "%d", princ->pw_expiration); ++ sprintf(buf, "%u", (unsigned int)princ->pw_expiration); + Tcl_DStringAppendElement(str, buf); + + sprintf(buf, "%d", princ->max_life); +@@ -722,7 +722,7 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ, + } else + Tcl_DStringAppendElement(str, "null"); + +- sprintf(buf, "%d", princ->mod_date); ++ sprintf(buf, "%u", (unsigned int)princ->mod_date); + Tcl_DStringAppendElement(str, buf); + + if (mask & KADM5_ATTRIBUTES) { +@@ -758,10 +758,10 @@ static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ, + sprintf(buf, "%d", princ->max_renewable_life); + Tcl_DStringAppendElement(str, buf); + +- sprintf(buf, "%d", princ->last_success); ++ sprintf(buf, "%u", (unsigned int)princ->last_success); + Tcl_DStringAppendElement(str, buf); + +- sprintf(buf, "%d", princ->last_failed); ++ sprintf(buf, "%u", (unsigned int)princ->last_failed); + Tcl_DStringAppendElement(str, buf); + + sprintf(buf, "%d", princ->fail_auth_count); +diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c +index 712ccb794..59a39cd30 100644 +--- a/src/kdc/do_as_req.c ++++ b/src/kdc/do_as_req.c +@@ -87,7 +87,7 @@ get_key_exp(krb5_db_entry *entry) + return entry->pw_expiration; + if (entry->pw_expiration == 0) + return entry->expiration; +- return min(entry->expiration, entry->pw_expiration); ++ return ts_min(entry->expiration, entry->pw_expiration); + } + + /* +diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c +index 547a41441..aacd2f20d 100644 +--- a/src/kdc/do_tgs_req.c ++++ b/src/kdc/do_tgs_req.c +@@ -500,12 +500,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt, + + old_starttime = enc_tkt_reply.times.starttime ? + enc_tkt_reply.times.starttime : enc_tkt_reply.times.authtime; +- old_life = enc_tkt_reply.times.endtime - old_starttime; ++ old_life = ts_delta(enc_tkt_reply.times.endtime, old_starttime); + + enc_tkt_reply.times.starttime = kdc_time; + enc_tkt_reply.times.endtime = +- min(header_ticket->enc_part2->times.renew_till, +- kdc_time + old_life); ++ ts_min(header_ticket->enc_part2->times.renew_till, ++ ts_incr(kdc_time, old_life)); + } else { + /* not a renew request */ + enc_tkt_reply.times.starttime = kdc_time; +diff --git a/src/kdc/extern.c b/src/kdc/extern.c +index fe627494b..84b5c6ad5 100644 +--- a/src/kdc/extern.c ++++ b/src/kdc/extern.c +@@ -37,6 +37,8 @@ + kdc_realm_t **kdc_realmlist = (kdc_realm_t **) NULL; + int kdc_numrealms = 0; + krb5_data empty_string = {0, 0, ""}; +-krb5_timestamp kdc_infinity = KRB5_INT32_MAX; /* XXX */ + krb5_keyblock psr_key; + krb5_int32 max_dgram_reply_size = MAX_DGRAM_SIZE; ++ ++/* With ts_after(), this is the largest timestamp value. */ ++krb5_timestamp kdc_infinity = -1; +diff --git a/src/kdc/fast_util.c b/src/kdc/fast_util.c +index 9df940219..e05107ef3 100644 +--- a/src/kdc/fast_util.c ++++ b/src/kdc/fast_util.c +@@ -607,7 +607,7 @@ kdc_fast_read_cookie(krb5_context context, struct kdc_request_state *state, + ret = krb5_timeofday(context, &now); + if (ret) + goto cleanup; +- if (now - COOKIE_LIFETIME > cookie->time) { ++ if (ts2tt(now) > cookie->time + COOKIE_LIFETIME) { + /* Don't accept the cookie contents. Only return an error if the + * cookie is relevant to the request. */ + if (is_relevant(cookie->data, req->padata)) +@@ -700,7 +700,7 @@ kdc_fast_make_cookie(krb5_context context, struct kdc_request_state *state, + ret = krb5_timeofday(context, &now); + if (ret) + goto cleanup; +- cookie.time = now; ++ cookie.time = ts2tt(now); + cookie.data = contents; + ret = encode_krb5_secure_cookie(&cookie, &der_cookie); + if (ret) +diff --git a/src/kdc/kdc_log.c b/src/kdc/kdc_log.c +index 94a2a1c87..c044a3553 100644 +--- a/src/kdc/kdc_log.c ++++ b/src/kdc/kdc_log.c +@@ -79,9 +79,9 @@ log_as_req(krb5_context context, const krb5_fulladdr *from, + /* success */ + char rep_etypestr[128]; + rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), reply); +- krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %d, %s, " ++ krb5_klog_syslog(LOG_INFO, _("AS_REQ (%s) %s: ISSUE: authtime %u, %s, " + "%s for %s"), +- ktypestr, fromstring, authtime, ++ ktypestr, fromstring, (unsigned int)authtime, + rep_etypestr, cname2, sname2); + } else { + /* fail */ +@@ -156,10 +156,10 @@ 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) { +- krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %d, %s%s " ++ krb5_klog_syslog(LOG_INFO, _("TGS_REQ (%s) %s: %s: authtime %u, %s%s " + "%s for %s%s%s"), +- ktypestr, fromstring, status, authtime, rep_etypestr, +- !errcode ? "," : "", logcname, logsname, ++ ktypestr, fromstring, status, (unsigned int)authtime, ++ rep_etypestr, !errcode ? "," : "", logcname, logsname, + errcode ? ", " : "", errcode ? emsg : ""); + if (isflagset(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION)) + krb5_klog_syslog(LOG_INFO, +@@ -171,9 +171,9 @@ log_tgs_req(krb5_context ctx, const krb5_fulladdr *from, + logaltcname); + + } else +- krb5_klog_syslog(LOG_INFO, _("TGS_REQ %s: %s: authtime %d, %s for %s, " ++ krb5_klog_syslog(LOG_INFO, _("TGS_REQ %s: %s: authtime %u, %s for %s, " + "2nd tkt client %s"), +- fromstring, status, authtime, ++ fromstring, status, (unsigned int)authtime, + logcname, logsname, logaltcname); + + /* OpenSolaris: audit_krb5kdc_tgs_req(...) or +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index 29f9dbbf0..778a629e5 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -654,7 +654,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + } + + /* The client must not be expired */ +- if (client.expiration && client.expiration < kdc_time) { ++ if (client.expiration && ts_after(kdc_time, client.expiration)) { + *status = "CLIENT EXPIRED"; + if (vague_errors) + return(KRB_ERR_GENERIC); +@@ -664,7 +664,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + + /* The client's password must not be expired, unless the server is + a KRB5_KDC_PWCHANGE_SERVICE. */ +- if (client.pw_expiration && client.pw_expiration < kdc_time && ++ if (client.pw_expiration && ts_after(kdc_time, client.pw_expiration) && + !isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) { + *status = "CLIENT KEY EXPIRED"; + if (vague_errors) +@@ -674,7 +674,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm, + } + + /* The server must not be expired */ +- if (server.expiration && server.expiration < kdc_time) { ++ if (server.expiration && ts_after(kdc_time, server.expiration)) { + *status = "SERVICE EXPIRED"; + return(KDC_ERR_SERVICE_EXP); + } +@@ -1765,9 +1765,9 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm, + if (till == 0) + till = kdc_infinity; + +- until = min(till, endtime); ++ until = ts_min(till, endtime); + +- life = until - starttime; ++ life = ts_delta(until, starttime); + + if (client != NULL && client->max_life != 0) + life = min(life, client->max_life); +@@ -1776,7 +1776,7 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm, + if (kdc_active_realm->realm_maxlife != 0) + life = min(life, kdc_active_realm->realm_maxlife); + +- *out_endtime = starttime + life; ++ *out_endtime = ts_incr(starttime, life); + } + + /* +@@ -1806,22 +1806,22 @@ kdc_get_ticket_renewtime(kdc_realm_t *realm, krb5_kdc_req *request, + if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE)) + rtime = request->rtime ? request->rtime : kdc_infinity; + else if (isflagset(request->kdc_options, KDC_OPT_RENEWABLE_OK) && +- tkt->times.endtime < request->till) ++ ts_after(request->till, tkt->times.endtime)) + rtime = request->till; + else + return; + + /* Truncate it to the allowable renewable time. */ + if (tgt != NULL) +- rtime = min(rtime, tgt->times.renew_till); ++ rtime = ts_min(rtime, tgt->times.renew_till); + max_rlife = min(server->max_renewable_life, realm->realm_maxrlife); + if (client != NULL) + max_rlife = min(max_rlife, client->max_renewable_life); +- rtime = min(rtime, tkt->times.starttime + max_rlife); ++ rtime = ts_min(rtime, ts_incr(tkt->times.starttime, max_rlife)); + + /* Make the ticket renewable if the truncated requested time is larger than + * the ticket end time. */ +- if (rtime > tkt->times.endtime) { ++ if (ts_after(rtime, tkt->times.endtime)) { + setflag(tkt->flags, TKT_FLG_RENEWABLE); + tkt->times.renew_till = rtime; + } +diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h +index bcf05fc27..672f94380 100644 +--- a/src/kdc/kdc_util.h ++++ b/src/kdc/kdc_util.h +@@ -452,6 +452,8 @@ struct krb5_kdcpreauth_rock_st { + #define max(a, b) ((a) > (b) ? (a) : (b)) + #endif + ++#define ts_min(a, b) (ts_after(a, b) ? (b) : (a)) ++ + #define ADDRTYPE2FAMILY(X) \ + ((X) == ADDRTYPE_INET6 ? AF_INET6 : (X) == ADDRTYPE_INET ? AF_INET : -1) + +diff --git a/src/kdc/replay.c b/src/kdc/replay.c +index 8da7ac19a..fab39cf88 100644 +--- a/src/kdc/replay.c ++++ b/src/kdc/replay.c +@@ -61,7 +61,7 @@ static size_t total_size = 0; + static krb5_ui_4 seed; + + #define STALE_TIME (2*60) /* two minutes */ +-#define STALE(ptr, now) (abs((ptr)->timein - (now)) >= STALE_TIME) ++#define STALE(ptr, now) (labs(ts_delta((ptr)->timein, now)) >= STALE_TIME) + + /* Return x rotated to the left by r bits. */ + static inline krb5_ui_4 +diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c +index a30cacc66..d0f25d1b7 100644 +--- a/src/kdc/tgs_policy.c ++++ b/src/kdc/tgs_policy.c +@@ -186,7 +186,7 @@ static int + check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt, + krb5_timestamp kdc_time, const char **status) + { +- if (server.expiration && server.expiration < kdc_time) { ++ if (server.expiration && ts_after(kdc_time, server.expiration)) { + *status = "SERVICE EXPIRED"; + return KDC_ERR_SERVICE_EXP; + } +@@ -222,7 +222,7 @@ check_tgs_times(krb5_kdc_req *req, krb5_ticket_times *times, + KDC time. */ + if (req->kdc_options & KDC_OPT_VALIDATE) { + starttime = times->starttime ? times->starttime : times->authtime; +- if (starttime > kdc_time) { ++ if (ts_after(starttime, kdc_time)) { + *status = "NOT_YET_VALID"; + return KRB_AP_ERR_TKT_NYV; + } +@@ -231,7 +231,8 @@ check_tgs_times(krb5_kdc_req *req, krb5_ticket_times *times, + * Check the renew_till time. The endtime was already + * been checked in the initial authentication check. + */ +- if ((req->kdc_options & KDC_OPT_RENEW) && times->renew_till < kdc_time) { ++ if ((req->kdc_options & KDC_OPT_RENEW) && ++ ts_after(kdc_time, times->renew_till)) { + *status = "TKT_EXPIRED"; + return KRB_AP_ERR_TKT_EXPIRED; + } +diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c +index 580d08cbf..06967aa27 100644 +--- a/src/lib/gssapi/krb5/accept_sec_context.c ++++ b/src/lib/gssapi/krb5/accept_sec_context.c +@@ -351,8 +351,10 @@ kg_accept_dce(minor_status, context_handle, verifier_cred_handle, + if (mech_type) + *mech_type = ctx->mech_used; + +- if (time_rec) +- *time_rec = ctx->krb_times.endtime + ctx->k5_context->clockskew - now; ++ if (time_rec) { ++ *time_rec = ts_delta(ctx->krb_times.endtime, now) + ++ ctx->k5_context->clockskew; ++ } + + /* Never return GSS_C_DELEG_FLAG since we don't support DCE credential + * delegation yet. */ +@@ -1146,7 +1148,7 @@ kg_accept_krb5(minor_status, context_handle, + /* Add the maximum allowable clock skew as a grace period for context + * expiration, just as we do for the ticket. */ + if (time_rec) +- *time_rec = ctx->krb_times.endtime + context->clockskew - now; ++ *time_rec = ts_delta(ctx->krb_times.endtime, now) + context->clockskew; + + if (ret_flags) + *ret_flags = ctx->gss_flags; +diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c +index 03ee25ec1..362ba9d86 100644 +--- a/src/lib/gssapi/krb5/acquire_cred.c ++++ b/src/lib/gssapi/krb5/acquire_cred.c +@@ -550,7 +550,7 @@ set_refresh_time(krb5_context context, krb5_ccache ccache, + char buf[128]; + krb5_data d; + +- snprintf(buf, sizeof(buf), "%ld", (long)refresh_time); ++ snprintf(buf, sizeof(buf), "%u", (unsigned int)ts2tt(refresh_time)); + d = string2data(buf); + (void)krb5_cc_set_config(context, ccache, NULL, KRB5_CC_CONF_REFRESH_TIME, + &d); +@@ -566,8 +566,9 @@ kg_cred_time_to_refresh(krb5_context context, krb5_gss_cred_id_rec *cred) + + if (krb5_timeofday(context, &now)) + return FALSE; +- if (cred->refresh_time != 0 && now >= cred->refresh_time) { +- set_refresh_time(context, cred->ccache, cred->refresh_time + 30); ++ if (cred->refresh_time != 0 && !ts_after(cred->refresh_time, now)) { ++ set_refresh_time(context, cred->ccache, ++ ts_incr(cred->refresh_time, 30)); + return TRUE; + } + return FALSE; +@@ -586,7 +587,8 @@ kg_cred_set_initial_refresh(krb5_context context, krb5_gss_cred_id_rec *cred, + return; + + /* Make a note to refresh these when they are halfway to expired. */ +- refresh = times->starttime + (times->endtime - times->starttime) / 2; ++ refresh = ts_incr(times->starttime, ++ ts_delta(times->endtime, times->starttime) / 2); + set_refresh_time(context, cred->ccache, refresh); + } + +@@ -848,7 +850,8 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, + GSS_C_NO_NAME); + if (GSS_ERROR(ret)) + goto error_out; +- *time_rec = (cred->expire > now) ? (cred->expire - now) : 0; ++ *time_rec = ts_after(cred->expire, now) ? ++ ts_delta(cred->expire, now) : 0; + k5_mutex_unlock(&cred->lock); + } + } +diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c +index 450593288..1fdb5a16f 100644 +--- a/src/lib/gssapi/krb5/context_time.c ++++ b/src/lib/gssapi/krb5/context_time.c +@@ -51,7 +51,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec) + return(GSS_S_FAILURE); + } + +- lifetime = ctx->krb_times.endtime - now; ++ lifetime = ts_delta(ctx->krb_times.endtime, now); + if (!ctx->initiate) + lifetime += ctx->k5_context->clockskew; + if (lifetime <= 0) { +diff --git a/src/lib/gssapi/krb5/export_cred.c b/src/lib/gssapi/krb5/export_cred.c +index 652b2604b..8054e4a77 100644 +--- a/src/lib/gssapi/krb5/export_cred.c ++++ b/src/lib/gssapi/krb5/export_cred.c +@@ -410,10 +410,11 @@ json_kgcred(krb5_context context, krb5_gss_cred_id_t cred, + if (ret) + goto cleanup; + +- ret = k5_json_array_fmt(&array, "ivvbbvvvvbiivs", cred->usage, name, imp, ++ ret = k5_json_array_fmt(&array, "ivvbbvvvvbLLvs", cred->usage, name, imp, + cred->default_identity, cred->iakerb_mech, keytab, + rcache, ccache, ckeytab, cred->have_tgt, +- cred->expire, cred->refresh_time, etypes, ++ (long long)ts2tt(cred->expire), ++ (long long)ts2tt(cred->refresh_time), etypes, + cred->password); + if (ret) + goto cleanup; +diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c +index 2dc4d0c1a..bb1072fe4 100644 +--- a/src/lib/gssapi/krb5/iakerb.c ++++ b/src/lib/gssapi/krb5/iakerb.c +@@ -494,7 +494,7 @@ iakerb_tkt_creds_ctx(iakerb_ctx_id_t ctx, + if (code != 0) + goto cleanup; + +- creds.times.endtime = now + time_req; ++ creds.times.endtime = ts_incr(now, time_req); + } + + if (cred->name->ad_context != NULL) { +@@ -669,7 +669,7 @@ iakerb_get_initial_state(iakerb_ctx_id_t ctx, + if (code != 0) + goto cleanup; + +- in_creds.times.endtime = now + time_req; ++ in_creds.times.endtime = ts_incr(now, time_req); + } + + /* Make an AS request if we have no creds or it's time to refresh them. */ +diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c +index 70f7955ae..8e5cc37fb 100644 +--- a/src/lib/gssapi/krb5/init_sec_context.c ++++ b/src/lib/gssapi/krb5/init_sec_context.c +@@ -214,7 +214,8 @@ static krb5_error_code get_credentials(context, cred, server, now, + * boundaries) because accept_sec_context code is also similarly + * non-forgiving. + */ +- if (!krb5_gss_dbg_client_expcreds && result_creds->times.endtime < now) { ++ if (!krb5_gss_dbg_client_expcreds && ++ ts_after(now, result_creds->times.endtime)) { + code = KRB5KRB_AP_ERR_TKT_EXPIRED; + goto cleanup; + } +@@ -575,7 +576,7 @@ kg_new_connection( + if (time_req == 0 || time_req == GSS_C_INDEFINITE) { + ctx->krb_times.endtime = 0; + } else { +- ctx->krb_times.endtime = now + time_req; ++ ctx->krb_times.endtime = ts_incr(now, time_req); + } + + if ((code = kg_duplicate_name(context, cred->name, &ctx->here))) +@@ -659,7 +660,7 @@ kg_new_connection( + if (time_rec) { + if ((code = krb5_timeofday(context, &now))) + goto cleanup; +- *time_rec = ctx->krb_times.endtime - now; ++ *time_rec = ts_delta(ctx->krb_times.endtime, now); + } + + /* set the other returns */ +@@ -873,7 +874,7 @@ mutual_auth( + if (time_rec) { + if ((code = krb5_timeofday(context, &now))) + goto fail; +- *time_rec = ctx->krb_times.endtime - now; ++ *time_rec = ts_delta(ctx->krb_times.endtime, now); + } + + if (ret_flags) +diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c +index d2e466e60..cac024da1 100644 +--- a/src/lib/gssapi/krb5/inq_context.c ++++ b/src/lib/gssapi/krb5/inq_context.c +@@ -120,7 +120,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name, + + /* Add the maximum allowable clock skew as a grace period for context + * expiration, just as we do for the ticket during authentication. */ +- lifetime = ctx->krb_times.endtime - now; ++ lifetime = ts_delta(ctx->krb_times.endtime, now); + if (!ctx->initiate) + lifetime += context->clockskew; + if (lifetime < 0) +diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c +index 4e35a0563..e662ae53a 100644 +--- a/src/lib/gssapi/krb5/inq_cred.c ++++ b/src/lib/gssapi/krb5/inq_cred.c +@@ -130,8 +130,9 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, + goto fail; + } + +- if (cred->expire > 0) { +- if ((lifetime = cred->expire - now) < 0) ++ if (cred->expire != 0) { ++ lifetime = ts_delta(cred->expire, now); ++ if (lifetime < 0) + lifetime = 0; + } + else +diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c +index ff1c310bc..10848c1df 100644 +--- a/src/lib/gssapi/krb5/s4u_gss_glue.c ++++ b/src/lib/gssapi/krb5/s4u_gss_glue.c +@@ -284,7 +284,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status, + if (code != 0) + goto cleanup; + +- *time_rec = cred->expire - now; ++ *time_rec = ts_delta(cred->expire, now); + } + + major_status = GSS_S_COMPLETE; +diff --git a/src/lib/kadm5/chpass_util.c b/src/lib/kadm5/chpass_util.c +index 408b0eb31..1680a5504 100644 +--- a/src/lib/kadm5/chpass_util.c ++++ b/src/lib/kadm5/chpass_util.c +@@ -4,15 +4,11 @@ + */ + + +-#include "autoconf.h" +-#include +-#include +-#include ++#include "k5-int.h" + + #include + #include "admin_internal.h" + +-#include + + #define string_text error_message + +@@ -218,7 +214,7 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, + time_t until; + char *time_string, *ptr; + +- until = princ_ent.last_pwd_change + policy_ent.pw_min_life; ++ until = ts_incr(princ_ent.last_pwd_change, policy_ent.pw_min_life); + + time_string = ctime(&until); + if (*(ptr = &time_string[strlen(time_string)-1]) == '\n') +diff --git a/src/lib/kadm5/srv/server_acl.c b/src/lib/kadm5/srv/server_acl.c +index 59ed0b975..656dddff5 100644 +--- a/src/lib/kadm5/srv/server_acl.c ++++ b/src/lib/kadm5/srv/server_acl.c +@@ -408,13 +408,14 @@ kadm5int_acl_impose_restrictions(kcontext, recp, maskp, rp) + } + if (rp->mask & KADM5_PRINC_EXPIRE_TIME) { + if (!(*maskp & KADM5_PRINC_EXPIRE_TIME) +- || (recp->princ_expire_time > (now + rp->princ_lifetime))) ++ || ts_after(recp->princ_expire_time, ++ ts_incr(now, rp->princ_lifetime))) + recp->princ_expire_time = now + rp->princ_lifetime; + *maskp |= KADM5_PRINC_EXPIRE_TIME; + } + if (rp->mask & KADM5_PW_EXPIRATION) { + if (!(*maskp & KADM5_PW_EXPIRATION) +- || (recp->pw_expiration > (now + rp->pw_lifetime))) ++ || ts_after(recp->pw_expiration, ts_incr(now, rp->pw_lifetime))) + recp->pw_expiration = now + rp->pw_lifetime; + *maskp |= KADM5_PW_EXPIRATION; + } +diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c +index 0640b47c4..f4a9a2ad2 100644 +--- a/src/lib/kadm5/srv/svr_principal.c ++++ b/src/lib/kadm5/srv/svr_principal.c +@@ -400,7 +400,7 @@ kadm5_create_principal_3(void *server_handle, + kdb->pw_expiration = 0; + if (have_polent) { + if(polent.pw_max_life) +- kdb->pw_expiration = now + polent.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, polent.pw_max_life); + else + kdb->pw_expiration = 0; + } +@@ -612,7 +612,7 @@ kadm5_modify_principal(void *server_handle, + &(kdb->pw_expiration)); + if (ret) + goto done; +- kdb->pw_expiration += pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(kdb->pw_expiration, pol.pw_max_life); + } else { + kdb->pw_expiration = 0; + } +@@ -1445,7 +1445,7 @@ kadm5_chpass_principal_3(void *server_handle, + } + + if (pol.pw_max_life) +- kdb->pw_expiration = now + pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, pol.pw_max_life); + else + kdb->pw_expiration = 0; + } else { +@@ -1624,7 +1624,7 @@ kadm5_randkey_principal_3(void *server_handle, + #endif + + if (pol.pw_max_life) +- kdb->pw_expiration = now + pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, pol.pw_max_life); + else + kdb->pw_expiration = 0; + } else { +@@ -1774,7 +1774,7 @@ kadm5_setv4key_principal(void *server_handle, + #endif + + if (pol.pw_max_life) +- kdb->pw_expiration = now + pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, pol.pw_max_life); + else + kdb->pw_expiration = 0; + } else { +@@ -2024,7 +2024,7 @@ kadm5_setkey_principal_4(void *server_handle, krb5_principal principal, + } + if (have_pol) { + if (pol.pw_max_life) +- kdb->pw_expiration = now + pol.pw_max_life; ++ kdb->pw_expiration = ts_incr(now, pol.pw_max_life); + else + kdb->pw_expiration = 0; + } else { +diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c +index 4adf0fcbb..7f33c7e68 100644 +--- a/src/lib/kdb/kdb5.c ++++ b/src/lib/kdb/kdb5.c +@@ -1296,7 +1296,7 @@ find_actkvno(krb5_actkvno_node *list, krb5_timestamp now) + * are in the future, we will return the first node; if all are in the + * past, we will return the last node. + */ +- while (list->next != NULL && list->next->act_time <= now) ++ while (list->next != NULL && !ts_after(list->next->act_time, now)) + list = list->next; + return list->act_kvno; + } +diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c +index a827ca608..889460989 100644 +--- a/src/lib/krb5/asn.1/asn1_k_encode.c ++++ b/src/lib/krb5/asn.1/asn1_k_encode.c +@@ -158,8 +158,7 @@ static asn1_error_code + encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag, + size_t *len_out) + { +- /* Range checking for time_t vs krb5_timestamp? */ +- time_t val = *(krb5_timestamp *)p; ++ time_t val = ts2tt(*(krb5_timestamp *)p); + rettag->asn1class = UNIVERSAL; + rettag->construction = PRIMITIVE; + rettag->tagnum = ASN1_GENERALTIME; +diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c +index 4fe3f0d6f..fba710b1b 100644 +--- a/src/lib/krb5/ccache/cc_keyring.c ++++ b/src/lib/krb5/ccache/cc_keyring.c +@@ -751,7 +751,7 @@ update_keyring_expiration(krb5_context context, krb5_ccache id) + for (;;) { + if (krcc_next_cred(context, id, &cursor, &creds) != 0) + break; +- if (creds.times.endtime > endtime) ++ if (ts_after(creds.times.endtime, endtime)) + endtime = creds.times.endtime; + krb5_free_cred_contents(context, &creds); + } +@@ -765,7 +765,7 @@ update_keyring_expiration(krb5_context context, krb5_ccache id) + + /* Setting the timeout to zero would reset the timeout, so we set it to one + * second instead if creds are already expired. */ +- timeout = (endtime > now) ? endtime - now : 1; ++ timeout = ts_after(endtime, now) ? ts_delta(endtime, now) : 1; + (void)keyctl_set_timeout(data->cache_id, timeout); + } + +@@ -1316,8 +1316,10 @@ krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds) + if (ret) + goto errout; + +- if (creds->times.endtime > now) +- (void)keyctl_set_timeout(cred_key, creds->times.endtime - now); ++ if (ts_after(creds->times.endtime, now)) { ++ (void)keyctl_set_timeout(cred_key, ++ ts_delta(creds->times.endtime, now)); ++ } + + update_keyring_expiration(context, id); + +@@ -1680,8 +1682,8 @@ static void + krcc_update_change_time(krcc_data *data) + { + krb5_timestamp now_time = time(NULL); +- data->changetime = (data->changetime >= now_time) ? +- data->changetime + 1 : now_time; ++ data->changetime = ts_after(now_time, data->changetime) ? ++ now_time : ts_incr(data->changetime, 1); + } + + /* +diff --git a/src/lib/krb5/ccache/cc_memory.c b/src/lib/krb5/ccache/cc_memory.c +index 0354575c5..c5425eb3a 100644 +--- a/src/lib/krb5/ccache/cc_memory.c ++++ b/src/lib/krb5/ccache/cc_memory.c +@@ -720,8 +720,8 @@ static void + update_mcc_change_time(krb5_mcc_data *d) + { + krb5_timestamp now_time = time(NULL); +- d->changetime = (d->changetime >= now_time) ? +- d->changetime + 1 : now_time; ++ d->changetime = ts_after(now_time, d->changetime) ? ++ now_time : ts_incr(d->changetime, 1); + } + + static krb5_error_code KRB5_CALLCONV +diff --git a/src/lib/krb5/ccache/cc_retr.c b/src/lib/krb5/ccache/cc_retr.c +index 1314d24bd..1a32e00c8 100644 +--- a/src/lib/krb5/ccache/cc_retr.c ++++ b/src/lib/krb5/ccache/cc_retr.c +@@ -46,11 +46,11 @@ static krb5_boolean + times_match(const krb5_ticket_times *t1, const krb5_ticket_times *t2) + { + if (t1->renew_till) { +- if (t1->renew_till > t2->renew_till) ++ if (ts_after(t1->renew_till, t2->renew_till)) + return FALSE; /* this one expires too late */ + } + if (t1->endtime) { +- if (t1->endtime > t2->endtime) ++ if (ts_after(t1->endtime, t2->endtime)) + return FALSE; /* this one expires too late */ + } + /* only care about expiration on a times_match */ +diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c +index 9f44af3d0..6092ee432 100644 +--- a/src/lib/krb5/ccache/ccapi/stdcc_util.c ++++ b/src/lib/krb5/ccache/ccapi/stdcc_util.c +@@ -16,8 +16,8 @@ + #include + #endif + ++#include "k5-int.h" + #include "stdcc_util.h" +-#include "krb5.h" + #ifdef _WIN32 /* it's part of krb5.h everywhere else */ + #include "kv5m_err.h" + #endif +@@ -321,10 +321,10 @@ copy_cc_cred_union_to_krb5_creds (krb5_context in_context, + keyblock_contents = NULL; + + /* copy times */ +- out_creds->times.authtime = cv5->authtime + offset_seconds; +- out_creds->times.starttime = cv5->starttime + offset_seconds; +- out_creds->times.endtime = cv5->endtime + offset_seconds; +- out_creds->times.renew_till = cv5->renew_till + offset_seconds; ++ out_creds->times.authtime = ts_incr(cv5->authtime, offset_seconds); ++ out_creds->times.starttime = ts_incr(cv5->starttime, offset_seconds); ++ out_creds->times.endtime = ts_incr(cv5->endtime, offset_seconds); ++ out_creds->times.renew_till = ts_incr(cv5->renew_till, offset_seconds); + out_creds->is_skey = cv5->is_skey; + out_creds->ticket_flags = cv5->ticket_flags; + +@@ -451,11 +451,11 @@ copy_krb5_creds_to_cc_cred_union (krb5_context in_context, + cv5->keyblock.data = keyblock_data; + keyblock_data = NULL; + +- cv5->authtime = in_creds->times.authtime - offset_seconds; +- cv5->starttime = in_creds->times.starttime - offset_seconds; +- cv5->endtime = in_creds->times.endtime - offset_seconds; +- cv5->renew_till = in_creds->times.renew_till - offset_seconds; +- cv5->is_skey = in_creds->is_skey; ++ cv5->authtime = ts_incr(in_creds->times.authtime, -offset_seconds); ++ cv5->starttime = ts_incr(in_creds->times.starttime, -offset_seconds); ++ cv5->endtime = ts_incr(in_creds->times.endtime, -offset_seconds); ++ cv5->renew_till = ts_incr(in_creds->times.renew_till, -offset_seconds); ++ cv5->is_skey = in_creds->is_skey; + cv5->ticket_flags = in_creds->ticket_flags; + + if (in_creds->ticket.data) { +@@ -732,10 +732,10 @@ void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest) + err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds); + if (err) return; + #endif +- dest->times.authtime = src->authtime + offset_seconds; +- dest->times.starttime = src->starttime + offset_seconds; +- dest->times.endtime = src->endtime + offset_seconds; +- dest->times.renew_till = src->renew_till + offset_seconds; ++ dest->times.authtime = ts_incr(src->authtime, offset_seconds); ++ dest->times.starttime = ts_incr(src->starttime, offset_seconds); ++ dest->times.endtime = ts_incr(src->endtime, offset_seconds); ++ dest->times.renew_till = ts_incr(src->renew_till, offset_seconds); + dest->is_skey = src->is_skey; + dest->ticket_flags = src->ticket_flags; + +@@ -804,10 +804,10 @@ void dupK5toCC(krb5_context context, krb5_creds *creds, cred_union **cu) + err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds); + if (err) return; + #endif +- c->authtime = creds->times.authtime - offset_seconds; +- c->starttime = creds->times.starttime - offset_seconds; +- c->endtime = creds->times.endtime - offset_seconds; +- c->renew_till = creds->times.renew_till - offset_seconds; ++ c->authtime = ts_incr(creds->times.authtime, -offset_seconds); ++ c->starttime = ts_incr(creds->times.starttime, -offset_seconds); ++ c->endtime = ts_incr(creds->times.endtime, -offset_seconds); ++ c->renew_till = ts_incr(creds->times.renew_till, -offset_seconds); + c->is_skey = creds->is_skey; + c->ticket_flags = creds->ticket_flags; + +@@ -925,11 +925,11 @@ times_match(t1, t2) + register const krb5_ticket_times *t2; + { + if (t1->renew_till) { +- if (t1->renew_till > t2->renew_till) ++ if (ts_after(t1->renew_till, t2->renew_till)) + return FALSE; /* this one expires too late */ + } + if (t1->endtime) { +- if (t1->endtime > t2->endtime) ++ if (ts_after(t1->endtime, t2->endtime)) + return FALSE; /* this one expires too late */ + } + /* only care about expiration on a times_match */ +diff --git a/src/lib/krb5/ccache/cccursor.c b/src/lib/krb5/ccache/cccursor.c +index c31a3f5f0..e631f2051 100644 +--- a/src/lib/krb5/ccache/cccursor.c ++++ b/src/lib/krb5/ccache/cccursor.c +@@ -159,7 +159,7 @@ krb5_cccol_last_change_time(krb5_context context, + ret = krb5_cccol_cursor_next(context, c, &ccache); + if (ccache) { + ret = krb5_cc_last_change_time(context, ccache, &last_time); +- if (!ret && last_time > max_change_time) { ++ if (!ret && ts_after(last_time, max_change_time)) { + max_change_time = last_time; + } + ret = 0; +diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c +index 131549ffe..b014abf0b 100644 +--- a/src/lib/krb5/keytab/kt_file.c ++++ b/src/lib/krb5/keytab/kt_file.c +@@ -264,9 +264,11 @@ more_recent(const krb5_keytab_entry *k1, const krb5_keytab_entry *k2) + * limitations (8-bit kvno storage), pre-1.14 kadmin protocol limitations + * (8-bit kvno marshalling), or KDB limitations (16-bit kvno storage). + */ +- if (k1->timestamp >= k2->timestamp && k1->vno < 128 && k2->vno > 240) ++ if (!ts_after(k2->timestamp, k1->timestamp) && ++ k1->vno < 128 && k2->vno > 240) + return TRUE; +- if (k1->timestamp <= k2->timestamp && k1->vno > 240 && k2->vno < 128) ++ if (!ts_after(k1->timestamp, k2->timestamp) && ++ k1->vno > 240 && k2->vno < 128) + return FALSE; + + /* Otherwise do a simple version comparison. */ +diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c +index c85d8b8d8..cf1ea361f 100644 +--- a/src/lib/krb5/krb/gc_via_tkt.c ++++ b/src/lib/krb5/krb/gc_via_tkt.c +@@ -287,18 +287,19 @@ krb5int_process_tgs_reply(krb5_context context, + retval = KRB5_KDCREP_MODIFIED; + + if ((in_cred->times.endtime != 0) && +- (dec_rep->enc_part2->times.endtime > in_cred->times.endtime)) ++ ts_after(dec_rep->enc_part2->times.endtime, in_cred->times.endtime)) + retval = KRB5_KDCREP_MODIFIED; + + if ((kdcoptions & KDC_OPT_RENEWABLE) && + (in_cred->times.renew_till != 0) && +- (dec_rep->enc_part2->times.renew_till > in_cred->times.renew_till)) ++ ts_after(dec_rep->enc_part2->times.renew_till, ++ in_cred->times.renew_till)) + retval = KRB5_KDCREP_MODIFIED; + + if ((kdcoptions & KDC_OPT_RENEWABLE_OK) && + (dec_rep->enc_part2->flags & KDC_OPT_RENEWABLE) && + (in_cred->times.endtime != 0) && +- (dec_rep->enc_part2->times.renew_till > in_cred->times.endtime)) ++ ts_after(dec_rep->enc_part2->times.renew_till, in_cred->times.endtime)) + retval = KRB5_KDCREP_MODIFIED; + + if (retval != 0) +diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c +index 110abeb2b..be5b2d18c 100644 +--- a/src/lib/krb5/krb/get_creds.c ++++ b/src/lib/krb5/krb/get_creds.c +@@ -816,7 +816,7 @@ get_cached_local_tgt(krb5_context context, krb5_tkt_creds_context ctx, + return code; + + /* Check if the TGT is expired before bothering the KDC with it. */ +- if (now > tgt->times.endtime) { ++ if (ts_after(now, tgt->times.endtime)) { + krb5_free_creds(context, tgt); + return KRB5KRB_AP_ERR_TKT_EXPIRED; + } +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index a058f5bd7..40aba1905 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -39,24 +39,6 @@ static krb5_error_code sort_krb5_padata_sequence(krb5_context context, + krb5_data *realm, + krb5_pa_data **padata); + +-/* +- * This function performs 32 bit bounded addition so we can generate +- * lifetimes without overflowing krb5_int32 +- */ +-static krb5_int32 +-krb5int_addint32 (krb5_int32 x, krb5_int32 y) +-{ +- if ((x > 0) && (y > (KRB5_INT32_MAX - x))) { +- /* sum will be be greater than KRB5_INT32_MAX */ +- return KRB5_INT32_MAX; +- } else if ((x < 0) && (y < (KRB5_INT32_MIN - x))) { +- /* sum will be less than KRB5_INT32_MIN */ +- return KRB5_INT32_MIN; +- } +- +- return x + y; +-} +- + /* + * Decrypt the AS reply in ctx, populating ctx->reply->enc_part2. If + * strengthen_key is not null, combine it with the reply key as specified in +@@ -267,21 +249,21 @@ verify_as_reply(krb5_context context, + (request->from != 0) && + (request->from != as_reply->enc_part2->times.starttime)) + || ((request->till != 0) && +- (as_reply->enc_part2->times.endtime > request->till)) ++ ts_after(as_reply->enc_part2->times.endtime, request->till)) + || ((request->kdc_options & KDC_OPT_RENEWABLE) && + (request->rtime != 0) && +- (as_reply->enc_part2->times.renew_till > request->rtime)) ++ ts_after(as_reply->enc_part2->times.renew_till, request->rtime)) + || ((request->kdc_options & KDC_OPT_RENEWABLE_OK) && + !(request->kdc_options & KDC_OPT_RENEWABLE) && + (as_reply->enc_part2->flags & KDC_OPT_RENEWABLE) && + (request->till != 0) && +- (as_reply->enc_part2->times.renew_till > request->till)) ++ ts_after(as_reply->enc_part2->times.renew_till, request->till)) + ) { + return KRB5_KDCREP_MODIFIED; + } + + if (context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) { +- time_offset = as_reply->enc_part2->times.authtime - time_now; ++ time_offset = ts_delta(as_reply->enc_part2->times.authtime, time_now); + retval = krb5_set_time_offsets(context, time_offset, 0); + if (retval) + return retval; +@@ -790,15 +772,15 @@ set_request_times(krb5_context context, krb5_init_creds_context ctx) + return code; + + /* Omit request start time unless the caller explicitly asked for one. */ +- from = krb5int_addint32(now, ctx->start_time); ++ from = ts_incr(now, ctx->start_time); + if (ctx->start_time != 0) + ctx->request->from = from; + +- ctx->request->till = krb5int_addint32(from, ctx->tkt_life); ++ ctx->request->till = ts_incr(from, ctx->tkt_life); + + if (ctx->renew_life > 0) { + /* Don't ask for a smaller renewable time than the lifetime. */ +- ctx->request->rtime = krb5int_addint32(from, ctx->renew_life); ++ ctx->request->rtime = ts_incr(from, ctx->renew_life); + if (ctx->request->rtime < ctx->request->till) + ctx->request->rtime = ctx->request->till; + ctx->request->kdc_options &= ~KDC_OPT_RENEWABLE_OK; +@@ -1438,7 +1420,7 @@ note_req_timestamp(krb5_context context, krb5_init_creds_context ctx, + + if (k5_time_with_offset(0, 0, &now, &usec) != 0) + return; +- ctx->pa_offset = kdc_time - now; ++ ctx->pa_offset = ts_delta(kdc_time, now); + ctx->pa_offset_usec = kdc_usec - usec; + ctx->pa_offset_state = (ctx->fast_state->armor_key != NULL) ? + AUTH_OFFSET : UNAUTH_OFFSET; +@@ -1807,6 +1789,7 @@ k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **out, + { + int i; + krb5_int32 starttime; ++ krb5_deltat lifetime; + krb5_get_init_creds_opt *opt; + krb5_error_code retval; + +@@ -1838,7 +1821,8 @@ k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **out, + if (retval) + goto cleanup; + if (creds->times.starttime) starttime = creds->times.starttime; +- krb5_get_init_creds_opt_set_tkt_life(opt, creds->times.endtime - starttime); ++ lifetime = ts_delta(creds->times.endtime, starttime); ++ krb5_get_init_creds_opt_set_tkt_life(opt, lifetime); + } + *out = opt; + return 0; +diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c +index 6f3a29f2c..3565a7c4c 100644 +--- a/src/lib/krb5/krb/gic_pwd.c ++++ b/src/lib/krb5/krb/gic_pwd.c +@@ -211,7 +211,7 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options, + if (ret != 0) + return; + if (!is_last_req && +- (pw_exp < now || (pw_exp - now) > 7 * 24 * 60 * 60)) ++ (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60)) + return; + + if (!prompter) +@@ -221,7 +221,7 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options, + if (ret != 0) + return; + +- delta = pw_exp - now; ++ delta = ts_delta(pw_exp, now); + if (delta < 3600) { + snprintf(banner, sizeof(banner), + _("Warning: Your password will expire in less than one hour " +diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h +index 44eca359f..48bd9f8f7 100644 +--- a/src/lib/krb5/krb/int-proto.h ++++ b/src/lib/krb5/krb/int-proto.h +@@ -84,7 +84,7 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options, + krb5_flags *fields); + + #define in_clock_skew(context, date, now) \ +- (labs((date) - (now)) < (context)->clockskew) ++ (labs(ts_delta(date, now)) < (context)->clockskew) + + #define IS_TGS_PRINC(p) ((p)->length == 2 && \ + data_eq_string((p)->data[0], KRB5_TGS_NAME)) +diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c +index 9098927b5..c70585a9e 100644 +--- a/src/lib/krb5/krb/pac.c ++++ b/src/lib/krb5/krb/pac.c +@@ -378,7 +378,7 @@ k5_time_to_seconds_since_1970(int64_t ntTime, krb5_timestamp *elapsedSeconds) + + abstime = ntTime > 0 ? ntTime - NT_TIME_EPOCH : -ntTime; + +- if (abstime > KRB5_INT32_MAX) ++ if (abstime > UINT32_MAX) + return ERANGE; + + *elapsedSeconds = abstime; +diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c +index 3ab7eacac..f0a2ae20b 100644 +--- a/src/lib/krb5/krb/str_conv.c ++++ b/src/lib/krb5/krb/str_conv.c +@@ -207,7 +207,7 @@ krb5_error_code KRB5_CALLCONV + krb5_timestamp_to_string(krb5_timestamp timestamp, char *buffer, size_t buflen) + { + size_t ret; +- time_t timestamp2 = timestamp; ++ time_t timestamp2 = ts2tt(timestamp); + struct tm tmbuf; + const char *fmt = "%c"; /* This is to get around gcc -Wall warning that + the year returned might be two digits */ +@@ -229,7 +229,7 @@ krb5_timestamp_to_sfstring(krb5_timestamp timestamp, char *buffer, size_t buflen + struct tm *tmp; + size_t i; + size_t ndone; +- time_t timestamp2 = timestamp; ++ time_t timestamp2 = ts2tt(timestamp); + struct tm tmbuf; + + static const char * const sftime_format_table[] = { +diff --git a/src/lib/krb5/krb/t_kerb.c b/src/lib/krb5/krb/t_kerb.c +index 60cfb5b15..74ac14d9a 100644 +--- a/src/lib/krb5/krb/t_kerb.c ++++ b/src/lib/krb5/krb/t_kerb.c +@@ -5,16 +5,8 @@ + */ + + #include "autoconf.h" +-#include "krb5.h" +-#include +-#include +-#include +-#include ++#include "k5-int.h" + #include +-#include +-#include +-#include +-#include + + #include "com_err.h" + +@@ -37,7 +29,7 @@ test_string_to_timestamp(krb5_context ctx, char *ktime) + com_err("krb5_string_to_timestamp", retval, 0); + return; + } +- t = (time_t) timestamp; ++ t = ts2tt(timestamp); + printf("Parsed time was %s", ctime(&t)); + } + +diff --git a/src/lib/krb5/krb/valid_times.c b/src/lib/krb5/krb/valid_times.c +index d63122183..9e509b2dd 100644 +--- a/src/lib/krb5/krb/valid_times.c ++++ b/src/lib/krb5/krb/valid_times.c +@@ -47,10 +47,10 @@ krb5int_validate_times(krb5_context context, krb5_ticket_times *times) + else + starttime = times->authtime; + +- if (starttime - currenttime > context->clockskew) ++ if (ts_delta(starttime, currenttime) > context->clockskew) + return KRB5KRB_AP_ERR_TKT_NYV; /* ticket not yet valid */ + +- if ((currenttime - times->endtime) > context->clockskew) ++ if (ts_delta(currenttime, times->endtime) > context->clockskew) + return KRB5KRB_AP_ERR_TKT_EXPIRED; /* ticket expired */ + + return 0; +diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c +index 9786d63b5..b4878ba38 100644 +--- a/src/lib/krb5/krb/vfy_increds.c ++++ b/src/lib/krb5/krb/vfy_increds.c +@@ -120,7 +120,7 @@ get_vfy_cred(krb5_context context, krb5_creds *creds, krb5_principal server, + ret = krb5_timeofday(context, &in_creds.times.endtime); + if (ret) + goto cleanup; +- in_creds.times.endtime += 5*60; ++ in_creds.times.endtime = ts_incr(in_creds.times.endtime, 5 * 60); + ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds); + if (ret) + goto cleanup; +diff --git a/src/lib/krb5/os/timeofday.c b/src/lib/krb5/os/timeofday.c +index fddb12142..887f24c22 100644 +--- a/src/lib/krb5/os/timeofday.c ++++ b/src/lib/krb5/os/timeofday.c +@@ -60,7 +60,7 @@ krb5_check_clockskew(krb5_context context, krb5_timestamp date) + retval = krb5_timeofday(context, ¤ttime); + if (retval) + return retval; +- if (!(labs((date)-currenttime) < context->clockskew)) ++ if (labs(ts_delta(date, currenttime)) >= context->clockskew) + return KRB5KRB_AP_ERR_SKEW; + + return 0; +diff --git a/src/lib/krb5/os/toffset.c b/src/lib/krb5/os/toffset.c +index 456193a41..37bc69f49 100644 +--- a/src/lib/krb5/os/toffset.c ++++ b/src/lib/krb5/os/toffset.c +@@ -47,7 +47,7 @@ krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 micr + if (retval) + return retval; + +- os_ctx->time_offset = seconds - sec; ++ os_ctx->time_offset = ts_delta(seconds, sec); + os_ctx->usec_offset = (microseconds > -1) ? microseconds - usec : 0; + + os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) | +diff --git a/src/lib/krb5/os/ustime.c b/src/lib/krb5/os/ustime.c +index 056357683..1c1b571eb 100644 +--- a/src/lib/krb5/os/ustime.c ++++ b/src/lib/krb5/os/ustime.c +@@ -49,13 +49,13 @@ k5_time_with_offset(krb5_timestamp offset, krb5_int32 offset_usec, + usec += offset_usec; + if (usec > 1000000) { + usec -= 1000000; +- sec++; ++ sec = ts_incr(sec, 1); + } + if (usec < 0) { + usec += 1000000; +- sec--; ++ sec = ts_incr(sec, -1); + } +- sec += offset; ++ sec = ts_incr(sec, offset); + + *time_out = sec; + *usec_out = usec; +diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c +index c0f12ed9d..6b043844d 100644 +--- a/src/lib/krb5/rcache/rc_dfl.c ++++ b/src/lib/krb5/rcache/rc_dfl.c +@@ -97,8 +97,7 @@ alive(krb5_int32 mytime, krb5_donot_replay *new1, krb5_deltat t) + { + if (mytime == 0) + return CMP_HOHUM; /* who cares? */ +- /* I hope we don't have to worry about overflow */ +- if (new1->ctime + t < mytime) ++ if (ts_after(mytime, ts_incr(new1->ctime, t))) + return CMP_EXPIRED; + return CMP_HOHUM; + } +diff --git a/src/lib/krb5/rcache/t_replay.c b/src/lib/krb5/rcache/t_replay.c +index db273ec2f..b99cdf1ab 100644 +--- a/src/lib/krb5/rcache/t_replay.c ++++ b/src/lib/krb5/rcache/t_replay.c +@@ -110,7 +110,7 @@ store(krb5_context ctx, char *rcspec, char *client, char *server, char *msg, + krb5_donot_replay rep; + krb5_data d; + +- if (now_timestamp > 0) ++ if (now_timestamp != 0) + krb5_set_debugging_time(ctx, now_timestamp, now_usec); + if ((retval = krb5_rc_resolve_full(ctx, &rc, rcspec))) + goto cleanup; +@@ -221,13 +221,13 @@ main(int argc, char **argv) + msg = (**argv) ? *argv : NULL; + argc--; argv++; + if (!argc) usage(progname); +- timestamp = (krb5_timestamp) atol(*argv); ++ timestamp = (krb5_timestamp) atoll(*argv); + argc--; argv++; + if (!argc) usage(progname); + usec = (krb5_int32) atol(*argv); + argc--; argv++; + if (!argc) usage(progname); +- now_timestamp = (krb5_timestamp) atol(*argv); ++ now_timestamp = (krb5_timestamp) atoll(*argv); + argc--; argv++; + if (!argc) usage(progname); + now_usec = (krb5_int32) atol(*argv); +@@ -249,7 +249,7 @@ main(int argc, char **argv) + rcspec = *argv; + argc--; argv++; + if (!argc) usage(progname); +- now_timestamp = (krb5_timestamp) atol(*argv); ++ now_timestamp = (krb5_timestamp) atoll(*argv); + argc--; argv++; + if (!argc) usage(progname); + now_usec = (krb5_int32) atol(*argv); +diff --git a/src/plugins/kdb/db2/lockout.c b/src/plugins/kdb/db2/lockout.c +index 7d151b55b..3a4f41821 100644 +--- a/src/plugins/kdb/db2/lockout.c ++++ b/src/plugins/kdb/db2/lockout.c +@@ -100,7 +100,7 @@ locked_check_p(krb5_context context, + + /* If the entry was unlocked since the last failure, it's not locked. */ + if (krb5_dbe_lookup_last_admin_unlock(context, entry, &unlock_time) == 0 && +- entry->last_failed <= unlock_time) ++ !ts_after(entry->last_failed, unlock_time)) + return FALSE; + + if (max_fail == 0 || entry->fail_auth_count < max_fail) +@@ -109,7 +109,7 @@ locked_check_p(krb5_context context, + if (lockout_duration == 0) + return TRUE; /* principal permanently locked */ + +- return (stamp < entry->last_failed + lockout_duration); ++ return ts_after(ts_incr(entry->last_failed, lockout_duration), stamp); + } + + krb5_error_code +@@ -200,13 +200,13 @@ krb5_db2_lockout_audit(krb5_context context, + status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) { + if (krb5_dbe_lookup_last_admin_unlock(context, entry, + &unlock_time) == 0 && +- entry->last_failed <= unlock_time) { ++ !ts_after(entry->last_failed, unlock_time)) { + /* Reset fail_auth_count after administrative unlock. */ + entry->fail_auth_count = 0; + } + + if (failcnt_interval != 0 && +- stamp > entry->last_failed + failcnt_interval) { ++ ts_after(stamp, ts_incr(entry->last_failed, failcnt_interval))) { + /* Reset fail_auth_count after failcnt_interval. */ + entry->fail_auth_count = 0; + } +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +index 7ba53f959..88a170495 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +@@ -1734,7 +1734,7 @@ getstringtime(krb5_timestamp epochtime) + { + struct tm tme; + char *strtime=NULL; +- time_t posixtime = epochtime; ++ time_t posixtime = ts2tt(epochtime); + + strtime = calloc (50, 1); + if (strtime == NULL) +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c +index 0fc56c2fe..1088ecc5a 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c +@@ -93,7 +93,7 @@ locked_check_p(krb5_context context, + + /* If the entry was unlocked since the last failure, it's not locked. */ + if (krb5_dbe_lookup_last_admin_unlock(context, entry, &unlock_time) == 0 && +- entry->last_failed <= unlock_time) ++ !ts_after(entry->last_failed, unlock_time)) + return FALSE; + + if (max_fail == 0 || entry->fail_auth_count < max_fail) +@@ -102,7 +102,7 @@ locked_check_p(krb5_context context, + if (lockout_duration == 0) + return TRUE; /* principal permanently locked */ + +- return (stamp < entry->last_failed + lockout_duration); ++ return ts_after(ts_incr(entry->last_failed, lockout_duration), stamp); + } + + krb5_error_code +@@ -196,14 +196,14 @@ krb5_ldap_lockout_audit(krb5_context context, + status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) { + if (krb5_dbe_lookup_last_admin_unlock(context, entry, + &unlock_time) == 0 && +- entry->last_failed <= unlock_time) { ++ !ts_after(entry->last_failed, unlock_time)) { + /* Reset fail_auth_count after administrative unlock. */ + entry->fail_auth_count = 0; + entry->mask |= KADM5_FAIL_AUTH_COUNT; + } + + if (failcnt_interval != 0 && +- stamp > entry->last_failed + failcnt_interval) { ++ ts_after(stamp, ts_incr(entry->last_failed, failcnt_interval))) { + /* Reset fail_auth_count after failcnt_interval */ + entry->fail_auth_count = 0; + entry->mask |= KADM5_FAIL_AUTH_COUNT; +diff --git a/src/windows/cns/tktlist.c b/src/windows/cns/tktlist.c +index f2805f5cd..26e699fae 100644 +--- a/src/windows/cns/tktlist.c ++++ b/src/windows/cns/tktlist.c +@@ -35,6 +35,8 @@ + #include "cns.h" + #include "tktlist.h" + ++#define ts2tt(t) (time_t)(uint32_t)(t) ++ + /* + * Ticket information for a list line + */ +@@ -167,10 +169,10 @@ ticket_init_list (HWND hwnd) + + ncred++; + strcpy (buf, " "); +- strncat(buf, short_date (c.times.starttime - kwin_get_epoch()), ++ strncat(buf, short_date(ts2tt(c.times.starttime) - kwin_get_epoch()), + sizeof(buf) - 1 - strlen(buf)); + strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); +- strncat(buf, short_date (c.times.endtime - kwin_get_epoch()), ++ strncat(buf, short_date(ts2tt(c.times.endtime) - kwin_get_epoch()), + sizeof(buf) - 1 - strlen(buf)); + strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); + +@@ -192,8 +194,8 @@ ticket_init_list (HWND hwnd) + return -1; + + lpinfo->ticket = TRUE; +- lpinfo->issue_time = c.times.starttime - kwin_get_epoch(); +- lpinfo->lifetime = c.times.endtime - c.times.starttime; ++ lpinfo->issue_time = ts2tt(c.times.starttime) - kwin_get_epoch(); ++ lpinfo->lifetime = ts2tt(c.times.endtime) - c.times.starttime; + strcpy(lpinfo->buf, buf); + + rc = ListBox_AddItemData(hwnd, lpinfo); +diff --git a/src/windows/include/leashwin.h b/src/windows/include/leashwin.h +index 9577365a7..325dce2e9 100644 +--- a/src/windows/include/leashwin.h ++++ b/src/windows/include/leashwin.h +@@ -111,9 +111,9 @@ struct TicketList { + TicketList *next; + char *service; + char *encTypes; +- krb5_timestamp issued; +- krb5_timestamp valid_until; +- krb5_timestamp renew_until; ++ time_t issued; ++ time_t valid_until; ++ time_t renew_until; + unsigned long flags; + }; + +@@ -124,9 +124,9 @@ struct TICKETINFO { + char *ccache_name; + TicketList *ticket_list; + int btickets; /* Do we have tickets? */ +- long issued; /* The issue time */ +- long valid_until; /* */ +- long renew_until; /* The Renew time (k5 only) */ ++ time_t issued; /* The issue time */ ++ time_t valid_until; /* */ ++ time_t renew_until; /* The Renew time (k5 only) */ + unsigned long flags; + }; + +diff --git a/src/windows/leash/KrbListTickets.cpp b/src/windows/leash/KrbListTickets.cpp +index beab0ea11..5dd37b05a 100644 +--- a/src/windows/leash/KrbListTickets.cpp ++++ b/src/windows/leash/KrbListTickets.cpp +@@ -92,10 +92,10 @@ etype_string(krb5_enctype enctype) + static void + CredToTicketInfo(krb5_creds KRBv5Credentials, TICKETINFO *ticketinfo) + { +- ticketinfo->issued = KRBv5Credentials.times.starttime; +- ticketinfo->valid_until = KRBv5Credentials.times.endtime; ++ ticketinfo->issued = (DWORD)KRBv5Credentials.times.starttime; ++ ticketinfo->valid_until = (DWORD)KRBv5Credentials.times.endtime; + ticketinfo->renew_until = KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ? +- KRBv5Credentials.times.renew_till : 0; ++ (DWORD)KRBv5Credentials.times.renew_till : (DWORD)0; + _tzset(); + if ( ticketinfo->valid_until - time(0) <= 0L ) + ticketinfo->btickets = EXPD_TICKETS; +@@ -137,10 +137,10 @@ CredToTicketList(krb5_context ctx, krb5_creds KRBv5Credentials, + functionName = "calloc()"; + goto cleanup; + } +- list->issued = KRBv5Credentials.times.starttime; +- list->valid_until = KRBv5Credentials.times.endtime; ++ list->issued = (DWORD)KRBv5Credentials.times.starttime; ++ list->valid_until = (DWORD)KRBv5Credentials.times.endtime; + if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE) +- list->renew_until = KRBv5Credentials.times.renew_till; ++ list->renew_until = (DWORD)KRBv5Credentials.times.renew_till; + else + list->renew_until = 0; + +diff --git a/src/windows/leash/LeashView.cpp b/src/windows/leash/LeashView.cpp +index ef2a5a3e0..253ae3f06 100644 +--- a/src/windows/leash/LeashView.cpp ++++ b/src/windows/leash/LeashView.cpp +@@ -229,22 +229,22 @@ static HFONT CreateBoldItalicFont(HFONT font) + + bool change_icon_size = true; + +-void krb5TimestampToFileTime(krb5_timestamp t, LPFILETIME pft) ++void TimestampToFileTime(time_t t, LPFILETIME pft) + { + // Note that LONGLONG is a 64-bit value +- LONGLONG ll; ++ ULONGLONG ll; + +- ll = Int32x32To64(t, 10000000) + 116444736000000000; ++ ll = UInt32x32To64((DWORD)t, 10000000) + 116444736000000000; + pft->dwLowDateTime = (DWORD)ll; + pft->dwHighDateTime = ll >> 32; + } + + // allocate outstr +-void krb5TimestampToLocalizedString(krb5_timestamp t, LPTSTR *outStr) ++void TimestampToLocalizedString(time_t t, LPTSTR *outStr) + { + FILETIME ft, lft; + SYSTEMTIME st; +- krb5TimestampToFileTime(t, &ft); ++ TimestampToFileTime(t, &ft); + FileTimeToLocalFileTime(&ft, &lft); + FileTimeToSystemTime(&lft, &st); + TCHAR timeFormat[80]; // 80 is max required for LOCALE_STIMEFORMAT +@@ -1125,9 +1125,9 @@ void CLeashView::AddDisplayItem(CListCtrl &list, + CCacheDisplayData *elem, + int iItem, + char *principal, +- long issued, +- long valid_until, +- long renew_until, ++ time_t issued, ++ time_t valid_until, ++ time_t renew_until, + char *encTypes, + unsigned long flags, + char *ccache_name) +@@ -1145,7 +1145,7 @@ void CLeashView::AddDisplayItem(CListCtrl &list, + if (issued == 0) { + list.SetItemText(iItem, iSubItem++, "Unknown"); + } else { +- krb5TimestampToLocalizedString(issued, &localTimeStr); ++ TimestampToLocalizedString(issued, &localTimeStr); + list.SetItemText(iItem, iSubItem++, localTimeStr); + } + } +@@ -1155,7 +1155,7 @@ void CLeashView::AddDisplayItem(CListCtrl &list, + } else if (valid_until < now) { + list.SetItemText(iItem, iSubItem++, "Expired"); + } else if (renew_until) { +- krb5TimestampToLocalizedString(renew_until, &localTimeStr); ++ TimestampToLocalizedString(renew_until, &localTimeStr); + DurationToString(renew_until - now, &durationStr); + if (localTimeStr && durationStr) { + _snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr); +@@ -1172,7 +1172,7 @@ void CLeashView::AddDisplayItem(CListCtrl &list, + } else if (valid_until < now) { + list.SetItemText(iItem, iSubItem++, "Expired"); + } else { +- krb5TimestampToLocalizedString(valid_until, &localTimeStr); ++ TimestampToLocalizedString(valid_until, &localTimeStr); + DurationToString(valid_until - now, &durationStr); + if (localTimeStr && durationStr) { + _snprintf(tempStr, MAX_DURATION_STR, "%s %s", localTimeStr, durationStr); +diff --git a/src/windows/leashdll/lshfunc.c b/src/windows/leashdll/lshfunc.c +index 0f76cc334..8dafb7bed 100644 +--- a/src/windows/leashdll/lshfunc.c ++++ b/src/windows/leashdll/lshfunc.c +@@ -2898,7 +2898,7 @@ static BOOL cc_have_tickets(krb5_context ctx, krb5_ccache cache) + _tzset(); + while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) { + if ((!pkrb5_is_config_principal(ctx, creds.server)) && +- (creds.times.endtime - time(0) > 0)) ++ ((time_t)(DWORD)creds.times.endtime - time(0) > 0)) + have_tickets = TRUE; + + pkrb5_free_cred_contents(ctx, &creds); +diff --git a/src/windows/ms2mit/ms2mit.c b/src/windows/ms2mit/ms2mit.c +index c3325034a..2b4373cc1 100644 +--- a/src/windows/ms2mit/ms2mit.c ++++ b/src/windows/ms2mit/ms2mit.c +@@ -74,7 +74,7 @@ cc_has_tickets(krb5_context kcontext, krb5_ccache ccache, int *has_tickets) + break; + + if (!krb5_is_config_principal(kcontext, creds.server) && +- creds.times.endtime > now) ++ ts_after(creds.times.endtime, now)) + *has_tickets = 1; + + krb5_free_cred_contents(kcontext, &creds); diff --git a/SOURCES/Prevent-KDC-unset-status-assertion-failures.patch b/SOURCES/Prevent-KDC-unset-status-assertion-failures.patch new file mode 100644 index 00000000..e57ad45e --- /dev/null +++ b/SOURCES/Prevent-KDC-unset-status-assertion-failures.patch @@ -0,0 +1,108 @@ +From 3b2376b47a9f1fc7dfd138d4ecc70e5d8897dc2b Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Thu, 13 Jul 2017 12:14:20 -0400 +Subject: [PATCH] Prevent KDC unset status assertion failures + +Assign status values if S4U2Self padata fails to decode, if an +S4U2Proxy request uses invalid KDC options, or if an S4U2Proxy request +uses an evidence ticket which does not match the canonicalized request +server principal name. Reported by Samuel Cabrero. + +If a status value is not assigned during KDC processing, default to +"UNKNOWN_REASON" rather than failing an assertion. This change will +prevent future denial of service bugs due to similar mistakes, and +will allow us to omit assigning status values for unlikely errors such +as small memory allocation failures. + +CVE-2017-11368: + +In MIT krb5 1.7 and later, an authenticated attacker can cause an +assertion failure in krb5kdc by sending an invalid S4U2Self or +S4U2Proxy request. + + CVSSv3 Vector: AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H/E:H/RL:O/RC:C + +ticket: 8599 (new) +target_version: 1.15-next +target_version: 1.14-next +tags: pullup + +(cherry picked from commit ffb35baac6981f9e8914f8f3bffd37f284b85970) +--- + src/kdc/do_as_req.c | 4 ++-- + src/kdc/do_tgs_req.c | 3 ++- + src/kdc/kdc_util.c | 10 ++++++++-- + 3 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c +index 241b05b40..f5cf8ad89 100644 +--- a/src/kdc/do_as_req.c ++++ b/src/kdc/do_as_req.c +@@ -372,8 +372,8 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode) + did_log = 1; + + egress: +- if (errcode != 0) +- assert (state->status != 0); ++ if (errcode != 0 && state->status == NULL) ++ state->status = "UNKNOWN_REASON"; + + au_state->status = state->status; + au_state->reply = &state->reply; +diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c +index 4c722a4a3..0009a9319 100644 +--- a/src/kdc/do_tgs_req.c ++++ b/src/kdc/do_tgs_req.c +@@ -829,7 +829,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt, + free(reply.enc_part.ciphertext.data); + + cleanup: +- assert(status != NULL); ++ if (status == NULL) ++ status = "UNKNOWN_REASON"; + if (reply_key) + krb5_free_keyblock(kdc_context, reply_key); + if (errcode) +diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c +index 8cbdf2c5b..5455e2a67 100644 +--- a/src/kdc/kdc_util.c ++++ b/src/kdc/kdc_util.c +@@ -1213,8 +1213,10 @@ kdc_process_for_user(kdc_realm_t *kdc_active_realm, + req_data.data = (char *)pa_data->contents; + + code = decode_krb5_pa_for_user(&req_data, &for_user); +- if (code) ++ if (code) { ++ *status = "DECODE_PA_FOR_USER"; + return code; ++ } + + code = verify_for_user_checksum(kdc_context, tgs_session, for_user); + if (code) { +@@ -1313,8 +1315,10 @@ kdc_process_s4u_x509_user(krb5_context context, + req_data.data = (char *)pa_data->contents; + + code = decode_krb5_pa_s4u_x509_user(&req_data, s4u_x509_user); +- if (code) ++ if (code) { ++ *status = "DECODE_PA_S4U_X509_USER"; + return code; ++ } + + code = verify_s4u_x509_user_checksum(context, + tgs_subkey ? tgs_subkey : +@@ -1617,6 +1621,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, + * that is validated previously in validate_tgs_request(). + */ + if (request->kdc_options & (NON_TGT_OPTION | KDC_OPT_ENC_TKT_IN_SKEY)) { ++ *status = "INVALID_S4U2PROXY_OPTIONS"; + return KRB5KDC_ERR_BADOPTION; + } + +@@ -1624,6 +1629,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, + if (!krb5_principal_compare(kdc_context, + server->princ, /* after canon */ + server_princ)) { ++ *status = "EVIDENCE_TICKET_MISMATCH"; + return KRB5KDC_ERR_SERVER_NOMATCH; + } diff --git a/SOURCES/Remove-incomplete-PKINIT-OCSP-support.patch b/SOURCES/Remove-incomplete-PKINIT-OCSP-support.patch new file mode 100644 index 00000000..83d6dc70 --- /dev/null +++ b/SOURCES/Remove-incomplete-PKINIT-OCSP-support.patch @@ -0,0 +1,134 @@ +From 9ff3ed399f9a5bb0c6101a986798d80ecc7a1b92 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 31 Jul 2017 16:03:41 -0400 +Subject: [PATCH] Remove incomplete PKINIT OCSP support + +pkinit_kdc_ocsp is non-functional in the PKINIT OpenSSL crypto +implementation, so remove most traces of it, including its man page +entry. If it is present in kdc.conf, error out of PKINIT +initialization instead of silently ignoring the realm entirely. + +ticket: 8603 (new) +(cherry picked from commit 3ff426b9048a8024e5c175256c63cd0ad0572320) +--- + doc/admin/conf_files/kdc_conf.rst | 3 --- + src/man/kdc.conf.man | 3 --- + src/plugins/preauth/pkinit/pkinit.h | 2 +- + src/plugins/preauth/pkinit/pkinit_identity.c | 11 ----------- + src/plugins/preauth/pkinit/pkinit_srv.c | 12 ++++++++++-- + 5 files changed, 11 insertions(+), 20 deletions(-) + +diff --git a/doc/admin/conf_files/kdc_conf.rst b/doc/admin/conf_files/kdc_conf.rst +index 13077ecf4..a4b2a5432 100644 +--- a/doc/admin/conf_files/kdc_conf.rst ++++ b/doc/admin/conf_files/kdc_conf.rst +@@ -765,9 +765,6 @@ For information about the syntax of some of these options, see + pkinit is used to authenticate. This option may be specified + multiple times. (New in release 1.14.) + +-**pkinit_kdc_ocsp** +- Specifies the location of the KDC's OCSP. +- + **pkinit_pool** + Specifies the location of intermediate certificates which may be + used by the KDC to complete the trust chain between a client's +diff --git a/src/man/kdc.conf.man b/src/man/kdc.conf.man +index 10b333c38..166e68f9a 100644 +--- a/src/man/kdc.conf.man ++++ b/src/man/kdc.conf.man +@@ -886,9 +886,6 @@ Specifies an authentication indicator to include in the ticket if + pkinit is used to authenticate. This option may be specified + multiple times. (New in release 1.14.) + .TP +-.B \fBpkinit_kdc_ocsp\fP +-Specifies the location of the KDC\(aqs OCSP. +-.TP + .B \fBpkinit_pool\fP + Specifies the location of intermediate certificates which may be + used by the KDC to complete the trust chain between a client\(aqs +diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h +index 876db94c3..a49f3078e 100644 +--- a/src/plugins/preauth/pkinit/pkinit.h ++++ b/src/plugins/preauth/pkinit/pkinit.h +@@ -73,6 +73,7 @@ + #define KRB5_CONF_PKINIT_IDENTITIES "pkinit_identities" + #define KRB5_CONF_PKINIT_IDENTITY "pkinit_identity" + #define KRB5_CONF_PKINIT_KDC_HOSTNAME "pkinit_kdc_hostname" ++/* pkinit_kdc_ocsp has been removed */ + #define KRB5_CONF_PKINIT_KDC_OCSP "pkinit_kdc_ocsp" + #define KRB5_CONF_PKINIT_POOL "pkinit_pool" + #define KRB5_CONF_PKINIT_REQUIRE_CRL_CHECKING "pkinit_require_crl_checking" +@@ -173,7 +174,6 @@ typedef struct _pkinit_identity_opts { + char **anchors; + char **intermediates; + char **crls; +- char *ocsp; + int idtype; + char *cert_filename; + char *key_filename; +diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c +index 177a2cad8..a897efa25 100644 +--- a/src/plugins/preauth/pkinit/pkinit_identity.c ++++ b/src/plugins/preauth/pkinit/pkinit_identity.c +@@ -125,7 +125,6 @@ pkinit_init_identity_opts(pkinit_identity_opts **idopts) + opts->anchors = NULL; + opts->intermediates = NULL; + opts->crls = NULL; +- opts->ocsp = NULL; + + opts->cert_filename = NULL; + opts->key_filename = NULL; +@@ -174,12 +173,6 @@ pkinit_dup_identity_opts(pkinit_identity_opts *src_opts, + if (retval) + goto cleanup; + +- if (src_opts->ocsp != NULL) { +- newopts->ocsp = strdup(src_opts->ocsp); +- if (newopts->ocsp == NULL) +- goto cleanup; +- } +- + if (src_opts->cert_filename != NULL) { + newopts->cert_filename = strdup(src_opts->cert_filename); + if (newopts->cert_filename == NULL) +@@ -674,10 +667,6 @@ pkinit_identity_prompt(krb5_context context, + if (retval) + goto errout; + } +- if (idopts->ocsp != NULL) { +- retval = ENOTSUP; +- goto errout; +- } + + errout: + return retval; +diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c +index 731d14eb8..32ca122f2 100644 +--- a/src/plugins/preauth/pkinit/pkinit_srv.c ++++ b/src/plugins/preauth/pkinit/pkinit_srv.c +@@ -1252,7 +1252,7 @@ static krb5_error_code + pkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx) + { + krb5_error_code retval; +- char *eku_string = NULL; ++ char *eku_string = NULL, *ocsp_check = NULL; + + pkiDebug("%s: entered for realm %s\n", __FUNCTION__, plgctx->realmname); + retval = pkinit_kdcdefault_string(context, plgctx->realmname, +@@ -1287,7 +1287,15 @@ pkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx) + + pkinit_kdcdefault_string(context, plgctx->realmname, + KRB5_CONF_PKINIT_KDC_OCSP, +- &plgctx->idopts->ocsp); ++ &ocsp_check); ++ if (ocsp_check != NULL) { ++ free(ocsp_check); ++ retval = ENOTSUP; ++ krb5_set_error_message(context, retval, ++ _("OCSP is not supported: (realm: %s)"), ++ plgctx->realmname); ++ goto errout; ++ } + + pkinit_kdcdefault_integer(context, plgctx->realmname, + KRB5_CONF_PKINIT_DH_MIN_BITS, diff --git a/SOURCES/Use-krb5_timestamp-where-appropriate.patch b/SOURCES/Use-krb5_timestamp-where-appropriate.patch new file mode 100644 index 00000000..f6693b81 --- /dev/null +++ b/SOURCES/Use-krb5_timestamp-where-appropriate.patch @@ -0,0 +1,327 @@ +From f181bf6ee4ff66489895a8c543521cbec253d1f9 Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Wed, 17 May 2017 15:14:15 -0400 +Subject: [PATCH] Use krb5_timestamp where appropriate + +Where krb5_int32 is used to hold the number of seconds since the +epoch, use krb5_timestamp instead. + +(cherry picked from commit ae25f6ec5558140a546db34fea389412d81c0631) +--- + src/clients/klist/klist.c | 2 +- + src/include/k5-int.h | 2 +- + src/kadmin/server/misc.c | 2 +- + src/kdc/dispatch.c | 4 ++-- + src/lib/kadm5/srv/server_acl.c | 2 +- + src/lib/kadm5/srv/server_kdb.c | 2 +- + src/lib/kadm5/srv/svr_principal.c | 10 +++++----- + src/lib/krb5/krb/gen_save_subkey.c | 3 ++- + src/lib/krb5/krb/get_in_tkt.c | 2 +- + src/lib/krb5/krb/init_ctx.c | 3 ++- + src/lib/krb5/os/c_ustime.c | 7 +++++-- + src/lib/krb5/os/toffset.c | 3 ++- + src/lib/krb5/os/trace.c | 3 ++- + src/lib/krb5/os/ustime.c | 3 ++- + src/lib/krb5/rcache/rc_dfl.c | 10 +++++----- + src/tests/create/kdb5_mkdums.c | 2 +- + 16 files changed, 34 insertions(+), 26 deletions(-) + +diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c +index ffeecc394..4334415be 100644 +--- a/src/clients/klist/klist.c ++++ b/src/clients/klist/klist.c +@@ -56,7 +56,7 @@ int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0; + int show_config = 0; + char *defname; + char *progname; +-krb5_int32 now; ++krb5_timestamp now; + unsigned int timestamp_width; + + krb5_context kcontext; +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 82ee20760..ed9c7bf75 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -721,7 +721,7 @@ krb5_error_code krb5int_c_copy_keyblock_contents(krb5_context context, + const krb5_keyblock *from, + krb5_keyblock *to); + +-krb5_error_code krb5_crypto_us_timeofday(krb5_int32 *, krb5_int32 *); ++krb5_error_code krb5_crypto_us_timeofday(krb5_timestamp *, krb5_int32 *); + + /* + * End "los-proto.h" +diff --git a/src/kadmin/server/misc.c b/src/kadmin/server/misc.c +index a75b65a26..ba672d714 100644 +--- a/src/kadmin/server/misc.c ++++ b/src/kadmin/server/misc.c +@@ -159,7 +159,7 @@ kadm5_ret_t + check_min_life(void *server_handle, krb5_principal principal, + char *msg_ret, unsigned int msg_len) + { +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_ret_t ret; + kadm5_policy_ent_rec pol; + kadm5_principal_ent_rec princ; +diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c +index 16a35d2be..4ecc23481 100644 +--- a/src/kdc/dispatch.c ++++ b/src/kdc/dispatch.c +@@ -94,8 +94,8 @@ static void + reseed_random(krb5_context kdc_err_context) + { + krb5_error_code retval; +- krb5_int32 now, now_usec; +- krb5_int32 usec_difference; ++ krb5_timestamp now; ++ krb5_int32 now_usec, usec_difference; + krb5_data data; + + retval = krb5_crypto_us_timeofday(&now, &now_usec); +diff --git a/src/lib/kadm5/srv/server_acl.c b/src/lib/kadm5/srv/server_acl.c +index 656dddff5..c2cf69169 100644 +--- a/src/lib/kadm5/srv/server_acl.c ++++ b/src/lib/kadm5/srv/server_acl.c +@@ -375,7 +375,7 @@ kadm5int_acl_impose_restrictions(kcontext, recp, maskp, rp) + restriction_t *rp; + { + krb5_error_code code; +- krb5_int32 now; ++ krb5_timestamp now; + + DPRINT(DEBUG_CALLS, acl_debug_level, + ("* kadm5int_acl_impose_restrictions(..., *maskp=0x%08x, rp=0x%08x)\n", +diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c +index 612553ba3..f4b8aef2b 100644 +--- a/src/lib/kadm5/srv/server_kdb.c ++++ b/src/lib/kadm5/srv/server_kdb.c +@@ -365,7 +365,7 @@ kdb_put_entry(kadm5_server_handle_t handle, + krb5_db_entry *kdb, osa_princ_ent_rec *adb) + { + krb5_error_code ret; +- krb5_int32 now; ++ krb5_timestamp now; + XDR xdrs; + krb5_tl_data tl_data; + +diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c +index f4a9a2ad2..0d4f0a632 100644 +--- a/src/lib/kadm5/srv/svr_principal.c ++++ b/src/lib/kadm5/srv/svr_principal.c +@@ -296,7 +296,7 @@ kadm5_create_principal_3(void *server_handle, + osa_princ_ent_rec adb; + kadm5_policy_ent_rec polent; + krb5_boolean have_polent = FALSE; +- krb5_int32 now; ++ krb5_timestamp now; + krb5_tl_data *tl_data_tail; + unsigned int ret; + kadm5_server_handle_t handle = server_handle; +@@ -1322,7 +1322,7 @@ kadm5_chpass_principal_3(void *server_handle, + int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, + char *password) + { +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_policy_ent_rec pol; + osa_princ_ent_rec adb; + krb5_db_entry *kdb; +@@ -1544,7 +1544,7 @@ kadm5_randkey_principal_3(void *server_handle, + { + krb5_db_entry *kdb; + osa_princ_ent_rec adb; +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_policy_ent_rec pol; + int ret, last_pwd, n_new_keys; + krb5_boolean have_pol = FALSE; +@@ -1686,7 +1686,7 @@ kadm5_setv4key_principal(void *server_handle, + { + krb5_db_entry *kdb; + osa_princ_ent_rec adb; +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_policy_ent_rec pol; + krb5_keysalt keysalt; + int i, kvno, ret; +@@ -1888,7 +1888,7 @@ kadm5_setkey_principal_4(void *server_handle, krb5_principal principal, + { + krb5_db_entry *kdb; + osa_princ_ent_rec adb; +- krb5_int32 now; ++ krb5_timestamp now; + kadm5_policy_ent_rec pol; + krb5_key_data *new_key_data = NULL; + int i, j, ret, n_new_key_data = 0; +diff --git a/src/lib/krb5/krb/gen_save_subkey.c b/src/lib/krb5/krb/gen_save_subkey.c +index 61f36aa36..bc2c46d30 100644 +--- a/src/lib/krb5/krb/gen_save_subkey.c ++++ b/src/lib/krb5/krb/gen_save_subkey.c +@@ -38,7 +38,8 @@ k5_generate_and_save_subkey(krb5_context context, + to guarantee randomness, but to make it less likely that multiple + sessions could pick the same subkey. */ + struct { +- krb5_int32 sec, usec; ++ krb5_timestamp sec; ++ krb5_int32 usec; + } rnd_data; + krb5_data d; + krb5_error_code retval; +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index 40aba1905..7178bd87b 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -1788,7 +1788,7 @@ k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **out, + krb5_creds *creds) + { + int i; +- krb5_int32 starttime; ++ krb5_timestamp starttime; + krb5_deltat lifetime; + krb5_get_init_creds_opt *opt; + krb5_error_code retval; +diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c +index cf226fdba..4246c5dd2 100644 +--- a/src/lib/krb5/krb/init_ctx.c ++++ b/src/lib/krb5/krb/init_ctx.c +@@ -139,7 +139,8 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags, + krb5_context ctx = 0; + krb5_error_code retval; + struct { +- krb5_int32 now, now_usec; ++ krb5_timestamp now; ++ krb5_int32 now_usec; + long pid; + } seed_data; + krb5_data seed; +diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c +index 68fb381f4..f69f2ea4c 100644 +--- a/src/lib/krb5/os/c_ustime.c ++++ b/src/lib/krb5/os/c_ustime.c +@@ -29,7 +29,10 @@ + + k5_mutex_t krb5int_us_time_mutex = K5_MUTEX_PARTIAL_INITIALIZER; + +-struct time_now { krb5_int32 sec, usec; }; ++struct time_now { ++ krb5_timestamp sec; ++ krb5_int32 usec; ++}; + + #if defined(_WIN32) + +@@ -73,7 +76,7 @@ get_time_now(struct time_now *n) + static struct time_now last_time; + + krb5_error_code +-krb5_crypto_us_timeofday(krb5_int32 *seconds, krb5_int32 *microseconds) ++krb5_crypto_us_timeofday(krb5_timestamp *seconds, krb5_int32 *microseconds) + { + struct time_now now; + krb5_error_code err; +diff --git a/src/lib/krb5/os/toffset.c b/src/lib/krb5/os/toffset.c +index 37bc69f49..4bbcdde52 100644 +--- a/src/lib/krb5/os/toffset.c ++++ b/src/lib/krb5/os/toffset.c +@@ -40,7 +40,8 @@ krb5_error_code KRB5_CALLCONV + krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds) + { + krb5_os_context os_ctx = &context->os_context; +- krb5_int32 sec, usec; ++ krb5_timestamp sec; ++ krb5_int32 usec; + krb5_error_code retval; + + retval = krb5_crypto_us_timeofday(&sec, &usec); +diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c +index 74c315c90..8750b7650 100644 +--- a/src/lib/krb5/os/trace.c ++++ b/src/lib/krb5/os/trace.c +@@ -340,7 +340,8 @@ krb5int_trace(krb5_context context, const char *fmt, ...) + va_list ap; + krb5_trace_info info; + char *str = NULL, *msg = NULL; +- krb5_int32 sec, usec; ++ krb5_timestamp sec; ++ krb5_int32 usec; + + if (context == NULL || context->trace_callback == NULL) + return; +diff --git a/src/lib/krb5/os/ustime.c b/src/lib/krb5/os/ustime.c +index 1c1b571eb..a80fdf68c 100644 +--- a/src/lib/krb5/os/ustime.c ++++ b/src/lib/krb5/os/ustime.c +@@ -40,7 +40,8 @@ krb5_error_code + k5_time_with_offset(krb5_timestamp offset, krb5_int32 offset_usec, + krb5_timestamp *time_out, krb5_int32 *usec_out) + { +- krb5_int32 sec, usec; ++ krb5_timestamp sec; ++ krb5_int32 usec; + krb5_error_code retval; + + retval = krb5_crypto_us_timeofday(&sec, &usec); +diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c +index 6b043844d..41ebf94da 100644 +--- a/src/lib/krb5/rcache/rc_dfl.c ++++ b/src/lib/krb5/rcache/rc_dfl.c +@@ -93,7 +93,7 @@ cmp(krb5_donot_replay *old, krb5_donot_replay *new1, krb5_deltat t) + } + + static int +-alive(krb5_int32 mytime, krb5_donot_replay *new1, krb5_deltat t) ++alive(krb5_timestamp mytime, krb5_donot_replay *new1, krb5_deltat t) + { + if (mytime == 0) + return CMP_HOHUM; /* who cares? */ +@@ -129,7 +129,7 @@ struct authlist + + static int + rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep, +- krb5_int32 now, krb5_boolean fromfile) ++ krb5_timestamp now, krb5_boolean fromfile) + { + struct dfl_data *t = (struct dfl_data *)id->data; + unsigned int rephash; +@@ -536,7 +536,7 @@ krb5_rc_dfl_recover_locked(krb5_context context, krb5_rcache id) + krb5_error_code retval; + long max_size; + int expired_entries = 0; +- krb5_int32 now; ++ krb5_timestamp now; + + if ((retval = krb5_rc_io_open(context, &t->d, t->name))) { + return retval; +@@ -706,7 +706,7 @@ krb5_rc_dfl_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep) + { + krb5_error_code ret; + struct dfl_data *t; +- krb5_int32 now; ++ krb5_timestamp now; + + ret = krb5_timeofday(context, &now); + if (ret) +@@ -762,7 +762,7 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id) + struct authlist **qt; + struct authlist *r; + struct authlist *rt; +- krb5_int32 now; ++ krb5_timestamp now; + + if (krb5_timestamp(context, &now)) + now = 0; +diff --git a/src/tests/create/kdb5_mkdums.c b/src/tests/create/kdb5_mkdums.c +index 622f549f9..7c0666601 100644 +--- a/src/tests/create/kdb5_mkdums.c ++++ b/src/tests/create/kdb5_mkdums.c +@@ -247,7 +247,7 @@ add_princ(context, str_newprinc) + + { + /* Add mod princ to db entry */ +- krb5_int32 now; ++ krb5_timestamp now; + + retval = krb5_timeofday(context, &now); + if (retval) { diff --git a/SOURCES/Use-the-canonical-client-principal-name-for-OTP.patch b/SOURCES/Use-the-canonical-client-principal-name-for-OTP.patch new file mode 100644 index 00000000..90f42132 --- /dev/null +++ b/SOURCES/Use-the-canonical-client-principal-name-for-OTP.patch @@ -0,0 +1,29 @@ +From 685698f8d33810ce085da4d75d1d8febe5323fd3 Mon Sep 17 00:00:00 2001 +From: Matt Rogers +Date: Wed, 5 Apr 2017 16:48:55 -0400 +Subject: [PATCH] Use the canonical client principal name for OTP + +In the OTP module, when constructing the RADIUS request, use the +canonicalized client principal (using the new client_name kdcpreauth +callback) instead of the request client principal. + +ticket: 8571 (new) +(cherry picked from commit 6411398e35e343cdc4d2d103b079c4d3b9031f7e) +--- + src/plugins/preauth/otp/main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/plugins/preauth/otp/main.c b/src/plugins/preauth/otp/main.c +index 2649e9a90..a1b681682 100644 +--- a/src/plugins/preauth/otp/main.c ++++ b/src/plugins/preauth/otp/main.c +@@ -331,7 +331,8 @@ otp_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request, + + /* Send the request. */ + otp_state_verify((otp_state *)moddata, cb->event_context(context, rock), +- request->client, config, req, on_response, rs); ++ cb->client_name(context, rock), config, req, on_response, ++ rs); + cb->free_string(context, rock, config); + + k5_free_pa_otp_req(context, req); diff --git a/SOURCES/_kadmind b/SOURCES/_kadmind new file mode 100644 index 00000000..b073cfb1 --- /dev/null +++ b/SOURCES/_kadmind @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Check for error conditions which the init system expects us to check and +# for other common errors, and exit with the expected status codes. +# +kadmind=/usr/sbin/kadmind +if test -f /var/kerberos/krb5kdc/kpropd.acl ; then + echo $"Error. This appears to be a slave server, found kpropd.acl" + exit 6 +fi +if ! test -x "$kadmind" ; then + exit 5 +fi +exec "$kadmind" "$@" diff --git a/SOURCES/_kpropd b/SOURCES/_kpropd new file mode 100644 index 00000000..18083683 --- /dev/null +++ b/SOURCES/_kpropd @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Check for error conditions which the init system expects us to check and +# for other common errors, and exit with the expected status codes. +# +kpropd=/usr/sbin/kpropd +if ! test -f /var/kerberos/krb5kdc/kpropd.acl ; then + echo $"Error. This does not appear to be a slave server, kpropd.acl not found" + exit 6 +fi +if ! test -x "$kpropd" ; then + exit 5 +fi +exec "$kpropd" "$@" diff --git a/SOURCES/kadm5.acl b/SOURCES/kadm5.acl new file mode 100644 index 00000000..dc93eb0a --- /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 00000000..ede159ed --- /dev/null +++ b/SOURCES/kadmin.service @@ -0,0 +1,13 @@ +[Unit] +Description=Kerberos 5 Password-changing and Administration +After=syslog.target network.target + +[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 00000000..fa72039b --- /dev/null +++ b/SOURCES/kadmin.sysconfig @@ -0,0 +1 @@ +KADMIND_ARGS= diff --git a/SOURCES/kadmind.init b/SOURCES/kadmind.init new file mode 100755 index 00000000..40d94548 --- /dev/null +++ b/SOURCES/kadmind.init @@ -0,0 +1,108 @@ +#!/bin/bash +# +# kadmind Start and stop the Kerberos 5 administrative server. +# +# chkconfig: - 35 65 +# description: Kerberos 5 is a trusted third-party authentication system. \ +# This script starts and stops the Kerberos 5 administrative \ +# server, which should only be run on the master server for a \ +# realm. +# processname: kadmind +# config: /etc/sysconfig/kadmin +# pidfile: /var/run/kadmind.pid +# + +### BEGIN INIT INFO +# Provides: kadmin +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Should-Start: portreserve +# Default-Start: +# Default-Stop: 0 1 2 3 4 5 6 +# Short-Description: start and stop the Kerberos 5 admin server +# Description: The kadmind service allows administrators to remotely manage \ +# the Kerberos 5 realm database. It should only be run on a \ +# master KDC. +### END INIT INFO + +# Get config. +. /etc/sysconfig/network + +# Get config. +[ -r /etc/sysconfig/kadmin ] && . /etc/sysconfig/kadmin + +# Source function library. +. /etc/init.d/functions +prog="Kerberos 5 Admin Server" +kadmind=/usr/sbin/kadmind +pidfile=/var/run/kadmind.pid + +RETVAL=0 + +# Shell functions to cut down on useless shell instances. +start() { + if [ -f /var/kerberos/krb5kdc/kpropd.acl ] ; then + echo $"Error. This appears to be a slave server, found kpropd.acl" + exit 6 + else + [ -x $kadmind ] || exit 5 + fi + echo -n $"Starting $prog: " + # tell portreserve to release the kerberos-adm port + [ -x /sbin/portrelease ] && /sbin/portrelease kerberos-adm &>/dev/null || : + daemon ${kadmind} ${KRB5REALM:+-r ${KRB5REALM}} -P $pidfile $KADMIND_ARGS + RETVAL=$? + echo + if test $RETVAL -ne 0 ; then + if status -l kadmin ${kadmind} > /dev/null ; then + RETVAL=0 + fi + fi + [ $RETVAL = 0 ] && touch /var/lock/subsys/kadmin +} +stop() { + echo -n $"Stopping $prog: " + killproc ${kadmind} + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f /var/lock/subsys/kadmin +} +reload() { + echo -n $"Reopening $prog log file: " + killproc ${kadmind} -HUP + RETVAL=$? + echo +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + status -l kadmin ${kadmind} + RETVAL=$? + ;; + reload) + reload + ;; + condrestart) + if [ -f /var/lock/subsys/kadmin ] ; then + stop + start + fi + ;; + *) + echo $"Usage: $0 {start|stop|status|condrestart|reload|restart}" + RETVAL=2 + ;; +esac + +exit $RETVAL diff --git a/SOURCES/kadmind.logrotate b/SOURCES/kadmind.logrotate new file mode 100644 index 00000000..52a66c41 --- /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 00000000..e99219a3 --- /dev/null +++ b/SOURCES/kdc.conf @@ -0,0 +1,12 @@ +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[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 des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal + } diff --git a/SOURCES/kerberos-adm.portreserve b/SOURCES/kerberos-adm.portreserve new file mode 100644 index 00000000..eb6080d7 --- /dev/null +++ b/SOURCES/kerberos-adm.portreserve @@ -0,0 +1 @@ +kerberos-adm/tcp diff --git a/SOURCES/kprop.service b/SOURCES/kprop.service new file mode 100644 index 00000000..da6a6b89 --- /dev/null +++ b/SOURCES/kprop.service @@ -0,0 +1,11 @@ +[Unit] +Description=Kerberos 5 Propagation +After=syslog.target network.target + +[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 00000000..f43e8bb9 --- /dev/null +++ b/SOURCES/kprop.sysconfig @@ -0,0 +1 @@ +KPROPD_ARGS= diff --git a/SOURCES/kpropd.init b/SOURCES/kpropd.init new file mode 100755 index 00000000..b057fc1c --- /dev/null +++ b/SOURCES/kpropd.init @@ -0,0 +1,92 @@ +#!/bin/bash +# +# kpropd.init Start and stop the Kerberos 5 propagation client. +# +# chkconfig: - 35 65 +# description: Kerberos 5 is a trusted third-party authentication system. \ +# This script starts and stops the service that allows this \ +# KDC to receive updates from your master KDC. +# processname: kpropd +# + +### BEGIN INIT INFO +# Provides: kprop +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Should-Start: portreserve +# Default-Start: +# Default-Stop: 0 1 2 3 4 5 6 +# Short-Description: start and stop the Kerberos 5 propagation client +# Description: The kpropd service accepts database updates pushed to it from \ +# the master KDC. It will never be needed on a master KDC. +### END INIT INFO + +# Get config. +. /etc/sysconfig/network + +# Source function library. +. /etc/init.d/functions + +RETVAL=0 +prog="Kerberos 5 Propagation Server" +kpropd=/usr/sbin/kpropd + +# Shell functions to cut down on useless shell instances. +start() { + [ -f /var/kerberos/krb5kdc/kpropd.acl ] || exit 6 + [ -x $kpropd ] || exit 5 + echo -n $"Starting $prog: " + # tell portreserve to release the krb5_prop port + [ -x /sbin/portrelease ] && /sbin/portrelease krb5_prop &>/dev/null || : + daemon ${kpropd} -S + RETVAL=$? + echo + if test $RETVAL -ne 0 ; then + if status -l kprop ${kpropd} > /dev/null ; then + RETVAL=0 + fi + fi + [ $RETVAL = 0 ] && touch /var/lock/subsys/kprop +} +stop() { + echo -n $"Stopping $prog: " + killproc ${kpropd} + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f /var/lock/subsys/kprop +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + # We don't really "do" reload, so treat it as a restart. + restart|force-reload) + stop + start + ;; + reload) + echo "can't reload configuration, you have to restart it" + RETVAL=3 + ;; + status) + status -l kprop ${kpropd} + RETVAL=$? + ;; + condrestart) + if [ -f /var/lock/subsys/kprop ] ; then + stop + start + fi + ;; + *) + echo $"Usage: $0 {start|stop|restart|condrestart|reload|status|force-reload}" + RETVAL=2 + ;; +esac + +exit $RETVAL diff --git a/SOURCES/krb5-1.11-kpasswdtest.patch b/SOURCES/krb5-1.11-kpasswdtest.patch new file mode 100644 index 00000000..25fec7cc --- /dev/null +++ b/SOURCES/krb5-1.11-kpasswdtest.patch @@ -0,0 +1,20 @@ +From c21187b3a9f37fd88230e963275d3242344f8f82 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:03:40 -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 00000000..6bb90e2e --- /dev/null +++ b/SOURCES/krb5-1.11-run_user_0.patch @@ -0,0 +1,41 @@ +From b22fe94f6965ebdd2e0cbf2ac002e0e5f9c11789 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:03:22 -0400 +Subject: [PATCH] krb5-1.11-run_user_0.patch + +--- + 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 + ++#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 00000000..63c23de3 --- /dev/null +++ b/SOURCES/krb5-1.12-api.patch @@ -0,0 +1,34 @@ +From a609a605d87b3107de64141cd3d60c2a73c7b38f Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 09:59:22 -0400 +Subject: [PATCH] krb5-1.12-api.patch + +--- + 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 00000000..b5fbac5e --- /dev/null +++ b/SOURCES/krb5-1.12-ksu-path.patch @@ -0,0 +1,21 @@ +From fc004dc501c6fc1f1f423a8d87cdc9137d7f6bbf Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 09:57:25 -0400 +Subject: [PATCH] krb5-1.12-ksu-path.patch + +--- + 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 00000000..210956bd --- /dev/null +++ b/SOURCES/krb5-1.12-ktany.patch @@ -0,0 +1,363 @@ +From 5c9294c37210d01f59c54ea623a66618ed2e0e6e Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 09:58:00 -0400 +Subject: [PATCH] krb5-1.12-ktany.patch + +--- + 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 00000000..5bf7ee40 --- /dev/null +++ b/SOURCES/krb5-1.12.1-pam.patch @@ -0,0 +1,757 @@ +From 9a6c3d9c1f4286a1a17cd89a1225712606863da8 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 18 Apr 2016 15:57:38 -0400 +Subject: [PATCH] krb5-1.12.1-pam.patch + +--- + 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 9c46da4b5..508e5fe90 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -1675,3 +1675,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 28342c2d7..cab0c1806 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 +@@ -33,6 +34,10 @@ + #include + #include + ++#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" +@@ -515,6 +521,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 " +@@ -575,6 +598,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){ +@@ -632,6 +673,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"); +@@ -729,7 +794,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); +@@ -759,16 +824,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 ++#include ++#include ++#include ++#include ++#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 ++#ifdef HAVE_SECURITY_PAM_APPL_H ++#include ++#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 037c9f316..daabd12c8 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1336,6 +1336,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 00000000..9611a254 --- /dev/null +++ b/SOURCES/krb5-1.13-dirsrv-accountlock.patch @@ -0,0 +1,73 @@ +From f8404b502015b4a9806894d212462c63c3307fa8 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:01:15 -0400 +Subject: [PATCH] krb5-1.13-dirsrv-accountlock.patch + +--- + src/aclocal.m4 | 9 +++++++++ + src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c | 17 +++++++++++++++++ + src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c | 3 +++ + 3 files changed, 29 insertions(+) + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index f5667c35f..2bfb99496 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -1656,6 +1656,15 @@ if test "$with_ldap" = yes; then + AC_MSG_NOTICE(enabling OpenLDAP database backend module support) + OPENLDAP_PLUGIN=yes + fi ++AC_ARG_WITH([dirsrv-account-locking], ++[ --with-dirsrv-account-locking compile 389/Red Hat/Fedora/Netscape Directory Server database backend module], ++[case "$withval" in ++ yes | no) ;; ++ *) AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;; ++esac], with_dirsrv_account_locking=no) ++if test $with_dirsrv_account_locking = yes; then ++ AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.]) ++fi + ])dnl + dnl + dnl If libkeyutils exists (on Linux) include it and use keyring ccache +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c +index 32efc4f54..af8b2db7b 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c +@@ -1674,6 +1674,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 00000000..a80c3498 --- /dev/null +++ b/SOURCES/krb5-1.15-beta1-buildconf.patch @@ -0,0 +1,65 @@ +From eda215b5fdf43de6d5e0ee3641bb4bb42728ab11 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 4 Jan 2017 13:18:18 -0500 +Subject: [PATCH] krb5-1.15-beta1-buildconf.patch + +--- + 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 fcea229bd..d961b5621 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.15-beta1-selinux-label.patch b/SOURCES/krb5-1.15-beta1-selinux-label.patch new file mode 100644 index 00000000..7688559d --- /dev/null +++ b/SOURCES/krb5-1.15-beta1-selinux-label.patch @@ -0,0 +1,1033 @@ +From 71fe21b5aeac1834df824ff5c6475e653ceb8b6b Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Wed, 4 Jan 2017 13:17:28 -0500 +Subject: [PATCH] krb5-1.15-beta1-selinux-label.patch + +--- + 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/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/slave/kpropd.c | 9 + + 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 508e5fe90..607859f17 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 +@@ -1742,3 +1743,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 e0626320c..fcea229bd 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= +@@ -399,7 +400,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME) + # HESIOD_LIBS is -lhesiod... + HESIOD_LIBS = @HESIOD_LIBS@ + +-KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB) ++KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB) + KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS) + GSS_LIBS = $(GSS_KRB5_LIB) + # needs fixing if ever used on Mac OS X! +diff --git a/src/configure.in b/src/configure.in +index daabd12c8..acf3a458b 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1338,6 +1338,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 64991738a..173cb0264 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 ++#include ++#include ++#include ++#include ++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 ac22f4c55..cf60d6c41 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 +diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c +index f7889bd23..cad53cfbf 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; + +@@ -194,7 +203,7 @@ prep_ok_file(krb5_context context, char *file_name, int *fd) + return 0; + } + +- *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); ++ *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (*fd == -1) { + com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok); + exit_status++; +diff --git a/src/kdc/main.c b/src/kdc/main.c +index ebc852bba..a4dffb29a 100644 +--- a/src/kdc/main.c ++++ b/src/kdc/main.c +@@ -872,7 +872,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/lib/kadm5/logger.c b/src/lib/kadm5/logger.c +index ce79fabf7..c53a5743f 100644 +--- a/src/lib/kadm5/logger.c ++++ b/src/lib/kadm5/logger.c +@@ -414,7 +414,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"); +@@ -918,7 +918,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 766d3002a..6466417b7 100644 +--- a/src/lib/kdb/kdb_log.c ++++ b/src/lib/kdb/kdb_log.c +@@ -476,7 +476,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries) + int ulogfd = -1; + + if (stat(logname, &st) == -1) { +- ulogfd = open(logname, O_RDWR | O_CREAT, 0600); ++ ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600); + if (ulogfd == -1) + return errno; + +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 6a42f267d..674d88bab 100644 +--- a/src/lib/krb5/keytab/kt_file.c ++++ b/src/lib/krb5/keytab/kt_file.c +@@ -1022,14 +1022,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 83c8d4db8..a19246128 100644 +--- a/src/lib/krb5/os/trace.c ++++ b/src/lib/krb5/os/trace.c +@@ -397,7 +397,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 c4d2c744d..c0f12ed9d 100644 +--- a/src/lib/krb5/rcache/rc_dfl.c ++++ b/src/lib/krb5/rcache/rc_dfl.c +@@ -794,6 +794,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; +@@ -815,7 +818,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 4c4036eb4..d90bdeaba 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 + #include + ++#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 76f5d4709..1fa8b8389 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 + #endif + ++#include "k5-int.h" + #include "db-int.h" + #include "hash.h" + #include "page.h" +@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info, 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 + #include + ++#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 022156a5e..3d6994c67 100644 +--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c ++++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c +@@ -203,7 +203,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)); +@@ -244,6 +244,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; + +@@ -255,7 +258,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/slave/kpropd.c b/src/slave/kpropd.c +index 056c31a42..b78c3d9e5 100644 +--- a/src/slave/kpropd.c ++++ b/src/slave/kpropd.c +@@ -464,6 +464,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); +@@ -520,9 +523,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/util/profile/prof_file.c b/src/util/profile/prof_file.c +index 907c119bb..0f5462aea 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 */ +@@ -423,7 +424,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 6239e4176..17bcd2a67 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 \ +@@ -148,7 +149,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..230263421 +--- /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 ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* #define DEBUG 1 */ ++static void ++debug_log(const char *fmt, ...) ++{ ++#ifdef DEBUG ++ va_list ap; ++ va_start(ap, str); ++ 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(¤tsc); ++ ++ /* 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.3.1-dns.patch b/SOURCES/krb5-1.3.1-dns.patch new file mode 100644 index 00000000..9c4a2ebb --- /dev/null +++ b/SOURCES/krb5-1.3.1-dns.patch @@ -0,0 +1,21 @@ +From e48799ea02841461af9a97a8f490bcf4f4ac5666 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 09:59:05 -0400 +Subject: [PATCH] krb5-1.3.1-dns.patch + +--- + src/aclocal.m4 | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index 607859f17..f5667c35f 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -703,6 +703,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 00000000..43770e5f --- /dev/null +++ b/SOURCES/krb5-1.9-debuginfo.patch @@ -0,0 +1,36 @@ +From 502177c9256aa52ee3f7812f5127619475b3c7a5 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:02:40 -0400 +Subject: [PATCH] krb5-1.9-debuginfo.patch + +--- + 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 00000000..eadeb51f --- /dev/null +++ b/SOURCES/krb5-krb5kdc.conf @@ -0,0 +1 @@ +d /var/run/krb5kdc 0755 root root diff --git a/SOURCES/krb5-kvno-230379.patch b/SOURCES/krb5-kvno-230379.patch new file mode 100644 index 00000000..7ef0fe85 --- /dev/null +++ b/SOURCES/krb5-kvno-230379.patch @@ -0,0 +1,53 @@ +From 16c9dd3d2f8d74958495674f4906626a74ef8c12 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:03:07 -0400 +Subject: [PATCH] krb5-kvno-230379.patch + +--- + src/kadmin/ktutil/ktutil.c | 5 +++-- + src/lib/krb5/keytab/kt_file.c | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/kadmin/ktutil/ktutil.c b/src/kadmin/ktutil/ktutil.c +index ef16d37a5..64a6d6ab1 100644 +--- a/src/kadmin/ktutil/ktutil.c ++++ b/src/kadmin/ktutil/ktutil.c +@@ -140,7 +140,7 @@ void ktutil_add_entry(argc, argv) + char *princ = NULL; + char *enctype = NULL; + krb5_kvno kvno = 0; +- int use_pass = 0, use_key = 0, i; ++ int use_pass = 0, use_key = 0, use_kvno = 0, i; + + for (i = 1; i < argc; i++) { + if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) { +@@ -149,6 +149,7 @@ void ktutil_add_entry(argc, argv) + } + if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) { + kvno = (krb5_kvno) atoi(argv[++i]); ++ use_kvno++; + continue; + } + if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { +@@ -165,7 +166,7 @@ void ktutil_add_entry(argc, argv) + } + } + +- if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) { ++ if (argc != 8 || !(princ && use_kvno && enctype) || (use_pass+use_key != 1)) { + fprintf(stderr, _("usage: %s (-key | -password) -p principal " + "-k kvno -e enctype\n"), argv[0]); + return; +diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c +index 674d88bab..131549ffe 100644 +--- a/src/lib/krb5/keytab/kt_file.c ++++ b/src/lib/krb5/keytab/kt_file.c +@@ -377,7 +377,7 @@ krb5_ktfile_get_entry(krb5_context context, krb5_keytab id, + * Otherwise, remember that we were here so we can return the right + * error, and free the new. + */ +- if (new_entry.vno == kvno) { ++ if (new_entry.vno == kvno || new_entry.vno == IGNORE_VNO) { + krb5_kt_free_entry(context, &cur_entry); + cur_entry = new_entry; + if (new_entry.vno == kvno) diff --git a/SOURCES/krb5.conf b/SOURCES/krb5.conf new file mode 100644 index 00000000..77d794ad --- /dev/null +++ b/SOURCES/krb5.conf @@ -0,0 +1,25 @@ +# Configuration snippets may be placed in this directory as well +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 +# 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/krb5_prop.portreserve b/SOURCES/krb5_prop.portreserve new file mode 100644 index 00000000..54eeff2e --- /dev/null +++ b/SOURCES/krb5_prop.portreserve @@ -0,0 +1 @@ +krb5_prop/tcp diff --git a/SOURCES/krb5kdc.init b/SOURCES/krb5kdc.init new file mode 100755 index 00000000..3462ca65 --- /dev/null +++ b/SOURCES/krb5kdc.init @@ -0,0 +1,102 @@ +#!/bin/bash +# +# krb5kdc Start and stop the Kerberos 5 servers. +# +# chkconfig: - 35 65 +# description: Kerberos 5 is a trusted third-party authentication system. \ +# This script starts and stops the server that Kerberos 5 \ +# clients need to connect to in order to obtain credentials. +# processname: krb5kdc +# config: /etc/sysconfig/krb5kdc +# pidfile: /var/run/krb5kdc.pid +# + +### BEGIN INIT INFO +# Provides: krb5kdc +# Required-Start: $local_fs $network +# Required-Stop: $local_fs $network +# Should-Start: portreserve +# Default-Start: +# Default-Stop: 0 1 2 3 4 5 6 +# Short-Description: start and stop the Kerberos 5 KDC +# Description: The krb5kdc is the Kerberos 5 key distribution center, which \ +# issues credentials to Kerberos 5 clients. +### END INIT INFO + +# Get config. +. /etc/sysconfig/network + +# Get config. +[ -r /etc/sysconfig/krb5kdc ] && . /etc/sysconfig/krb5kdc + +# Source function library. +. /etc/rc.d/init.d/functions + +RETVAL=0 +prog="Kerberos 5 KDC" +krb5kdc=/usr/sbin/krb5kdc +pidfile=/var/run/krb5kdc.pid +PATH=/usr/lib64/krb5:/usr/lib/krb5:"$PATH" + +# Shell functions to cut down on useless shell instances. +start() { + [ -x $krb5kdc ] || exit 5 + echo -n $"Starting $prog: " + # tell portreserve to release the kerberos-iv port + [ -x /sbin/portrelease ] && /sbin/portrelease kerberos-iv &>/dev/null || : + daemon ${krb5kdc} ${KRB5REALM:+-r ${KRB5REALM}} -P $pidfile $KRB5KDC_ARGS + RETVAL=$? + echo + if test $RETVAL -ne 0 ; then + if status ${krb5kdc} > /dev/null ; then + RETVAL=0 + fi + fi + [ $RETVAL = 0 ] && touch /var/lock/subsys/krb5kdc +} +stop() { + echo -n $"Stopping $prog: " + killproc ${krb5kdc} + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f /var/lock/subsys/krb5kdc +} +reload() { + echo -n $"Reopening $prog log file: " + killproc ${krb5kdc} -HUP + RETVAL=$? + echo +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + reload) + reload + ;; + status) + status ${krb5kdc} + RETVAL=$? + ;; + condrestart) + if [ -f /var/lock/subsys/krb5kdc ] ; then + stop + start + fi + ;; + *) + echo $"Usage: $0 {start|stop|status|reload|restart|condrestart}" + RETVAL=2 + ;; +esac + +exit $RETVAL diff --git a/SOURCES/krb5kdc.logrotate b/SOURCES/krb5kdc.logrotate new file mode 100644 index 00000000..1100ed3a --- /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 00000000..bc492047 --- /dev/null +++ b/SOURCES/krb5kdc.service @@ -0,0 +1,13 @@ +[Unit] +Description=Kerberos 5 KDC +After=syslog.target network.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 00000000..791216d3 --- /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 00000000..66f5b2cc --- /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/SOURCES/noport.c b/SOURCES/noport.c new file mode 100644 index 00000000..22088eb0 --- /dev/null +++ b/SOURCES/noport.c @@ -0,0 +1,111 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +static int +port_is_okay(unsigned short port) +{ + char *p, *q; + long l; + + p = getenv("NOPORT"); + while ((p != NULL) && (*p != '\0')) { + l = strtol(p, &q, 10); + if ((q == NULL) || (q == p)) { + break; + } + if ((*q == '\0') || (*q == ',')) { + if (port == l) { + errno = ECONNREFUSED; + return -1; + } + } + p = q; + p += strspn(p, ","); + } + return 0; +} + +int +connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + unsigned short port; + static int (*next_connect)(int, const struct sockaddr *, socklen_t); + + if (next_connect == NULL) { + next_connect = dlsym(RTLD_NEXT, "connect"); + if (next_connect == NULL) { + errno = ENOSYS; + return -1; + } + } + + if (getenv("NOPORT") == NULL) { + return next_connect(sockfd, addr, addrlen); + } + + switch (addr->sa_family) { + case AF_INET: + port = ntohs(((struct sockaddr_in *)addr)->sin_port); + if (port_is_okay(port) != 0) { + return -1; + } + break; + case AF_INET6: + port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port); + if (port_is_okay(port) != 0) { + return -1; + } + break; + default: + break; + } + return next_connect(sockfd, addr, addrlen); +} + +ssize_t +sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + unsigned short port; + static int (*next_sendto)(int, const void *, size_t, int, + const struct sockaddr *, socklen_t); + + if (next_sendto == NULL) { + next_sendto = dlsym(RTLD_NEXT, "sendto"); + if (next_sendto == NULL) { + errno = ENOSYS; + return -1; + } + } + + if (getenv("NOPORT") == NULL) { + return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen); + } + + if (dest_addr != NULL) { + switch (dest_addr->sa_family) { + case AF_INET: + port = ((struct sockaddr_in *)dest_addr)->sin_port; + port = ntohs(port); + if (port_is_okay(port) != 0) { + return -1; + } + break; + case AF_INET6: + port = ((struct sockaddr_in6 *)dest_addr)->sin6_port; + port = ntohs(port); + if (port_is_okay(port) != 0) { + return -1; + } + break; + default: + break; + } + } + return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen); +} diff --git a/SPECS/krb5.spec b/SPECS/krb5.spec new file mode 100644 index 00000000..5ea0c61c --- /dev/null +++ b/SPECS/krb5.spec @@ -0,0 +1,3569 @@ +%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 configured_default_ccache_name KEYRING:persistent:%%{uid} + +Summary: The Kerberos network authentication system +Name: krb5 +Version: 1.15.1 +Release: 19%{?dist} + +# - Maybe we should explode from the now-available-to-everybody tarball instead? +# http://web.mit.edu/kerberos/dist/krb5/1.13/krb5-1.13.2-signed.tar +# - The sources below are stored in a lookaside cache. Upload with +# $ rhpkg upload krb5-1.13.2.tar.gz krb5-1.13.2.tar.gz.asc # (and don't +# remove, otherwise you can't go back or branch from a previous point) +Source0: krb5-%{version}.tar.gz +Source1: krb5-%{version}.tar.gz.asc +Source3: krb5-%{version}-pdfs.tar +Source2: kprop.service +Source4: kadmin.service +Source5: krb5kdc.service +Source6: krb5.conf +Source7: _kpropd +Source8: _kadmind +Source10: kdc.conf +Source11: kadm5.acl +Source19: krb5kdc.sysconfig +Source20: kadmin.sysconfig +Source21: kprop.sysconfig +Source29: ksu.pamd +Source31: kerberos-adm.portreserve +Source32: krb5_prop.portreserve +Source33: krb5kdc.logrotate +Source34: kadmind.logrotate +Source36: kpropd.init +Source37: kadmind.init +Source38: krb5kdc.init +Source39: krb5-krb5kdc.conf + +BuildRequires: cmake xz +# Carry this locally until it's available in a packaged form. +Source100: nss_wrapper-0.0-20140204195100.git3d58327.tar.xz +Source101: noport.c +Source102: socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz + +Patch136: krb5-1.12.1-pam.patch +Patch137: krb5-1.15-beta1-selinux-label.patch +Patch138: krb5-1.12-ksu-path.patch +Patch139: krb5-1.12-ktany.patch +Patch140: krb5-1.15-beta1-buildconf.patch +Patch141: krb5-1.3.1-dns.patch +Patch142: krb5-1.12-api.patch +Patch143: krb5-1.13-dirsrv-accountlock.patch +Patch144: krb5-1.9-debuginfo.patch +Patch145: krb5-kvno-230379.patch +Patch146: krb5-1.11-run_user_0.patch +Patch147: krb5-1.11-kpasswdtest.patch +Patch148: Improve-PKINIT-UPN-SAN-matching.patch +Patch149: Deindent-crypto_retrieve_X509_sans.patch +Patch152: Add-certauth-pluggable-interface.patch +Patch153: Correct-error-handling-bug-in-prior-commit.patch +Patch154: Add-the-client_name-kdcpreauth-callback.patch +Patch155: Use-the-canonical-client-principal-name-for-OTP.patch +Patch156: Remove-incomplete-PKINIT-OCSP-support.patch +Patch157: Add-support-to-query-the-SSF-of-a-GSS-context.patch +Patch158: Add-k5test-expected_msg-expected_trace.patch +Patch159: Add-PKINIT-UPN-tests-to-t_pkinit.py.patch +Patch160: Add-test-cert-generation-to-make-certs.sh.patch +Patch161: Fix-make-certs.sh-for-OpenSSL-1.1.patch +Patch162: Allow-clock-skew-in-krb5-gss_context_time.patch +Patch163: Fix-in_clock_skew-and-use-it-in-AS-client-code.patch +Patch164: Add-timestamp-helper-functions.patch +Patch165: Make-timestamp-manipulations-y2038-safe.patch +Patch166: Add-timestamp-tests.patch +Patch167: Add-y2038-documentation.patch +Patch168: Fix-more-time-manipulations-for-y2038.patch +Patch169: Use-krb5_timestamp-where-appropriate.patch +Patch170: Add-KDC-policy-pluggable-interface.patch +Patch171: Fix-bugs-in-kdcpolicy-commit.patch +Patch172: Prevent-KDC-unset-status-assertion-failures.patch +Patch173: Convert-some-pkiDebug-messages-to-TRACE-macros.patch +Patch174: Fix-certauth-built-in-module-returns.patch +Patch175: Add-test-cert-with-no-extensions.patch +Patch176: Expose-context-errors-in-pkinit_server_plugin_init.patch +Patch177: Limit-ticket-lifetime-to-2-31-1-seconds.patch + +License: MIT +URL: http://web.mit.edu/kerberos/www/ +Group: System Environment/Libraries +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +BuildRequires: autoconf, bison, flex, gawk, gettext, pkgconfig, sed +BuildRequires: libcom_err-devel, libedit-devel, libss-devel +BuildRequires: gzip, ncurses-devel +BuildRequires: python-sphinx, texlive-pdftex + +# Taken from \usepackage directives produced by sphinx: +BuildRequires: tex(babel.sty) +BuildRequires: tex(bookmark.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(times.sty) +BuildRequires: tex(titlesec.sty) +BuildRequires: tex(threeparttable.sty) +BuildRequires: tex(wrapfig.sty) +BuildRequires: tex(report.cls) + +# 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: keyutils, keyutils-libs-devel >= 1.5.8 +BuildRequires: libselinux-devel +BuildRequires: pam-devel +BuildRequires: systemd-units +# For the test framework. +BuildRequires: perl, dejagnu, tcl-devel +BuildRequires: net-tools, rpcbind +BuildRequires: hostname +BuildRequires: iproute + +# someday... +%if 0%{?fedora} >= 9 +BuildRequires: python-pyrad +%endif +%if 0%{?fedora} >= 8 +%ifarch %{ix86} x86_64 +BuildRequires: yasm +%endif +%endif + +BuildRequires: openldap-devel +BuildRequires: openssl-devel >= 0.9.8 +BuildRequires: libverto-devel + +%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 + +%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 + +%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: krb5-server-1.11.3-49.el7.i686 +%endif +%ifarch ppc64 +Obsoletes: krb5-server-1.11.3-49.el7.ppc +%endif +%ifarch s390x +Obsoletes: krb5-server-1.11.3-49.el7.s390 +%endif +Requires: libkadm5%{?_isa} = %{version}-%{release} + +%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: krb5-server-ldap-1.11.3-49.el7.i686 +%endif +%ifarch ppc64 +Obsoletes: krb5-server-ldap-1.11.3-49.el7.ppc +%endif +%ifarch s390x +Obsoletes: krb5-server-ldap-1.11.3-49.el7.s390 +%endif + +%description server-ldap +Kerberos is a network authentication system. The krb5-server package +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} +# mktemp is used by krb5-send-pr +Requires: coreutils + +%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 the libkadm5clnt and libkadm5serv shared objects, for use +ONLY by kerberos itself. Do not depend on this package. + +%prep +# Apply run_user_0 when the hard-wired or configured default location is +# DIR:/run/user/%%{uid}/krb5cc. +%setup -q -a 3 -a 100 -a 102 +%patch136 -p1 -b .krb5-1.12.1-pam +%patch137 -p1 -b .krb5-1.15-beta1-selinux-label +%patch138 -p1 -b .krb5-1.12-ksu-path +%patch139 -p1 -b .krb5-1.12-ktany +%patch140 -p1 -b .krb5-1.15-beta1-buildconf +%patch141 -p1 -b .krb5-1.3.1-dns +%patch142 -p1 -b .krb5-1.12-api +%patch143 -p1 -b .krb5-1.13-dirsrv-accountlock +%patch144 -p1 -b .krb5-1.9-debuginfo +%patch145 -p1 -b .krb5-kvno-230379 +%patch146 -p1 -b .krb5-1.11-run_user_0 +%patch147 -p1 -b .krb5-1.11-kpasswdtest +%patch148 -p1 -b .Improve-PKINIT-UPN-SAN-matching +%patch149 -p1 -b .Deindent-crypto_retrieve_X509_sans +%patch152 -p1 -b .Add-certauth-pluggable-interface +%patch153 -p1 -b .Correct-error-handling-bug-in-prior-commit +%patch154 -p1 -b .Add-the-client_name-kdcpreauth-callback +%patch155 -p1 -b .Use-the-canonical-client-principal-name-for-OTP +%patch156 -p1 -b .Remove-incomplete-PKINIT-OCSP-support +%patch157 -p1 -b .Add-support-to-query-the-SSF-of-a-GSS-context +%patch158 -p1 -b .Add-k5test-expected_msg-expected_trace +%patch159 -p1 -b .Add-PKINIT-UPN-tests-to-t_pkinit.py +%patch160 -p1 -b .Add-test-cert-generation-to-make-certs.sh +%patch161 -p1 -b .Fix-make-certs.sh-for-OpenSSL-1.1 +%patch162 -p1 -b .Allow-clock-skew-in-krb5-gss_context_time +%patch163 -p1 -b .Fix-in_clock_skew-and-use-it-in-AS-client-code +%patch164 -p1 -b .Add-timestamp-helper-functions +%patch165 -p1 -b .Make-timestamp-manipulations-y2038-safe +%patch166 -p1 -b .Add-timestamp-tests +%patch167 -p1 -b .Add-y2038-documentation +%patch168 -p1 -b .Fix-more-time-manipulations-for-y2038 +%patch169 -p1 -b .Use-krb5_timestamp-where-appropriate +%patch170 -p1 -b .Add-KDC-policy-pluggable-interface +%patch171 -p1 -b .Fix-bugs-in-kdcpolicy-commit +%patch172 -p1 -b .Prevent-KDC-unset-status-assertion-failures +%patch173 -p1 -b .Convert-some-pkiDebug-messages-to-TRACE-macros +%patch174 -p1 -b .Fix-certauth-built-in-module-returns +%patch175 -p1 -b .Add-test-cert-with-no-extensions +%patch176 -p1 -b .Expose-context-errors-in-pkinit_server_plugin_init +%patch177 -p1 -b .Limit-ticket-lifetime-to-2-31-1-seconds + +ln NOTICE LICENSE + +chmod u+x src/util/paste-kdcproxy.py +# 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 + +# Create build spaces for the test wrappers. +mkdir -p nss_wrapper/build +mkdir -p socket_wrapper/build + +# 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. +runstatedir=%{_localstatedir}/run; export runstatedir +# 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" \ +%if 0%{?fedora} >= 7 || 0%{?rhel} >= 6 + SS_LIB="-lss" \ +%else + SS_LIB="-lss -lncurses" \ +%endif + --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-pkinit-crypto-impl=openssl \ + --with-tls-impl=openssl \ + --with-system-verto \ + --with-pam \ + --with-selinux \ + --with-prng-alg=os +# 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}-pdfs.tar.new" build-pdf/*.pdf + +# Build the test wrappers. +pushd nss_wrapper/build +cmake .. +make +popd +pushd socket_wrapper/build +cmake .. +make +popd + +# We need to cut off any access to locally-running nameservers, too. +%{__cc} -fPIC -shared -o noport.so -Wall -Wextra $RPM_SOURCE_DIR/noport.c + +%check +# Alright, this much is still a work in progress. +%if %{?__isa_bits:%{__isa_bits}}%{!?__isa_bits:32} == 64 +if hostname | grep -q build ; then + sleep 600 +fi +%endif + +# Set things up to use the test wrappers. +NSS_WRAPPER_HOSTNAME=test.example.com ; export NSS_WRAPPER_HOSTNAME +NSS_WRAPPER_HOSTS="`pwd`/nss_wrapper/fakehosts" ; export NSS_WRAPPER_HOSTS +echo 127.0.0.1 $NSS_WRAPPER_HOSTNAME $NSS_WRAPPER_HOSTNAME localhost localhost >"$NSS_WRAPPER_HOSTS" +NOPORT=53,111; export NOPORT +SOCKET_WRAPPER_DIR=`pwd`/sockets; mkdir -p $SOCKET_WRAPPER_DIR; export SOCKET_WRAPPER_DIR +LD_PRELOAD=`pwd`/noport.so:`pwd`/nss_wrapper/build/src/libnss_wrapper.so:`pwd`/socket_wrapper/build/src/libsocket_wrapper.so ; export LD_PRELOAD + +# Run the test suite. We can't actually run the whole thing in the build +# system, but we can at least run more than we used to. The build system may +# give us a revoked session keyring, so run affected tests with a new one. +make -C src runenv.py +: make -C src check TMPDIR=%{_tmppath} +keyctl session - make -C src/lib check TMPDIR=%{_tmppath} OFFLINE=yes +make -C src/kdc check TMPDIR=%{_tmppath} +keyctl session - make -C src/appl check TMPDIR=%{_tmppath} +make -C src/clients check TMPDIR=%{_tmppath} +keyctl session - make -C src/util check TMPDIR=%{_tmppath} + +%install +[ "$RPM_BUILD_ROOT" != '/' ] && rm -rf -- $RPM_BUILD_ROOT + +# 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 + +# 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. +DEFCCNAME="%{configured_default_ccache_name}"; export DEFCCNAME +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 + +# 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%{_sbindir} +for wrapper in \ + %{SOURCE7} \ + %{SOURCE8} ; do + install -pm 755 ${wrapper} $RPM_BUILD_ROOT%{_sbindir}/ +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/ 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 + +# FIXME: Temporay workaround for RH bug #1204646 ("krb5-config +# returns wrong -specs path") so that development of krb5 +# dependicies gets unstuck. +sed -r -i -e "s/-specs=\/.+?\/redhat-hardened-ld//g" $RPM_BUILD_ROOT%{_bindir}/krb5-config + +if [[ "$(< $RPM_BUILD_ROOT%{_bindir}/krb5-config )" == *redhat-hardened-ld* ]] ; then + printf '# redhat-hardened-ld for krb5-config failed' 1>&2 + exit 1 +fi + +# 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 -f -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/kdc.conf" +rm -f -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/krb5.conf" +rm -f -- "$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} + +%clean +[ "$RPM_BUILD_ROOT" != '/' ] && rm -rf -- $RPM_BUILD_ROOT + +%post libs -p /sbin/ldconfig + +%triggerun libs -- krb5-libs < 1.15.1-13 +if ! grep -q 'includedir /etc/krb5.conf.d' /etc/krb5.conf ; then + sed -i '1i # Other applications require this directory to perform krb5 configuration.\nincludedir /etc/krb5.conf.d/\n' /etc/krb5.conf +fi + +%postun libs -p /sbin/ldconfig + +%post server-ldap -p /sbin/ldconfig + +%postun server-ldap -p /sbin/ldconfig + +%post server +# assert sanity. A cleaner solution probably exists but it is opaque. +/bin/systemctl daemon-reload +exit 0 + +%preun server +if [ "$1" -eq "0" ] ; then + /bin/systemctl --no-reload disable krb5kdc.service > /dev/null 2>&1 || : + /bin/systemctl --no-reload disable kadmin.service > /dev/null 2>&1 || : + /bin/systemctl --no-reload disable kprop.service > /dev/null 2>&1 || : + /bin/systemctl stop krb5kdc.service > /dev/null 2>&1 || : + /bin/systemctl stop kadmin.service > /dev/null 2>&1 || : + /bin/systemctl stop kprop.service > /dev/null 2>&1 || : +fi +exit 0 + +%postun server +/bin/systemctl daemon-reload >/dev/null 2>&1 || : +if [ "$1" -ge 1 ] ; then + /bin/systemctl try-restart krb5kdc.service >/dev/null 2>&1 || : + /bin/systemctl try-restart kadmin.service >/dev/null 2>&1 || : + /bin/systemctl try-restart kprop.service >/dev/null 2>&1 || : +fi +exit 0 + +%post -n libkadm5 -p /sbin/ldconfig + +%postun -n libkadm5 -p /sbin/ldconfig + +%files workstation +%defattr(-,root,root,-) +%doc src/config-files/services.append +%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 +%defattr(-,root,root,-) +%docdir %{_mandir} +%doc build-pdf/admin.pdf build-pdf/build.pdf +%{_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 +%{_sbindir}/_kadmind +%{_mandir}/man8/kadmind.8* +%{_sbindir}/kdb5_util +%{_mandir}/man8/kdb5_util.8* +%{_sbindir}/kprop +%{_mandir}/man8/kprop.8* +%{_sbindir}/kpropd +%{_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 +# in -devel. +%{_bindir}/sclient +%{_mandir}/man1/sclient.1* +%{_sbindir}/sserver +%{_mandir}/man8/sserver.8* + +%files server-ldap +%defattr(-,root,root,-) +%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 +%defattr(-,root,root,-) +%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 +/%{_mandir}/man5/.k5identity.5* +/%{_mandir}/man5/.k5login.5* +/%{_mandir}/man5/k5identity.5* +/%{_mandir}/man5/k5login.5* +/%{_mandir}/man5/krb5.conf.5* +%{_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 +%dir %{_var}/kerberos +%dir %{_var}/kerberos/krb5 +%dir %{_var}/kerberos/krb5/user + +%files pkinit +%defattr(-,root,root,-) +%dir %{_libdir}/krb5 +%dir %{_libdir}/krb5/plugins +%dir %{_libdir}/krb5/plugins/preauth +%{_libdir}/krb5/plugins/preauth/pkinit.so + +%files devel +%defattr(-,root,root,-) +%docdir %{_mandir} + +%{_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 +%defattr(-,root,root,-) +%{_libdir}/libkadm5clnt.so +%{_libdir}/libkadm5clnt_mit.so +%{_libdir}/libkadm5srv.so +%{_libdir}/libkadm5srv_mit.so +%{_libdir}/libkadm5clnt_mit.so.* +%{_libdir}/libkadm5srv_mit.so.* + +%changelog +* Fri Mar 02 2018 Robbie Harwood - 1.15.1-19 +- Limit ticket lifetime to 2^31-1 seconds +- Resolves: #1554723 + +* Tue Nov 28 2017 Robbie Harwood - 1.15.1-18 +- Expose context errors in pkinit_server_plugin_init +- Resolves: #1460089 + +* Thu Nov 02 2017 Robbie Harwood - 1.15.1-17 +- Drop certauth test changes that prevented runnig it +- Resolves: #1498767 + +* Thu Nov 02 2017 Robbie Harwood - 1.15.1-16 +- Drop irrelevant DIR trigger logic +- Resolves: #1431198 + +* Thu Oct 05 2017 Robbie Harwood - 1.15.1-15 +- Fix CVE-2017-7562 (certauth eku bypass) +- Resolves: #1498767 + +* Thu Oct 05 2017 Robbie Harwood - 1.15.1-14 +- Fix CVE-2017-11368 (s4u2 request assertion failures) +- Resolves: #1498768 + +* Tue Oct 03 2017 Robbie Harwood - 1.15.1-13 +- Force-add /etc/krb5.conf.d so we can guarantee it exists +- Resolves: #1431198 + +* Tue Sep 26 2017 Robbie Harwood - 1.15.1-12 +- Add krb5 policy plugin interface +- Remove soname downgrade +- Resolves: #1462982 + +* Wed Sep 06 2017 Robbie Harwood - 1.15.1-11 +- Make t_certauth.py runnable +- Resolves: #1443388 + +* Tue Sep 05 2017 Robbie Harwood - 1.15.1-10 +- Add context SSF query support +- Resolves: #1472956 + +* Thu Aug 17 2017 Robbie Harwood - 1.15.1-9 +- Remove incomplete PKINIT OCSP support +- Resolves: #1460089 + +* Fri Apr 28 2017 Robbie Harwood - 1.15.1-8 +- Add kprop.service argument file +- Resolves: #1389073 + +* Fri Apr 07 2017 Robbie Harwood - 1.15.1-7 +- Fix enterprise principal forwarding +- Resolves: #1378440 + +* Thu Apr 06 2017 Robbie Harwood - 1.15.1-6 +- Fix bug in certauth backport +- Resolves: #1428484 + +* Wed Mar 22 2017 Robbie Harwood - 1.15.1-5 +- rubygem-rkerberos still needs us to lie about soname +- Resolves: #1389073 + +* Wed Mar 22 2017 Robbie Harwood - 1.15.1-4 +- Backport certauth plugin and related pkinit changes +- Note: related changes cannot be tested because RHEL does not allow + binary git diffs +- Resolves: #1428484 + +* Tue Mar 07 2017 Robbie Harwood - 1.15.1-3 +- Remove duplication between subpackages +- Resolves: #1254640 + +* Mon Mar 06 2017 Robbie Harwood - 1.15.1-2 +- Add back deleted sources +- Resolves: #1389073 + +* Mon Mar 06 2017 Robbie Harwood - 1.15.1-1 +- Bump to krb5-1.15.1 (very small change) +- Apply some sanity to our patches and ordering +- Resolves: #1389073 + +* Mon Jan 23 2017 Robbie Harwood - 1.15-2 +- Reinstate e_data free method; bumps KDB to 6.1 +- Resolves: #1389073 + +* Wed Jan 04 2017 Robbie Harwood - 1.15-1 +- Rebase to 1.15-final +- Resolves: #1389073 +- Resolves: #1367169 +- Resolves: #1389072 +- Resolves: #1366863 + +* Wed Nov 02 2016 Robbie Harwood - 1.14.1-27 +- Properly handle EOF on libkrad sockets +- Resolves: #1382449 + +* Wed Aug 17 2016 Robbie Harwood - 1.14.1-26 +- Use responder in non-preauth AS reqs +- Resolves: #1363690 + +* Wed Aug 17 2016 Robbie Harwood - 1.14.1-25 +- Fix bad debug_log() call in selinux handling +- Resolves: #1292153 + +* Wed Aug 10 2016 Robbie Harwood - 1.14.1-24 +- Fix KKDCPP with TLS SNI by always presenting "Host:" header +- Resolves: #1364993 + +* Fri Aug 05 2016 Robbie Harwood - 1.14.1-23 +- Add dependency on libkadm5 to krb5-devel +- Resolves: #1347403 + +* Fri Jul 29 2016 Robbie Harwood - 1.14.1-22 +- Builders have new version of mock; adapt. +- Resolves: #1290239 + +* Fri Jul 29 2016 Robbie Harwood - 1.14.1-21 +- Fix CVE-2016-3120 +- Resolves: #1361504 + +* Wed Jul 20 2016 Robbie Harwood - 1.14.1-20 +- Make version dependencies on libkadm5 more explicit to appease rpmdiff +- Resolves: #1347403 + +* Wed Jul 20 2016 Robbie Harwood - 1.14.1-19 +- Add in upstream version of kprop port and tests +- Resolves: #1292795 + +* Wed Jun 29 2016 Robbie Harwood - 1.14.1-18 +- Fix incorrect recv() size calculation in libkrad +- Resolves: #1349042 + +* Wed Jun 15 2016 Robbie Harwood - 1.14.1-17 +- Separate out the kadm5 libs +- Resolves: #1347403 + +* Mon Jun 13 2016 Robbie Harwood - 1.14.1-16 +- Fix kprop/iprop handling of default realm +- Fix t_kprop.py +- Resolves: #1290561 +- Resolves: #1302967 +- Resolves: #1292795 + +* Thu Jun 02 2016 Robbie Harwood - 1.14.1-15 +- Fix SPNEGO with NTLM to conform to MS-SPNG section 3.3.5.1 +- Resolves: #1341726 + +* Sat May 28 2016 Robbie Harwood - 1.14.1-14 +- Do not indicate depricated mechanisms when requested +- Resolves: #1293908 + +* Fri May 27 2016 Robbie Harwood - 1.14.1-13 +- Fix OTP module incorrectly overwriting as_key +- Resolves: #1340304 + +* Wed May 25 2016 Robbie Harwood - 1.14.1-12 +- Fix CVE-2016-3119 (LDAP NULL dereference) +- Resolves: #1339562 + +* Thu Apr 28 2016 Robbie Harwood - 1.14.1-11 +- Make ksu not ask for password without -n +- Resolves: #1247261 + +* Wed Apr 20 2016 Robbie Harwood - 1.14.1-10 +- Frob kadm5 soname version so that the rebase does not break things +- Resolves: #1292153 + +* Tue Apr 19 2016 Robbie Harwood - 1.14.1-9 +- Revamp selinux patch to not leak memory +- Resolves: #1313457 + +* Mon Apr 11 2016 Robbie Harwood - 1.14.1-8 +- Add snippet support in /etc/krb5.conf.d +- Resolves: #1146945 + +* Fri Apr 08 2016 Robbie Harwood - 1.14.1-7 +- Skip unnecessary mech calls in gss_inquire_cred +- Resolves: #1314493 + +* Thu Apr 07 2016 Robbie Harwood - 1.14.1-6 +- Fix impersonate_name to work with interposers +- Resolves: #1284987 + +* Thu Apr 07 2016 Robbie Harwood - 1.14.1-5 +- Fix change tracking of krb5.conf +- Resolves: #1208243 + +* Tue Apr 05 2016 Robbie Harwood - 1.14.1-4 +- Ensure log files are not world-readable +- Resolves: #1256735 + +* Wed Mar 30 2016 Robbie Harwood - 1.14.1-3 +- Clean up initscript handling in spec file +- Resolves: #1283902 +- Resolves: #1183058 + +* Wed Mar 30 2016 Robbie Harwood - 1.14.1-2 +- Backport spec file changes from Fedora +- Resolves: #1290239 + +* Thu Mar 10 2016 Robbie Harwood - 1.14.1-1 +- Rebase to new upstream version 1.14.1 +- Remove pax logic +- Resolves: #1292153 +- Resolves: #1135427 +- Resolves: #1265509 +- Resolves: #1265510 +- Resolves: #1296241 + +* Fri Feb 12 2016 Robbie Harwood - 1.13.2-12 +- Remove obsolete trigger to enable building of package +- Resolves: #1306970 + +* Fri Feb 12 2016 Robbie Harwood - 1.13.2-11 +- Fix CVE-2015-8631, CVE-2015-8630, and CVE-2015-8629 +- Resolves: #1306970 + +* Fri Sep 04 2015 Robbie Harwood 1.13.2-9 +- Add patch and test case for "KDC does not return proper + client principal for client referrals" +- Resolves: #1259846 + +* Mon Aug 31 2015 Roland Mainz - 1.13.2-9 +- Ammend patch for RedHat bug #1252454 ('testsuite complains + "Lifetime has increased by 32436 sec while 0 sec passed!", + while rhel5-libkrb5 passes') to handle the newly introduced + valgrind hits. + +* Wed Aug 19 2015 Roland Mainz - 1.13.2-8 +- Add a patch to fix RH Bug #1250154 ("[s390x, ppc64, ppc64le]: + kadmind does not accept ACL if kadm5.acl does not end with EOL") + The code "accidently" works on x86/AMD64 because declaring a + variable |char| results in an |unsigned char| by default while + most other platforms (e.g. { s390x, ppc64, ppc64le, ...}) + default to |signed char| (still have to use lint(1) to clean + up 38 more instances of this kind of bug). + +* Wed Aug 19 2015 Roland Mainz - 1.13.2-7 +- Obsolete multilib versions of server packages to fix RH + bug #1251913 ("krb5 should obsolete the multilib versions + of krb5-server and krb5-server-ldap"). + The following packages are declared obsolete: + - krb5-server-1.11.3-49.el7.i686 + - krb5-server-1.11.3-49.el7.ppc + - krb5-server-1.11.3-49.el7.s390 + - krb5-server-ldap-1.11.3-49.el7.i686 + - krb5-server-ldap-1.11.3-49.el7.ppc + - krb5-server-ldap-1.11.3-49.el7.s390 + +* Wed Aug 19 2015 Roland Mainz - 1.13.2-6 +- Add a patch to fix RedHat bug #1252454 ('testsuite complains + "Lifetime has increased by 32436 sec while 0 sec passed!", + while rhel5-libkrb5 passes') so that krb5 resolves GSS creds + if |time_rec| is requested. + +* Fri Aug 7 2015 Roland Mainz - 1.13.2-5 +- Add a patch to fix RedHat bug #1251586 ("KDC sends multiple + requests to ipa-otpd for the same authentication") which causes + the KDC to send multiple retries to ipa-otpd for TCP transports + while it should only be done for UDP. + +* Tue Jul 28 2015 Roland Mainz - 1.13.2-4 +- the rebase to krb5 1.13.2 in vers 1.13.2-0 also fixed: + - Redhat Bug #1247761 ("RFE: Minor krb5 spec file cleanup and sync + with recent Fedora 22/23 changes") + - Redhat Bug #1247751 ("krb5-config returns wrong -specs path") + - Redhat Bug #1247608 ('Add support for multi-hop preauth mechs + via |KDC_ERR_MORE_PREAUTH_DATA_REQUIRED| for RFC 6113 ("A + Generalized Framework for Kerberos Pre-Authentication")') +- Removed "krb5-1.10-kprop-mktemp.patch" and + "krb5-1.3.4-send-pr-tempfile.patch", both are no longer used since + the rebase to krb5 1.13.1 + +* Fri May 29 2015 Roland Mainz - 1.13.2-3 +- Add patch to fix Redhat Bug #1222903 ("[SELinux] AVC denials may appear + when kadmind starts"). The issue was caused by an unneeded |htons()| + which triggered SELinux AVC denials due to the "random" port usage. + +* Thu May 21 2015 Roland Mainz - 1.13.2-2 +- Add fix for RedHat Bug #1164304 ("Upstream unit tests loads + the installed shared libraries instead the ones from the build") + +* Fri May 15 2015 Roland Mainz - 1.13.2-1 +- the rebase to krb5 1.13.1 in vers 1.13.1-0 also fixed: + - Bug 1144498 ("Fix the race condition in the libkrb5 replay cache") + - Bug 1163402 ("kdb5_ldap_util view_policy does not shows ticket flags on s390x and ppc64") + - Bug 1185770 ("Missing upstream test in krb5-1.12.2: src/tests/gssapi/t_invalid.c") + - Bug 1204211 ("CVE-2014-5355 krb5: unauthenticated denial of service in recvauth_common() and other") + +* Fri May 15 2015 Roland Mainz - 1.13.2-0 +- Update to krb5-1.13.2 + - drop patch for krb5-1.13.2-CVE_2015_2694_requires_preauth_bypass_in_PKINIT_enabled_KDC, fixed in krb5-1.13.2 + - drop patch for krb5-1.12.1-CVE_2014_5355_fix_krb5_read_message_handling, fixed in krb5-1.13.2 + +* Thu May 14 2015 Roland Mainz - 1.13.1-2 +- the rebase to krb5 1.13.1 in vers 1.13.1-0 also fixed RH + bug #1156144 ("krb5 upstream test t_kdb.py failure") + +* Mon May 4 2015 Roland Mainz - 1.13.1-1 +- fix for CVE-2015-2694 (#1218020) "requires_preauth bypass + in PKINIT-enabled KDC". + In MIT krb5 1.12 and later, when the KDC is configured with + PKINIT support, an unauthenticated remote attacker can + bypass the requires_preauth flag on a client principal and + obtain a ciphertext encrypted in the principal's long-term + key. This ciphertext could be used to conduct an off-line + dictionary attack against the user's password. + +* Fri Apr 24 2015 Roland Mainz - 1.13.1-0 +- Update to krb5-1.13.1 + - patch krb5-1.12-selinux-label was updated and renamed to krb5-1.13-selinux-label + - patch krb5-1.11-dirsrv-accountlock was updated and renamed to krb5-1.13-dirsrv-accountlock + - drop patch for krb5-1.12-pwdch-fast, fixed in krb5-1.13 + - drop patch for krb5-1.12ish-kpasswd_tcp, fixed in krb5-1.13 + - drop patch for krb5-master-rcache-internal-const, no longer needed + - drop patch for krb5-master-rcache-acquirecred-cleanup, no longer needed + - drop patch for krb5-master-rcache-acquirecred-source, no longer needed + - drop patch for krb5-master-rcache-acquirecred-test, no longer needed + - drop patch for krb5-master-move-otp-sockets, no longer needed + - drop patch for krb5-master-mechd, no longer needed + - drop patch for krb5-master-strdupcheck, no longer needed + - drop patch for krb5-master-compatible-keys, no longer needed + - drop patch for krb5-1.12-system-exts, fixed in krb5-1.13 + - drop patch for 0001-In-ksu-merge-krb5_ccache_copy-and-_restricted, no longer needed + - drop patch for 0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals, no longer needed + - drop patch for 0003-Use-an-intermediate-memory-cache-in-ksu, no longer needed + - drop patch for 0004-Make-ksu-respect-the-default_ccache_name-setting, no longer needed + - drop patch for 0005-Copy-config-entries-to-the-ksu-target-ccache, no longer needed + - drop patch for 0006-Use-more-randomness-for-ksu-secondary-cache-names, no longer needed + - drop patch for 0007-Make-krb5_cc_new_unique-create-DIR-directories, no longer needed + - drop patch for krb5-1.12-kpasswd-skip-address-check, fixed in krb5-1.13 + - drop patch for 0000-Refactor-cm-functions-in-sendto_kdc.c, no longer needed + - drop patch for 0001-Simplify-sendto_kdc.c, no longer needed + - drop patch for 0002-Add-helper-to-determine-if-a-KDC-is-the-master, no longer needed + - drop patch for 0003-Use-k5_transport-_strategy-enums-for-k5_sendto, no longer needed + - drop patch for 0004-Build-support-for-TLS-used-by-HTTPS-proxy-support, no longer needed + - drop patch for 0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE, no longer needed + - drop patch for 0006-Dispatch-style-protocol-switching-for-transport, no longer needed + - drop patch for 0007-HTTPS-transport-Microsoft-KKDCPP-implementation, no longer needed + - drop patch for 0008-Load-custom-anchors-when-using-KKDCP, no longer needed + - drop patch for 0009-Check-names-in-the-server-s-cert-when-using-KKDCP, no longer needed + - drop patch for 0010-Add-some-longer-form-docs-for-HTTPS, no longer needed + - drop patch for 0011-Have-k5test.py-provide-runenv-to-python-tests, no longer needed + - drop patch for 0012-Add-a-simple-KDC-proxy-test-server, no longer needed + - drop patch for 0013-Add-tests-for-MS-KKDCP-client-support, no longer needed + - drop patch for krb5-1.12ish-tls-plugins, fixed in krb5-1.13.1 + - drop patch for krb5-1.12-nodelete-plugins, fixed in krb5-1.13.1 + - drop patch for krb5-1.12-ksu-untyped-default-ccache-name, fixed in krb5-1.13.1 + - drop patch for krb5-1.12-ksu-no-ccache, fixed in krb5-1.13.1 + - drop patch for krb5-ksu_not_working_with_default_principal, fixed in krb5-1.13.1 + - drop patch for CVE_2014_5353_fix_LDAP_misused_policy_name_crash, fixed in krb5-1.13.1 + - drop patch for CVE_2014_5354_support_keyless_principals_in_ldap, fixed in krb5-1.13.1 + - drop patch for kinit -C loops (MIT/krb5 bug #243), fixed in krb5-1.13.1 + - drop patch for CVEs { 2014-9421, 2014-9422, 2014-9423, 2014-5352 }, fixed in krb5-1.13.1 + - added patch krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED + - added patch krb5-1.12.1-CVE_2014_5355_fix_krb5_read_message_handling +- Minor spec cleanup + +* Mon Jan 26 2015 Roland Mainz - 1.12.2-14 +- fix for kinit -C loops (#1184629, MIT/krb5 issue 243, "Do not + loop on principal unknown errors"). + +* Mon Jan 12 2015 Roland Mainz - 1.12.2-13 +- 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)" + +* Mon Dec 22 2014 Roland Mainz - 1.12.2-12 +- fix for CVE-2014-5354 (#1174546) "krb5: NULL pointer + dereference when using keyless entries" + +* Mon Dec 22 2014 Roland Mainz - 1.12.2-11 +- fix for CVE-2014-5353 (#1174543) "Fix LDAP misused policy + name crash" + +* Sun Dec 7 2014 Roland Mainz - 1.12.2-10 +- In ksu, without the -e flag, also check .k5users (#1105489) + When ksu was explicitly told to spawn a shell, a line in .k5users which + listed "*" as the allowed command would cause the principal named on the + line to be considered as a candidate for authentication. + When ksu was not passed a command to run, which implicitly meant that + the invoking user wanted to run the target user's login shell, knowledge + that the principal was a valid candidate was ignored, which could cause + a less optimal choice of the default target principal. + This doesn't impact the authorization checks which we perform later. + Patch by Nalin Dahyabhai + +* Wed Dec 3 2014 Roland Mainz - 1.12.2-9 +- Undo libkadmclnt SONAME change (from 8 to 9) which originally + happened in the krb5 1.12 rebase (#1166012) but broke + rubygem-rkerberos (sort of ruby language bindings for + libkadmclnt&co.) dependicies, as side effect of + rubygem-rkerberos using private interfaces in libkadmclnt. + +* Mon Sep 8 2014 Nalin Dahyabhai - 1.12.2-8 +- fix the problem where the %%license file has been a dangling symlink +- ksu: pull in fix from pull #206 to avoid breakage when the + default_ccache_name doesn't include a cache type as a prefix +- ksu: pull in a proposed fix for pull #207 to avoid breakage when the + invoking user doesn't already have a ccache + +* Sat Sep 6 2014 Nalin Dahyabhai - 1.12.2-7 +- pull in patch from master to load plugins with RTLD_NODELETE, when + defined (RT#7947) + +* Fri Sep 5 2014 Nalin Dahyabhai - 1.12.2-6 +- backport patch to make the client skip checking the server's reply + address when processing responses to password-change requests, which + between NAT and upcoming HTTPS support, can cause us to erroneously + report an error to the user when the server actually reported success + (RT#7886) +- backport support for accessing KDCs and kpasswd services via HTTPS + proxies (marked by being specified as https URIs instead as hostnames + or hostname-and-port), such as the one implemented in python-kdcproxy + (RT#7929, #109919), and pick up a subsequent patch to build HTTPS + as a plugin + +* Thu Aug 28 2014 Nalin Dahyabhai - 1.12.2-5 +- backport fix for trying all compatible keys when not being strict about + acceptor names while reading AP-REQs (RT#7883, #1078888) +- define _GNU_SOURCE in files where we use EAI_NODATA, to make sure that + it's declared (#1059730,#1084068,#1109102) + +* Tue Aug 26 2014 Nalin Dahyabhai - 1.12.2-4 +- kpropd hasn't bothered with -S since 1.11; stop trying to use that flag + in the systemd unit file + +* Wed Aug 20 2014 Nalin Dahyabhai - 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 - 1.12.1-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sun Aug 17 2014 Fedora Release Engineering - 1.12.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Fri Aug 15 2014 Nalin Dahyabhai - 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 - 1.12.1-14 +- incorporate fix for MITKRB5-SA-2014-001 (CVE-2014-4345) + +* Mon Jul 21 2014 Nalin Dahyabhai - 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 - 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 - 1.12.1-11 +- fix license handling + +* Mon Jul 7 2014 Nalin Dahyabhai - 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 - 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 - 1.12.1-8 +- pull in fix for building against tcl 8.6 (#1107061) + +* Sun Jun 08 2014 Fedora Release Engineering - 1.12.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue Mar 04 2014 Nathaniel McCallum - 1.12.1-6 +- Backport fix for change password requests when using FAST (RT#7868) + +* Mon Feb 17 2014 Nalin Dahyabhai - 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 - 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 - 1.12.1-3 +- refresh nss_wrapper and add socket_wrapper to the %%check environment + +* Fri Jan 31 2014 Nalin Dahyabhai +- 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 - 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 - 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 - 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 +- pass -Wl,--warn-shared-textrel to the compiler when we're creating shared + libraries + +* Thu Jan 9 2014 Nalin Dahyabhai - 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 - 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 - 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 - 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 - 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 - 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 +- 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 - 1.12-4 +- revise previous patch to initialize one more element + +* Wed Dec 18 2013 Nalin Dahyabhai - 1.12-3 +- backport fixes to krb5_copy_context (RT#7807, #1044735/#1044739) + +* Wed Dec 18 2013 Nalin Dahyabhai - 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 - 1.12-1 +- update to 1.12 final + +* Mon Dec 2 2013 Nalin Dahyabhai - 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 - 1.12-beta1.0 +- rebase to master +- update to beta1 + - drop obsolete backport of fix for RT#7706 + +* Mon Nov 18 2013 Nalin Dahyabhai - 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 - 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 - 1.11.3-31 +- switch to the simplified version of the patch for #1029110 (RT#7764) + +* Mon Nov 11 2013 Nalin Dahyabhai - 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 - 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 - 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 - 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 - 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 - 1.11.3-26 +- create and own /etc/gss (#1019937) + +* Tue Oct 15 2013 Nalin Dahyabhai - 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 - 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 - 1.11.3-23 +- fix trigger scriptlet's invocation of sed (#1016945) + +* Fri Oct 4 2013 Nalin Dahyabhai - 1.11.3-22 +- rebuild with keyutils 1.5.8 (part of #1012043) + +* Wed Oct 2 2013 Nalin Dahyabhai - 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 - 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 - 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 - 1.11.3-18 +- fix broken dependency on awk (should be gawk, rdieter) + +* Wed Sep 25 2013 Nalin Dahyabhai - 1.11.3-17 +- add missing dependency on newer keyutils-libs (#1012034) + +* Tue Sep 24 2013 Nalin Dahyabhai - 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 - 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 - 1.11.3-14 +- incorporate Simo's updated backport of his updated persistent-keyring changes + (more of #991148) + +* Fri Sep 13 2013 Nalin Dahyabhai - 1.11.3-13 +- don't break during %%check when the session keyring is revoked + +* Fri Sep 13 2013 Nalin Dahyabhai - 1.11.3-12 +- pull the newer F21 defaults back to F20 (sgallagh) + +* Mon Sep 9 2013 Nalin Dahyabhai +- 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 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 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 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 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 1.11.3-7 +- attempt to account for UnversionedDocdirs for the -libs subpackage + +* Fri Jul 26 2013 Nalin Dahyabhai 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 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 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 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 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 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 1.11.2-10 +- respin with updated version of patch for RT#7650 (#969331) + +* Thu May 30 2013 Nalin Dahyabhai 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 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 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 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 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 1.11.2-4 +- Update otp patches +- Merge otp patches into a single patch +- Add keycheck patch + +* Tue Apr 23 2013 Nalin Dahyabhai 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 1.11.2-2 +- correct some configuration file paths which the KDC_DIR patch missed + +* Mon Apr 15 2013 Nalin Dahyabhai 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 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 - 1.11.1-8 +- Update otp backport patches (libk5radius => libkrad) + +* Wed Apr 3 2013 Nalin Dahyabhai 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 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 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 +- 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 1.11.1-4 +- Add libverto-devel requires for krb5-devel +- Add otp support + +* Thu Feb 28 2013 Nalin Dahyabhai 1.11.1-3 +- fix a memory leak when acquiring credentials using a keytab (RT#7586, #911110) + +* Wed Feb 27 2013 Nalin Dahyabhai 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 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 1.11-2 +- set "rdns = false" in the default krb5.conf (#908323,#908324) + +* Tue Dec 18 2012 Nalin Dahyabhai 1.11-1 +- update to 1.11 release + +* Thu Dec 13 2012 Nalin Dahyabhai 1.11-0.beta2.0 +- update to 1.11 beta 2 + +* Thu Dec 13 2012 Nalin Dahyabhai +- when building with our bundled copy of libverto, package it in with -libs + rather than with -server (#886049) + +* Wed Nov 21 2012 Nalin Dahyabhai 1.11-0.beta1.0 +- update to 1.11 beta 1 + +* Fri Nov 16 2012 Nalin Dahyabhai 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 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 +- 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 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 1.10.3-6 +- actually pull up the patch for RT#7063, and not some other ticket (#773496) + +* Mon Sep 10 2012 Nalin Dahyabhai 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 +- 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 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 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 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 1.10.3-1 +- update to 1.10.3, rolling in the fixes from MITKRB5-SA-2012-001 + +* Thu Aug 2 2012 Nalin Dahyabhai 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 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 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 - 1.10.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jun 22 2012 Nalin Dahyabhai 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 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 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 +- skip the setfscreatecon() if fopen() is passed "rb" as the open mode (part + of #819115) + +* Tue May 1 2012 Nalin Dahyabhai 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 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 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 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 - 1.10-4 +- Fix string RPC ACLs (RT#7093); CVE-2012-1012 + +* Tue Jan 31 2012 Nathaniel McCallum - 1.10-3 +- Add upstream lookaside cache behavior fix (RT#7082) + +* Mon Jan 30 2012 Nalin Dahyabhai 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 1.10-1 +- update to 1.10 final + +* Thu Jan 26 2012 Nathaniel McCallum - 1.10-0.beta1.2 +- Add upstream crashfix patch (RT#7081) + +* Thu Jan 12 2012 Nalin Dahyabhai 1.10-0.beta1.1 +- update to beta 1 + +* Wed Jan 11 2012 Peter Robinson +- mktemp was long obsoleted by coreutils + +* Wed Jan 4 2012 Nalin Dahyabhai 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 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 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 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 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 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 - 1.9.1-19 +- Rebuilt for glibc bug#747377 + +* Tue Oct 18 2011 Nalin Dahyabhai 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 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 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 1.9.1-15 +- hardcode pid file as option in krb5kdc.service + +* Fri Sep 30 2011 Tom Callaway 1.9.1-14 +- fix pid path in krb5kdc.service + +* Mon Sep 19 2011 Tom Callaway 1.9.1-13 +- convert to systemd + +* Tue Sep 6 2011 Nalin Dahyabhai 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 1.9.1-11 +- switch to the upstream patch for #727829 + +* Wed Aug 31 2011 Nalin Dahyabhai 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 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 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 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 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 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 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 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 +- incorporate a fix to teach the file labeling bits about when replay caches + are expunged (#576093) + +* Thu May 26 2011 Nalin Dahyabhai +- switch to the upstream patch for #707145 + +* Wed May 25 2011 Nalin Dahyabhai 1.9.1-2 +- klist: don't trip over referral entries when invoked with -s (#707145, + RT#6915) + +* Fri May 6 2011 Nalin Dahyabhai +- fixup URL in a comment +- when built with NSS, require 3.12.10 rather than 3.12.9 + +* Thu May 5 2011 Nalin Dahyabhai 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 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 +- 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 +- 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 1.9-8 +- backport change from SVN to fix a computed-value-not-used warning in + kpropd (#684065) + +* Tue Mar 15 2011 Nalin Dahyabhai 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 +- 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 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 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 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 - 1.9-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Feb 7 2011 Nalin Dahyabhai +- fix a compile error in the SELinux labeling patch when -DDEBUG is used (Sumit + Bose) + +* Tue Feb 1 2011 Nalin Dahyabhai +- properly advertise that the kpropd init script now supports force-reload + (Zbysek Mraz, #630587) + +* Wed Jan 26 2011 Nalin Dahyabhai 1.9-2 +- pkinit: when verifying signed data, use the CMS APIs for better + interoperability (#636985, RT#6851) + +* Wed Dec 22 2010 Nalin Dahyabhai 1.9-1 +- update to 1.9 final + +* Mon Dec 20 2010 Nalin Dahyabhai 1.9-0.beta3.1 +- fix link flags and permissions on shared libraries (ausil) + +* Thu Dec 16 2010 Nalin Dahyabhai 1.9-0.beta3.0 +- update to 1.9 beta 3 + +* Mon Dec 6 2010 Nalin Dahyabhai 1.9-0.beta2.0 +- update to 1.9 beta 2 + +* Tue Nov 9 2010 Nalin Dahyabhai 1.9-0.beta1.1 +- drop not-needed-since-1.8 build dependency on rsh (ssorce) + +* Fri Nov 5 2010 Nalin Dahyabhai 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 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 1.8.3-7 +- rebuild + +* Mon Oct 4 2010 Nalin Dahyabhai 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 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 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 1.8.3-2 +- fix a logic bug in computing key expiration times (RT#6762, #627022) + +* Wed Aug 4 2010 Nalin Dahyabhai 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 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 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 +- 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 1.8.2-1 +- update to 1.8.2 + - drop patches for CVE-2010-1320, CVE-2010-1321 + +* Tue Jun 1 2010 Nalin Dahyabhai 1.8.1-7 +- rebuild + +* Thu May 27 2010 Nalin Dahyabhai +- 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 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 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 1.8.1-4 +- fix output of kprop's init script's "status" and "reload" commands (#588222) + +* Tue Apr 20 2010 Nalin Dahyabhai 1.8.1-3 +- incorporate patch to fix double-free in the KDC (CVE-2010-1320, #581922) + +* Wed Apr 14 2010 Nalin Dahyabhai 1.8.1-2 +- fix a typo in kerberos.ldif + +* Fri Apr 9 2010 Nalin Dahyabhai 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 +- kdc.conf: no more need to suggest a v4 mode, or listening on the v4 port + +* Thu Apr 8 2010 Nalin Dahyabhai +- 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 - 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 - 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 - 1.8-3 +- add documentation for the ticket_lifetime option (#561174) + +* Mon Mar 8 2010 Nalin Dahyabhai - 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 - 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 - 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 - 1.7.1-5 +- fix a regression (not labeling a kdb database lock file correctly, #569902) + +* Thu Feb 25 2010 Nalin Dahyabhai - 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 - 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 - 1.7.1-2 +- apply patch from upstream to fix KDC denial of service (CVE-2010-0283, + #566002) + +* Wed Feb 3 2010 Nalin Dahyabhai - 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 - 1.7-23 +- tighten up default permissions on kdc.conf and kadm5.acl (#558343) + +* Fri Jan 22 2010 Nalin Dahyabhai - 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 - 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 - 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 - 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 - 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 - 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 - 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 +- fix conditional for future RHEL + +* Mon Jan 4 2010 Nalin Dahyabhai - 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 - 1.7-14 +- refresh patch for #542868 from trunk + +* Thu Dec 10 2009 Nalin Dahyabhai +- 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 - 1.7-13 +- and put it back in + +* Tue Dec 8 2009 Nalin Dahyabhai +- back that last change out + +* Tue Dec 8 2009 Nalin Dahyabhai - 1.7-12 +- try to make gss_krb5_copy_ccache() work correctly for spnego (#542868) + +* Fri Dec 4 2009 Nalin Dahyabhai +- make krb5-config suppress CFLAGS output when called with --libs (#544391) + +* Thu Dec 3 2009 Nalin Dahyabhai - 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 - 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 - 1.7-9 +- add some conditional logic to simplify building on older Fedora releases + +* Tue Oct 13 2009 Nalin Dahyabhai +- don't forget the README + +* Mon Sep 14 2009 Nalin Dahyabhai - 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 +- 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 - 1.7-7 +- work around a compile problem with new openssl + +* Fri Aug 21 2009 Tomas Mraz - 1.7-6 +- rebuilt with new openssl + +* Fri Jul 24 2009 Fedora Release Engineering - 1.7-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Tue Jul 7 2009 Nalin Dahyabhai 1.7-5 +- rebuild to pick up the current forms of various patches + +* Mon Jul 6 2009 Nalin Dahyabhai +- 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 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 +- pam_rhosts_auth.so's been gone, use pam_rhosts.so instead + +* Mon Jun 29 2009 Nalin Dahyabhai 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 +- 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 +- 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 1.7-2 +- add and own %%{_libdir}/krb5/plugins/authdata + +* Thu Jun 4 2009 Nalin Dahyabhai 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 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 1.6.3-105 +- make PAM support for ksu also set PAM_RUSER + +* Thu Apr 23 2009 Nalin Dahyabhai 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 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 1.6.3-102 +- add LSB-style init script info + +* Fri Apr 17 2009 Nalin Dahyabhai +- explicitly run the pdf generation script using sh (part of #225974) + +* Tue Apr 7 2009 Nalin Dahyabhai 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 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 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 - 1.6.3-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Jan 16 2009 Nalin Dahyabhai 1.6.3-17 +- rebuild + +* Thu Sep 4 2008 Nalin Dahyabhai +- 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 1.6.3-16 +- fix license tag + +* Wed Jul 16 2008 Nalin Dahyabhai +- 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 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 1.6.3-14 +- generate src/include/krb5/krb5.h before building +- fix conditional for sparcv9 + +* Wed Apr 16 2008 Nalin Dahyabhai 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 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 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 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 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 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 +- 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 +- 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 +- 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 +- 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 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 1.6.3-6 +- patch to avoid depending on to define NI_MAXHOST and NI_MAXSERV + +* Tue Feb 12 2008 Nalin Dahyabhai 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 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 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 1.6.3-2 +- rebuild + +* Tue Oct 23 2007 Nalin Dahyabhai 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 1.6.2-10 +- make proper use of pam_loginuid and pam_selinux in rshd and ftpd + +* Fri Oct 12 2007 Nalin Dahyabhai +- make krb5.conf %%verify(not md5 size mtime) in addition to + %%config(noreplace), like /etc/nsswitch.conf (#329811) + +* Mon Oct 1 2007 Nalin Dahyabhai 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 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 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 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 1.6.2-5 +- incorporate fixes for MITKRB5-SA-2007-006 (CVE-2007-3999, CVE-2007-4000) + +* Sat Aug 25 2007 Nalin Dahyabhai 1.6.2-4 +- cover more cases in labeling files on creation +- add missing gawk build dependency + +* Thu Aug 23 2007 Nalin Dahyabhai 1.6.2-3 +- rebuild + +* Thu Jul 26 2007 Nalin Dahyabhai 1.6.2-2 +- kdc.conf: default to listening for TCP clients, too (#248415) + +* Thu Jul 19 2007 Nalin Dahyabhai 1.6.2-1 +- update to 1.6.2 +- add "buildrequires: texinfo-tex" to get texi2pdf + +* Wed Jun 27 2007 Nalin Dahyabhai 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 1.6.1-7 +- reintroduce missing %%postun for the non-split_workstation case + +* Mon Jun 25 2007 Nalin Dahyabhai 1.6.1-6 +- rebuild + +* Mon Jun 25 2007 Nalin Dahyabhai 1.6.1-5.1 +- rebuild + +* Sun Jun 24 2007 Nalin Dahyabhai 1.6.1-5 +- add missing pam-devel build requirement, force selinux-or-fail build + +* Sun Jun 24 2007 Nalin Dahyabhai 1.6.1-4 +- rebuild + +* Sun Jun 24 2007 Nalin Dahyabhai 1.6.1-3 +- label all files at creation-time according to the SELinux policy (#228157) + +* Fri Jun 22 2007 Nalin Dahyabhai +- 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 +- 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 +- 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 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 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 +- 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 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 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 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 +- 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 1.5-24 +- merge security fixes from RHSA-2007:0095 + +* Tue Apr 3 2007 Nalin Dahyabhai 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 +- back out buildrequires: keyutils-libs-devel for now + +* Thu Mar 22 2007 Nalin Dahyabhai 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 1.5-23 +- fix bug ID in changelog + +* Thu Mar 15 2007 Nalin Dahyabhai 1.5-22 + +* Thu Mar 15 2007 Nalin Dahyabhai 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 +- add patch to build semi-useful static libraries, but don't apply it unless + we need them + +* Tue Feb 27 2007 Nalin Dahyabhai - 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 +- make profile.d scriptlets mode 644 instead of 755 (part of #225974) + +* Tue Jan 30 2007 Nalin Dahyabhai 1.6-1 +- clean up quoting of command-line arguments passed to the krsh/krlogin + wrapper scripts + +* Mon Jan 22 2007 Nalin Dahyabhai +- 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 - 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 - 1.5-17 +- move to using pregenerated PDF docs to cure multilib conflicts (#222721) + +* Fri Jan 12 2007 Nalin Dahyabhai - 1.5-16 +- update backport of the preauth module interface (part of #194654) + +* Tue Jan 9 2007 Nalin Dahyabhai - 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 - 1.5-12 +- update backport of the preauth module interface + +* Mon Oct 30 2006 Nalin Dahyabhai +- 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 - 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 - 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 - 1.5-9.pal_18695 +- add backport of in-development preauth module interface (#208643) + +* Mon Oct 9 2006 Nalin Dahyabhai - 1.5-9 +- provide docs in PDF format instead of as tex source (Enrico Scholz, #209943) + +* Wed Oct 4 2006 Nalin Dahyabhai - 1.5-8 +- add missing shebang headers to krsh and krlogin wrapper scripts (#209238) + +* Wed Sep 6 2006 Nalin Dahyabhai - 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 - 1.5-6 +- switch to the updated patch for MITKRB-SA-2006-001 + +* Tue Aug 8 2006 Nalin Dahyabhai - 1.5-5 +- apply patch to address MITKRB-SA-2006-001 (CVE-2006-3084) + +* Mon Aug 7 2006 Nalin Dahyabhai - 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 - 1.5-3 +- rebuild + +* Tue Jul 25 2006 Nalin Dahyabhai - 1.5-2 +- pull up latest revision of patch to reduce lockups in rsh/rshd + +* Mon Jul 17 2006 Nalin Dahyabhai - 1.5-1.2 +- rebuild + +* Wed Jul 12 2006 Jesse Keating - 1.5-1.1 +- rebuild + +* Thu Jul 6 2006 Nalin Dahyabhai 1.5-1 +- build + +* Wed Jul 5 2006 Nalin Dahyabhai 1.5-0 +- update to 1.5 + +* Fri Jun 23 2006 Nalin Dahyabhai 1.4.3-9 +- mark profile.d config files noreplace (Laurent Rineau, #196447) + +* Thu Jun 8 2006 Nalin Dahyabhai 1.4.3-8 +- add buildprereq for autoconf + +* Mon May 22 2006 Nalin Dahyabhai 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 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 1.4.3-5 +- Fix formatting typo in kinit.1 (krb5-kinit-man-typo.patch) + +* Fri Feb 10 2006 Jesse Keating 1.4.3-4.1 +- bump again for double-long bug on ppc(64) + +* Mon Feb 6 2006 Nalin Dahyabhai 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 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 1.4.3-2 +- Use full paths in krb5.sh to avoid path lookups + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Thu Dec 1 2005 Nalin Dahyabhai +- login: don't truncate passwords before passing them into crypt(), in + case they're significant (#149476) + +* Thu Nov 17 2005 Nalin Dahyabhai 1.4.3-1 +- update to 1.4.3 +- make ksu setuid again (#137934, others) + +* Tue Sep 13 2005 Nalin Dahyabhai 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 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 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 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 1.4.1-6 +- rebuild + +* Wed Jun 29 2005 Nalin Dahyabhai 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 +- 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 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 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 1.4.1-2 +- add deadlock patch, removed old patch + +* Fri May 6 2005 Nalin Dahyabhai 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 1.4-3 +- drop krshd patch for now + +* Thu Mar 17 2005 Nalin Dahyabhai +- 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 1.4-2 +- don't include into the telnet client when we're not using curses + +* Thu Feb 24 2005 Nalin Dahyabhai 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 1.3.6-3 +- rebuild + +* Mon Dec 20 2004 Nalin Dahyabhai 1.3.6-2 +- rebuild + +* Mon Dec 20 2004 Nalin Dahyabhai 1.3.6-1 +- update to 1.3.6, which includes the previous fix + +* Mon Dec 20 2004 Nalin Dahyabhai 1.3.5-8 +- apply fix from Tom Yu for MITKRB5-SA-2004-004 (CAN-2004-1189) + +* Fri Dec 17 2004 Martin Stransky 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 1.3.5-6 +- rebuild + +* Mon Nov 22 2004 Nalin Dahyabhai 1.3.5-3 +- fix predictable-tempfile-name bug in krb5-send-pr (CAN-2004-0971, #140036) + +* Tue Nov 16 2004 Nalin Dahyabhai +- 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 1.3.5-2 +- fix globbing patch port mode (#139075) + +* Mon Nov 1 2004 Nalin Dahyabhai 1.3.5-1 +- fix segfault in telnet due to incorrect checking of gethostbyname_r result + codes (#129059) + +* Fri Oct 15 2004 Nalin Dahyabhai +- 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 1.3.4-7 +- rebuild + +* Tue Aug 24 2004 Nalin Dahyabhai 1.3.4-6 +- rebuild + +* Tue Aug 24 2004 Nalin Dahyabhai 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 1.3.4-4 +- rebuild + +* Mon Aug 23 2004 Nalin Dahyabhai 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 1.3.4-2 +- fix indexing error in server sorting patch (#127336) + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Mon Jun 14 2004 Nalin Dahyabhai 1.3.4-0.1 +- update to 1.3.4 final + +* Mon Jun 7 2004 Nalin Dahyabhai 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 1.3.3-8 +- rebuild + +* Fri Jun 4 2004 Nalin Dahyabhai 1.3.3-7 +- rebuild + +* Fri Jun 4 2004 Nalin Dahyabhai 1.3.3-6 +- apply updated patch from MITKRB5-SA-2004-001 (revision 2004-06-02) + +* Tue Jun 1 2004 Nalin Dahyabhai 1.3.3-5 +- rebuild + +* Tue Jun 1 2004 Nalin Dahyabhai 1.3.3-4 +- apply patch from MITKRB5-SA-2004-001 (#125001) + +* Wed May 12 2004 Thomas Woerner 1.3.3-3 +- removed rpath + +* Thu Apr 15 2004 Nalin Dahyabhai 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 1.3.3-1 +- update to 1.3.3 + +* Wed Mar 10 2004 Nalin Dahyabhai 1.3.2-1 +- update to 1.3.2 + +* Mon Mar 8 2004 Nalin Dahyabhai 1.3.1-12 +- rebuild + +* Tue Mar 02 2004 Elliot Lee 1.3.1-11.1 +- rebuilt + +* Fri Feb 13 2004 Elliot Lee 1.3.1-11 +- rebuilt + +* Mon Feb 9 2004 Nalin Dahyabhai 1.3.1-10 +- catch krb4 send_to_kdc cases in kdc preference patch + +* Mon Feb 2 2004 Nalin Dahyabhai 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 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 +- prefer the kdc which last replied to a request when sending requests to kdcs + +* Mon Nov 24 2003 Nalin Dahyabhai 1.3.1-7 +- fix combination of --with-netlib and --enable-dns (#82176) + +* Tue Nov 18 2003 Nalin Dahyabhai +- remove libdefault ticket_lifetime option from the default krb5.conf, it is + ignored by libkrb5 + +* Thu Sep 25 2003 Nalin Dahyabhai 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 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 +- 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 1.3.1-4 +- fix 32/64-bit bug storing and retrieving the issue_date in v4 credentials + +* Wed Sep 3 2003 Dan Walsh 1.3.1-3 +- Don't check for write access on /etc/krb5.conf if SELinux + +* Tue Aug 26 2003 Nalin Dahyabhai 1.3.1-2 +- fixup some int/pointer varargs wackiness + +* Tue Aug 5 2003 Nalin Dahyabhai 1.3.1-1 +- rebuild + +* Mon Aug 4 2003 Nalin Dahyabhai 1.3.1-0 +- update to 1.3.1 + +* Thu Jul 24 2003 Nalin Dahyabhai 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 1.3-1 +- update to 1.3 + +* Mon Jul 7 2003 Nalin Dahyabhai 1.2.8-4 +- correctly use stdargs + +* Wed Jun 18 2003 Nalin Dahyabhai 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 +- rebuilt + +* Wed May 21 2003 Jeremy Katz 1.2.8-2 +- gcc 3.3 doesn't implement varargs.h, include stdarg.h instead + +* Wed Apr 9 2003 Nalin Dahyabhai 1.2.8-1 +- update to 1.2.8 + +* Mon Mar 31 2003 Nalin Dahyabhai 1.2.7-14 +- fix double-free of enc_part2 in krb524d + +* Fri Mar 21 2003 Nalin Dahyabhai 1.2.7-13 +- update to latest patch kit for MITKRB5-SA-2003-004 + +* Wed Mar 19 2003 Nalin Dahyabhai 1.2.7-12 +- add patch included in MITKRB5-SA-2003-003 (CAN-2003-0028) + +* Mon Mar 17 2003 Nalin Dahyabhai 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 1.2.7-10 +- rebuild + +* Thu Mar 6 2003 Nalin Dahyabhai 1.2.7-9 +- fix buffer underrun in unparsing certain principals (CAN-2003-0082) + +* Tue Feb 4 2003 Nalin Dahyabhai 1.2.7-8 +- add patch to document the reject-bad-transited option in kdc.conf + +* Mon Feb 3 2003 Nalin Dahyabhai +- add patch to fix server-side crashes when principals have no + components (CAN-2003-0072) + +* Thu Jan 23 2003 Nalin Dahyabhai 1.2.7-7 +- add patch from Mark Cox for exploitable bugs in ftp client + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Wed Jan 15 2003 Nalin Dahyabhai 1.2.7-5 +- use PICFLAGS when building code from the ktany patch + +* Thu Jan 9 2003 Bill Nottingham 1.2.7-4 +- debloat + +* Tue Jan 7 2003 Jeremy Katz 1.2.7-3 +- include .so.* symlinks as well as .so.*.* + +* Mon Dec 9 2002 Jakub Jelinek 1.2.7-2 +- always #include to access errno, never do it directly +- enable LFS on a bunch of other 32-bit arches + +* Wed Dec 4 2002 Nalin Dahyabhai +- increase the maximum name length allowed by kuserok() to the higher value + used in development versions + +* Mon Dec 2 2002 Nalin Dahyabhai +- install src/krb524/README as README.krb524 in the -servers package, + includes information about converting for AFS principals + +* Fri Nov 15 2002 Nalin Dahyabhai 1.2.7-1 +- update to 1.2.7 +- disable use of tcl + +* Mon Nov 11 2002 Nalin Dahyabhai +- update to 1.2.7-beta2 (internal only, not for release), dropping dnsparse + and kadmind4 fixes + +* Wed Oct 23 2002 Nalin Dahyabhai 1.2.6-5 +- add patch for buffer overflow in kadmind4 (not used by default) + +* Fri Oct 11 2002 Nalin Dahyabhai 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 1.2.6-3 +- patch to handle truncated dns responses + +* Mon Oct 7 2002 Nalin Dahyabhai 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 1.2.6-1 +- update to 1.2.6 + +* Fri Sep 13 2002 Nalin Dahyabhai 1.2.5-7 +- use %%{_lib} for the sake of multilib systems + +* Fri Aug 2 2002 Nalin Dahyabhai 1.2.5-6 +- add patch from Tom Yu for exploitable bugs in rpc code used in kadmind + +* Tue Jul 23 2002 Nalin Dahyabhai 1.2.5-5 +- fix bug in krb5.csh which would cause the path check to always succeed + +* Fri Jul 19 2002 Jakub Jelinek 1.2.5-4 +- build even libdb.a with -fPIC and $RPM_OPT_FLAGS. + +* Fri Jun 21 2002 Tim Powers +- automated rebuild + +* Sun May 26 2002 Tim Powers +- automated rebuild + +* Wed May 1 2002 Nalin Dahyabhai 1.2.5-1 +- update to 1.2.5 +- disable statglue + +* Fri Mar 1 2002 Nalin Dahyabhai 1.2.4-1 +- update to 1.2.4 + +* Wed Feb 20 2002 Nalin Dahyabhai 1.2.3-5 +- rebuild in new environment +- reenable statglue + +* Sat Jan 26 2002 Florian La Roche +- prereq chkconfig for the server subpackage + +* Wed Jan 16 2002 Nalin Dahyabhai 1.2.3-3 +- build without -g3, which gives us large static libraries in -devel + +* Tue Jan 15 2002 Nalin Dahyabhai 1.2.3-2 +- reintroduce ld.so.conf munging in the -libs %%post + +* Thu Jan 10 2002 Nalin Dahyabhai 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 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 1.2.2-13 +- bump release number and rebuild + +* Wed Aug 1 2001 Nalin Dahyabhai +- add patch to fix telnetd vulnerability + +* Fri Jul 20 2001 Nalin Dahyabhai +- tweak statglue.c to fix stat/stat64 aliasing problems +- be cleaner in use of gcc to build shlibs + +* Wed Jul 11 2001 Nalin Dahyabhai +- use gcc to build shared libraries + +* Wed Jun 27 2001 Nalin Dahyabhai +- 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 +- Bump release + rebuild. + +* Tue May 29 2001 Nalin Dahyabhai +- pass some structures by address instead of on the stack in krb5kdc + +* Tue May 22 2001 Nalin Dahyabhai +- rebuild in new environment + +* Thu Apr 26 2001 Nalin Dahyabhai +- add patch from Tom Yu to fix ftpd overflows (#37731) + +* Wed Apr 18 2001 Than Ngo +- disable optimizations on the alpha again + +* Fri Mar 30 2001 Nalin Dahyabhai +- add in glue code to make sure that libkrb5 continues to provide a + weak copy of stat() + +* Thu Mar 15 2001 Nalin Dahyabhai +- build alpha with -O0 for now + +* Thu Mar 8 2001 Nalin Dahyabhai +- fix the kpropd init script + +* Mon Mar 5 2001 Nalin Dahyabhai +- 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 +- build alpha with -O0 for now +- own %%{_var}/kerberos + +* Tue Feb 6 2001 Nalin Dahyabhai +- own the directories which are created for each package (#26342) + +* Tue Jan 23 2001 Nalin Dahyabhai +- gettextize init scripts + +* Fri Jan 19 2001 Nalin Dahyabhai +- add some comments to the ksu patches for the curious +- re-enable optimization on alphas + +* Mon Jan 15 2001 Nalin Dahyabhai +- 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 +- force -fPIC + +* Fri Dec 1 2000 Nalin Dahyabhai +- rebuild in new environment + +* Tue Oct 31 2000 Nalin Dahyabhai +- add bison as a BuildPrereq (#20091) + +* Mon Oct 30 2000 Nalin Dahyabhai +- change /usr/dict/words to /usr/share/dict/words in default kdc.conf (#20000) + +* Thu Oct 5 2000 Nalin Dahyabhai +- apply kpasswd bug fixes from David Wragg + +* Wed Oct 4 2000 Nalin Dahyabhai +- 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 +- 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 +- 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 +- rebuild to compress man pages. + +* Sat Jul 15 2000 Bill Nottingham +- move initscript back + +* Fri Jul 14 2000 Nalin Dahyabhai +- disable servers by default to keep linuxconf from thinking they need to be + started when they don't + +* Thu Jul 13 2000 Prospector +- automatic rebuild + +* Mon Jul 10 2000 Nalin Dahyabhai +- change cleanup code in post to not tickle chkconfig +- add grep as a Prereq: for -libs + +* Thu Jul 6 2000 Nalin Dahyabhai +- 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 +- 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 +- 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 +- tweak graceful start/stop logic in post and preun + +* Mon Jun 26 2000 Nalin Dahyabhai +- 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 +- only remove old krb5server init script links if the init script is there + +* Sat Jun 17 2000 Nalin Dahyabhai +- disable kshell and eklogin by default + +* Thu Jun 15 2000 Nalin Dahyabhai +- 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 +- make sure workstation servers are all disabled by default +- clean up krb5server init script + +* Fri Jun 9 2000 Nalin Dahyabhai +- 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 +- make ksu and v4rcp owned by root + +* Sat Jun 3 2000 Nalin Dahyabhai +- 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 +- 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 +- fix config_subpackage logic + +* Tue May 16 2000 Nalin Dahyabhai +- 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 +- 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 +- 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 +- fix configure stuff for ia64 + +* Mon Apr 10 2000 Nalin Dahyabhai +- 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 +- add man pages for kerberos(1), kvno(1), .k5login(5) +- add kvno to -workstation + +* Mon Apr 03 2000 Nalin Dahyabhai +- 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 +- Make klogind pass a clean environment to children, like NetKit's rlogind does. + +* Wed Mar 08 2000 Nalin Dahyabhai +- 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 +- Correct copyright: it's exportable now, provided the proper paperwork is + filed with the government. + +* Fri Mar 03 2000 Nalin Dahyabhai +- 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 +- run kadmin.local correctly at startup + +* Mon Feb 28 2000 Nalin Dahyabhai +- pass absolute path to kadm5.keytab if/when extracting keys at startup + +* Sat Feb 19 2000 Nalin Dahyabhai +- fix info page insertions + +* Wed Feb 9 2000 Nalin Dahyabhai +- 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 +- fix for potentially gzipped man pages + +* Fri Jan 21 2000 Nalin Dahyabhai +- fix comments in krb5-configs + +* Fri Jan 7 2000 Nalin Dahyabhai +- move /usr/kerberos/bin to end of PATH + +* Tue Dec 28 1999 Nalin Dahyabhai +- install kadmin header files + +* Tue Dec 21 1999 Nalin Dahyabhai +- 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 +- remove hesiod dependency at build-time + +* Sun Dec 19 1999 Nalin Dahyabhai +- rebuild on 1.1.1 + +* Thu Oct 7 1999 Nalin Dahyabhai +- 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 +- 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 +- added -lncurses to telnet and telnetd makefiles + +* Mon Jul 5 1999 Nalin Dahyabhai +- added krb5.csh and krb5.sh to /etc/profile.d + +* Tue Jun 22 1999 Nalin Dahyabhai +- broke out configuration files + +* Mon Jun 14 1999 Nalin Dahyabhai +- fixed server package so that it works now + +* Sat May 15 1999 Nalin Dahyabhai +- 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