diff --git a/.gitignore b/.gitignore index d4151c9..61533df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -SOURCES/krb5-1.14.1-pdfs.tar -SOURCES/krb5-1.14.1.tar.gz +SOURCES/krb5-1.15.1-pdfs.tar +SOURCES/krb5-1.15.1.tar.gz SOURCES/nss_wrapper-0.0-20140204195100.git3d58327.tar.xz SOURCES/socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz diff --git a/.krb5.metadata b/.krb5.metadata index cfff662..22193ae 100644 --- a/.krb5.metadata +++ b/.krb5.metadata @@ -1,4 +1,4 @@ -a374c9aec97659bebf99244c83c24c069764e6a3 SOURCES/krb5-1.14.1-pdfs.tar -f12dc3b8630fd1fefb7058cd782754489377308b SOURCES/krb5-1.14.1.tar.gz +0feda2b6393a4ac9ecc449fc7b4215da5ca6860d SOURCES/krb5-1.15.1-pdfs.tar +810210a61070ea371014ac514d191bbe5cdac2e2 SOURCES/krb5-1.15.1.tar.gz 7e2c80565c726a6be9a62615752196710e2e2faa SOURCES/nss_wrapper-0.0-20140204195100.git3d58327.tar.xz ca7b62bd60d45817a059063bb0efd68cd1ecc889 SOURCES/socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz diff --git a/SOURCES/Add-certauth-pluggable-interface.patch b/SOURCES/Add-certauth-pluggable-interface.patch new file mode 100644 index 0000000..30a25ca --- /dev/null +++ b/SOURCES/Add-certauth-pluggable-interface.patch @@ -0,0 +1,1146 @@ +From c206d6f3351d51ef3a916ef8522ab58c1a8572f7 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-the-client_name-kdcpreauth-callback.patch b/SOURCES/Add-the-client_name-kdcpreauth-callback.patch new file mode 100644 index 0000000..7cd1b67 --- /dev/null +++ b/SOURCES/Add-the-client_name-kdcpreauth-callback.patch @@ -0,0 +1,58 @@ +From b0f389ad69cbd68f2825fe32556e4b4a599a0ac3 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/Correct-error-handling-bug-in-prior-commit.patch b/SOURCES/Correct-error-handling-bug-in-prior-commit.patch new file mode 100644 index 0000000..e080091 --- /dev/null +++ b/SOURCES/Correct-error-handling-bug-in-prior-commit.patch @@ -0,0 +1,32 @@ +From e9a48c7c89def99b0e60a8b83646a345966c077c 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 0000000..330820d --- /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/Improve-PKINIT-UPN-SAN-matching.patch b/SOURCES/Improve-PKINIT-UPN-SAN-matching.patch new file mode 100644 index 0000000..d4d45c6 --- /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/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 0000000..2089450 --- /dev/null +++ b/SOURCES/Use-the-canonical-client-principal-name-for-OTP.patch @@ -0,0 +1,29 @@ +From 7c922602fe8fec44c55558daa32061cea86355cb 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/kprop.service b/SOURCES/kprop.service index 4ed2247..da6a6b8 100644 --- a/SOURCES/kprop.service +++ b/SOURCES/kprop.service @@ -4,7 +4,8 @@ After=syslog.target network.target [Service] Type=forking -ExecStart=/usr/sbin/_kpropd +EnvironmentFile=-/etc/sysconfig/kprop +ExecStart=/usr/sbin/_kpropd $KPROPD_ARGS [Install] WantedBy=multi-user.target diff --git a/SOURCES/kprop.sysconfig b/SOURCES/kprop.sysconfig new file mode 100644 index 0000000..f43e8bb --- /dev/null +++ b/SOURCES/kprop.sysconfig @@ -0,0 +1 @@ +KPROPD_ARGS= diff --git a/SOURCES/krb5-1.11-kpasswdtest.patch b/SOURCES/krb5-1.11-kpasswdtest.patch index f07b225..4657926 100644 --- a/SOURCES/krb5-1.11-kpasswdtest.patch +++ b/SOURCES/krb5-1.11-kpasswdtest.patch @@ -1,6 +1,17 @@ ---- krb5-1.11.3/src/kadmin/testing/proto/krb5.conf.proto -+++ krb5-1.11.3/src/kadmin/testing/proto/krb5.conf.proto -@@ -7,6 +7,7 @@ +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 diff --git a/SOURCES/krb5-1.11-run_user_0.patch b/SOURCES/krb5-1.11-run_user_0.patch index 6be760a..734341c 100644 --- a/SOURCES/krb5-1.11-run_user_0.patch +++ b/SOURCES/krb5-1.11-run_user_0.patch @@ -1,9 +1,16 @@ -A hack: if we're looking at creating a ccache directory directly below -the /run/user/0 directory, and /run/user/0 doesn't exist, try to create -it, too. +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 ---- krb5/src/lib/krb5/ccache/cc_dir.c -+++ krb5/src/lib/krb5/ccache/cc_dir.c +--- + 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 @@ -13,7 +20,7 @@ it, too. extern const krb5_cc_ops krb5_dcc_ops; extern const krb5_cc_ops krb5_fcc_ops; -@@ -239,6 +241,18 @@ +@@ -237,6 +239,18 @@ verify_dir(krb5_context context, const char *dirname) if (stat(dirname, &st) < 0) { if (errno == ENOENT) { diff --git a/SOURCES/krb5-1.12-api.patch b/SOURCES/krb5-1.12-api.patch index f5432a3..ae261d5 100644 --- a/SOURCES/krb5-1.12-api.patch +++ b/SOURCES/krb5-1.12-api.patch @@ -1,10 +1,17 @@ -Reference docs don't define what happens if you call krb5_realm_compare() with -malformed krb5_principal structures. Define a behavior which keeps it from -crashing if applications don't check ahead of time. +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 ---- krb5/src/lib/krb5/krb/princ_comp.c -+++ krb5/src/lib/krb5/krb/princ_comp.c -@@ -41,6 +41,10 @@ realm_compare_flags(krb5_context context +--- + 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; @@ -15,7 +22,7 @@ crashing if applications don't check ahead of time. if (realm1->length != realm2->length) return FALSE; if (realm1->length == 0) -@@ -92,6 +98,9 @@ krb5_principal_compare_flags(krb5_contex +@@ -88,6 +92,9 @@ krb5_principal_compare_flags(krb5_context context, krb5_principal upn2 = NULL; krb5_boolean ret = FALSE; diff --git a/SOURCES/krb5-1.12-buildconf.patch b/SOURCES/krb5-1.12-buildconf.patch deleted file mode 100644 index 11b816f..0000000 --- a/SOURCES/krb5-1.12-buildconf.patch +++ /dev/null @@ -1,54 +0,0 @@ -Build binaries in this package as RELRO PIEs, libraries as partial RELRO, -and install shared libraries with the execute bit set on them. Prune out -the -L/usr/lib* and PIE flags where they might leak out and affect -apps which just want to link with the libraries. FIXME: needs to check and -not just assume that the compiler supports using these flags. - ---- krb5/src/config/shlib.conf -+++ krb5/src/config/shlib.conf -@@ -419,7 +419,7 @@ mips-*-netbsd*) - SHLIBEXT=.so - # Linux ld doesn't default to stuffing the SONAME field... - # Use objdump -x to examine the fields of the library -- LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT),--no-undefined' -+ LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT),--no-undefined -Wl,-z,relro -Wl,--warn-shared-textrel' - # - LDCOMBINE_TAIL='-Wl,--version-script binutils.versions && $(PERL) -w $(top_srcdir)/util/export-check.pl $(SHLIB_EXPORT_FILE) $@' - SHLIB_EXPORT_FILE_DEP=binutils.versions -@@ -430,7 +430,8 @@ - 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)' ---- krb5/src/build-tools/krb5-config.in -+++ krb5/src/build-tools/krb5-config.in -@@ -189,6 +189,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 ---- krb5/src/config/pre.in -+++ krb5/src/config/pre.in -@@ -188,7 +188,7 @@ - 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/SOURCES/krb5-1.12-ksu-path.patch b/SOURCES/krb5-1.12-ksu-path.patch index 65552c9..7127916 100644 --- a/SOURCES/krb5-1.12-ksu-path.patch +++ b/SOURCES/krb5-1.12-ksu-path.patch @@ -1,7 +1,16 @@ -Set the default PATH to the one set by login. +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 ---- krb5/src/clients/ksu/Makefile.in -+++ krb5/src/clients/ksu/Makefile.in +--- + 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).. diff --git a/SOURCES/krb5-1.12-ktany.patch b/SOURCES/krb5-1.12-ktany.patch index 88f1a7e..a518ebf 100644 --- a/SOURCES/krb5-1.12-ktany.patch +++ b/SOURCES/krb5-1.12-ktany.patch @@ -1,10 +1,48 @@ -Adds an "ANY" keytab type which is a list of other keytab locations to search -when searching for a specific entry. When iterated through, it only presents -the contents of the first keytab. +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 -diff -up /dev/null krb5-1.7/src/lib/krb5/keytab/kt_any.c ---- /dev/null 2009-06-04 10:34:55.169007373 -0400 -+++ krb5-1.7/src/lib/krb5/keytab/kt_any.c 2009-06-04 13:54:36.000000000 -0400 +--- + 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 @@ -298,10 +336,11 @@ diff -up /dev/null krb5-1.7/src/lib/krb5/keytab/kt_any.c + free(data->choices); + free(data); +} -diff -up krb5-1.7/src/lib/krb5/keytab/ktbase.c krb5-1.7/src/lib/krb5/keytab/ktbase.c ---- krb5-1.7/src/lib/krb5/keytab/ktbase.c 2009-02-18 13:18:56.000000000 -0500 -+++ krb5-1.7/src/lib/krb5/keytab/ktbase.c 2009-06-04 13:54:36.000000000 -0400 -@@ -59,14 +59,19 @@ extern const krb5_kt_ops krb5_ktf_ops; +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; @@ -322,30 +361,3 @@ diff -up krb5-1.7/src/lib/krb5/keytab/ktbase.c krb5-1.7/src/lib/krb5/keytab/ktba }; const static struct krb5_kt_typelist krb5_kt_typelist_memory = { &krb5_mkt_ops, -diff -up krb5-1.7/src/lib/krb5/keytab/Makefile.in krb5-1.7/src/lib/krb5/keytab/Makefile.in ---- krb5-1.7/src/lib/krb5/keytab/Makefile.in 2009-01-05 15:27:53.000000000 -0500 -+++ krb5-1.7/src/lib/krb5/keytab/Makefile.in 2009-06-04 13:54:36.000000000 -0400 -@@ -19,6 +19,7 @@ STLIBOBJS= \ - ktfr_entry.o \ - ktremove.o \ - ktfns.o \ -+ kt_any.o \ - kt_file.o \ - kt_memory.o \ - kt_srvtab.o \ -@@ -31,6 +32,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) \ -@@ -43,6 +45,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/SOURCES/krb5-1.12.1-pam.patch b/SOURCES/krb5-1.12.1-pam.patch index 5a8e65e..87eeec9 100644 --- a/SOURCES/krb5-1.12.1-pam.patch +++ b/SOURCES/krb5-1.12.1-pam.patch @@ -1,21 +1,24 @@ -Modify ksu so that it performs account and session management on behalf of -the target user account, mimicking the action of regular su. The default -service name is "ksu", because on Fedora at least the configuration used -is determined by whether or not a login shell is being opened, and so -this may need to vary, too. At run-time, ksu's behavior can be reset to -the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu] -section of /etc/krb5.conf. +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 -When enabled, ksu gains a dependency on libpam. +--- + 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 -Originally RT#5939, though it's changed since then to perform the account -and session management before dropping privileges, and to apply on top of -changes we're proposing for how it handles cache collections. - -diff -up krb5/src/aclocal.m4.pam krb5/src/aclocal.m4 ---- krb5/src/aclocal.m4.pam 2009-11-22 12:00:45.000000000 -0500 -+++ krb5/src/aclocal.m4 2010-03-05 10:48:08.000000000 -0500 -@@ -1703,3 +1703,70 @@ AC_DEFUN(KRB5_AC_KEYRING_CCACHE,[ +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 @@ -86,9 +89,48 @@ diff -up krb5/src/aclocal.m4.pam krb5/src/aclocal.m4 +AC_SUBST(PAM_MAN) +AC_SUBST(NON_PAM_MAN) +])dnl -diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c ---- krb5/src/clients/ksu/main.c.pam 2009-11-02 22:27:56.000000000 -0500 -+++ krb5/src/clients/ksu/main.c 2010-03-05 10:48:08.000000000 -0500 +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 */ @@ -116,7 +158,7 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c /***********/ #define KS_TEMPORARY_CACHE "MEMORY:_ksu" -@@ -586,6 +592,23 @@ main (argc, argv) +@@ -515,6 +521,23 @@ main (argc, argv) prog_name,target_user,client_name, source_user,ontty()); @@ -140,7 +182,7 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c /* Run authorization as target.*/ if (krb5_seteuid(target_uid)) { com_err(prog_name, errno, _("while switching to target for " -@@ -651,6 +676,24 @@ +@@ -575,6 +598,24 @@ main (argc, argv) exit(1); } @@ -165,7 +207,7 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c } if( some_rest_copy){ -@@ -720,6 +745,30 @@ +@@ -632,6 +673,30 @@ main (argc, argv) exit(1); } @@ -196,7 +238,7 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c /* set permissions */ if (setgid(target_pwd->pw_gid) < 0) { perror("ksu: setgid"); -@@ -792,7 +817,7 @@ main (argc, argv) +@@ -729,7 +794,7 @@ main (argc, argv) fprintf(stderr, "program to be execed %s\n",params[0]); } @@ -205,7 +247,7 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c execv(params[0], params); com_err(prog_name, errno, _("while trying to execv %s"), params[0]); sweep_up(ksu_context, cc_target); -@@ -823,16 +875,35 @@ main (argc, argv) +@@ -759,16 +824,35 @@ main (argc, argv) if (ret_pid == -1) { com_err(prog_name, errno, _("while calling waitpid")); } @@ -242,46 +284,11 @@ diff -up krb5/src/clients/ksu/main.c.pam krb5/src/clients/ksu/main.c exit (1); } } -diff -up krb5/src/clients/ksu/Makefile.in.pam krb5/src/clients/ksu/Makefile.in ---- krb5/src/clients/ksu/Makefile.in.pam 2009-11-22 13:13:29.000000000 -0500 -+++ krb5/src/clients/ksu/Makefile.in 2010-03-05 11:55:14.000000000 -0500 -@@ -7,12 +7,14 @@ - 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 -@@ -21,13 +23,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 -up krb5/src/clients/ksu/pam.c.pam krb5/src/clients/ksu/pam.c ---- krb5/src/clients/ksu/pam.c.pam 2010-03-05 10:48:08.000000000 -0500 -+++ krb5/src/clients/ksu/pam.c 2010-03-05 10:48:08.000000000 -0500 +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 @@ -672,9 +679,11 @@ diff -up krb5/src/clients/ksu/pam.c.pam krb5/src/clients/ksu/pam.c + return ret; +} +#endif -diff -up krb5/src/clients/ksu/pam.h.pam krb5/src/clients/ksu/pam.h ---- krb5/src/clients/ksu/pam.h.pam 2010-03-05 10:48:08.000000000 -0500 -+++ krb5/src/clients/ksu/pam.h 2010-03-05 10:48:08.000000000 -0500 +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 @@ -733,10 +742,11 @@ diff -up krb5/src/clients/ksu/pam.h.pam krb5/src/clients/ksu/pam.h +int appl_pam_cred_init(void); +void appl_pam_cleanup(void); +#endif -diff -up krb5/src/configure.in.pam krb5/src/configure.in ---- krb5/src/configure.in.pam 2009-12-31 18:13:56.000000000 -0500 -+++ krb5/src/configure.in 2010-03-05 10:48:08.000000000 -0500 -@@ -1051,6 +1051,8 @@ if test "$ac_cv_lib_socket" = "yes" -a " +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) diff --git a/SOURCES/krb5-1.13-dirsrv-accountlock.patch b/SOURCES/krb5-1.13-dirsrv-accountlock.patch index 0a6661c..1c7182a 100644 --- a/SOURCES/krb5-1.13-dirsrv-accountlock.patch +++ b/SOURCES/krb5-1.13-dirsrv-accountlock.patch @@ -1,10 +1,19 @@ -Treat 'nsAccountLock: true' the same as 'loginDisabled: true'. Updated from -original version filed as RT#5891. +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 -diff -up krb5-1.8/src/aclocal.m4.dirsrv-accountlock krb5-1.8/src/aclocal.m4 ---- krb5-1.8/src/aclocal.m4.dirsrv-accountlock 2010-03-05 11:03:09.000000000 -0500 -+++ krb5-1.8/src/aclocal.m4 2010-03-05 11:03:10.000000000 -0500 -@@ -1656,6 +1656,15 @@ if test $with_ldap = yes; then +--- + 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 @@ -20,10 +29,11 @@ diff -up krb5-1.8/src/aclocal.m4.dirsrv-accountlock krb5-1.8/src/aclocal.m4 ])dnl dnl dnl If libkeyutils exists (on Linux) include it and use keyring ccache -diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c ---- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock 2009-11-24 18:52:25.000000000 -0500 -+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c 2010-03-05 11:03:10.000000000 -0500 -@@ -1546,6 +1546,23 @@ populate_krb5_db_entry(krb5_context cont +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; @@ -47,11 +57,11 @@ diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountloc ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname); if (ret) - goto cleanup; -diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c ---- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock 2009-11-24 18:52:25.000000000 -0500 -+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c 2010-03-05 11:03:10.000000000 -0500 -@@ -59,6 +59,9 @@ char *principal_attributes[] = { "kr +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", @@ -60,4 +70,4 @@ diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accou +#endif "krbLastPwdChange", "krbLastAdminUnlock", - "krbExtraData", + "krbPrincipalAuthInd", diff --git a/SOURCES/krb5-1.14.1-selinux-label.patch b/SOURCES/krb5-1.14.1-selinux-label.patch deleted file mode 100644 index e3585c7..0000000 --- a/SOURCES/krb5-1.14.1-selinux-label.patch +++ /dev/null @@ -1,1065 +0,0 @@ -From f9a89d1c197897707ebf13a7bb99a0d495686c93 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Mon, 18 Apr 2016 16:05:22 -0400 -Subject: [PATCH] krb5-1.14.1-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/gss-kernel-lib/Makefile.in | 5 +- - src/util/profile/prof_file.c | 3 +- - src/util/support/Makefile.in | 3 +- - src/util/support/selinux.c | 407 +++++++++++++++++++++ - 26 files changed, 592 insertions(+), 22 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 ce045ab..2b47aee 100644 ---- a/src/aclocal.m4 -+++ b/src/aclocal.m4 -@@ -87,6 +87,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 -@@ -1739,3 +1740,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 f6184da..c17cb5e 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 b0d9015..63271e7 100644 ---- a/src/config/pre.in -+++ b/src/config/pre.in -@@ -174,6 +174,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= -@@ -395,7 +396,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 8846ca0..9ec8d84 100644 ---- a/src/configure.in -+++ b/src/configure.in -@@ -1329,6 +1329,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 41c3d1b..6b7b2e3 100644 ---- a/src/include/k5-int.h -+++ b/src/include/k5-int.h -@@ -129,6 +129,7 @@ typedef unsigned char u_char; - - - #include "k5-platform.h" -+#include "k5-label.h" - - #define KRB5_KDB_MAX_LIFE (60*60*24) /* one day */ - #define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */ -diff --git a/src/include/k5-label.h b/src/include/k5-label.h -new file mode 100644 -index 0000000..dfaaa84 ---- /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 851cea3..2a814e5 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 07f62e9..5562d7e 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 82dfc0e..936f46b 100644 ---- a/src/kdc/main.c -+++ b/src/kdc/main.c -@@ -847,7 +847,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 19c4355..64f9641 100644 ---- a/src/lib/kadm5/logger.c -+++ b/src/lib/kadm5/logger.c -@@ -423,7 +423,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do - * Check for append/overwrite, then open the file. - */ - if (cp[4] == ':' || cp[4] == '=') { -- f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w"); -+ f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w"); - if (f) { - set_cloexec_file(f); - log_control.log_entries[i].lfu_filep = f; -@@ -959,7 +959,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 d377a20..74aa523 100644 ---- a/src/lib/kdb/kdb_log.c -+++ b/src/lib/kdb/kdb_log.c -@@ -480,7 +480,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries) - 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 b00a6bb..4a218c3 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 ace654d..c9580ca 100644 ---- a/src/lib/krb5/keytab/kt_file.c -+++ b/src/lib/krb5/keytab/kt_file.c -@@ -1030,7 +1030,7 @@ 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) ? - fopen_mode_rbplus : fopen_mode_rb); - if (!KTFILEP(id)) { -@@ -1038,7 +1038,7 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode) - /* try making it first time around */ - k5_create_secure_file(context, KTFILENAME(id)); - errno = 0; -- KTFILEP(id) = fopen(KTFILENAME(id), fopen_mode_rbplus); -+ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), fopen_mode_rbplus); - if (!KTFILEP(id)) - goto report_errno; - writevno = 1; -diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c -index 83c8d4d..a192461 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 2fb6aa0..c453189 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 9bad905..90df3b0 100644 ---- a/src/plugins/kdb/db2/adb_openclose.c -+++ b/src/plugins/kdb/db2/adb_openclose.c -@@ -147,7 +147,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char *filename, char *lockfilename, - * POSIX systems - */ - lockp->lockinfo.filename = strdup(lockfilename); -- if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) { -+ if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) { - /* - * maybe someone took away write permission so we could only - * get shared locks? -diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c -index 1b7bc16..9d449c0 100644 ---- a/src/plugins/kdb/db2/kdb_db2.c -+++ b/src/plugins/kdb/db2/kdb_db2.c -@@ -695,8 +695,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 2977b17..d5809a5 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 2a5b4f8..7239d03 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 d8b26e7..b0daa7c 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 64d0f91..5d5c0a6 100644 ---- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c -+++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c -@@ -178,7 +178,7 @@ done: - - /* set password in the file */ - old_mode = umask(0177); -- pfile = fopen(file_name, "a+"); -+ pfile = WRITABLEFOPEN(file_name, "a+"); - if (pfile == NULL) { - com_err(me, errno, _("Failed to open file %s: %s"), file_name, - strerror (errno)); -@@ -219,6 +219,9 @@ done: - * Delete the existing entry and add the new entry - */ - FILE *newfile; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - mode_t omask; - -@@ -230,7 +233,13 @@ done: - } - - omask = umask(077); -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(file_name); -+#endif - newfile = fopen(tmp_file, "w"); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif - umask (omask); - if (newfile == NULL) { - com_err(me, errno, _("Error creating file %s"), tmp_file); -diff --git a/src/slave/kpropd.c b/src/slave/kpropd.c -index 1383156..a950924 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/gss-kernel-lib/Makefile.in b/src/util/gss-kernel-lib/Makefile.in -index f70f3c6..7a2f9cc 100644 ---- a/src/util/gss-kernel-lib/Makefile.in -+++ b/src/util/gss-kernel-lib/Makefile.in -@@ -61,6 +61,7 @@ HEADERS= \ - gssapi_err_generic.h \ - k5-int.h \ - k5-int-pkinit.h \ -+ k5-label.h \ - k5-thread.h \ - k5-platform.h \ - k5-buf.h \ -@@ -162,10 +163,12 @@ gssapi_generic.h: $(GSS_GENERIC)/gssapi_generic.h - $(CP) $(GSS_GENERIC)/gssapi_generic.h $@ - gssapi_err_generic.h: $(GSS_GENERIC_BUILD)/gssapi_err_generic.h - $(CP) $(GSS_GENERIC_BUILD)/gssapi_err_generic.h $@ --k5-int.h: $(INCLUDE)/k5-int.h -+k5-int.h: $(INCLUDE)/k5-int.h k5-label.h - $(CP) $(INCLUDE)/k5-int.h $@ - k5-int-pkinit.h: $(INCLUDE)/k5-int-pkinit.h - $(CP) $(INCLUDE)/k5-int-pkinit.h $@ -+k5-label.h: $(INCLUDE)/k5-label.h -+ $(CP) $(INCLUDE)/k5-label.h $@ - k5-thread.h: $(INCLUDE)/k5-thread.h - $(CP) $(INCLUDE)/k5-thread.h $@ - k5-platform.h: $(INCLUDE)/k5-platform.h -diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c -index d774593..ccc671b 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 5181762..f77acd4 100644 ---- a/src/util/support/Makefile.in -+++ b/src/util/support/Makefile.in -@@ -59,6 +59,7 @@ IPC_SYMS= \ - - STLIBOBJS= \ - threads.o \ -+ selinux.o \ - init-addrinfo.o \ - plugins.o \ - errors.o \ -@@ -131,7 +132,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 0000000..6cf1b0c ---- /dev/null -+++ b/src/util/support/selinux.c -@@ -0,0 +1,407 @@ -+/* -+ * 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 */ --- -2.8.0.rc3 - diff --git a/SOURCES/krb5-1.14.1.tar.gz.asc b/SOURCES/krb5-1.14.1.tar.gz.asc deleted file mode 100644 index e42bf86..0000000 --- a/SOURCES/krb5-1.14.1.tar.gz.asc +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1 - -iQGcBAABAgAGBQJW1KZzAAoJEKMvF/0AVcMF9cQMAKZNlrtrB6ZS6CLFqGpRPfG2 -T6WbhJ5GEYl4kmdINbJ/RQUMk2APwxMSmsl7q8VNM1JIxQVAL7cBZTu+7cfs3mZE -z9eCMmQsKdhZ3bnF52KB5LM2JfNUMidGEqzvOwK7mUgMXaPihiqYA0f2P10paOZl -cW1as0bvTbjWrnAO+jpW3AuW50h7zOpicX4F8gmD0gaqzcKZO9uZA3p6bjIgVRsO -XzofLkv0NxKWqcdLWocsVb2s4gezsQuRNIWmvpnR7ZFS2tfTuqrmdRNTm9t/yWMV -5YmTBKE0/R9JRRmqLm/IglIqrq7G/ZYRHSYpT5oSu72iZRrf5pKQ/jwB0jpFMN00 -7xORKTWNwiGmAvIBBZqH+3emyIrcIdIw/3MN+HEZaLisJ1K/4bWJLB+0ju9dEcU/ -naNhagonxFbVfE7SrlW/WflZpun2PVZ4c9WTG6z1OWPXZkXMLqdv+mNSoCHcvpOt -Z2+3HnWWanFncCn81oSLo/Zp3/0k7XBXtjp2Pb18CQ== -=Py+v ------END PGP SIGNATURE----- diff --git a/SOURCES/krb5-1.14.2-log_file_mode.patch b/SOURCES/krb5-1.14.2-log_file_mode.patch deleted file mode 100644 index 0fb965c..0000000 --- a/SOURCES/krb5-1.14.2-log_file_mode.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 9914b93516bbce9b1123ed5f9f796b7028944892 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Thu, 17 Dec 2015 13:31:39 -0500 -Subject: [PATCH] Create KDC and kadmind log files with mode 0640 - -In krb5_klog_init(), use open() and fdopen() to open log files so that -we can specify a mode. Specify a mode which doesn't include the -group-write, other-read, or other-write bits even if the process umask -allows them. - -[ghudson@mit.edu: wrote commit message, de-indented post-open setup -code] -[rharwood@redhat.com: backport not clean due to SELinux patching] - -ticket: 8344 (new) ---- - src/lib/kadm5/logger.c | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - -diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c -index 19c4355..f4a9387 100644 - ---- a/src/lib/kadm5/logger.c 2016-01-21 18:52:52.529544902 +0000 -+++ b/src/lib/kadm5/logger.c 2016-01-21 18:57:22.923972419 +0000 -@@ -354,7 +354,7 @@ - const char *logging_profent[3]; - const char *logging_defent[3]; - char **logging_specs; -- int i, ngood; -+ int i, ngood, fd, append; - char *cp, *cp2; - char savec = '\0'; - int error; -@@ -422,18 +422,21 @@ - /* - * Check for append/overwrite, then open the file. - */ -- if (cp[4] == ':' || cp[4] == '=') { -- f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w"); -- if (f) { -- set_cloexec_file(f); -- log_control.log_entries[i].lfu_filep = f; -- log_control.log_entries[i].log_type = K_LOG_FILE; -- log_control.log_entries[i].lfu_fname = &cp[5]; -- } else { -+ append = (cp[4] == ':') ? O_APPEND : 0; -+ if (append || cp[4] == '=') { -+ fd = THREEPARAMOPEN(&cp[5], O_CREAT | O_WRONLY | append, -+ S_IRUSR | S_IWUSR | S_IRGRP); -+ if (fd != -1) -+ f = fdopen(fd, append ? "a" : "w"); -+ if (fd == -1 || f == NULL) { - fprintf(stderr,"Couldn't open log file %s: %s\n", - &cp[5], error_message(errno)); - continue; - } -+ set_cloexec_file(f); -+ log_control.log_entries[i].lfu_filep = f; -+ log_control.log_entries[i].log_type = K_LOG_FILE; -+ log_control.log_entries[i].lfu_fname = &cp[5]; - } - } - #ifdef HAVE_SYSLOG diff --git a/SOURCES/krb5-1.14.2-skip_unnecessary_mech_inquire_cred.patch b/SOURCES/krb5-1.14.2-skip_unnecessary_mech_inquire_cred.patch deleted file mode 100644 index b3e9af6..0000000 --- a/SOURCES/krb5-1.14.2-skip_unnecessary_mech_inquire_cred.patch +++ /dev/null @@ -1,79 +0,0 @@ -From ff5eb892910eeac335d989ae14020da4ffbcc8ec Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Mon, 29 Feb 2016 16:51:22 -0500 -Subject: [PATCH] Skip unnecessary mech calls in gss_inquire_cred() - -If the caller does not request a name, lifetime, or cred_usage when -calling gss_inquire_cred(), service the call by copying the mechanism -list (if requested) but do not call into the mech. - -This change alleviates an issue (reported by Adam Bernstein) where -SPNEGO can fail in the presence of expired krb5 credentials rather -than proceeding with a different mechanism, or can resolve a krb5 -credential without the benefit of the target name. - -ticket: 8373 -target_version: 1.14-next -target_version: 1.13-next -tags: pullup ---- - src/lib/gssapi/mechglue/g_inq_cred.c | 39 ++++++++++++++++++++---------------- - 1 file changed, 22 insertions(+), 17 deletions(-) - -diff --git a/src/lib/gssapi/mechglue/g_inq_cred.c b/src/lib/gssapi/mechglue/g_inq_cred.c -index c5577d4..9111962 100644 ---- a/src/lib/gssapi/mechglue/g_inq_cred.c -+++ b/src/lib/gssapi/mechglue/g_inq_cred.c -@@ -92,27 +92,32 @@ gss_OID_set * mechanisms; - mech_cred = GSS_C_NO_CREDENTIAL; - mech = gssint_get_mechanism(GSS_C_NULL_OID); - } -- if (mech == NULL) -- return (GSS_S_DEFECTIVE_CREDENTIAL); -- if (!mech->gss_inquire_cred) -- return (GSS_S_UNAVAILABLE); - -- status = mech->gss_inquire_cred(minor_status, mech_cred, -- name ? &mech_name : NULL, -- lifetime, cred_usage, NULL); -- if (status != GSS_S_COMPLETE) { -- map_error(minor_status, mech); -- return(status); -- } -+ /* Skip the call into the mech if the caller doesn't care about any of the -+ * values we would ask for. */ -+ if (name != NULL || lifetime != NULL || cred_usage != NULL) { -+ if (mech == NULL) -+ return (GSS_S_DEFECTIVE_CREDENTIAL); -+ if (!mech->gss_inquire_cred) -+ return (GSS_S_UNAVAILABLE); - -- if (name) { -- /* Convert mech_name into a union_name equivalent. */ -- status = gssint_convert_name_to_union_name(&temp_minor_status, -- mech, mech_name, name); -+ status = mech->gss_inquire_cred(minor_status, mech_cred, -+ name ? &mech_name : NULL, -+ lifetime, cred_usage, NULL); - if (status != GSS_S_COMPLETE) { -- *minor_status = temp_minor_status; - map_error(minor_status, mech); -- return (status); -+ return(status); -+ } -+ -+ if (name) { -+ /* Convert mech_name into a union_name equivalent. */ -+ status = gssint_convert_name_to_union_name(&temp_minor_status, -+ mech, mech_name, name); -+ if (status != GSS_S_COMPLETE) { -+ *minor_status = temp_minor_status; -+ map_error(minor_status, mech); -+ return (status); -+ } - } - } - --- -2.8.0.rc3 - diff --git a/SOURCES/krb5-1.14.3-fix_otp_as_key.patch b/SOURCES/krb5-1.14.3-fix_otp_as_key.patch deleted file mode 100644 index 0a47bf0..0000000 --- a/SOURCES/krb5-1.14.3-fix_otp_as_key.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 9929130f03f6a7f8a5f1acc23e92a609c8f27938 Mon Sep 17 00:00:00 2001 -From: Nathaniel McCallum -Date: Thu, 26 May 2016 16:54:29 -0400 -Subject: [PATCH] Avoid setting AS key when OTP preauth fails - -In otp_client_process(), call cb->set_as_key() later in the function -after the OTP request has been created. The previous position of this -call caused the AS key to be replaced even when later code in the -function failed, preventing other preauth mechanisms from retrieving -the correct AS key. - -ticket: 8421 (new) -target_version: 1.14-new -target_version: 1.13-new -tags: pullup ---- - src/lib/krb5/krb/preauth_otp.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/lib/krb5/krb/preauth_otp.c b/src/lib/krb5/krb/preauth_otp.c -index d9ddc8b..3de528b 100644 ---- a/src/lib/krb5/krb/preauth_otp.c -+++ b/src/lib/krb5/krb/preauth_otp.c -@@ -1081,11 +1081,6 @@ otp_client_process(krb5_context context, krb5_clpreauth_moddata moddata, - if (as_key == NULL) - return ENOENT; - -- /* Use FAST armor key as response key. */ -- retval = cb->set_as_key(context, rock, as_key); -- if (retval != 0) -- return retval; -- - /* Attempt to get token selection from the responder. */ - pin = empty_data(); - value = empty_data(); -@@ -1115,6 +1110,11 @@ otp_client_process(krb5_context context, krb5_clpreauth_moddata moddata, - if (retval != 0) - goto error; - -+ /* Use FAST armor key as response key. */ -+ retval = cb->set_as_key(context, rock, as_key); -+ if (retval != 0) -+ goto error; -+ - /* Encode the request into the pa_data output. */ - retval = set_pa_data(req, pa_data_out); - error: --- -2.8.1 - diff --git a/SOURCES/krb5-1.14.3-krad-recv.patch b/SOURCES/krb5-1.14.3-krad-recv.patch deleted file mode 100644 index 9016c88..0000000 --- a/SOURCES/krb5-1.14.3-krad-recv.patch +++ /dev/null @@ -1,44 +0,0 @@ -From c969e8a37617e9c7743a28177dd3808f7d08cee9 Mon Sep 17 00:00:00 2001 -From: Nathaniel McCallum -Date: Tue, 21 Jun 2016 16:12:36 -0400 -Subject: [PATCH] Fix incorrect recv() size calculation in libkrad - -Before this patch libkrad would always subtract the existing buffer -length from pktlen before passing it to recv(). In the case of stream -sockets, this is incorrect since krad_packet_bytes_needed() already -performs this calculation. Subtracting the buffer length twice could -cause integer underflow on the len parameter to recv(). - -ticket: 8430 (new) -target_version: 1.14-next -target_version: 1.13-next -tags: pullup ---- - src/lib/krad/remote.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c -index aaabffd..df3de3a 100644 ---- a/src/lib/krad/remote.c -+++ b/src/lib/krad/remote.c -@@ -315,7 +315,7 @@ on_io_read(krad_remote *rr) - request *tmp, *r; - int i; - -- pktlen = sizeof(rr->buffer_); -+ pktlen = sizeof(rr->buffer_) - rr->buffer.length; - if (rr->info->ai_socktype == SOCK_STREAM) { - pktlen = krad_packet_bytes_needed(&rr->buffer); - if (pktlen < 0) { -@@ -328,7 +328,7 @@ on_io_read(krad_remote *rr) - - /* Read the packet. */ - i = recv(verto_get_fd(rr->io), rr->buffer.data + rr->buffer.length, -- pktlen - rr->buffer.length, 0); -+ pktlen, 0); - if (i < 0) { - /* Should we try again? */ - if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR) --- -2.8.1 - diff --git a/SOURCES/krb5-1.14.3-ksu_root_prompt.patch b/SOURCES/krb5-1.14.3-ksu_root_prompt.patch deleted file mode 100644 index 356f2c7..0000000 --- a/SOURCES/krb5-1.14.3-ksu_root_prompt.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 324342ebf3a6b6e6d69268dc8640c642fdb25778 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Thu, 28 Apr 2016 16:20:22 -0400 -Subject: [PATCH] krb5-1.14.3-ksu_root_prompt.patch - -Backport: 2f8b9ef90829b031448d4547190c72438a69aacd ---- - src/clients/ksu/main.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c -index 1b2ca83..cab0c18 100644 ---- a/src/clients/ksu/main.c -+++ b/src/clients/ksu/main.c -@@ -122,7 +122,7 @@ main (argc, argv) - extern char * getpass(), *crypt(); - int pargc; - char ** pargv; -- krb5_boolean stored = FALSE, cc_reused = FALSE; -+ krb5_boolean stored = FALSE, cc_reused = FALSE, given_princ = FALSE; - krb5_boolean zero_password; - krb5_boolean restrict_creds; - krb5_deltat lifetime, rlife; -@@ -244,6 +244,7 @@ main (argc, argv) - com_err(prog_name, retval, _("when parsing name %s"), optarg); - errflg++; - } -+ given_princ = TRUE; - break; - #ifdef DEBUG - case 'D': -@@ -468,7 +469,7 @@ main (argc, argv) - - if ((source_uid == 0) || (target_uid == source_uid)){ - #ifdef GET_TGT_VIA_PASSWD -- if ((!all_rest_copy) && client != NULL && (stored == FALSE)){ -+ if (!all_rest_copy && given_princ && client != NULL && !stored) { - fprintf(stderr, _("WARNING: Your password may be exposed if you " - "enter it here and are logged\n")); - fprintf(stderr, _(" in remotely using an unsecure " --- -2.8.0.rc3 - diff --git a/SOURCES/krb5-1.14.4-CVE-2016-3120.patch b/SOURCES/krb5-1.14.4-CVE-2016-3120.patch deleted file mode 100644 index fa412aa..0000000 --- a/SOURCES/krb5-1.14.4-CVE-2016-3120.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 93b4a6306a0026cf1cc31ac4bd8a49ba5d034ba7 Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Tue, 19 Jul 2016 11:00:28 -0400 -Subject: [PATCH] Fix S4U2Self KDC crash when anon is restricted - -In validate_as_request(), when enforcing restrict_anonymous_to_tgt, -use client.princ instead of request->client; the latter is NULL when -validating S4U2Self requests. - -CVE-2016-3120: - -In MIT krb5 1.9 and later, an authenticated attacker can cause krb5kdc -to dereference a null pointer if the restrict_anonymous_to_tgt option -is set to true, by making an S4U2Self request. - - CVSSv2 Vector: AV:N/AC:H/Au:S/C:N/I:N/A:C/E:H/RL:OF/RC:C - -ticket: 8458 (new) -target_version: 1.14-next -target_version: 1.13-next ---- - src/kdc/kdc_util.c | 2 +- - src/tests/t_pkinit.py | 5 +++++ - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c -index 776e130..29f9dbb 100644 ---- a/src/kdc/kdc_util.c -+++ b/src/kdc/kdc_util.c -@@ -739,7 +739,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm, - return(KDC_ERR_MUST_USE_USER2USER); - } - -- if (check_anon(kdc_active_realm, request->client, request->server) != 0) { -+ if (check_anon(kdc_active_realm, client.princ, request->server) != 0) { - *status = "ANONYMOUS NOT ALLOWED"; - return(KDC_ERR_POLICY); - } -diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py -index b66c458..f0214b6 100755 ---- a/src/tests/t_pkinit.py -+++ b/src/tests/t_pkinit.py -@@ -93,6 +93,11 @@ out = realm.run([kvno, realm.host_princ], expected_code=1) - if 'KDC policy rejects request' not in out: - fail('Wrong error for restricted anonymous PKINIT') - -+# Regression test for #8458: S4U2Self requests crash the KDC if -+# anonymous is restricted. -+realm.kinit(realm.host_princ, flags=['-k']) -+realm.run([kvno, '-U', 'user', realm.host_princ]) -+ - # Go back to a normal KDC and disable anonymous PKINIT. - realm.stop_kdc() - realm.start_kdc() --- -2.8.1 - diff --git a/SOURCES/krb5-1.14.4-Fix-responder-without-preauth.patch b/SOURCES/krb5-1.14.4-Fix-responder-without-preauth.patch deleted file mode 100644 index c6693c4..0000000 --- a/SOURCES/krb5-1.14.4-Fix-responder-without-preauth.patch +++ /dev/null @@ -1,86 +0,0 @@ -From c45c43a82491f5c4487087cb424381e884559433 Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Fri, 5 Aug 2016 12:28:03 -0400 -Subject: [PATCH] Use responder for non-preauth AS requests - -If no AS reply key is computed during pre-authentication (typically -because no pre-authentication was required by the KDC), ask for the -password using the responder before calling gak_fct for the key, and -supply any resulting responder items to gak_fct. - -ticket: 8454 -target_version: 1.14-next -target_version: 1.13-next -tags: pullup ---- - src/lib/krb5/krb/get_in_tkt.c | 24 +++++++++++++++++++++++- - src/tests/t_general.py | 5 +++++ - 2 files changed, 28 insertions(+), 1 deletion(-) - -diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c -index 24cd970..4290d0c 100644 ---- a/src/lib/krb5/krb/get_in_tkt.c -+++ b/src/lib/krb5/krb/get_in_tkt.c -@@ -1391,6 +1391,8 @@ init_creds_step_reply(krb5_context context, - krb5_keyblock encrypting_key; - krb5_boolean fast_avail; - krb5_ccache out_ccache = k5_gic_opt_get_out_ccache(ctx->opt); -+ krb5_responder_fn responder; -+ void *responder_data; - - encrypting_key.length = 0; - encrypting_key.contents = NULL; -@@ -1549,13 +1551,33 @@ init_creds_step_reply(krb5_context context, - code = -1; - - if (code != 0) { -+ /* If a responder was provided and we are using a password, ask for the -+ * password using the responder before falling back to the prompter. */ -+ k5_gic_opt_get_responder(ctx->opt, &responder, &responder_data); -+ if (responder != NULL && !ctx->as_key.length) { -+ /* Indicate a need for the AS key by calling the gak_fct with a -+ * NULL as_key. */ -+ code = ctx->gak_fct(context, ctx->request->client, ctx->etype, -+ NULL, NULL, NULL, NULL, NULL, ctx->gak_data, -+ ctx->rctx.items); -+ if (code != 0) -+ goto cleanup; -+ -+ /* If that produced a responder question, invoke the responder. */ -+ if (!k5_response_items_empty(ctx->rctx.items)) { -+ code = (*responder)(context, responder_data, &ctx->rctx); -+ if (code != 0) -+ goto cleanup; -+ } -+ } -+ - /* if we haven't get gotten a key, get it now */ - TRACE_INIT_CREDS_GAK(context, &ctx->salt, &ctx->s2kparams); - code = (*ctx->gak_fct)(context, ctx->request->client, - ctx->reply->enc_part.enctype, - ctx->prompter, ctx->prompter_data, - &ctx->salt, &ctx->s2kparams, -- &ctx->as_key, ctx->gak_data, NULL); -+ &ctx->as_key, ctx->gak_data, ctx->rctx.items); - if (code != 0) - goto cleanup; - TRACE_INIT_CREDS_AS_KEY_GAK(context, &ctx->as_key); -diff --git a/src/tests/t_general.py b/src/tests/t_general.py -index fbdeddf..6d523fe 100755 ---- a/src/tests/t_general.py -+++ b/src/tests/t_general.py -@@ -34,6 +34,11 @@ realm.stop() - - realm = K5Realm(create_host=False) - -+# Regression test for #8454 (responder callback isn't used when -+# preauth is not required). -+realm.run(['./responder', '-r', 'password=%s' % password('user'), -+ realm.user_princ]) -+ - # Test that WRONG_REALM responses aren't treated as referrals unless - # they contain a crealm field pointing to a different realm. - # (Regression test for #8060.) --- -2.8.1 - diff --git a/SOURCES/krb5-1.14.4-SNI-HTTP-Host.patch b/SOURCES/krb5-1.14.4-SNI-HTTP-Host.patch deleted file mode 100644 index a34faad..0000000 --- a/SOURCES/krb5-1.14.4-SNI-HTTP-Host.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 69c8662190bcd46f2300d0cea139681001ea5b26 Mon Sep 17 00:00:00 2001 -From: Christian Heimes -Date: Mon, 8 Aug 2016 12:38:17 +0200 -Subject: [PATCH] Add Host HTTP header to MS-KKDCP requests - -Some web servers require a Host HTTP header for TLS connections with -SNI (server name indicator). It is also required for virtual hosts. - -ticket: 8472 (new) -target_version: 1.14-next -tags: pullup ---- - src/lib/krb5/os/sendto_kdc.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index c85fdba..a2b7359 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -78,6 +78,7 @@ - #define MAX_PASS 3 - #define DEFAULT_UDP_PREF_LIMIT 1465 - #define HARD_UDP_LIMIT 32700 /* could probably do 64K-epsilon ? */ -+#define PORT_LENGTH 6 /* decimal repr of UINT16_MAX */ - - /* Select state flags. */ - #define SSF_READ 0x01 -@@ -138,6 +139,7 @@ struct conn_state { - struct { - const char *uri_path; - const char *servername; -+ char port[PORT_LENGTH]; - char *https_request; - k5_tls_handle tls; - } http; -@@ -611,6 +613,8 @@ make_proxy_request(struct conn_state *state, const krb5_data *realm, - k5_buf_init_dynamic(&buf); - uri_path = (state->http.uri_path != NULL) ? state->http.uri_path : ""; - k5_buf_add_fmt(&buf, "POST /%s HTTP/1.0\r\n", uri_path); -+ k5_buf_add_fmt(&buf, "Host: %s:%s\r\n", state->http.servername, -+ state->http.port); - k5_buf_add(&buf, "Cache-Control: no-cache\r\n"); - k5_buf_add(&buf, "Pragma: no-cache\r\n"); - k5_buf_add(&buf, "User-Agent: kerberos/1.0\r\n"); -@@ -673,7 +677,7 @@ static krb5_error_code - add_connection(struct conn_state **conns, k5_transport transport, - krb5_boolean defer, struct addrinfo *ai, size_t server_index, - const krb5_data *realm, const char *hostname, -- const char *uri_path, char **udpbufp) -+ const char *port, const char *uri_path, char **udpbufp) - { - struct conn_state *state, **tailptr; - -@@ -695,11 +699,13 @@ add_connection(struct conn_state **conns, k5_transport transport, - state->service_write = service_tcp_write; - state->service_read = service_tcp_read; - } else if (transport == HTTPS) { -+ assert(hostname != NULL && port != NULL); - state->service_connect = service_tcp_connect; - state->service_write = service_https_write; - state->service_read = service_https_read; - state->http.uri_path = uri_path; - state->http.servername = hostname; -+ strlcpy(state->http.port, port, PORT_LENGTH); - } else { - state->service_connect = NULL; - state->service_write = NULL; -@@ -785,7 +791,7 @@ resolve_server(krb5_context context, const krb5_data *realm, - struct addrinfo *addrs, *a, hint, ai; - krb5_boolean defer; - int err, result; -- char portbuf[64]; -+ char portbuf[PORT_LENGTH]; - - /* Skip UDP entries if we don't want UDP. */ - if (strategy == NO_UDP && entry->transport == UDP) -@@ -800,7 +806,7 @@ resolve_server(krb5_context context, const krb5_data *realm, - ai.ai_addr = (struct sockaddr *)&entry->addr; - defer = (entry->transport != transport); - return add_connection(conns, entry->transport, defer, &ai, ind, realm, -- NULL, entry->uri_path, udpbufp); -+ NULL, NULL, entry->uri_path, udpbufp); - } - - /* If the entry has a specified transport, use it. */ -@@ -826,7 +832,8 @@ resolve_server(krb5_context context, const krb5_data *realm, - retval = 0; - for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { - retval = add_connection(conns, transport, FALSE, a, ind, realm, -- entry->hostname, entry->uri_path, udpbufp); -+ entry->hostname, portbuf, entry->uri_path, -+ udpbufp); - } - - /* For TCP_OR_UDP entries, add each address again with the non-preferred -@@ -836,7 +843,8 @@ resolve_server(krb5_context context, const krb5_data *realm, - for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { - a->ai_socktype = socktype_for_transport(transport); - retval = add_connection(conns, transport, TRUE, a, ind, realm, -- entry->hostname, entry->uri_path, udpbufp); -+ entry->hostname, portbuf, -+ entry->uri_path, udpbufp); - } - } - freeaddrinfo(addrs); --- -2.8.1 - diff --git a/SOURCES/krb5-1.15-NTLM_SPNEGO.patch b/SOURCES/krb5-1.15-NTLM_SPNEGO.patch deleted file mode 100644 index 9a61843..0000000 --- a/SOURCES/krb5-1.15-NTLM_SPNEGO.patch +++ /dev/null @@ -1,97 +0,0 @@ -From a7e899281f24aadec536f3cb0adf7340683c27cb Mon Sep 17 00:00:00 2001 -From: Simo Sorce -Date: Wed, 30 Mar 2016 13:00:19 -0400 -Subject: [PATCH] Add SPNEGO special case for NTLMSSP+MechListMIC - -MS-SPNG section 3.3.5.1 documents an odd behavior the SPNEGO layer -needs to implement specifically for the NTLMSSP mechanism. This is -required for compatibility with Windows services. - -ticket: 8423 (new) ---- - src/lib/gssapi/spnego/spnego_mech.c | 48 +++++++++++++++++++++++++++++++++---- - 1 file changed, 43 insertions(+), 5 deletions(-) - -diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c -index bb754d9..b76f7d6 100644 ---- a/src/lib/gssapi/spnego/spnego_mech.c -+++ b/src/lib/gssapi/spnego/spnego_mech.c -@@ -520,6 +520,45 @@ mech_requires_mechlistMIC(spnego_gss_ctx_id_t sc) - return result; - } - -+/* iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) Microsoft(311) -+ * security(2) mechanisms(2) NTLM(10) */ -+static const gss_OID_desc gss_mech_ntlmssp_oid = -+ { 10, "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a" }; -+ -+/* iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) samba(7165) -+ * gssntlmssp(655) controls(1) ntlmssp_reset_crypto(3) */ -+static const gss_OID_desc ntlmssp_reset_crypto_oid = -+ { 11, "\x2B\x06\x01\x04\x01\xB7\x7D\x85\x0F\x01\x03" }; -+ -+/* -+ * MS-SPNG section 3.3.5.1 warns that the NTLM mechanism requires special -+ * handling of the crypto state to interop with Windows. If the mechanism for -+ * sc is SPNEGO, invoke a mechanism-specific operation on the context to reset -+ * the RC4 state after producing or verifying a MIC. Ignore a result of -+ * GSS_S_UNAVAILABLE for compatibility with older versions of the mechanism -+ * that do not support this functionality. -+ */ -+static OM_uint32 -+ntlmssp_reset_crypto_state(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc, -+ OM_uint32 verify) -+{ -+ OM_uint32 major, minor; -+ gss_buffer_desc value; -+ -+ if (!g_OID_equal(sc->internal_mech, &gss_mech_ntlmssp_oid)) -+ return GSS_S_COMPLETE; -+ -+ value.length = sizeof(verify); -+ value.value = &verify; -+ major = gss_set_sec_context_option(&minor, &sc->ctx_handle, -+ (gss_OID)&ntlmssp_reset_crypto_oid, -+ &value); -+ if (major == GSS_S_UNAVAILABLE) -+ return GSS_S_COMPLETE; -+ *minor_status = minor; -+ return major; -+} -+ - /* - * Both initiator and acceptor call here to verify and/or create mechListMIC, - * and to consistency-check the MIC state. handle_mic is invoked only if the -@@ -601,6 +640,8 @@ process_mic(OM_uint32 *minor_status, gss_buffer_t mic_in, - ret = gss_verify_mic(minor_status, sc->ctx_handle, - &sc->DER_mechTypes, - mic_in, &qop_state); -+ if (ret == GSS_S_COMPLETE) -+ ret = ntlmssp_reset_crypto_state(minor_status, sc, 1); - if (ret != GSS_S_COMPLETE) { - *negState = REJECT; - *tokflag = ERROR_TOKEN_SEND; -@@ -615,6 +656,8 @@ process_mic(OM_uint32 *minor_status, gss_buffer_t mic_in, - GSS_C_QOP_DEFAULT, - &sc->DER_mechTypes, - &tmpmic); -+ if (ret == GSS_S_COMPLETE) -+ ret = ntlmssp_reset_crypto_state(minor_status, sc, 0); - if (ret != GSS_S_COMPLETE) { - gss_release_buffer(&tmpmin, &tmpmic); - *tokflag = NO_TOKEN_SEND; -@@ -820,11 +863,6 @@ init_ctx_nego(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc, - return ret; - } - --/* iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) Microsoft(311) -- * security(2) mechanisms(2) NTLM(10) */ --static const gss_OID_desc gss_mech_ntlmssp_oid = -- { 10, "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a" }; -- - /* - * Handle acceptor's counter-proposal of an alternative mechanism. - */ --- -2.8.1 - diff --git a/SOURCES/krb5-1.15-beta1-buildconf.patch b/SOURCES/krb5-1.15-beta1-buildconf.patch new file mode 100644 index 0000000..958cfdf --- /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 0000000..0e79ce9 --- /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.15-fix_t_kprop.patch b/SOURCES/krb5-1.15-fix_t_kprop.patch deleted file mode 100644 index c43fdbe..0000000 --- a/SOURCES/krb5-1.15-fix_t_kprop.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 9bcb30c91723e63c16c8a2cdbcd94f61f370a6a9 Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Wed, 10 Feb 2016 11:50:54 -0500 -Subject: [PATCH 1/3] Fix and adjust t_kprop.py - -The listprincs check was at the wrong indentation level and had the -wrong argument grouping; fix it so we actually verify the propagation. - -Stop using the -t (runonce) flag to kpropd, so that kpropd continues -to run until k5test.py terminates it. Quit out of the read loop when -we see that the load process is completed, instead of looking for end -of input. This change is needed in order to add hooks in k5test.py -for checking daemons for memory leaks before terminating them. ---- - src/tests/t_kprop.py | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/tests/t_kprop.py b/src/tests/t_kprop.py -index e2026c8..d625627 100755 ---- a/src/tests/t_kprop.py -+++ b/src/tests/t_kprop.py -@@ -24,21 +24,21 @@ for realm in multipass_realms(create_user=False): - realm.addprinc('wakawaka') - - # Start kpropd. -- kpropd = realm.start_kpropd(slave, ['-d', '-t']) -+ kpropd = realm.start_kpropd(slave, ['-d']) - - realm.run([kdb5_util, 'dump', dumpfile]) - realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) - output('*** kpropd output follows\n') - while True: - line = kpropd.stdout.readline() -- if line == '': -+ if 'Database load process for full propagation completed' in line: - break - output('kpropd: ' + line) - if 'Rejected connection' in line: - fail('kpropd rejected connection from kprop') - -- out = realm.run([kadminl, 'listprincs', slave]) -- if 'wakawaka' not in out: -- fail('Slave does not have all principals from master') -+ out = realm.run([kadminl, 'listprincs'], slave) -+ if 'wakawaka' not in out: -+ fail('Slave does not have all principals from master') - - success('kprop tests') --- -2.8.1 - diff --git a/SOURCES/krb5-1.15-hide_deperecated_on_indicate.patch b/SOURCES/krb5-1.15-hide_deperecated_on_indicate.patch deleted file mode 100644 index dc9db7a..0000000 --- a/SOURCES/krb5-1.15-hide_deperecated_on_indicate.patch +++ /dev/null @@ -1,89 +0,0 @@ -From a5e1c99acf3b7260ce9baa29d0bfbb350d026bb6 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Thu, 19 May 2016 20:31:38 -0400 -Subject: [PATCH] Do not indicate deprecated GSS mechanisms - -The mechanisms themeselves will continue to work if requested, but will -not be included in the gss_indicate_mech() list. This works around a -bug in some legacy applications that cannot cope with deprecated mechs -being returned. - -ticket: 8419 (new) ---- - src/lib/gssapi/mechglue/g_initialize.c | 47 ++++++++++++++++++++++++++++++++++ - 1 file changed, 47 insertions(+) - -diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c -index b7e8a8d..213ea19 100644 ---- a/src/lib/gssapi/mechglue/g_initialize.c -+++ b/src/lib/gssapi/mechglue/g_initialize.c -@@ -202,12 +202,55 @@ gss_OID *oid; - return (generic_gss_release_oid(minor_status, oid)); - } /* gss_release_oid */ - -+/* -+ * Wrapper around inquire_attrs_for_mech to determine whether a mechanism has -+ * the deprecated attribute. Must be called without g_mechSetLock since it -+ * will call into the mechglue. -+ */ -+static int -+is_deprecated(gss_OID element) -+{ -+ OM_uint32 major, minor; -+ gss_OID_set mech_attrs = GSS_C_NO_OID_SET; -+ int deprecated = 0; -+ -+ major = gss_inquire_attrs_for_mech(&minor, element, &mech_attrs, NULL); -+ if (major == GSS_S_COMPLETE) { -+ gss_test_oid_set_member(&minor, (gss_OID)GSS_C_MA_DEPRECATED, -+ mech_attrs, &deprecated); -+ } -+ -+ if (mech_attrs != GSS_C_NO_OID_SET) -+ gss_release_oid_set(&minor, &mech_attrs); -+ -+ return deprecated; -+} -+ -+/* -+ * Removes mechs with the deprecated attribute from an OID set. Must be -+ * called without g_mechSetLock held since it calls into the mechglue. -+ */ -+static void -+prune_deprecated(gss_OID_set mech_set) -+{ -+ OM_uint32 i, j; -+ -+ j = 0; -+ for (i = 0; i < mech_set->count; i++) { -+ if (!is_deprecated(&mech_set->elements[i])) -+ mech_set->elements[j++] = mech_set->elements[i]; -+ else -+ gssalloc_free(mech_set->elements[i].elements); -+ } -+ mech_set->count = j; -+} - - /* - * this function will return an oid set indicating available mechanisms. - * The set returned is based on configuration file entries and - * NOT on the loaded mechanisms. This function does not check if any - * of these can actually be loaded. -+ * Deprecated mechanisms will not be returned. - * This routine needs direct access to the mechanism list. - * To avoid reading the configuration file each call, we will save a - * a mech oid set, and only update it once the file has changed. -@@ -245,6 +288,10 @@ gss_OID_set *mechSet_out; - k5_mutex_lock(&g_mechSetLock); - status = generic_gss_copy_oid_set(minorStatus, &g_mechSet, mechSet_out); - k5_mutex_unlock(&g_mechSetLock); -+ -+ if (*mechSet_out != GSS_C_NO_OID_SET) -+ prune_deprecated(*mechSet_out); -+ - return (status); - } /* gss_indicate_mechs */ - --- -2.8.1 - diff --git a/SOURCES/krb5-1.15-kadmin-kprop-port-test.patch b/SOURCES/krb5-1.15-kadmin-kprop-port-test.patch deleted file mode 100644 index c96a851..0000000 --- a/SOURCES/krb5-1.15-kadmin-kprop-port-test.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 77c3f655f684761efe957722e500887f3199fc5f Mon Sep 17 00:00:00 2001 -From: Matt Rogers -Date: Fri, 15 Jul 2016 10:32:51 -0400 -Subject: [PATCH] Update iprop tests for kadmind -k - -Test the use of the -k kprop-port option. - -ticket: 8456 ---- - src/tests/t_iprop.py | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/src/tests/t_iprop.py b/src/tests/t_iprop.py -index 63ed118..e64fdd2 100755 ---- a/src/tests/t_iprop.py -+++ b/src/tests/t_iprop.py -@@ -223,10 +223,9 @@ if 'Attributes: DISALLOW_ALL_TIX' not in out: - slave1_out_dump_path = os.path.join(realm.testdir, 'dump.slave1.out') - slave2_in_dump_path = os.path.join(realm.testdir, 'dump.slave2.in') - slave2_kprop_port = str(realm.portbase + 9) --slave1m['KPROP_PORT'] = slave2_kprop_port - realm.start_server([kadmind, '-r', realm.realm, '-nofork', '-proponly', '-W', -- '-p', kdb5_util, '-K', kprop, '-F', slave1_out_dump_path], -- 'starting...', slave1m) -+ '-p', kdb5_util, '-K', kprop, '-k', slave2_kprop_port, -+ '-F', slave1_out_dump_path], 'starting...', slave1m) - - # Test similar default_realm and domain_realm map settings with -r realm. - slave3_in_dump_path = os.path.join(realm.testdir, 'dump.slave3.in') --- -2.8.1 - diff --git a/SOURCES/krb5-1.15-kadmin-kprop-port.patch b/SOURCES/krb5-1.15-kadmin-kprop-port.patch deleted file mode 100644 index 2f5f6e8..0000000 --- a/SOURCES/krb5-1.15-kadmin-kprop-port.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 7ed18b1e5a11a514461be2281ff884e8173299b1 Mon Sep 17 00:00:00 2001 -From: Matt Rogers -Date: Fri, 15 Jul 2016 10:17:45 -0400 -Subject: [PATCH] Add the kprop-port option to kadmind - -The -k option for kadmind sets the port number that kprop is spawned -with during an iprop full resync. Fall back to checking the -KPROP_PORT environment variable if the option is not set. - -ticket: 8456 (new) ---- - doc/admin/admin_commands/kadmind.rst | 6 ++++++ - src/kadmin/server/ipropd_svc.c | 6 +++--- - src/kadmin/server/ovsec_kadmd.c | 11 ++++++++++- - 3 files changed, 19 insertions(+), 4 deletions(-) - -diff --git a/doc/admin/admin_commands/kadmind.rst b/doc/admin/admin_commands/kadmind.rst -index acf25e3..f5b7733 100644 ---- a/doc/admin/admin_commands/kadmind.rst -+++ b/doc/admin/admin_commands/kadmind.rst -@@ -16,6 +16,7 @@ SYNOPSIS - [**-P** *pid_file*] - [**-p** *kdb5_util_path*] - [**-K** *kprop_path*] -+[**-k** *kprop_port*] - [**-F** *dump_file*] - - DESCRIPTION -@@ -101,6 +102,11 @@ OPTIONS - specifies the path to the kprop command to use to send full dumps - to slaves in response to full resync requests. - -+**-k** *kprop_port* -+ specifies the port by which the kprop process that is spawned by kadmind -+ connects to the slave kpropd, in order to transfer the dump file during -+ an iprop full resync request. -+ - **-F** *dump_file* - specifies the file path to be used for dumping the KDB in response - to full resync requests when iprop is enabled. -diff --git a/src/kadmin/server/ipropd_svc.c b/src/kadmin/server/ipropd_svc.c -index 62a0a2b..76d3fda 100644 ---- a/src/kadmin/server/ipropd_svc.c -+++ b/src/kadmin/server/ipropd_svc.c -@@ -36,6 +36,7 @@ extern short l_port; - extern char *kdb5_util; - extern char *kprop; - extern char *dump_file; -+extern char *kprop_port; - - static char *reply_ok_str = "UPDATE_OK"; - static char *reply_err_str = "UPDATE_ERROR"; -@@ -392,10 +393,9 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp) - - DPRINT("%s: exec `kprop -r %s -f %s %s' ...\n", - whoami, handle->params.realm, dump_file, clhost); -- /* XXX Yuck! */ -- if (getenv("KPROP_PORT")) { -+ if (kprop_port != NULL) { - pret = execl(kprop, "kprop", "-r", handle->params.realm, "-f", -- dump_file, "-P", getenv("KPROP_PORT"), clhost, NULL); -+ dump_file, "-P", kprop_port, clhost, NULL); - } else { - pret = execl(kprop, "kprop", "-r", handle->params.realm, "-f", - dump_file, clhost, NULL); -diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c -index 89bf4e6..bf780dc 100644 ---- a/src/kadmin/server/ovsec_kadmd.c -+++ b/src/kadmin/server/ovsec_kadmd.c -@@ -72,6 +72,7 @@ int nofork = 0; - char *kdb5_util = KPROPD_DEFAULT_KDB5_UTIL; - char *kprop = KPROPD_DEFAULT_KPROP; - char *dump_file = KPROP_DEFAULT_FILE; -+char *kprop_port = NULL; - - static krb5_context context; - static char *progname; -@@ -86,7 +87,7 @@ usage() - fprintf(stderr, _("Usage: kadmind [-x db_args]* [-r realm] [-m] [-nofork] " - "[-port port-number]\n" - "\t\t[-proponly] [-p path-to-kdb5_util] [-F dump-file]\n" -- "\t\t[-K path-to-kprop] [-P pid_file]\n" -+ "\t\t[-K path-to-kprop] [-k kprop-port] [-P pid_file]\n" - "\nwhere,\n\t[-x db_args]* - any number of database " - "specific arguments.\n" - "\t\t\tLook at each database documentation for " -@@ -433,6 +434,11 @@ main(int argc, char *argv[]) - if (!argc) - usage(); - kprop = *argv; -+ } else if (strcmp(*argv, "-k") == 0) { -+ argc--, argv++; -+ if (!argc) -+ usage(); -+ kprop_port = *argv; - } else { - break; - } -@@ -529,6 +535,9 @@ main(int argc, char *argv[]) - } - } - -+ if (kprop_port == NULL) -+ kprop_port = getenv("KPROP_PORT"); -+ - krb5_klog_syslog(LOG_INFO, _("starting")); - if (nofork) - fprintf(stderr, _("%s: starting...\n"), progname); --- -2.8.1 - diff --git a/SOURCES/krb5-1.15-kprop-debug-argument-order.patch b/SOURCES/krb5-1.15-kprop-debug-argument-order.patch deleted file mode 100644 index f17e495..0000000 --- a/SOURCES/krb5-1.15-kprop-debug-argument-order.patch +++ /dev/null @@ -1,26 +0,0 @@ -From e76c5f0b08da7129746fc8549c9a01d0af8d9ffa Mon Sep 17 00:00:00 2001 -From: Matt Rogers -Date: Mon, 20 Jun 2016 09:21:28 -0400 -Subject: [PATCH] Fix argument order for kprop debug message - -ticket: 8277 ---- - src/kadmin/server/ipropd_svc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/kadmin/server/ipropd_svc.c b/src/kadmin/server/ipropd_svc.c -index 336e5de..62a0a2b 100644 ---- a/src/kadmin/server/ipropd_svc.c -+++ b/src/kadmin/server/ipropd_svc.c -@@ -391,7 +391,7 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp) - } - - DPRINT("%s: exec `kprop -r %s -f %s %s' ...\n", -- handle->params.realm, whoami, dump_file, clhost); -+ whoami, handle->params.realm, dump_file, clhost); - /* XXX Yuck! */ - if (getenv("KPROP_PORT")) { - pret = execl(kprop, "kprop", "-r", handle->params.realm, "-f", --- -2.8.1 - diff --git a/SOURCES/krb5-1.15-kprop-iprop-default_realm-tests.patch b/SOURCES/krb5-1.15-kprop-iprop-default_realm-tests.patch deleted file mode 100644 index 854bddd..0000000 --- a/SOURCES/krb5-1.15-kprop-iprop-default_realm-tests.patch +++ /dev/null @@ -1,319 +0,0 @@ -From b133e1613751fbb2ce6ed2ba3b63bf45805968a5 Mon Sep 17 00:00:00 2001 -From: Matt Rogers -Date: Fri, 22 Apr 2016 12:23:37 -0400 -Subject: [PATCH 3/3] Add kprop and iprop default_realm tests - -Add tests to t_iprop.py and t_kprop.py that exercise cases where -default_realm and domain_realm maps differ, as well as overriding the -default realm with the -r argument. This includes the testing of -r -with kadmind, and an update of expected ulog numbers for tests following -the addition of an incremental test. Also refactor some common code in -t_kprop.py to use in the new tests. - -ticket: 8277 ---- - src/tests/t_iprop.py | 114 ++++++++++++++++++++++++++++++++++++++++----------- - src/tests/t_kprop.py | 77 ++++++++++++++++++++++++++++------ - 2 files changed, 155 insertions(+), 36 deletions(-) - -diff --git a/src/tests/t_iprop.py b/src/tests/t_iprop.py -index 6b38b8a..71f5415 100755 ---- a/src/tests/t_iprop.py -+++ b/src/tests/t_iprop.py -@@ -127,11 +127,35 @@ conf_slave2 = {'realms': {'$realm': {'iprop_slave_poll': '600', - 'iprop_port': '$port8'}}, - 'dbmodules': {'db': {'database_name': '$testdir/db.slave2'}}} - -+conf_foo = {'libdefaults': {'default_realm': 'FOO'}, -+ 'domain_realm': {hostname: 'FOO'}} -+ - realm = K5Realm(kdc_conf=conf, create_user=False, start_kadmind=True) - slave1 = realm.special_env('slave1', True, kdc_conf=conf_slave1) --slave1m = realm.special_env('slave1m', True, kdc_conf=conf_slave1m) -+slave1m = realm.special_env('slave1m', True, krb5_conf=conf_foo, -+ kdc_conf=conf_slave1m) - slave2 = realm.special_env('slave2', True, kdc_conf=conf_slave2) - -+# A default_realm and domain_realm that do not match the KDC's realm. -+# The FOO realm iprop_logfile setting is needed to run kproplog during -+# a slave3 test, since kproplog has no realm option. -+conf_slave3 = {'realms': {'$realm': {'iprop_slave_poll': '600', -+ 'iprop_logfile': '$testdir/ulog.slave3', -+ 'iprop_port': '$port8'}, -+ 'FOO': {'iprop_logfile': '$testdir/ulog.slave3'}}, -+ 'dbmodules': {'db': {'database_name': '$testdir/db.slave3'}}} -+slave3 = realm.special_env('slave3', True, krb5_conf=conf_foo, -+ kdc_conf=conf_slave3) -+ -+# A default realm and a domain realm map that differ. -+krb5_conf_slave4 = {'domain_realm': {hostname: 'FOO'}} -+conf_slave4 = {'realms': {'$realm': {'iprop_slave_poll': '600', -+ 'iprop_logfile': '$testdir/ulog.slave4', -+ 'iprop_port': '$port8'}}, -+ 'dbmodules': {'db': {'database_name': '$testdir/db.slave4'}}} -+slave4 = realm.special_env('slave4', True, krb5_conf=krb5_conf_slave4, -+ kdc_conf=conf_slave4) -+ - # Define some principal names. pr3 is long enough to cause internal - # reallocs, but not long enough to grow the basic ulog entry size. - pr1 = 'wakawaka@' + realm.realm -@@ -155,11 +179,13 @@ if not os.path.exists(ulog): - kiprop_princ = 'kiprop/' + hostname - realm.extract_keytab(kiprop_princ, realm.keytab) - --# Create the initial slave1 and slave2 databases. -+# Create the initial slave databases. - dumpfile = os.path.join(realm.testdir, 'dump') - realm.run([kdb5_util, 'dump', dumpfile]) - realm.run([kdb5_util, 'load', dumpfile], slave1) - realm.run([kdb5_util, 'load', dumpfile], slave2) -+realm.run([kdb5_util, '-r', realm.realm, 'load', dumpfile], slave3) -+realm.run([kdb5_util, 'load', dumpfile], slave4) - - # Reinitialize the master ulog so we know exactly what to expect in - # it. -@@ -198,9 +224,49 @@ slave1_out_dump_path = os.path.join(realm.testdir, 'dump.slave1.out') - slave2_in_dump_path = os.path.join(realm.testdir, 'dump.slave2.in') - slave2_kprop_port = str(realm.portbase + 9) - slave1m['KPROP_PORT'] = slave2_kprop_port --realm.start_server([kadmind, '-nofork', '-proponly', '-W', '-p', kdb5_util, -- '-K', kprop, '-F', slave1_out_dump_path], 'starting...', -- slave1m) -+realm.start_server([kadmind, '-r', realm.realm, '-nofork', '-proponly', '-W', -+ '-p', kdb5_util, '-K', kprop, '-F', slave1_out_dump_path], -+ 'starting...', slave1m) -+ -+# Test similar default_realm and domain_realm map settings with -r realm. -+slave3_in_dump_path = os.path.join(realm.testdir, 'dump.slave3.in') -+kpropd3 = realm.start_server([kpropd, '-d', '-D', '-r', realm.realm, '-P', -+ slave2_kprop_port, '-f', slave3_in_dump_path, -+ '-p', kdb5_util, '-a', acl_file, '-A', hostname], -+ 'ready', slave3) -+wait_for_prop(kpropd3, True, 1, 7) -+out = realm.run([kadminl, '-r', realm.realm, 'listprincs'], env=slave3) -+if pr1 not in out or pr2 not in out or pr3 not in out: -+ fail('slave3 does not have all principals from slave1') -+check_ulog(1, 7, 7, [None], env=slave3) -+ -+# Test an incremental propagation for the kpropd -r case. -+realm.run([kadminl, 'modprinc', '-maxlife', '20 minutes', pr1]) -+check_ulog(8, 1, 8, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1]) -+kpropd1.send_signal(signal.SIGUSR1) -+wait_for_prop(kpropd1, False, 7, 8) -+check_ulog(3, 6, 8, [None, pr2, pr1], slave1) -+out = realm.run([kadminl, 'getprinc', pr1], env=slave1) -+if 'Maximum ticket life: 0 days 00:20:00' not in out: -+ fail('slave1 does not have modification from master') -+kpropd3.send_signal(signal.SIGUSR1) -+wait_for_prop(kpropd3, False, 7, 8) -+check_ulog(2, 7, 8, [None, pr1], slave3) -+out = realm.run([kadminl, '-r', realm.realm, 'getprinc', pr1], env=slave3) -+if 'Maximum ticket life: 0 days 00:20:00' not in out: -+ fail('slave3 does not have modification from slave1') -+stop_daemon(kpropd3) -+ -+# Test dissimilar default_realm and domain_realm map settings (no -r realm). -+slave4_in_dump_path = os.path.join(realm.testdir, 'dump.slave4.in') -+kpropd4 = realm.start_server([kpropd, '-d', '-D', '-P', slave2_kprop_port, -+ '-f', slave4_in_dump_path, '-p', kdb5_util, -+ '-a', acl_file, '-A', hostname], 'ready', slave4) -+wait_for_prop(kpropd4, True, 1, 8) -+out = realm.run([kadminl, 'listprincs'], env=slave4) -+if pr1 not in out or pr2 not in out or pr3 not in out: -+ fail('slave4 does not have all principals from slave1') -+stop_daemon(kpropd4) - - # Start kpropd for slave2. The -A option isn't needed since we're - # talking to the same host as master (we specify it anyway to exercise -@@ -209,8 +275,8 @@ realm.start_server([kadmind, '-nofork', '-proponly', '-W', '-p', kdb5_util, - kpropd2 = realm.start_server([kpropd, '-d', '-D', '-P', slave2_kprop_port, - '-f', slave2_in_dump_path, '-p', kdb5_util, - '-a', acl_file, '-A', hostname], 'ready', slave2) --wait_for_prop(kpropd2, True, 1, 7) --check_ulog(1, 7, 7, [None], slave2) -+wait_for_prop(kpropd2, True, 1, 8) -+check_ulog(2, 7, 8, [None, pr1], slave2) - out = realm.run([kadminl, 'listprincs'], env=slave1) - if pr1 not in out or pr2 not in out or pr3 not in out: - fail('slave2 does not have all principals from slave1') -@@ -218,16 +284,16 @@ if pr1 not in out or pr2 not in out or pr3 not in out: - # Make another change and check that it propagates incrementally to - # both slaves. - realm.run([kadminl, 'modprinc', '-maxrenewlife', '22 hours', pr1]) --check_ulog(8, 1, 8, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1]) -+check_ulog(9, 1, 9, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr1]) - kpropd1.send_signal(signal.SIGUSR1) --wait_for_prop(kpropd1, False, 7, 8) --check_ulog(3, 6, 8, [None, pr2, pr1], slave1) -+wait_for_prop(kpropd1, False, 8, 9) -+check_ulog(4, 6, 9, [None, pr2, pr1, pr1], slave1) - out = realm.run([kadminl, 'getprinc', pr1], env=slave1) - if 'Maximum renewable life: 0 days 22:00:00\n' not in out: - fail('slave1 does not have modification from master') - kpropd2.send_signal(signal.SIGUSR1) --wait_for_prop(kpropd2, False, 7, 8) --check_ulog(2, 7, 8, [None, pr1], slave2) -+wait_for_prop(kpropd2, False, 8, 9) -+check_ulog(3, 7, 9, [None, pr1, pr1], slave2) - out = realm.run([kadminl, 'getprinc', pr1], env=slave2) - if 'Maximum renewable life: 0 days 22:00:00\n' not in out: - fail('slave2 does not have modification from slave1') -@@ -239,25 +305,25 @@ if 'Maximum renewable life: 0 days 22:00:00\n' not in out: - realm.run([kproplog, '-R'], slave1) - check_ulog(1, 1, 1, [None], slave1) - kpropd1.send_signal(signal.SIGUSR1) --wait_for_prop(kpropd1, True, 1, 8) --check_ulog(3, 6, 8, [None, pr2, pr1], slave1) -+wait_for_prop(kpropd1, True, 1, 9) -+check_ulog(4, 6, 9, [None, pr2, pr1, pr1], slave1) - kpropd2.send_signal(signal.SIGUSR1) --wait_for_prop(kpropd2, False, 8, 8) --check_ulog(2, 7, 8, [None, pr1], slave2) -+wait_for_prop(kpropd2, False, 9, 9) -+check_ulog(3, 7, 9, [None, pr1, pr1], slave2) - - # Make another change and check that it propagates incrementally to - # both slaves. --realm.run([kadminl, 'modprinc', '+allow_tix', 'w']) --check_ulog(9, 1, 9, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr2]) -+realm.run([kadminl, 'modprinc', '+allow_tix', pr2]) -+check_ulog(10, 1, 10, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr1, pr2]) - kpropd1.send_signal(signal.SIGUSR1) --wait_for_prop(kpropd1, False, 8, 9) --check_ulog(4, 6, 9, [None, pr2, pr1, pr2], slave1) -+wait_for_prop(kpropd1, False, 9, 10) -+check_ulog(5, 6, 10, [None, pr2, pr1, pr1, pr2], slave1) - out = realm.run([kadminl, 'getprinc', pr2], env=slave1) - if 'Attributes:\n' not in out: - fail('slave1 does not have modification from master') - kpropd2.send_signal(signal.SIGUSR1) --wait_for_prop(kpropd2, False, 8, 9) --check_ulog(3, 7, 9, [None, pr1, pr2], slave2) -+wait_for_prop(kpropd2, False, 9, 10) -+check_ulog(4, 7, 10, [None, pr1, pr1, pr2], slave2) - out = realm.run([kadminl, 'getprinc', pr2], env=slave2) - if 'Attributes:\n' not in out: - fail('slave2 does not have modification from slave1') -@@ -266,13 +332,13 @@ if 'Attributes:\n' not in out: - realm.run([kadminl, 'addpol', '-minclasses', '2', 'testpol']) - check_ulog(1, 1, 1, [None]) - kpropd1.send_signal(signal.SIGUSR1) --wait_for_prop(kpropd1, True, 9, 1) -+wait_for_prop(kpropd1, True, 10, 1) - check_ulog(1, 1, 1, [None], slave1) - out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1) - if 'Minimum number of password character classes: 2' not in out: - fail('slave1 does not have policy from master') - kpropd2.send_signal(signal.SIGUSR1) --wait_for_prop(kpropd2, True, 9, 1) -+wait_for_prop(kpropd2, True, 10, 1) - check_ulog(1, 1, 1, [None], slave2) - out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2) - if 'Minimum number of password character classes: 2' not in out: -diff --git a/src/tests/t_kprop.py b/src/tests/t_kprop.py -index d625627..02cdfee 100755 ---- a/src/tests/t_kprop.py -+++ b/src/tests/t_kprop.py -@@ -3,16 +3,29 @@ from k5test import * - - conf_slave = {'dbmodules': {'db': {'database_name': '$testdir/db.slave'}}} - -+def setup_acl(realm): -+ acl_file = os.path.join(realm.testdir, 'kpropd-acl') -+ acl = open(acl_file, 'w') -+ acl.write(realm.host_princ + '\n') -+ acl.close() -+ -+def check_output(kpropd): -+ output('*** kpropd output follows\n') -+ while True: -+ line = kpropd.stdout.readline() -+ if 'Database load process for full propagation completed' in line: -+ break -+ output('kpropd: ' + line) -+ if 'Rejected connection' in line: -+ fail('kpropd rejected connection from kprop') -+ - # kprop/kpropd are the only users of krb5_auth_con_initivector, so run - # this test over all enctypes to exercise mkpriv cipher state. - for realm in multipass_realms(create_user=False): - slave = realm.special_env('slave', True, kdc_conf=conf_slave) - - # Set up the kpropd acl file. -- acl_file = os.path.join(realm.testdir, 'kpropd-acl') -- acl = open(acl_file, 'w') -- acl.write(realm.host_princ + '\n') -- acl.close() -+ setup_acl(realm) - - # Create the slave db. - dumpfile = os.path.join(realm.testdir, 'dump') -@@ -28,17 +41,57 @@ for realm in multipass_realms(create_user=False): - - realm.run([kdb5_util, 'dump', dumpfile]) - realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) -- output('*** kpropd output follows\n') -- while True: -- line = kpropd.stdout.readline() -- if 'Database load process for full propagation completed' in line: -- break -- output('kpropd: ' + line) -- if 'Rejected connection' in line: -- fail('kpropd rejected connection from kprop') -+ check_output(kpropd) - - out = realm.run([kadminl, 'listprincs'], slave) - if 'wakawaka' not in out: - fail('Slave does not have all principals from master') - -+# default_realm tests follow. -+# default_realm and domain_realm different than realm.realm (test -r argument). -+conf_slave2 = {'dbmodules': {'db': {'database_name': '$testdir/db.slave2'}}} -+krb5_conf_slave2 = {'libdefaults': {'default_realm': 'FOO'}, -+ 'domain_realm': {hostname: 'FOO'}} -+# default_realm and domain_realm map differ. -+conf_slave3 = {'dbmodules': {'db': {'database_name': '$testdir/db.slave3'}}} -+krb5_conf_slave3 = {'domain_realm': {hostname: 'BAR'}} -+ -+realm = K5Realm(create_user=False) -+slave2 = realm.special_env('slave2', True, kdc_conf=conf_slave2, -+ krb5_conf=krb5_conf_slave2) -+slave3 = realm.special_env('slave3', True, kdc_conf=conf_slave3, -+ krb5_conf=krb5_conf_slave3) -+ -+setup_acl(realm) -+ -+# Create the slave db. -+dumpfile = os.path.join(realm.testdir, 'dump') -+realm.run([kdb5_util, 'dump', dumpfile]) -+realm.run([kdb5_util, '-r', realm.realm, 'load', dumpfile], slave2) -+realm.run([kdb5_util, 'load', dumpfile], slave3) -+ -+# Make some changes to the master db. -+realm.addprinc('wakawaka') -+ -+# Test override of default_realm with -r realm argument. -+kpropd = realm.start_kpropd(slave2, ['-r', realm.realm, '-d']) -+realm.run([kdb5_util, 'dump', dumpfile]) -+realm.run([kprop, '-r', realm.realm, '-f', dumpfile, '-P', -+ str(realm.kprop_port()), hostname]) -+check_output(kpropd) -+out = realm.run([kadminl, '-r', realm.realm, 'listprincs'], slave2) -+if 'wakawaka' not in out: -+ fail('Slave does not have all principals from master') -+ -+stop_daemon(kpropd) -+ -+# Test default_realm and domain_realm mismatch. -+kpropd = realm.start_kpropd(slave3, ['-d']) -+realm.run([kdb5_util, 'dump', dumpfile]) -+realm.run([kprop, '-f', dumpfile, '-P', str(realm.kprop_port()), hostname]) -+check_output(kpropd) -+out = realm.run([kadminl, 'listprincs'], slave3) -+if 'wakawaka' not in out: -+ fail('Slave does not have all principals from master') -+ - success('kprop tests') --- -2.8.1 - diff --git a/SOURCES/krb5-1.15-kprop-kpropd-realm.patch b/SOURCES/krb5-1.15-kprop-kpropd-realm.patch deleted file mode 100644 index d7c1242..0000000 --- a/SOURCES/krb5-1.15-kprop-kpropd-realm.patch +++ /dev/null @@ -1,366 +0,0 @@ -From dc89bf06626ab322cac50d94fa7ba361a5f29a67 Mon Sep 17 00:00:00 2001 -From: Matt Rogers -Date: Thu, 25 Feb 2016 10:38:07 -0500 -Subject: [PATCH 2/3] Fix kprop and kpropd realm handling - -Add the sn2princ_with_realm() helper function (currently duplicated in -kprop.c and kpropd.c) to simplify principal realm substitution. Use -sn2princ_with_realm() in kprop.c and kpropd.c in place of -krb5_sname_to_principal(), with the default realm if -r is not provided. -If a realm is given to kpropd, set it as the default realm on the -kpropd_context, allowing a later call of ulog_replay() to open the -correct database. - -Remove referral realm code in kprop.c and kpropd.c. Pass the realm -(default or provided) to the kdb5_util and kprop commands called by -kadmind. - -ticket: 8277 ---- - src/kadmin/server/ipropd_svc.c | 15 +++---- - src/slave/kprop.c | 80 ++++++++++++++++++++++-------------- - src/slave/kpropd.c | 93 +++++++++++++++++++++++------------------- - 3 files changed, 109 insertions(+), 79 deletions(-) - -diff --git a/src/kadmin/server/ipropd_svc.c b/src/kadmin/server/ipropd_svc.c -index 7c7f850..336e5de 100644 ---- a/src/kadmin/server/ipropd_svc.c -+++ b/src/kadmin/server/ipropd_svc.c -@@ -335,8 +335,8 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp) - * and timestamp are in the ulog (then the slaves can get the - * subsequent updates very iprop). - */ -- if (asprintf(&ubuf, "%s dump -i%d -c %s", -- kdb5_util, vers, dump_file) < 0) { -+ if (asprintf(&ubuf, "%s -r %s dump -i%d -c %s", kdb5_util, -+ handle->params.realm, vers, dump_file) < 0) { - krb5_klog_syslog(LOG_ERR, - _("%s: cannot construct kdb5 util dump string too long; out of memory"), - whoami); -@@ -390,14 +390,15 @@ ipropx_resync(uint32_t vers, struct svc_req *rqstp) - _exit(1); - } - -- DPRINT("%s: exec `kprop -f %s %s' ...\n", -- whoami, dump_file, clhost); -+ DPRINT("%s: exec `kprop -r %s -f %s %s' ...\n", -+ handle->params.realm, whoami, dump_file, clhost); - /* XXX Yuck! */ - if (getenv("KPROP_PORT")) { -- pret = execl(kprop, "kprop", "-f", dump_file, "-P", -- getenv("KPROP_PORT"), clhost, NULL); -+ pret = execl(kprop, "kprop", "-r", handle->params.realm, "-f", -+ dump_file, "-P", getenv("KPROP_PORT"), clhost, NULL); - } else { -- pret = execl(kprop, "kprop", "-f", dump_file, clhost, NULL); -+ pret = execl(kprop, "kprop", "-r", handle->params.realm, "-f", -+ dump_file, clhost, NULL); - } - perror(whoami); - krb5_klog_syslog(LOG_ERR, -diff --git a/src/slave/kprop.c b/src/slave/kprop.c -index 696e89c..955db50 100644 ---- a/src/slave/kprop.c -+++ b/src/slave/kprop.c -@@ -52,6 +52,7 @@ static int debug = 0; - static char *srvtab = NULL; - static char *slave_host; - static char *realm = NULL; -+static char *def_realm = NULL; - static char *file = KPROP_DEFAULT_FILE; - - /* The Kerberos principal we'll be sending as, initialized in get_tickets. */ -@@ -63,7 +64,7 @@ static krb5_address *receiver_addr; - static const char *port = KPROP_SERVICE; - static char *dbpathname; - --static void parse_args(int argc, char **argv); -+static void parse_args(krb5_context context, int argc, char **argv); - static void get_tickets(krb5_context context); - static void usage(void); - static void open_connection(krb5_context context, char *host, int *fd_out); -@@ -101,7 +102,7 @@ main(int argc, char **argv) - com_err(argv[0], retval, _("while initializing krb5")); - exit(1); - } -- parse_args(argc, argv); -+ parse_args(context, argc, argv); - get_tickets(context); - - database_fd = open_database(context, file, &database_size); -@@ -113,13 +114,15 @@ main(int argc, char **argv) - printf(_("Database propagation to %s: SUCCEEDED\n"), slave_host); - krb5_free_cred_contents(context, my_creds); - close_database(context, database_fd); -+ krb5_free_default_realm(context, def_realm); - exit(0); - } - - static void --parse_args(int argc, char **argv) -+parse_args(krb5_context context, int argc, char **argv) - { - char *word, ch; -+ krb5_error_code ret; - - progname = *argv++; - while (--argc && (word = *argv++) != NULL) { -@@ -168,51 +171,66 @@ parse_args(int argc, char **argv) - } - if (slave_host == NULL) - usage(); -+ -+ if (realm == NULL) { -+ ret = krb5_get_default_realm(context, &def_realm); -+ if (ret) { -+ com_err(progname, errno, _("while getting default realm")); -+ exit(1); -+ } -+ realm = def_realm; -+ } -+} -+ -+/* Runs krb5_sname_to_principal with a substitute realm -+ * Duplicated in kpropd.c, sharing TBD */ -+static krb5_error_code -+sn2princ_with_realm(krb5_context context, const char *hostname, -+ const char *sname, krb5_int32 type, const char *rrealm, -+ krb5_principal *princ_out) -+{ -+ krb5_error_code ret; -+ krb5_principal princ = NULL; -+ -+ *princ_out = NULL; -+ -+ if (rrealm == NULL) -+ return EINVAL; -+ -+ ret = krb5_sname_to_principal(context, hostname, sname, type, &princ); -+ if (ret) -+ return ret; -+ -+ ret = krb5_set_principal_realm(context, princ, rrealm); -+ if (ret) { -+ krb5_free_principal(context, princ); -+ return ret; -+ } -+ -+ *princ_out = princ; -+ return 0; - } - - static void - get_tickets(krb5_context context) - { -- char *def_realm, *server; -+ char *server; - krb5_error_code retval; - krb5_keytab keytab = NULL; - krb5_principal server_princ = NULL; - - /* Figure out what tickets we'll be using to send. */ -- retval = krb5_sname_to_principal(context, NULL, NULL, KRB5_NT_SRV_HST, -- &my_principal); -+ retval = sn2princ_with_realm(context, NULL, NULL, KRB5_NT_SRV_HST, realm, -+ &my_principal); - if (retval) { - com_err(progname, errno, _("while setting client principal name")); - exit(1); - } -- if (realm != NULL) { -- retval = krb5_set_principal_realm(context, my_principal, realm); -- if (retval) { -- com_err(progname, errno, -- _("while setting client principal realm")); -- exit(1); -- } -- } else if (krb5_is_referral_realm(krb5_princ_realm(context, -- my_principal))) { -- /* We're going to use this as a client principal, so it can't have the -- * referral realm. Use the default realm instead. */ -- retval = krb5_get_default_realm(context, &def_realm); -- if (retval) { -- com_err(progname, errno, _("while getting default realm")); -- exit(1); -- } -- retval = krb5_set_principal_realm(context, my_principal, def_realm); -- if (retval) { -- com_err(progname, errno, -- _("while setting client principal realm")); -- exit(1); -- } -- } - - /* Construct the principal name for the slave host. */ - memset(&creds, 0, sizeof(creds)); -- retval = krb5_sname_to_principal(context, slave_host, KPROP_SERVICE_NAME, -- KRB5_NT_SRV_HST, &server_princ); -+ retval = sn2princ_with_realm(context, slave_host, KPROP_SERVICE_NAME, -+ KRB5_NT_SRV_HST, realm, &server_princ); - if (retval) { - com_err(progname, errno, _("while setting server principal name")); - exit(1); -diff --git a/src/slave/kpropd.c b/src/slave/kpropd.c -index a950924..41ab446 100644 ---- a/src/slave/kpropd.c -+++ b/src/slave/kpropd.c -@@ -90,7 +90,6 @@ extern int daemon(int, int); - - #define SYSLOG_CLASS LOG_DAEMON - --char *def_realm = NULL; - int runonce = 0; - - /* -@@ -128,6 +127,7 @@ static krb5_principal client; /* This is who we're talking to */ - static krb5_context kpropd_context; - static krb5_auth_context auth_context; - static char *realm = NULL; /* Our realm */ -+static char *def_realm = NULL; /* Ref pointer for default realm */ - static char *file = KPROPD_DEFAULT_FILE; - static char *temp_file_name; - static char *kdb5_util = KPROPD_DEFAULT_KDB5_UTIL; -@@ -610,6 +610,34 @@ full_resync(CLIENT *clnt) - return (status == RPC_SUCCESS) ? &clnt_res : NULL; - } - -+/* Runs krb5_sname_to_principal with a substitute realm. -+ * Duplicated in kprop.c, sharing TBD */ -+static krb5_error_code -+sn2princ_with_realm(krb5_context context, const char *hostname, -+ const char *sname, krb5_int32 type, const char *rrealm, -+ krb5_principal *princ_out) -+{ -+ krb5_error_code ret; -+ krb5_principal princ = NULL; -+ -+ *princ_out = NULL; -+ -+ if (rrealm == NULL) -+ return EINVAL; -+ -+ ret = krb5_sname_to_principal(context, hostname, sname, type, &princ); -+ if (ret) -+ return ret; -+ -+ ret = krb5_set_principal_realm(context, princ, rrealm); -+ if (ret) { -+ krb5_free_principal(context, princ); -+ return ret; -+ } -+ -+ *princ_out = princ; -+ return 0; -+} - /* - * Beg for incrementals from the KDC. - * -@@ -640,53 +668,26 @@ do_iprop() - if (pollin == 0) - pollin = 10; - -- /* Grab the realm info and check if iprop is enabled. */ -- if (def_realm == NULL) { -- retval = krb5_get_default_realm(kpropd_context, &def_realm); -- if (retval) { -- com_err(progname, retval, _("Unable to get default realm")); -- return retval; -- } -- } -- -- params.mask |= KADM5_CONFIG_REALM; -- params.realm = def_realm; -- - if (master_svc_princstr == NULL) { -- retval = kadm5_get_kiprop_host_srv_name(kpropd_context, def_realm, -+ retval = kadm5_get_kiprop_host_srv_name(kpropd_context, realm, - &master_svc_princstr); - if (retval) { - com_err(progname, retval, - _("%s: unable to get kiprop host based " - "service name for realm %s\n"), -- progname, def_realm); -+ progname, realm); - return retval; - } - } - -- retval = krb5_sname_to_principal(kpropd_context, NULL, KIPROP_SVC_NAME, -- KRB5_NT_SRV_HST, &iprop_svc_principal); -+ retval = sn2princ_with_realm(kpropd_context, NULL, KIPROP_SVC_NAME, -+ KRB5_NT_SRV_HST, realm, &iprop_svc_principal); - if (retval) { - com_err(progname, retval, - _("while trying to construct host service principal")); - return retval; - } - -- /* XXX referrals? */ -- if (krb5_is_referral_realm(krb5_princ_realm(kpropd_context, -- iprop_svc_principal))) { -- krb5_data *r = krb5_princ_realm(kpropd_context, -- iprop_svc_principal); -- assert(def_realm != NULL); -- r->length = strlen(def_realm); -- r->data = strdup(def_realm); -- if (r->data == NULL) { -- com_err(progname, retval, -- _("while determining local service principal name")); -- return retval; -- } -- /* XXX Memory leak: Old r->data value. */ -- } - retval = krb5_unparse_name(kpropd_context, iprop_svc_principal, - &iprop_svc_princstr); - if (retval) { -@@ -1166,21 +1167,29 @@ parse_args(char **argv) - if (!debug) - set_com_err_hook(kpropd_com_err_proc); - -+ if (realm == NULL) { -+ retval = krb5_get_default_realm(kpropd_context, &def_realm); -+ if (retval) { -+ com_err(progname, retval, _("Unable to get default realm")); -+ exit(1); -+ } -+ realm = def_realm; -+ } else { -+ retval = krb5_set_default_realm(kpropd_context, realm); -+ if (retval) { -+ com_err(progname, retval, _("Unable to set default realm")); -+ exit(1); -+ } -+ } -+ - /* Construct service name from local hostname. */ -- retval = krb5_sname_to_principal(kpropd_context, NULL, KPROP_SERVICE_NAME, -- KRB5_NT_SRV_HST, &server); -+ retval = sn2princ_with_realm(kpropd_context, NULL, KPROP_SERVICE_NAME, -+ KRB5_NT_SRV_HST, realm, &server); - if (retval) { - com_err(progname, retval, - _("while trying to construct my service name")); - exit(1); - } -- if (realm != NULL) { -- retval = krb5_set_principal_realm(kpropd_context, server, realm); -- if (retval) { -- com_err(progname, errno, _("while constructing my service realm")); -- exit(1); -- } -- } - - /* Construct the name of the temporary file. */ - if (asprintf(&temp_file_name, "%s.temp", file) < 0) { -@@ -1189,6 +1198,8 @@ parse_args(char **argv) - exit(1); - } - -+ params.realm = realm; -+ params.mask |= KADM5_CONFIG_REALM; - retval = kadm5_get_config_params(kpropd_context, 1, ¶ms, ¶ms); - if (retval) { - com_err(progname, retval, _("while initializing")); --- -2.8.1 - diff --git a/SOURCES/krb5-1.15-krad-eof.patch b/SOURCES/krb5-1.15-krad-eof.patch deleted file mode 100644 index 6ed72ea..0000000 --- a/SOURCES/krb5-1.15-krad-eof.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 7fd9fc07cbccef7a6e682057e1560e5b343cb9ff Mon Sep 17 00:00:00 2001 -From: Nathaniel McCallum -Date: Fri, 30 Sep 2016 10:03:33 -0400 -Subject: [PATCH] Properly handle EOF condition on libkrad sockets - -In the previous code, when the remote peer performed an orderly shutdown -on the socket, libkrad would enter a state in which all future requests -timed out. Instead, if the peer shuts down its socket, we need to -attempt to reopen it. - -ticket: 8504 (new) -target_version: 1.14-next -tags: pullup - -(cherry picked from commit 248497427d5a45225817b6c22e9224e8ad969872) ---- - src/lib/krad/remote.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - -diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c -index df3de3a..68cd16f 100644 ---- a/src/lib/krad/remote.c -+++ b/src/lib/krad/remote.c -@@ -329,16 +329,15 @@ on_io_read(krad_remote *rr) - /* Read the packet. */ - i = recv(verto_get_fd(rr->io), rr->buffer.data + rr->buffer.length, - pktlen, 0); -- if (i < 0) { -- /* Should we try again? */ -- if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR) -- return; - -- /* The socket is unrecoverable. */ -+ /* On these errors, try again. */ -+ if (i < 0 && (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)) -+ return; -+ -+ /* On any other errors or on EOF, the socket is unrecoverable. */ -+ if (i <= 0) { - remote_shutdown(rr); - return; -- } else if (i == 0) { -- remote_del_flags(rr, FLAGS_READ); - } - - /* If we have a partial read or just the header, try again. */ --- -2.10.1 - diff --git a/SOURCES/krb5-1.15.1.tar.gz.asc b/SOURCES/krb5-1.15.1.tar.gz.asc new file mode 100644 index 0000000..15dad17 --- /dev/null +++ b/SOURCES/krb5-1.15.1.tar.gz.asc @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1 + +iQIVAwUAWLmTPQy6CFdfg3LfAQKWgBAAnahZbh9rFKBor8lz8icPdOAPyF7QP9xM +aDlxANUePQxN7BG68MPNL0A4/kIB1QHVl07t9vEnPBMKuF6RfVS1Sl9LYvxAF5Gf +pp5nbOOYf8bs5V/isMYjAu61D4Hyr/anKYZsbOTcR+c5CI4UXAB1uaznGcTUT+vL +MJie3ebWxJOPhv2HhkMU4BMkBxnGs1ONNsmU7yvCnbf6kgxpLaVITDzKGDrjIdQu +ej6HZQpwidUZDRICFks6pY4ASfSBEzUGswnnhdsq3uvUhxm5F6jn097K+3nIydVT +SgbJX4sBn5iJBBNumRZZ3OAovwBN+6XKM54ELWgyeQCY3Pk2P8qTojIWaqNJtyuf +q0FSR16rWKq7ZRxHwgc93YETmzIkdil5WFnTpAtqVR5RFOL/GNGh5Dwn645mC3XY +WOFBaVhX1libl+GApJjwriIzZ3e+gtaqsYa/A473BGJL+mKCp8xOfeTXeZCTCVgo +x32NhUcXTxr6RRCq/WTEH6reu4oU+VkostCv3yknHOHatYbzh2DDni+mUVnUpGw8 +WEh3XNjHrjPQ5Vr1F7/aIhmG80QXVKWfJgrVVTwUXjk8+v0enTWudsKYVanvPZDN +Yo1Jqrgc7tfRJpirVpJKxS0rNt/ES2I4heLkoz8j/DnDNqNmKV718jWVAms6jjuR +Cunhql8OvtU= +=Tvr2 +-----END PGP SIGNATURE----- diff --git a/SOURCES/krb5-1.3.1-dns.patch b/SOURCES/krb5-1.3.1-dns.patch index 5d27689..7f2cfdf 100644 --- a/SOURCES/krb5-1.3.1-dns.patch +++ b/SOURCES/krb5-1.3.1-dns.patch @@ -1,8 +1,17 @@ -We want to be able to use --with-netlib and --enable-dns at the same time. -RT#2022 ---- krb5-1.3.1/src/aclocal.m4 2003-11-24 11:17:30.000000000 -0500 -+++ krb5-1.3.1/src/aclocal.m4 2003-11-24 11:18:45.000000000 -0500 -@@ -647,6 +647,7 @@ +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 diff --git a/SOURCES/krb5-1.9-debuginfo.patch b/SOURCES/krb5-1.9-debuginfo.patch index ae81f7c..c9a6499 100644 --- a/SOURCES/krb5-1.9-debuginfo.patch +++ b/SOURCES/krb5-1.9-debuginfo.patch @@ -1,10 +1,18 @@ -We want to keep these y.tab.c files around because the debuginfo points to -them. It would be more elegant at the end to use symbolic links, but that -could mess up people working in the tree on other things. +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 -+++ src/kadmin/cli/Makefile.in -@@ -43,3 +43,8 @@ clean-unix:: +--- + 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 @@ -13,14 +21,16 @@ could mess up people working in the tree on other things. + $(RM) y.tab.c $@ + $(YACC.y) $< + $(CP) y.tab.c $@ ---- src/plugins/kdb/ldap/ldap_util/Makefile.in -+++ src/plugins/kdb/ldap/ldap_util/Makefile.in -@@ -22,7 +22,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KR +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: $(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG) diff --git a/SOURCES/krb5-CVE-2016-3119.patch b/SOURCES/krb5-CVE-2016-3119.patch deleted file mode 100644 index 2624d57..0000000 --- a/SOURCES/krb5-CVE-2016-3119.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 08c642c09c38a9c6454ab43a9b53b2a89b9eef99 Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Mon, 14 Mar 2016 17:26:34 -0400 -Subject: [PATCH] Fix LDAP null deref on empty arg [CVE-2016-3119] - -In the LDAP KDB module's process_db_args(), strtok_r() may return NULL -if there is an empty string in the db_args array. Check for this case -and avoid dereferencing a null pointer. - -CVE-2016-3119: - -In MIT krb5 1.6 and later, an authenticated attacker with permission -to modify a principal entry can cause kadmind to dereference a null -pointer by supplying an empty DB argument to the modify_principal -command, if kadmind is configured to use the LDAP KDB module. - - CVSSv2 Vector: AV:N/AC:H/Au:S/C:N/I:N/A:C/E:H/RL:OF/RC:ND - -ticket: 8383 (new) -target_version: 1.14-next -target_version: 1.13-next -tags: pullup ---- - src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c -index 6e591e1..79c4cf0 100644 ---- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c -+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c -@@ -296,6 +296,7 @@ process_db_args(krb5_context context, char **db_args, xargs_t *xargs, - if (db_args) { - for (i=0; db_args[i]; ++i) { - arg = strtok_r(db_args[i], "=", &arg_val); -+ arg = (arg != NULL) ? arg : ""; - if (strcmp(arg, TKTPOLICY_ARG) == 0) { - dptr = &xargs->tktpolicydn; - } else { --- -2.8.1 - diff --git a/SOURCES/krb5-acquire_cred_interposer.patch b/SOURCES/krb5-acquire_cred_interposer.patch deleted file mode 100644 index fa1c532..0000000 --- a/SOURCES/krb5-acquire_cred_interposer.patch +++ /dev/null @@ -1,222 +0,0 @@ -From b3901af6970fb7bde88eb16d51c8d05db6f37746 Mon Sep 17 00:00:00 2001 -From: Simo Sorce -Date: Fri, 13 Nov 2015 14:54:11 -0500 -Subject: [PATCH] Fix impersonate_name to work with interposers - -This follows the same modifications applied to -gss_acquire_cred_with_password() when interposer plugins were -introduced. - -[ghudson@mit.edu: minor whitespace changes; initialize out_mcred in -spnego_gss_acquire_cred_impersonate_name() since it is released in the -cleanup handler] - -ticket: 8280 (new) ---- - src/lib/gssapi/mechglue/g_acquire_cred_imp_name.c | 58 +++++++++++++++-------- - src/lib/gssapi/spnego/spnego_mech.c | 35 +++++++------- - 2 files changed, 54 insertions(+), 39 deletions(-) - -diff --git a/src/lib/gssapi/mechglue/g_acquire_cred_imp_name.c b/src/lib/gssapi/mechglue/g_acquire_cred_imp_name.c -index 0dd4f87..9eab25e 100644 ---- a/src/lib/gssapi/mechglue/g_acquire_cred_imp_name.c -+++ b/src/lib/gssapi/mechglue/g_acquire_cred_imp_name.c -@@ -334,6 +334,8 @@ gss_add_cred_impersonate_name(OM_uint32 *minor_status, - gss_cred_id_t cred = NULL; - gss_OID new_mechs_array = NULL; - gss_cred_id_t * new_cred_array = NULL; -+ gss_OID_set target_mechs = GSS_C_NO_OID_SET; -+ gss_OID selected_mech = GSS_C_NO_OID; - - status = val_add_cred_impersonate_name_args(minor_status, - input_cred_handle, -@@ -350,7 +352,12 @@ gss_add_cred_impersonate_name(OM_uint32 *minor_status, - if (status != GSS_S_COMPLETE) - return (status); - -- mech = gssint_get_mechanism(desired_mech); -+ status = gssint_select_mech_type(minor_status, desired_mech, -+ &selected_mech); -+ if (status != GSS_S_COMPLETE) -+ return status; -+ -+ mech = gssint_get_mechanism(selected_mech); - if (!mech) - return GSS_S_BAD_MECH; - else if (!mech->gss_acquire_cred_impersonate_name) -@@ -367,27 +374,26 @@ gss_add_cred_impersonate_name(OM_uint32 *minor_status, - internal_name = GSS_C_NO_NAME; - } else { - union_cred = (gss_union_cred_t)input_cred_handle; -- if (gssint_get_mechanism_cred(union_cred, desired_mech) != -+ if (gssint_get_mechanism_cred(union_cred, selected_mech) != - GSS_C_NO_CREDENTIAL) - return (GSS_S_DUPLICATE_ELEMENT); - } - - mech_impersonator_cred = - gssint_get_mechanism_cred((gss_union_cred_t)impersonator_cred_handle, -- desired_mech); -+ selected_mech); - if (mech_impersonator_cred == GSS_C_NO_CREDENTIAL) - return (GSS_S_NO_CRED); - - /* may need to create a mechanism specific name */ - union_name = (gss_union_name_t)desired_name; - if (union_name->mech_type && -- g_OID_equal(union_name->mech_type, -- &mech->mech_type)) -+ g_OID_equal(union_name->mech_type, selected_mech)) - internal_name = union_name->mech_name; - else { - if (gssint_import_internal_name(minor_status, -- &mech->mech_type, union_name, -- &allocated_name) != GSS_S_COMPLETE) -+ selected_mech, union_name, -+ &allocated_name) != GSS_S_COMPLETE) - return (GSS_S_BAD_NAME); - internal_name = allocated_name; - } -@@ -402,11 +408,21 @@ gss_add_cred_impersonate_name(OM_uint32 *minor_status, - else - time_req = 0; - -+ status = gss_create_empty_oid_set(minor_status, &target_mechs); -+ if (status != GSS_S_COMPLETE) -+ goto errout; -+ -+ status = gss_add_oid_set_member(minor_status, -+ gssint_get_public_oid(selected_mech), -+ &target_mechs); -+ if (status != GSS_S_COMPLETE) -+ goto errout; -+ - status = mech->gss_acquire_cred_impersonate_name(minor_status, - mech_impersonator_cred, - internal_name, - time_req, -- GSS_C_NULL_OID_SET, -+ target_mechs, - cred_usage, - &cred, - NULL, -@@ -445,19 +461,15 @@ gss_add_cred_impersonate_name(OM_uint32 *minor_status, - - new_cred_array[union_cred->count] = cred; - if ((new_mechs_array[union_cred->count].elements = -- malloc(mech->mech_type.length)) == NULL) -+ malloc(selected_mech->length)) == NULL) - goto errout; - -- g_OID_copy(&new_mechs_array[union_cred->count], -- &mech->mech_type); -+ g_OID_copy(&new_mechs_array[union_cred->count], selected_mech); - - if (actual_mechs != NULL) { -- gss_OID_set_desc oids; -- -- oids.count = union_cred->count + 1; -- oids.elements = new_mechs_array; -- -- status = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs); -+ status = gssint_make_public_oid_set(minor_status, new_mechs_array, -+ union_cred->count + 1, -+ actual_mechs); - if (GSS_ERROR(status)) { - free(new_mechs_array[union_cred->count].elements); - goto errout; -@@ -486,10 +498,12 @@ gss_add_cred_impersonate_name(OM_uint32 *minor_status, - /* We're done with the internal name. Free it if we allocated it. */ - - if (allocated_name) -- (void) gssint_release_internal_name(&temp_minor_status, -- &mech->mech_type, -+ (void) gssint_release_internal_name(&temp_minor_status, selected_mech, - &allocated_name); - -+ if (target_mechs) -+ (void) gss_release_oid_set(&temp_minor_status, &target_mechs); -+ - return (GSS_S_COMPLETE); - - errout: -@@ -503,8 +517,10 @@ errout: - - if (allocated_name) - (void) gssint_release_internal_name(&temp_minor_status, -- &mech->mech_type, -- &allocated_name); -+ selected_mech, &allocated_name); -+ -+ if (target_mechs) -+ (void) gss_release_oid_set(&temp_minor_status, &target_mechs); - - if (input_cred_handle == GSS_C_NO_CREDENTIAL && union_cred) - free(union_cred); -diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c -index e6703eb..28fb9b1 100644 ---- a/src/lib/gssapi/spnego/spnego_mech.c -+++ b/src/lib/gssapi/spnego/spnego_mech.c -@@ -2619,10 +2619,10 @@ spnego_gss_acquire_cred_impersonate_name(OM_uint32 *minor_status, - gss_OID_set *actual_mechs, - OM_uint32 *time_rec) - { -- OM_uint32 status; -+ OM_uint32 status, tmpmin; - gss_OID_set amechs = GSS_C_NULL_OID_SET; - spnego_gss_cred_id_t imp_spcred = NULL, out_spcred = NULL; -- gss_cred_id_t imp_mcred, out_mcred; -+ gss_cred_id_t imp_mcred, out_mcred = GSS_C_NO_CREDENTIAL; - - dsyslog("Entering spnego_gss_acquire_cred_impersonate_name\n"); - -@@ -2634,31 +2634,30 @@ spnego_gss_acquire_cred_impersonate_name(OM_uint32 *minor_status, - - imp_spcred = (spnego_gss_cred_id_t)impersonator_cred_handle; - imp_mcred = imp_spcred ? imp_spcred->mcred : GSS_C_NO_CREDENTIAL; -- if (desired_mechs == GSS_C_NO_OID_SET) { -- status = gss_inquire_cred(minor_status, imp_mcred, NULL, NULL, -- NULL, &amechs); -- if (status != GSS_S_COMPLETE) -- return status; -- -- desired_mechs = amechs; -- } -+ status = gss_inquire_cred(minor_status, imp_mcred, NULL, NULL, -+ NULL, &amechs); -+ if (status != GSS_S_COMPLETE) -+ return status; - - status = gss_acquire_cred_impersonate_name(minor_status, imp_mcred, - desired_name, time_req, -- desired_mechs, cred_usage, -+ amechs, cred_usage, - &out_mcred, actual_mechs, - time_rec); -- -- if (amechs != GSS_C_NULL_OID_SET) -- (void) gss_release_oid_set(minor_status, &amechs); -+ if (status != GSS_S_COMPLETE) -+ goto cleanup; - - status = create_spnego_cred(minor_status, out_mcred, &out_spcred); -- if (status != GSS_S_COMPLETE) { -- gss_release_cred(minor_status, &out_mcred); -- return (status); -- } -+ if (status != GSS_S_COMPLETE) -+ goto cleanup; -+ -+ out_mcred = GSS_C_NO_CREDENTIAL; - *output_cred_handle = (gss_cred_id_t)out_spcred; - -+cleanup: -+ (void) gss_release_oid_set(&tmpmin, &amechs); -+ (void) gss_release_cred(&tmpmin, &out_mcred); -+ - dsyslog("Leaving spnego_gss_acquire_cred_impersonate_name\n"); - return (status); - } --- -2.6.2 - diff --git a/SOURCES/krb5-kadm5clntmit_libsoname_version_downgrade.patch b/SOURCES/krb5-kadm5clntmit_libsoname_version_downgrade.patch index 7ecb9f1..c3a7290 100644 --- a/SOURCES/krb5-kadm5clntmit_libsoname_version_downgrade.patch +++ b/SOURCES/krb5-kadm5clntmit_libsoname_version_downgrade.patch @@ -1,13 +1,22 @@ -This patch is a hack so that we can rebase krb5 without breaking all -of our stricter dependents. +From 6fbda5af22095ed1b8ca690bc8269cad04e25034 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Fri, 22 Apr 2016 10:03:56 -0400 +Subject: [PATCH] krb5-kadm5clntmit_libsoname_version_downgrade.patch +[rharwood@redhat.com: Adjust for 1.15] +--- + src/lib/kadm5/clnt/Makefile.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in +index a180e85cd..b9aa7aa49 100644 --- a/src/lib/kadm5/clnt/Makefile.in +++ b/src/lib/kadm5/clnt/Makefile.in -@@ -3,7 +3,7 @@ +@@ -3,7 +3,7 @@ BUILDTOP=$(REL)..$(S)..$(S).. LOCALINCLUDES = -I$(BUILDTOP)/include/kadm5 LIBBASE=kadm5clnt_mit --LIBMAJOR=10 +-LIBMAJOR=11 +LIBMAJOR=8 LIBMINOR=0 STOBJLISTS=../OBJS.ST OBJS.ST diff --git a/SOURCES/krb5-kvno-230379.patch b/SOURCES/krb5-kvno-230379.patch index 46eda22..0e7c5d5 100644 --- a/SOURCES/krb5-kvno-230379.patch +++ b/SOURCES/krb5-kvno-230379.patch @@ -1,20 +1,18 @@ -From patch attached to http://krbdev.mit.edu/rt/Ticket/Display.html?id=3349, -at http://krbdev.mit.edu/rt/Ticket/Attachment/23851/13214/kvno.diff, adjusted -as needed to apply to 1.10. FIXME: I'd like to better handle cases where we -have a new key with the right version stored later in the keytab file. -Currently, we're setting up to overlook that possibility. +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 -Note that this only affects the path taken when krb5_rd_rep() is passed a -server principal name, as without a server principal name it already tries -all of the keys it finds in the keytab, regardless of version numbers. +--- + src/kadmin/ktutil/ktutil.c | 5 +++-- + src/lib/krb5/keytab/kt_file.c | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) -[rharwood@redhat.com Modify patch to apply to 1.14.1] - -Index: krb5/src/kadmin/ktutil/ktutil.c -=================================================================== ---- krb5/src/kadmin/ktutil/ktutil.c (revision 3367) -+++ krb5/src/kadmin/ktutil/ktutil.c (working copy) -@@ -155,7 +155,7 @@ +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; @@ -23,7 +21,7 @@ Index: krb5/src/kadmin/ktutil/ktutil.c for (i = 1; i < argc; i++) { if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) { -@@ -164,6 +164,7 @@ +@@ -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]); @@ -31,7 +29,7 @@ Index: krb5/src/kadmin/ktutil/ktutil.c continue; } if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { -@@ -180,7 +181,7 @@ +@@ -165,7 +166,7 @@ void ktutil_add_entry(argc, argv) } } @@ -40,11 +38,11 @@ Index: krb5/src/kadmin/ktutil/ktutil.c fprintf(stderr, _("usage: %s (-key | -password) -p principal " "-k kvno -e enctype\n"), argv[0]); return; -Index: krb5/src/lib/krb5/keytab/kt_file.c -=================================================================== ---- krb5/src/lib/krb5/keytab/kt_file.c (revision 3367) -+++ krb5/src/lib/krb5/keytab/kt_file.c (working copy) -@@ -349,7 +349,7 @@ +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. */ diff --git a/SPECS/krb5.spec b/SPECS/krb5.spec index 1351a7e..47b8fe9 100644 --- a/SPECS/krb5.spec +++ b/SPECS/krb5.spec @@ -12,8 +12,8 @@ Summary: The Kerberos network authentication system Name: krb5 -Version: 1.14.1 -Release: 27%{?dist} +Version: 1.15.1 +Release: 8%{?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 @@ -33,6 +33,7 @@ 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 @@ -49,38 +50,25 @@ Source100: nss_wrapper-0.0-20140204195100.git3d58327.tar.xz Source101: noport.c Source102: socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz -Patch6: krb5-1.12-ksu-path.patch -Patch12: krb5-1.12-ktany.patch -Patch16: krb5-1.12-buildconf.patch -Patch23: krb5-1.3.1-dns.patch -Patch39: krb5-1.12-api.patch -Patch60: krb5-1.12.1-pam.patch -Patch63: krb5-1.14.1-selinux-label.patch -Patch71: krb5-1.13-dirsrv-accountlock.patch -Patch86: krb5-1.9-debuginfo.patch -Patch105: krb5-kvno-230379.patch -Patch129: krb5-1.11-run_user_0.patch -Patch134: krb5-1.11-kpasswdtest.patch -Patch139: krb5-kadm5clntmit_libsoname_version_downgrade.patch -Patch135: krb5-1.14.2-log_file_mode.patch -Patch136: krb5-acquire_cred_interposer.patch -Patch137: krb5-1.14.2-skip_unnecessary_mech_inquire_cred.patch -Patch138: krb5-1.14.3-ksu_root_prompt.patch -Patch140: krb5-CVE-2016-3119.patch -Patch141: krb5-1.14.3-fix_otp_as_key.patch -Patch142: krb5-1.15-hide_deperecated_on_indicate.patch -Patch143: krb5-1.15-NTLM_SPNEGO.patch -Patch144: krb5-1.15-fix_t_kprop.patch -Patch145: krb5-1.15-kprop-kpropd-realm.patch -Patch146: krb5-1.15-kprop-iprop-default_realm-tests.patch -Patch147: krb5-1.14.3-krad-recv.patch -Patch148: krb5-1.15-kprop-debug-argument-order.patch -Patch149: krb5-1.15-kadmin-kprop-port.patch -Patch150: krb5-1.15-kadmin-kprop-port-test.patch -Patch151: krb5-1.14.4-CVE-2016-3120.patch -Patch152: krb5-1.14.4-SNI-HTTP-Host.patch -Patch153: krb5-1.14.4-Fix-responder-without-preauth.patch -Patch154: krb5-1.15-krad-eof.patch +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 +Patch151: krb5-kadm5clntmit_libsoname_version_downgrade.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 License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -260,55 +248,34 @@ 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 +%patch151 -p1 -b .krb5-kadm5clntmit_libsoname_version_downgrade +%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 + ln NOTICE LICENSE chmod u+x src/util/paste-kdcproxy.py - -%patch60 -p1 -b .pam - -%patch63 -p1 -b .selinux-label - -%patch6 -p1 -b .ksu-path -%patch12 -p1 -b .ktany -%patch16 -p1 -b .buildconf %{?_rawbuild} -%patch23 -p1 -b .dns %{?_rawbuild} -%patch39 -p1 -b .api -%patch71 -p1 -b .dirsrv-accountlock %{?_rawbuild} -%patch86 -p0 -b .debuginfo -%patch105 -p1 -b .kvno - -# Apply when the hard-wired or configured default location is -# DIR:/run/user/%%{uid}/krb5cc. -%patch129 -p1 -b .run_user_0 - -%patch134 -p1 -b .kpasswdtest -%patch139 -p1 -b .kadm5clntmit_libsoname_version_downgrade -%patch135 -p1 -b .log_file_mode -%patch136 -p1 -b .acquire_cred_interposer -%patch137 -p1 -b .skip_unnecessary_mech_inquire_cred -%patch138 -p1 -b .ksu_root_prompt -%patch140 -p1 -b .CVE-2016-3119 -%patch141 -p1 -b .fix_otp_as_key -%patch142 -p1 -b .hide_deperecated_on_indicate -%patch143 -p1 -b .NTLM_SPNEGO - -%patch144 -p1 -b .fix_t_kprop -%patch145 -p1 -b .kprop-kpropd-realm -%patch146 -p1 -b .kprop-iprop-default_realm-tests - -%patch147 -p1 -b .krad-recv - -%patch148 -p1 -b .kprop-debug-argument-order -%patch149 -p1 -b .kadmin-kprop-port -%patch150 -p1 -b .kadmin-kprop-port-test -%patch151 -p1 -b .CVE-2016-3120 -%patch152 -p1 -b .SNI-HTTP-Host -%patch153 -p1 -b .Fix-responder-without-preauth -%patch154 -p1 -b .krad-eof - # Take the execute bit off of documentation. -chmod -x doc/krb5-protocol/*.txt doc/ccapi/*.html +chmod -x doc/ccapi/*.html # Generate an FDS-compatible LDIF file. inldif=src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif @@ -323,9 +290,7 @@ touch -r $inldif 60kerberos.ldif # Rebuild the configure scripts. pushd src -#autoheader -#autoconf -./util/reconf --verbose +autoreconf -fiv popd # Create build spaces for the test wrappers. @@ -392,7 +357,8 @@ CPPFLAGS="`echo $DEFINES $INCLUDES`" --with-tls-impl=openssl \ --with-system-verto \ --with-pam \ - --with-selinux + --with-selinux \ + --with-prng-alg=os # Now build it. make popd @@ -520,7 +486,8 @@ mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/run/krb5kdc mkdir -p $RPM_BUILD_ROOT/etc/sysconfig for sysconfig in \ %{SOURCE19}\ - %{SOURCE20} ; do + %{SOURCE20}\ + %{SOURCE21} ; do install -pm 644 ${sysconfig} \ $RPM_BUILD_ROOT/etc/sysconfig/`basename ${sysconfig} .sysconfig` done @@ -716,6 +683,7 @@ exit 0 %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 @@ -752,8 +720,8 @@ exit 0 %{_sbindir}/krb5kdc %{_mandir}/man8/krb5kdc.8* -# This is here for people who want to test their server, and also -# included in devel package for similar reasons. +# 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 @@ -815,8 +783,6 @@ exit 0 %files devel %defattr(-,root,root,-) %docdir %{_mandir} -%doc doc/krb5-protocol -%doc build-pdf/appdev.pdf build-pdf/plugindev.pdf %{_includedir}/* %{_libdir}/libgssapi_krb5.so @@ -829,11 +795,7 @@ exit 0 %{_libdir}/pkgconfig/* %{_bindir}/krb5-config -%{_bindir}/sclient %{_mandir}/man1/krb5-config.1* -%{_mandir}/man1/sclient.1* -%{_mandir}/man8/sserver.8* -%{_sbindir}/sserver # Protocol test clients. %{_bindir}/sim_client @@ -855,6 +817,52 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* 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