diff --git a/.gitignore b/.gitignore index ff82334..d4151c9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -SOURCES/krb5-1.13.2-pdf.pax.xz -SOURCES/krb5-1.13.2.tar.gz +SOURCES/krb5-1.14.1-pdfs.tar +SOURCES/krb5-1.14.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 c837707..cfff662 100644 --- a/.krb5.metadata +++ b/.krb5.metadata @@ -1,4 +1,4 @@ -93795fb24ecb84cd2db15c28d67d17990614b693 SOURCES/krb5-1.13.2-pdf.pax.xz -a81dec5cf59b7a4b51c5be14d65518724ae25d56 SOURCES/krb5-1.13.2.tar.gz +a374c9aec97659bebf99244c83c24c069764e6a3 SOURCES/krb5-1.14.1-pdfs.tar +f12dc3b8630fd1fefb7058cd782754489377308b SOURCES/krb5-1.14.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/krb5-1.13-selinux-label.patch b/SOURCES/krb5-1.13-selinux-label.patch deleted file mode 100644 index 1cd86c0..0000000 --- a/SOURCES/krb5-1.13-selinux-label.patch +++ /dev/null @@ -1,979 +0,0 @@ -SELinux bases access to files on the domain of the requesting process, -the operation being performed, and the context applied to the file. - -In many cases, applications needn't be SELinux aware to work properly, -because SELinux can apply a default label to a file based on the label -of the directory in which it's created. - -In the case of files such as /etc/krb5.keytab, however, this isn't -sufficient, as /etc/krb5.keytab will almost always need to be given a -label which differs from that of /etc/issue or /etc/resolv.conf. The -the kdb stash file needs a different label than the database for which -it's holding a master key, even though both typically live in the same -directory. - -To give the file the correct label, we can either force a "restorecon" -call to fix a file's label after it's created, or create the file with -the right label, as we attempt to do here. We lean on THREEPARAMOPEN -and define a similar macro named WRITABLEFOPEN with which we replace -several uses of fopen(). - -The file creation context that we're manipulating here is a process-wide -attribute. While for the most part, applications which need to label -files when they're created have tended to be single-threaded, there's -not much we can do to avoid interfering with an application that -manipulates the creation context directly. Right now we're mediating -access using a library-local mutex, but that can only work for consumers -that are part of this package -- an unsuspecting application will still -stomp all over us. - -The selabel APIs for looking up the context should be thread-safe (per -Red Hat #273081), so switching to using them instead of matchpathcon(), -which we used earlier, is some improvement. - ---- krb5/src/aclocal.m4 -+++ krb5/src/aclocal.m4 -@@ -103,6 +103,7 @@ AC_SUBST_FILE(libnodeps_frag) - dnl - KRB5_AC_PRAGMA_WEAK_REF - WITH_LDAP -+KRB5_WITH_SELINUX - KRB5_LIB_PARAMS - KRB5_AC_INITFINI - KRB5_AC_ENABLE_THREADS -@@ -1791,3 +1792,51 @@ AC_SUBST(manlocalstatedir) - AC_SUBST(PAM_MAN) - AC_SUBST(NON_PAM_MAN) - ])dnl -+dnl -+dnl Use libselinux to set file contexts on newly-created files. -+dnl -+AC_DEFUN(KRB5_WITH_SELINUX,[ -+AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])], -+ withselinux="$withval",withselinux=auto) -+old_LIBS="$LIBS" -+if test "$withselinux" != no ; then -+ AC_MSG_RESULT([checking for libselinux...]) -+ SELINUX_LIBS= -+ AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h) -+ if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then -+ if test "$withselinux" = auto ; then -+ AC_MSG_RESULT([Unable to locate selinux/selinux.h.]) -+ withselinux=no -+ else -+ AC_MSG_ERROR([Unable to locate selinux/selinux.h.]) -+ fi -+ fi -+ -+ LIBS= -+ unset ac_cv_func_setfscreatecon -+ AC_CHECK_FUNCS(setfscreatecon selabel_open) -+ if test "x$ac_cv_func_setfscreatecon" = xno ; then -+ AC_CHECK_LIB(selinux,setfscreatecon) -+ unset ac_cv_func_setfscreatecon -+ AC_CHECK_FUNCS(setfscreatecon selabel_open) -+ if test "x$ac_cv_func_setfscreatecon" = xyes ; then -+ SELINUX_LIBS="$LIBS" -+ else -+ if test "$withselinux" = auto ; then -+ AC_MSG_RESULT([Unable to locate libselinux.]) -+ withselinux=no -+ else -+ AC_MSG_ERROR([Unable to locate libselinux.]) -+ fi -+ fi -+ fi -+ if test "$withselinux" != no ; then -+ AC_MSG_NOTICE([building with SELinux labeling support]) -+ AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.]) -+ SELINUX_LIBS="$LIBS" -+ EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon" -+ fi -+fi -+LIBS="$old_LIBS" -+AC_SUBST(SELINUX_LIBS) -+])dnl ---- krb5/src/config/pre.in -+++ krb5/src/config/pre.in -@@ -180,6 +180,7 @@ LD_UNRESOLVED_PREFIX = @LD_UNRESOLVED_PREFIX@ - KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include - LDFLAGS = @LDFLAGS@ - LIBS = @LIBS@ -+SELINUX_LIBS=@SELINUX_LIBS@ - - INSTALL=@INSTALL@ - INSTALL_STRIP= -@@ -379,7 +380,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME) - # HESIOD_LIBS is -lhesiod... - HESIOD_LIBS = @HESIOD_LIBS@ - --KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB) -+KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB) - KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS) - GSS_LIBS = $(GSS_KRB5_LIB) - # needs fixing if ever used on Mac OS X! ---- krb5/src/configure.in -+++ krb5/src/configure.in -@@ -1053,6 +1053,8 @@ fi - - KRB5_WITH_PAM - -+KRB5_WITH_SELINUX -+ - # Make localedir work in autoconf 2.5x. - if test "${localedir+set}" != set; then - localedir='$(datadir)/locale' ---- krb5/src/include/k5-int.h -+++ krb5/src/include/k5-int.h -@@ -129,6 +129,7 @@ typedef unsigned char u_char; - - - #include "k5-platform.h" -+#include "k5-label.h" - - #define KRB5_KDB_MAX_LIFE (60*60*24) /* one day */ - #define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */ ---- krb5/src/include/k5-label.h -+++ krb5/src/include/k5-label.h -@@ -0,0 +1,32 @@ -+#ifndef _KRB5_LABEL_H -+#define _KRB5_LABEL_H -+ -+#ifdef THREEPARAMOPEN -+#undef THREEPARAMOPEN -+#endif -+#ifdef WRITABLEFOPEN -+#undef WRITABLEFOPEN -+#endif -+ -+/* Wrapper functions which help us create files and directories with the right -+ * context labels. */ -+#ifdef USE_SELINUX -+#include -+#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 ---- krb5/src/include/krb5/krb5.hin -+++ krb5/src/include/krb5/krb5.hin -@@ -87,6 +87,12 @@ - #define THREEPARAMOPEN(x,y,z) open(x,y,z) - #endif - -+#if KRB5_PRIVATE -+#ifndef WRITABLEFOPEN -+#define WRITABLEFOPEN(x,y) fopen(x,y) -+#endif -+#endif -+ - #define KRB5_OLD_CRYPTO - - #include ---- krb5/src/kadmin/dbutil/dump.c -+++ krb5/src/kadmin/dbutil/dump.c -@@ -376,12 +376,21 @@ create_ofile(char *ofile, char **tmpname - { - int fd = -1; - FILE *f; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - *tmpname = NULL; - if (asprintf(tmpname, "%s-XXXXXX", ofile) < 0) - goto error; - -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(ofile); -+#endif - fd = mkstemp(*tmpname); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif - if (fd == -1) - goto error; - -@@ -514,7 +514,7 @@ prep_ok_file(krb5_context context, char - return 0; - } - -- *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); -+ *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (*fd == -1) { - com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok); - exit_status++; ---- krb5/src/build-tools/krb5-config.in -+++ krb5/src/build-tools/krb5-config.in -@@ -38,6 +38,7 @@ RPATH_FLAG='@RPATH_FLAG@' - DEFCCNAME='@DEFCCNAME@' - DEFKTNAME='@DEFKTNAME@' - DEFCKTNAME='@DEFCKTNAME@' -+SELINUX_LIBS='@SELINUX_LIBS@' - - LIBS='@LIBS@' - GEN_LIB=@GEN_LIB@ -@@ -218,7 +219,7 @@ - fi - - # If we ever support a flag to generate output suitable for static -- # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB" -+ # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB" - # here. - - echo $lib_flags ---- krb5/src/lib/kadm5/logger.c -+++ krb5/src/lib/kadm5/logger.c -@@ -425,7 +425,7 @@ krb5_klog_init(krb5_context kcontext, ch - * Check for append/overwrite, then open the file. - */ - if (cp[4] == ':' || cp[4] == '=') { -- f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w"); -+ f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w"); - if (f) { - set_cloexec_file(f); - log_control.log_entries[i].lfu_filep = f; -@@ -961,7 +961,7 @@ krb5_klog_reopen(krb5_context kcontext) - * In case the old logfile did not get moved out of the - * way, open for append to prevent squashing the old logs. - */ -- f = fopen(log_control.log_entries[lindex].lfu_fname, "a+"); -+ f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+"); - if (f) { - set_cloexec_file(f); - log_control.log_entries[lindex].lfu_filep = f; ---- krb5/src/lib/krb5/keytab/kt_file.c -+++ krb5/src/lib/krb5/keytab/kt_file.c -@@ -1050,7 +1050,7 @@ krb5_ktfileint_open(krb5_context context - - KTCHECKLOCK(id); - errno = 0; -- KTFILEP(id) = fopen(KTFILENAME(id), -+ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), - (mode == KRB5_LOCKMODE_EXCLUSIVE) ? - fopen_mode_rbplus : fopen_mode_rb); - if (!KTFILEP(id)) { -@@ -1058,7 +1058,7 @@ krb5_ktfileint_open(krb5_context context - /* try making it first time around */ - k5_create_secure_file(context, KTFILENAME(id)); - errno = 0; -- KTFILEP(id) = fopen(KTFILENAME(id), fopen_mode_rbplus); -+ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), fopen_mode_rbplus); - if (!KTFILEP(id)) - goto report_errno; - writevno = 1; ---- krb5/src/plugins/kdb/db2/adb_openclose.c -+++ krb5/src/plugins/kdb/db2/adb_openclose.c -@@ -201,7 +201,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char - * POSIX systems - */ - lockp->lockinfo.filename = strdup(lockfilename); -- if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) { -+ if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) { - /* - * maybe someone took away write permission so we could only - * get shared locks? ---- krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c -+++ krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c -@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8. - #include - #include - -+#include "k5-int.h" - #include "db-int.h" - #include "btree.h" - -@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, - goto einval; - } - -- if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0) -+ if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) - goto err; - - } else { ---- krb5/src/plugins/kdb/db2/libdb2/hash/hash.c -+++ krb5/src/plugins/kdb/db2/libdb2/hash/hash.c -@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 - #include - #endif - -+#include "k5-int.h" - #include "db-int.h" - #include "hash.h" - #include "page.h" -@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info - new_table = 1; - } - if (file) { -- if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1) -+ if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1) - RETURN_ERROR(errno, error0); - (void)fcntl(hashp->fp, F_SETFD, 1); - } ---- krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c -+++ krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c -@@ -179,7 +179,7 @@ done: - - /* set password in the file */ - old_mode = umask(0177); -- pfile = fopen(file_name, "a+"); -+ pfile = WRITABLEFOPEN(file_name, "a+"); - if (pfile == NULL) { - com_err(me, errno, _("Failed to open file %s: %s"), file_name, - strerror (errno)); -@@ -220,6 +220,9 @@ done: - * Delete the existing entry and add the new entry - */ - FILE *newfile; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - mode_t omask; - -@@ -231,7 +234,13 @@ done: - } - - omask = umask(077); -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(file_name); -+#endif - newfile = fopen(tmp_file, "w"); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif - umask (omask); - if (newfile == NULL) { - com_err(me, errno, _("Error creating file %s"), tmp_file); ---- krb5/src/slave/kpropd.c -+++ krb5/src/slave/kpropd.c -@@ -437,6 +437,9 @@ void doit(fd) - krb5_enctype etype; - int database_fd; - char host[INET6_ADDRSTRLEN + 1]; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - signal_wrapper(SIGALRM, alarm_handler); - alarm(params.iprop_resync_timeout); -@@ -515,9 +518,15 @@ void doit(fd) - free(name); - exit(1); - } -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(file); -+#endif - omask = umask(077); - lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600); - (void)umask(omask); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif - retval = krb5_lock_file(kpropd_context, lock_fd, - KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK); - if (retval) { ---- krb5/src/util/profile/prof_file.c -+++ krb5/src/util/profile/prof_file.c -@@ -30,6 +30,7 @@ - #endif - - #include "k5-platform.h" -+#include "k5-label.h" - - struct global_shared_profile_data { - /* This is the head of the global list of shared trees */ -@@ -418,7 +419,7 @@ static errcode_t write_data_to_file(prf_ - - errno = 0; - -- f = fopen(new_file, "w"); -+ f = WRITABLEFOPEN(new_file, "w"); - if (!f) { - retval = errno; - if (retval == 0) ---- krb5/src/util/support/Makefile.in -+++ krb5/src/util/support/Makefile.in -@@ -54,6 +54,7 @@ IPC_SYMS= \ - - STLIBOBJS= \ - threads.o \ -+ selinux.o \ - init-addrinfo.o \ - plugins.o \ - errors.o \ -@@ -108,7 +109,7 @@ SRCS=\ - - SHLIB_EXPDEPS = - # Add -lm if dumping thread stats, for sqrt. --SHLIB_EXPLIBS= $(LIBS) $(DL_LIB) -+SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB) - - DEPLIBS= - ---- krb5/src/util/support/selinux.c -+++ krb5/src/util/support/selinux.c -@@ -0,0 +1,381 @@ -+/* -+ * Copyright 2007,2008,2009,2011,2012,2013 Red Hat, Inc. All Rights Reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * -+ * Redistributions of source code must retain the above copyright notice, this -+ * list of conditions and the following disclaimer. -+ * -+ * Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * -+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be -+ * used to endorse or promote products derived from this software without -+ * specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ * -+ * File-opening wrappers for creating correctly-labeled files. So far, we can -+ * assume that this is Linux-specific, so we make many simplifying assumptions. -+ */ -+ -+#include "../../include/autoconf.h" -+ -+#ifdef USE_SELINUX -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef HAVE_SELINUX_LABEL_H -+#include -+#endif -+ -+/* #define DEBUG 1 */ -+ -+/* Mutex used to serialize use of the process-global file creation context. */ -+k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER; -+ -+/* Make sure we finish initializing that mutex before attempting to use it. */ -+k5_once_t labeled_once = K5_ONCE_INIT; -+static void -+label_mutex_init(void) -+{ -+ k5_mutex_finish_init(&labeled_mutex); -+} -+ -+#ifdef HAVE_SELINUX_LABEL_H -+static struct selabel_handle *selabel_ctx; -+static time_t selabel_last_changed; -+ -+MAKE_FINI_FUNCTION(cleanup_fscreatecon); -+ -+static void -+cleanup_fscreatecon(void) -+{ -+ if (selabel_ctx != NULL) { -+ selabel_close(selabel_ctx); -+ selabel_ctx = NULL; -+ } -+} -+#endif -+ -+static security_context_t -+push_fscreatecon(const char *pathname, mode_t mode) -+{ -+ security_context_t previous, configuredsc, currentsc, derivedsc; -+ context_t current, derived; -+ const char *fullpath, *currentuser; -+ -+ previous = NULL; -+ if (is_selinux_enabled()) { -+ if (getfscreatecon(&previous) == 0) { -+ char *genpath; -+ genpath = NULL; -+ if (pathname[0] != '/') { -+ char *wd; -+ size_t len; -+ len = 0; -+ wd = getcwd(NULL, len); -+ if (wd == NULL) { -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ len = strlen(wd) + 1 + strlen(pathname) + 1; -+ genpath = malloc(len); -+ if (genpath == NULL) { -+ free(wd); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ sprintf(genpath, "%s/%s", wd, pathname); -+ free(wd); -+ fullpath = genpath; -+ } else { -+ fullpath = pathname; -+ } -+#ifdef DEBUG -+ if (isatty(fileno(stderr))) { -+ fprintf(stderr, "Looking up context for " -+ "\"%s\"(%05o).\n", fullpath, mode); -+ } -+#endif -+ configuredsc = NULL; -+#ifdef HAVE_SELINUX_LABEL_H -+ if ((selabel_ctx != NULL) || -+ (selabel_last_changed == 0)) { -+ const char *cpath; -+ struct stat st; -+ int i = -1; -+ cpath = selinux_file_context_path(); -+ if ((cpath == NULL) || -+ ((i = stat(cpath, &st)) != 0) || -+ (st.st_mtime != selabel_last_changed)) { -+ if (selabel_ctx != NULL) { -+ selabel_close(selabel_ctx); -+ selabel_ctx = NULL; -+ } -+ selabel_last_changed = i ? -+ time(NULL) : -+ st.st_mtime; -+ } -+ } -+ if (selabel_ctx == NULL) { -+ selabel_ctx = selabel_open(SELABEL_CTX_FILE, -+ NULL, 0); -+ } -+ if (selabel_ctx != NULL) { -+ if (selabel_lookup(selabel_ctx, &configuredsc, -+ fullpath, mode) != 0) { -+ free(genpath); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ } -+#else -+ if (matchpathcon(fullpath, mode, &configuredsc) != 0) { -+ free(genpath); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+#endif -+ free(genpath); -+ if (configuredsc == NULL) { -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ currentsc = NULL; -+ getcon(¤tsc); -+ if (currentsc != NULL) { -+ derived = context_new(configuredsc); -+ if (derived != NULL) { -+ current = context_new(currentsc); -+ if (current != NULL) { -+ currentuser = context_user_get(current); -+ if (currentuser != NULL) { -+ if (context_user_set(derived, -+ currentuser) == 0) { -+ derivedsc = context_str(derived); -+ if (derivedsc != NULL) { -+ freecon(configuredsc); -+ configuredsc = strdup(derivedsc); -+ } -+ } -+ } -+ context_free(current); -+ } -+ context_free(derived); -+ } -+ freecon(currentsc); -+ } -+#ifdef DEBUG -+ if (isatty(fileno(stderr))) { -+ fprintf(stderr, "Setting file creation context " -+ "to \"%s\".\n", configuredsc); -+ } -+#endif -+ if (setfscreatecon(configuredsc) != 0) { -+ freecon(configuredsc); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ freecon(configuredsc); -+#ifdef DEBUG -+ } else { -+ if (isatty(fileno(stderr))) { -+ fprintf(stderr, "Unable to determine " -+ "current context.\n"); -+ } -+#endif -+ } -+ } -+ return previous; -+} -+ -+static void -+pop_fscreatecon(security_context_t previous) -+{ -+ if (is_selinux_enabled()) { -+#ifdef DEBUG -+ if (isatty(fileno(stderr))) { -+ if (previous != NULL) { -+ fprintf(stderr, "Resetting file creation " -+ "context to \"%s\".\n", previous); -+ } else { -+ fprintf(stderr, "Resetting file creation " -+ "context to default.\n"); -+ } -+ } -+#endif -+ setfscreatecon(previous); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ } -+} -+ -+void * -+krb5int_push_fscreatecon_for(const char *pathname) -+{ -+ struct stat st; -+ void *retval; -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ if (stat(pathname, &st) != 0) { -+ st.st_mode = S_IRUSR | S_IWUSR; -+ } -+ retval = push_fscreatecon(pathname, st.st_mode); -+ return retval ? retval : (void *) -1; -+} -+ -+void -+krb5int_pop_fscreatecon(void *con) -+{ -+ if (con != NULL) { -+ pop_fscreatecon((con == (void *) -1) ? NULL : con); -+ k5_mutex_unlock(&labeled_mutex); -+ } -+} -+ -+FILE * -+krb5int_labeled_fopen(const char *path, const char *mode) -+{ -+ FILE *fp; -+ int errno_save; -+ security_context_t ctx; -+ -+ if ((strcmp(mode, "r") == 0) || -+ (strcmp(mode, "rb") == 0)) { -+ return fopen(path, mode); -+ } -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, 0); -+ fp = fopen(path, mode); -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return fp; -+} -+ -+int -+krb5int_labeled_creat(const char *path, mode_t mode) -+{ -+ int fd; -+ int errno_save; -+ security_context_t ctx; -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, 0); -+ fd = creat(path, mode); -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return fd; -+} -+ -+int -+krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev) -+{ -+ int ret; -+ int errno_save; -+ security_context_t ctx; -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, mode); -+ ret = mknod(path, mode, dev); -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return ret; -+} -+ -+int -+krb5int_labeled_mkdir(const char *path, mode_t mode) -+{ -+ int ret; -+ int errno_save; -+ security_context_t ctx; -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, S_IFDIR); -+ ret = mkdir(path, mode); -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return ret; -+} -+ -+int -+krb5int_labeled_open(const char *path, int flags, ...) -+{ -+ int fd; -+ int errno_save; -+ security_context_t ctx; -+ mode_t mode; -+ va_list ap; -+ -+ if ((flags & O_CREAT) == 0) { -+ return open(path, flags); -+ } -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, 0); -+ -+ va_start(ap, flags); -+ mode = va_arg(ap, mode_t); -+ fd = open(path, flags, mode); -+ va_end(ap); -+ -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return fd; -+} -+ -+#endif ---- krb5/src/lib/krb5/rcache/rc_dfl.c -+++ krb5/src/lib/krb5/rcache/rc_dfl.c -@@ -813,6 +813,9 @@ krb5_rc_dfl_expunge_locked(krb5_context - krb5_error_code retval = 0; - krb5_rcache tmp; - krb5_deltat lifespan = t->lifespan; /* save original lifespan */ -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - if (! t->recovering) { - name = t->name; -@@ -834,7 +837,17 @@ krb5_rc_dfl_expunge_locked(krb5_context - retval = krb5_rc_resolve(context, tmp, 0); - if (retval) - goto cleanup; -+#ifdef USE_SELINUX -+ if (t->d.fn != NULL) -+ selabel = krb5int_push_fscreatecon_for(t->d.fn); -+ else -+ selabel = NULL; -+#endif - retval = krb5_rc_initialize(context, tmp, lifespan); -+#ifdef USE_SELINUX -+ if (selabel != NULL) -+ krb5int_pop_fscreatecon(selabel); -+#endif - if (retval) - goto cleanup; - for (q = t->a; q; q = q->na) { ---- krb5/src/lib/krb5/ccache/cc_dir.c -+++ krb5/src/lib/krb5/ccache/cc_dir.c -@@ -185,10 +185,19 @@ write_primary_file(const char *primary_p - char *newpath = NULL; - FILE *fp = NULL; - int fd = -1, status; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0) - return ENOMEM; -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(primary_path); -+#endif - fd = mkstemp(newpath); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif - if (fd < 0) - goto cleanup; - #ifdef HAVE_CHMOD -@@ -223,10 +232,23 @@ - verify_dir(krb5_context context, const char *dirname) - { - struct stat st; -+ int status; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - if (stat(dirname, &st) < 0) { -- if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0) -- return 0; -+ if (errno == ENOENT) { -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(dirname); -+#endif -+ status = mkdir(dirname, S_IRWXU); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif -+ if (status == 0) -+ return 0; -+ } - k5_setmsg(context, KRB5_FCC_NOFILE, - _("Credential cache directory %s does not exist"), - dirname); ---- krb5/src/lib/krb5/os/trace.c -+++ krb5/src/lib/krb5/os/trace.c -@@ -401,7 +401,7 @@ krb5_set_trace_filename(krb5_context con - fd = malloc(sizeof(*fd)); - if (fd == NULL) - return ENOMEM; -- *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); -+ *fd = THREEPARAMOPEN(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); - if (*fd == -1) { - free(fd); - return errno; ---- krb5/src/plugins/kdb/db2/kdb_db2.c -+++ krb5/src/plugins/kdb/db2/kdb_db2.c -@@ -683,8 +683,8 @@ - if (retval) - return retval; - -- dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC, -- 0600); -+ dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name, -+ O_CREAT | O_RDWR | O_TRUNC, 0600); - if (dbc->db_lf_file < 0) { - retval = errno; - goto cleanup; ---- krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c -+++ krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c -@@ -51,6 +51,7 @@ - #include - #include - -+#include "k5-int.h" - #include "db-int.h" - #include "recno.h" - -@@ -68,7 +69,8 @@ - int rfd = -1, sverrno; - - /* Open the user's file -- if this fails, we're done. */ -- if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0) -+ if (fname != NULL && -+ (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) - return (NULL); - - if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) { ---- krb5/src/kdc/main.c -+++ krb5/src/kdc/main.c -@@ -905,7 +905,7 @@ write_pid_file(const char *path) - FILE *file; - unsigned long pid; - -- file = fopen(path, "w"); -+ file = WRITABLEFOPEN(path, "w"); - if (file == NULL) - return errno; - pid = (unsigned long) getpid(); ---- krb5/src/lib/kdb/kdb_log.c -+++ krb5/src/lib/kdb/kdb_log.c -@@ -456,7 +456,7 @@ ulog_map(krb5_context context, const cha - int ulogfd = -1; - - if (stat(logname, &st) == -1) { -- ulogfd = open(logname, O_RDWR | O_CREAT, 0600); -+ ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600); - if (ulogfd == -1) - return errno; - ---- krb5/src/util/gss-kernel-lib/Makefile.in -+++ krb5/src/util/gss-kernel-lib/Makefile.in -@@ -60,6 +60,7 @@ HEADERS= \ - gssapi_err_generic.h \ - k5-int.h \ - k5-int-pkinit.h \ -+ k5-label.h \ - k5-thread.h \ - k5-platform.h \ - k5-buf.h \ -@@ -166,10 +167,12 @@ gssapi_generic.h: $(GSS_GENERIC)/gssapi_ - $(CP) $(GSS_GENERIC)/gssapi_generic.h $@ - gssapi_err_generic.h: $(GSS_GENERIC_BUILD)/gssapi_err_generic.h - $(CP) $(GSS_GENERIC_BUILD)/gssapi_err_generic.h $@ --k5-int.h: $(INCLUDE)/k5-int.h -+k5-int.h: $(INCLUDE)/k5-int.h k5-label.h - $(CP) $(INCLUDE)/k5-int.h $@ - k5-int-pkinit.h: $(INCLUDE)/k5-int-pkinit.h - $(CP) $(INCLUDE)/k5-int-pkinit.h $@ -+k5-label.h: $(INCLUDE)/k5-label.h -+ $(CP) $(INCLUDE)/k5-label.h $@ - k5-thread.h: $(INCLUDE)/k5-thread.h - $(CP) $(INCLUDE)/k5-thread.h $@ - k5-platform.h: $(INCLUDE)/k5-platform.h diff --git a/SOURCES/krb5-1.13.2.tar.gz.asc b/SOURCES/krb5-1.13.2.tar.gz.asc deleted file mode 100644 index 969169d..0000000 --- a/SOURCES/krb5-1.13.2.tar.gz.asc +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1 - -iQGcBAABAgAGBQJVTUldAAoJEKMvF/0AVcMF9IoMAIEawAFZ1pRw91oRN6c3eAxy -RYBuJWsEa73JtqKCRtz7LA3qgacnJ8FGTpXaGHB3zErO55+Bclo1KZsUoNDtT27O -bxjsptPBjp15zTZhavlIpAjANFmo6QpghUHpLNcLxH8pXgmQDztHnPaenStxF8Bv -P2oFKh31uY3gYzOKnYi/r14XKSTNpFiDiGty53KY61efAO4H7xRFMhBgN2Vv1pBm -FvekjCWRypN7ai2z+94cuVNIlu8eipDnU4oBb865fRKlflxCdpBmHLr1K5AgwSEb -OAvDUPAEV9GwBP94M0yAoPwGf5ZHPvdORXbHfX00lzX2SgV+9DH4BqJOnytOeuaT -PA1Z+7izF+Xja4iHMcYlyJ7a/sGWachlZrw2ifELlYUf4vtcPY5e6gH0hSMUoA7t -Ww18ryv5fPHT1l+/o2P03hzZSFllOXjVsComsfw6Ws7qzbFuigpiVYdBg1XKMi9L -kjA7j43FTHvVKjtrEubiW+YHxowQHu5DIeQWVqsBJg== -=KdUH ------END PGP SIGNATURE----- diff --git a/SOURCES/krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch b/SOURCES/krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch deleted file mode 100644 index fc3101f..0000000 --- a/SOURCES/krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0e65104d521d29664c129c1cf5e918bf54ac055e Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Tue, 19 May 2015 10:38:51 -0400 -Subject: [PATCH] Fix bindresvport_sa port byte swap bug - -The sa_setport() helper handles conversion to network byte order, so -bindresvport_sa() should not itself call htons() on the port argument. - -(This bug was introduced in commit -0d04b60d159ab83b943e43802b1449a3b074bc83 when adding -bindresvport_sa(). It was my fault, not Andreas Schneider's.) - -ticket: 8197 (new) -target_version: 1.13.3 -tags: pullup ---- - src/lib/rpc/bindresvport.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lib/rpc/bindresvport.c b/src/lib/rpc/bindresvport.c -index ccc4d73..a421dd8 100644 ---- a/src/lib/rpc/bindresvport.c -+++ b/src/lib/rpc/bindresvport.c -@@ -76,7 +76,7 @@ bindresvport_sa(int sd, struct sockaddr *sa) - res = -1; - errno = EADDRINUSE; - for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) { -- sa_setport(sa, htons(port++)); -+ sa_setport(sa, port++); - if (port > ENDPORT) { - port = STARTPORT; - } diff --git a/SOURCES/krb5-1.13.3-client_referrals.patch b/SOURCES/krb5-1.13.3-client_referrals.patch deleted file mode 100644 index 6b94e1b..0000000 --- a/SOURCES/krb5-1.13.3-client_referrals.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 4065b979071b6e34b440f1db24d66d8691792bee Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Thu, 3 Sep 2015 18:24:26 +0300 -Subject: [PATCH] client referral: return correct client principal in case of a - wrong realm - -prepare_error_as_req() gets protocol error code but compares it with -table code and misses to add proper client principal as returned by the -DAL driver. - -Use proper error code constant. ---- - src/kdc/do_as_req.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c -index 3a3ce8b..5440949 100644 ---- a/src/kdc/do_as_req.c -+++ b/src/kdc/do_as_req.c -@@ -862,7 +862,7 @@ prepare_error_as(struct kdc_request_state *rstate, krb5_kdc_req *request, - return retval; - errpkt.error = error; - errpkt.server = request->server; -- errpkt.client = (error == KRB5KDC_ERR_WRONG_REALM) ? canon_client : -+ errpkt.client = (error == KDC_ERR_WRONG_REALM) ? canon_client : - request->client; - errpkt.text = string2data((char *)status); - --- -2.4.3 - diff --git a/SOURCES/krb5-1.13.3-client_referrals_test.patch b/SOURCES/krb5-1.13.3-client_referrals_test.patch deleted file mode 100644 index 449646e..0000000 --- a/SOURCES/krb5-1.13.3-client_referrals_test.patch +++ /dev/null @@ -1,604 +0,0 @@ -diff --git a/src/plugins/kdb/test/Makefile.in b/src/plugins/kdb/test/Makefile.in -new file mode 100644 -index 0000000..f9578a3 ---- /dev/null -+++ b/src/plugins/kdb/test/Makefile.in -@@ -0,0 +1,21 @@ -+mydir=plugins$(S)kdb$(S)test -+BUILDTOP=$(REL)..$(S)..$(S).. -+ -+LIBBASE=test -+LIBMAJOR=0 -+LIBMINOR=0 -+RELDIR=../plugins/kdb/test -+SHLIB_EXPDEPS=$(KADMSRV_DEPLIB) $(KRB5_BASE_DEPLIBS) -+SHLIB_EXPLIBS=$(KADMSRV_LIBS) $(KRB5_BASE_LIBS) -+LOCALINCLUDES=-I../../../lib/kdb -I$(srcdir)/../../../lib/kdb -+ -+SRCS = $(srcdir)/kdb_test.c -+ -+STLIBOBJS = kdb_test.o -+ -+all-unix:: all-liblinks -+install-unix:: -+clean-unix:: clean-liblinks clean-libs clean-libobjs -+ -+@libnover_frag@ -+@libobj_frag@ -diff --git a/src/plugins/kdb/test/deps b/src/plugins/kdb/test/deps -new file mode 100644 -index 0000000..e69de29 -diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c -new file mode 100644 -index 0000000..a0e4970 ---- /dev/null -+++ b/src/plugins/kdb/test/kdb_test.c -@@ -0,0 +1,561 @@ -+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -+/* plugins/kdb/test/kdb_test.c - Test KDB module */ -+/* -+ * Copyright (C) 2015 by the Massachusetts Institute of Technology. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -+ * OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ * This is a read-only KDB module intended to help test KDC behavior which -+ * cannot be exercised with the DB2 module. Responses are read from the -+ * dbmodules subsection according to this example: -+ * -+ * [dbmodules] -+ * test = { -+ * alias = { -+ * aliasname = canonname -+ * # For cross-realm aliases, only the realm part will -+ * # matter to the client. -+ * aliasname = @FOREIGN_REALM -+ * enterprise@PRINC = @FOREIGN_REALM -+ * } -+ * princs = { -+ * krbtgt/KRBTEST.COM = { -+ * flags = +preauth +ok-to-auth-as-delegate -+ * maxlife = 1d -+ * maxrenewlife = 7d -+ * expiration = 14d # relative to current time -+ * pwexpiration = 1h -+ * # Initial number is kvno; defaults to 1. -+ * keys = 3 aes256-cts aes128-cts:normal -+ * keys = 2 rc4-hmac -+ * } -+ * } -+ * delegation = { -+ * intermediate_service = target_service -+ * } -+ * } -+ * -+ * Key values are generated using a hash of the kvno, enctype, salt type, and -+ * principal name. This module does not use master key encryption, so it -+ * serves as a partial test of the DAL's ability to avoid that. -+ */ -+ -+#include "k5-int.h" -+#include "kdb5.h" -+#include "adm_proto.h" -+#include -+ -+typedef struct { -+ void *profile; -+ char *section; -+ const char *names[6]; -+} *testhandle; -+ -+static void * -+ealloc(size_t sz) -+{ -+ void *p = calloc(sz, 1); -+ -+ if (p == NULL) -+ abort(); -+ return p; -+} -+ -+static char * -+estrdup(const char *s) -+{ -+ char *copy = strdup(s); -+ -+ if (copy == NULL) -+ abort(); -+ return copy; -+} -+ -+static void -+check(krb5_error_code code) -+{ -+ if (code != 0) -+ abort(); -+} -+ -+/* Set up for a profile query using h->names. Look up s1 -> s2 -> s3 (some of -+ * which may be NULL) within this database's dbmodules section. */ -+static void -+set_names(testhandle h, const char *s1, const char *s2, const char *s3) -+{ -+ h->names[0] = KDB_MODULE_SECTION; -+ h->names[1] = h->section; -+ h->names[2] = s1; -+ h->names[3] = s2; -+ h->names[4] = s3; -+ h->names[5] = NULL; -+} -+ -+/* Look up a string within this database's dbmodules section. */ -+static char * -+get_string(testhandle h, const char *s1, const char *s2, const char *s3) -+{ -+ krb5_error_code ret; -+ char **values, *val; -+ -+ set_names(h, s1, s2, s3); -+ ret = profile_get_values(h->profile, h->names, &values); -+ if (ret == PROF_NO_RELATION) -+ return NULL; -+ if (ret) -+ abort(); -+ val = estrdup(values[0]); -+ profile_free_list(values); -+ return val; -+} -+ -+/* Look up a duration within this database's dbmodules section. */ -+static krb5_deltat -+get_duration(testhandle h, const char *s1, const char *s2, const char *s3) -+{ -+ char *strval = get_string(h, s1, s2, s3); -+ krb5_deltat val; -+ -+ if (strval == NULL) -+ return 0; -+ check(krb5_string_to_deltat(strval, &val)); -+ free(strval); -+ return val; -+} -+ -+/* Look up an absolute time within this database's dbmodules section. The time -+ * is expressed in the profile as an interval relative to the current time. */ -+static krb5_timestamp -+get_time(testhandle h, const char *s1, const char *s2, const char *s3) -+{ -+ char *strval = get_string(h, s1, s2, s3); -+ krb5_deltat val; -+ -+ if (strval == NULL) -+ return 0; -+ check(krb5_string_to_deltat(strval, &val)); -+ free(strval); -+ return val + time(NULL); -+} -+ -+/* Initialize kb_out with a key of type etype, using a hash of kvno, etype, -+ * salttype, and princstr for the key bytes. */ -+static void -+make_keyblock(krb5_kvno kvno, krb5_enctype etype, int32_t salttype, -+ const char *princstr, krb5_keyblock *kb_out) -+{ -+ size_t keybytes, keylength, pos, n; -+ char *hashstr; -+ krb5_data d, rndin; -+ krb5_checksum cksum; -+ -+ check(krb5_c_keylengths(NULL, etype, &keybytes, &keylength)); -+ alloc_data(&rndin, keybytes); -+ -+ /* Hash the kvno, enctype, salt type, and principal name together. */ -+ if (asprintf(&hashstr, "%d %d %d %s", (int)kvno, (int)etype, -+ (int)salttype, princstr) < 0) -+ abort(); -+ d = string2data(hashstr); -+ check(krb5_c_make_checksum(NULL, CKSUMTYPE_NIST_SHA, NULL, 0, &d, &cksum)); -+ -+ /* Make the appropriate number of input bytes from the hash result. */ -+ for (pos = 0; pos < keybytes; pos += n) { -+ n = (cksum.length < keybytes - pos) ? cksum.length : keybytes - pos; -+ memcpy(rndin.data + pos, cksum.contents, n); -+ } -+ -+ kb_out->enctype = etype; -+ kb_out->length = keylength; -+ kb_out->contents = ealloc(keylength); -+ check(krb5_c_random_to_key(NULL, etype, &rndin, kb_out)); -+ free(cksum.contents); -+ free(rndin.data); -+ free(hashstr); -+} -+ -+/* Return key data for the given key/salt tuple strings, using hashes of the -+ * enctypes, salts, and princstr for the key contents. */ -+static void -+make_keys(char **strings, const char *princstr, krb5_db_entry *ent) -+{ -+ krb5_key_data *key_data, *kd; -+ krb5_keyblock kb; -+ int32_t *ks_list_sizes, nstrings, nkeys, i, j; -+ krb5_key_salt_tuple **ks_lists, *ks; -+ krb5_kvno *kvnos; -+ char *s; -+ -+ for (nstrings = 0; strings[nstrings] != NULL; nstrings++); -+ ks_lists = ealloc(nstrings * sizeof(*ks_lists)); -+ ks_list_sizes = ealloc(nstrings * sizeof(*ks_list_sizes)); -+ kvnos = ealloc(nstrings * sizeof(*kvnos)); -+ -+ /* Convert each string into a key/salt tuple list and count the total -+ * number of key data structures needed. */ -+ nkeys = 0; -+ for (i = 0; i < nstrings; i++) { -+ s = strings[i]; -+ /* Read a leading kvno if present; otherwise assume kvno 1. */ -+ if (isdigit(*s)) { -+ kvnos[i] = strtol(s, &s, 10); -+ while (isspace(*s)) -+ s++; -+ } else { -+ kvnos[i] = 1; -+ } -+ check(krb5_string_to_keysalts(s, NULL, NULL, FALSE, &ks_lists[i], -+ &ks_list_sizes[i])); -+ nkeys += ks_list_sizes[i]; -+ } -+ -+ /* Turn each key/salt tuple into a key data entry. */ -+ kd = key_data = ealloc(nkeys * sizeof(*kd)); -+ for (i = 0; i < nstrings; i++) { -+ ks = ks_lists[i]; -+ for (j = 0; j < ks_list_sizes[i]; j++) { -+ make_keyblock(kvnos[i], ks[j].ks_enctype, ks[j].ks_salttype, -+ princstr, &kb); -+ kd->key_data_ver = 2; -+ kd->key_data_kvno = kvnos[i]; -+ kd->key_data_type[0] = ks[j].ks_enctype; -+ kd->key_data_length[0] = kb.length; -+ kd->key_data_contents[0] = kb.contents; -+ kd->key_data_type[1] = ks[j].ks_salttype; -+ kd++; -+ } -+ } -+ -+ for (i = 0; i < nstrings; i++) -+ free(ks_lists[i]); -+ free(ks_lists); -+ free(ks_list_sizes); -+ free(kvnos); -+ ent->key_data = key_data; -+ ent->n_key_data = nkeys; -+} -+ -+static krb5_error_code -+test_init() -+{ -+ return 0; -+} -+ -+static krb5_error_code -+test_cleanup() -+{ -+ return 0; -+} -+ -+static krb5_error_code -+test_open(krb5_context context, char *conf_section, char **db_args, int mode) -+{ -+ testhandle h; -+ -+ h = ealloc(sizeof(*h)); -+ h->profile = context->profile; -+ h->section = estrdup(conf_section); -+ context->dal_handle->db_context = h; -+ return 0; -+} -+ -+static krb5_error_code -+test_close(krb5_context context) -+{ -+ testhandle h = context->dal_handle->db_context; -+ -+ free(h->section); -+ free(h); -+ return 0; -+} -+ -+static krb5_error_code -+test_get_principal(krb5_context context, krb5_const_principal search_for, -+ unsigned int flags, krb5_db_entry **entry) -+{ -+ krb5_error_code ret; -+ krb5_principal princ = NULL; -+ krb5_principal_data empty_princ = { KV5M_PRINCIPAL }; -+ testhandle h = context->dal_handle->db_context; -+ char *search_name = NULL, *canon = NULL, *flagstr, **names, **key_strings; -+ const char *ename; -+ krb5_db_entry *ent; -+ -+ *entry = NULL; -+ -+ check(krb5_unparse_name_flags(context, search_for, -+ KRB5_PRINCIPAL_UNPARSE_NO_REALM, -+ &search_name)); -+ canon = get_string(h, "alias", search_name, NULL); -+ if (canon != NULL) { -+ if (!(flags & KRB5_KDB_FLAG_ALIAS_OK)) { -+ ret = KRB5_KDB_NOENTRY; -+ goto cleanup; -+ } -+ check(krb5_parse_name(context, canon, &princ)); -+ if (!krb5_realm_compare(context, search_for, princ)) { -+ if (flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) { -+ /* Return a client referral by creating an entry with only the -+ * principal set. */ -+ *entry = ealloc(sizeof(**entry)); -+ (*entry)->princ = princ; -+ princ = NULL; -+ ret = 0; -+ goto cleanup; -+ } else { -+ /* We could look up a cross-realm TGS entry, but we don't need -+ * that behavior yet. */ -+ ret = KRB5_KDB_NOENTRY; -+ goto cleanup; -+ } -+ } -+ ename = canon; -+ } else { -+ check(krb5_copy_principal(context, search_for, &princ)); -+ ename = search_name; -+ } -+ -+ /* Check that the entry exists. */ -+ set_names(h, "princs", ename, NULL); -+ ret = profile_get_relation_names(h->profile, h->names, &names); -+ if (ret == PROF_NO_RELATION) { -+ ret = KRB5_KDB_NOENTRY; -+ goto cleanup; -+ } -+ profile_free_list(names); -+ -+ /* No error exits after this point. */ -+ -+ ent = ealloc(sizeof(*ent)); -+ ent->princ = princ; -+ princ = NULL; -+ -+ flagstr = get_string(h, "princs", ename, "flags"); -+ if (flagstr != NULL) { -+ check(krb5_flagspec_to_mask(flagstr, &ent->attributes, -+ &ent->attributes)); -+ } -+ free(flagstr); -+ -+ ent->max_life = get_duration(h, "princs", ename, "maxlife"); -+ ent->max_renewable_life = get_duration(h, "princs", ename, "maxrenewlife"); -+ ent->expiration = get_time(h, "princs", ename, "expiration"); -+ ent->pw_expiration = get_time(h, "princs", ename, "pwexpiration"); -+ -+ /* Leave last_success, last_failed, fail_auth_count zeroed. */ -+ /* Leave tl_data and e_data empty. */ -+ -+ set_names(h, "princs", ename, "keys"); -+ ret = profile_get_values(h->profile, h->names, &key_strings); -+ if (ret != PROF_NO_RELATION) { -+ make_keys(key_strings, ename, ent); -+ profile_free_list(key_strings); -+ } -+ -+ /* We must include mod-princ data or kadm5_get_principal() won't work and -+ * we can't extract keys with kadmin.local. */ -+ check(krb5_dbe_update_mod_princ_data(context, ent, 0, &empty_princ)); -+ -+ *entry = ent; -+ -+cleanup: -+ krb5_free_unparsed_name(context, search_name); -+ krb5_free_principal(context, princ); -+ free(canon); -+ return ret; -+} -+ -+static void -+test_free_principal(krb5_context context, krb5_db_entry *entry) -+{ -+ krb5_tl_data *tl, *next; -+ int i, j; -+ -+ if (entry == NULL) -+ return; -+ free(entry->e_data); -+ krb5_free_principal(context, entry->princ); -+ for (tl = entry->tl_data; tl != NULL; tl = next) { -+ next = tl->tl_data_next; -+ free(tl->tl_data_contents); -+ free(tl); -+ } -+ for (i = 0; i < entry->n_key_data; i++) { -+ for (j = 0; j < entry->key_data[i].key_data_ver; j++) { -+ if (entry->key_data[i].key_data_length[j]) { -+ zapfree(entry->key_data[i].key_data_contents[j], -+ entry->key_data[i].key_data_length[j]); -+ } -+ entry->key_data[i].key_data_contents[j] = NULL; -+ entry->key_data[i].key_data_length[j] = 0; -+ entry->key_data[i].key_data_type[j] = 0; -+ } -+ } -+ free(entry->key_data); -+ free(entry); -+} -+ -+static void * -+test_alloc(krb5_context context, void *ptr, size_t size) -+{ -+ return realloc(ptr, size); -+} -+ -+static void -+test_free(krb5_context context, void *ptr) -+{ -+ free(ptr); -+} -+ -+static krb5_error_code -+test_fetch_master_key(krb5_context context, krb5_principal mname, -+ krb5_keyblock *key_out, krb5_kvno *kvno_out, -+ char *db_args) -+{ -+ memset(key_out, 0, sizeof(*key_out)); -+ *kvno_out = 0; -+ return 0; -+} -+ -+static krb5_error_code -+test_fetch_master_key_list(krb5_context context, krb5_principal mname, -+ const krb5_keyblock *key, -+ krb5_keylist_node **mkeys_out) -+{ -+ /* krb5_dbe_get_mkvno() returns an error if we produce NULL, so return an -+ * empty node to make kadm5_get_principal() work. */ -+ *mkeys_out = ealloc(sizeof(**mkeys_out)); -+ return 0; -+} -+ -+static krb5_error_code -+test_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey, -+ const krb5_key_data *kd, krb5_keyblock *key_out, -+ krb5_keysalt *salt_out) -+{ -+ key_out->magic = KV5M_KEYBLOCK; -+ key_out->enctype = kd->key_data_type[0]; -+ key_out->length = kd->key_data_length[0]; -+ key_out->contents = ealloc(key_out->length); -+ memcpy(key_out->contents, kd->key_data_contents[0], key_out->length); -+ if (salt_out != NULL) { -+ salt_out->type = (kd->key_data_ver > 1) ? kd->key_data_type[1] : -+ KRB5_KDB_SALTTYPE_NORMAL; -+ salt_out->data = empty_data(); -+ } -+ return 0; -+} -+ -+static krb5_error_code -+test_encrypt_key_data(krb5_context context, const krb5_keyblock *mkey, -+ const krb5_keyblock *key, const krb5_keysalt *salt, -+ int kvno, krb5_key_data *kd_out) -+{ -+ memset(kd_out, 0, sizeof(*kd_out)); -+ kd_out->key_data_ver = 2; -+ kd_out->key_data_kvno = kvno; -+ kd_out->key_data_type[0] = key->enctype; -+ kd_out->key_data_length[0] = key->length; -+ kd_out->key_data_contents[0] = ealloc(key->length); -+ memcpy(kd_out->key_data_contents[0], key->contents, key->length); -+ kd_out->key_data_type[1] = (salt != NULL) ? salt->type : -+ KRB5_KDB_SALTTYPE_NORMAL; -+ return 0; -+} -+ -+static krb5_error_code -+test_check_allowed_to_delegate(krb5_context context, -+ krb5_const_principal client, -+ const krb5_db_entry *server, -+ krb5_const_principal proxy) -+{ -+ krb5_error_code ret; -+ testhandle h = context->dal_handle->db_context; -+ char *sprinc, *tprinc, **values, **v; -+ krb5_boolean found = FALSE; -+ -+ check(krb5_unparse_name_flags(context, server->princ, -+ KRB5_PRINCIPAL_UNPARSE_NO_REALM, &sprinc)); -+ check(krb5_unparse_name_flags(context, proxy, -+ KRB5_PRINCIPAL_UNPARSE_NO_REALM, &tprinc)); -+ set_names(h, "delegation", sprinc, NULL); -+ ret = profile_get_values(h->profile, h->names, &values); -+ if (ret == PROF_NO_RELATION) -+ return KRB5KDC_ERR_POLICY; -+ for (v = values; *v != NULL; v++) { -+ if (strcmp(*v, tprinc) == 0) { -+ found = TRUE; -+ break; -+ } -+ } -+ profile_free_list(values); -+ return found ? 0 : KRB5KDC_ERR_POLICY; -+} -+ -+kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_test, kdb_function_table) = { -+ KRB5_KDB_DAL_MAJOR_VERSION, /* major version number */ -+ 0, /* minor version number 0 */ -+ test_init, -+ test_cleanup, -+ test_open, -+ test_close, -+ NULL, /* create */ -+ NULL, /* destroy */ -+ NULL, /* get_age */ -+ NULL, /* lock */ -+ NULL, /* unlock */ -+ test_get_principal, -+ test_free_principal, -+ NULL, /* put_principal */ -+ NULL, /* delete_principal */ -+ NULL, /* iterate */ -+ NULL, /* create_policy */ -+ NULL, /* get_policy */ -+ NULL, /* put_policy */ -+ NULL, /* iter_policy */ -+ NULL, /* delete_policy */ -+ NULL, /* free_policy */ -+ test_alloc, -+ test_free, -+ test_fetch_master_key, -+ test_fetch_master_key_list, -+ NULL, /* store_master_key_list */ -+ NULL, /* dbe_search_enctype */ -+ NULL, /* change_pwd */ -+ NULL, /* promote_db */ -+ test_decrypt_key_data, -+ test_encrypt_key_data, -+ NULL, /* sign_authdata */ -+ NULL, /* check_transited_realms */ -+ NULL, /* check_policy_as */ -+ NULL, /* check_policy_tgs */ -+ NULL, /* audit_as_req */ -+ NULL, /* refresh_config */ -+ test_check_allowed_to_delegate -+}; -diff --git a/src/plugins/kdb/test/test.exports b/src/plugins/kdb/test/test.exports -new file mode 100644 -index 0000000..f2b7c11 ---- /dev/null -+++ b/src/plugins/kdb/test/test.exports -@@ -0,0 +1 @@ -+kdb_function_table diff --git a/SOURCES/krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad.patch b/SOURCES/krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad.patch deleted file mode 100644 index e17972b..0000000 --- a/SOURCES/krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 25e0656fdf9862faf9aa91288023776e9a47caad Mon Sep 17 00:00:00 2001 -From: Nathaniel McCallum -Date: Fri, 7 Aug 2015 15:35:58 -0400 -Subject: [PATCH] Do not allow stream socket retries in libkrad - -Before this patch, libkrad would follow the same exact logic for all -socket types when the retries parameter was non-zero. This meant that -when connecting with SOCK_STREAM, multiple requests were sent in case -of packet drops, which, of course, cannot happen for SOCK_STREAM. - -Instead, just disable retries for SOCK_STREAM sockets. - -[ghudson@mit.edu: minor wording edits] - -ticket: 8229 (new) -target_version: 1.13.3 -tags: pullup ---- -Patch for RH Bug #1251586 ("KDC sends multiple requests to ipa-otpd -for the same authentication") ---- - src/include/krad.h | 3 ++- - src/lib/krad/remote.c | 3 +++ - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/include/krad.h b/src/include/krad.h -index 913464c..e4edb52 100644 ---- a/src/include/krad.h -+++ b/src/include/krad.h -@@ -251,7 +251,8 @@ krad_client_free(krad_client *client); - * - hostname:service - * - * The timeout parameter (milliseconds) is the total timeout across all remote -- * hosts (when DNS returns multiple entries) and all retries. -+ * hosts (when DNS returns multiple entries) and all retries. For stream -+ * sockets, the retries parameter is ignored and no retries are performed. - * - * The cb function will be called with the data argument when either a response - * is received or the request times out on all possible remote hosts. -diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c -index 795485f..aaabffd 100644 ---- a/src/lib/krad/remote.c -+++ b/src/lib/krad/remote.c -@@ -448,6 +448,9 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs, - krb5_error_code retval; - request *r; - -+ if (rr->info->ai_socktype == SOCK_STREAM) -+ retries = 0; -+ - r = TAILQ_FIRST(&rr->list); - retval = krad_packet_new_request(rr->kctx, rr->secret, code, attrs, - (krad_packet_iter_cb)iterator, &r, &tmp); diff --git a/SOURCES/krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch b/SOURCES/krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch deleted file mode 100644 index 7757885..0000000 --- a/SOURCES/krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 95c3cab051aa1b8b4f7eb309bf135e8f51665baa Mon Sep 17 00:00:00 2001 -From: Nathaniel McCallum -Date: Sun, 25 Jan 2015 16:53:49 -0500 -Subject: [PATCH] Support KDC_ERR_MORE_PREAUTH_DATA_REQUIRED - -Add support for multi-hop preauth mechs. - -In the KDC, allow kdcpreauth modules to return -KDC_ERR_MORE_PREAUTH_DATA_REQUIRED as defined in RFC 6113. - -In libkrb5, treat this code like KDC_ERR_PREAUTH_REQUIRED. clpreauth -modules can use the modreq parameter to distinguish between the first -and subsequent KDC messages. We assume that the error padata will -include an element of the preauth mech's type, or at least of a type -recognized by the clpreauth module. - -Also reset the list of previously attempted preauth types for both -kinds of errors. That list is really only appropriate for retrying -after a failed preauth attempt, which we don't currently do. Add an -intermediate variable for the reply code to avoid a long conditional -expression. - -[ghudson@mit.edu: adjust get_in_tkt.c logic to avoid needing a helper -function; clarify commit message] - -ticket: 8063 (new) ---- - doc/plugindev/clpreauth.rst | 6 +++--- - src/include/k5-int.h | 1 + - src/kdc/kdc_preauth.c | 2 ++ - src/lib/krb5/error_tables/krb5_err.et | 2 +- - src/lib/krb5/krb/get_in_tkt.c | 13 ++++++++----- - 5 files changed, 15 insertions(+), 9 deletions(-) - -diff --git a/doc/plugindev/clpreauth.rst b/doc/plugindev/clpreauth.rst -index c3e7298..38aa52e 100644 ---- a/doc/plugindev/clpreauth.rst -+++ b/doc/plugindev/clpreauth.rst -@@ -21,9 +21,9 @@ A clpreauth module is generally responsible for: - just returns ``PA_REAL``, indicating that it implements a normal - preauthentication type. - --* Examining the padata information included in the preauth_required -- error and producing padata values for the next AS request. This is -- done with the **process** method. -+* Examining the padata information included in a PREAUTH_REQUIRED or -+ MORE_PREAUTH_DATA_REQUIRED error and producing padata values for the -+ next AS request. This is done with the **process** method. - - * Examining the padata information included in a successful ticket - reply, possibly verifying the KDC identity and computing a reply -diff --git a/src/include/k5-int.h b/src/include/k5-int.h -index a1ea25a..4868e7d 100644 ---- a/src/include/k5-int.h -+++ b/src/include/k5-int.h -@@ -391,6 +391,7 @@ typedef unsigned char u_char; - not find a KDC */ - #define KRB_AP_ERR_IAKERB_KDC_NO_RESPONSE 86 /* The KDC did not respond - to the IAKERB proxy */ -+#define KDC_ERR_MORE_PREAUTH_DATA_REQUIRED 91 /* RFC 6113 */ - #define KRB_ERR_MAX 127 /* err table base max offset for protocol err codes */ - - /* -diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c -index 50cc252..dd83844 100644 ---- a/src/kdc/kdc_preauth.c -+++ b/src/kdc/kdc_preauth.c -@@ -1000,6 +1000,8 @@ finish_check_padata(struct padata_state *state, krb5_error_code code) - case KRB5KDC_ERR_DISCARD: - /* pkinit alg-agility */ - case KRB5KDC_ERR_NO_ACCEPTABLE_KDF: -+ /* rfc 6113 */ -+ case KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED: - (*oldrespond)(oldarg, code); - return; - default: -diff --git a/src/lib/krb5/error_tables/krb5_err.et b/src/lib/krb5/error_tables/krb5_err.et -index 5c6f10b..7ba7c1e 100644 ---- a/src/lib/krb5/error_tables/krb5_err.et -+++ b/src/lib/krb5/error_tables/krb5_err.et -@@ -132,7 +132,7 @@ error_code KRB5PLACEHOLD_87, "KRB5 error code 87" - error_code KRB5PLACEHOLD_88, "KRB5 error code 88" - error_code KRB5PLACEHOLD_89, "KRB5 error code 89" - error_code KRB5PLACEHOLD_90, "KRB5 error code 90" --error_code KRB5PLACEHOLD_91, "KRB5 error code 91" -+error_code KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, "More preauthentication data is required" - error_code KRB5PLACEHOLD_92, "KRB5 error code 92" - error_code KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION, "An unsupported critical FAST option was requested" - error_code KRB5PLACEHOLD_94, "KRB5 error code 94" -diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c -index f9bc027..fa8afcc 100644 ---- a/src/lib/krb5/krb/get_in_tkt.c -+++ b/src/lib/krb5/krb/get_in_tkt.c -@@ -1239,7 +1239,8 @@ init_creds_step_request(krb5_context context, - clear_cc_config_out_data(context, ctx); - - if (ctx->err_reply == NULL) { -- /* either our first attempt, or retrying after PREAUTH_NEEDED */ -+ /* Either our first attempt, or retrying after KDC_ERR_PREAUTH_REQUIRED -+ * or KDC_ERR_MORE_PREAUTH_DATA_REQUIRED. */ - code = k5_preauth(context, ctx, ctx->preauth_to_use, - ctx->preauth_required, &ctx->request->padata, - &ctx->selected_preauth_type); -@@ -1408,6 +1409,7 @@ init_creds_step_reply(krb5_context context, - krb5_preauthtype kdc_pa_type; - krb5_boolean retry = FALSE; - int canon_flag = 0; -+ uint32_t reply_code; - krb5_keyblock *strengthen_key = NULL; - krb5_keyblock encrypting_key; - krb5_boolean fast_avail; -@@ -1431,6 +1433,7 @@ init_creds_step_reply(krb5_context context, - &retry); - if (code != 0) - goto cleanup; -+ reply_code = ctx->err_reply->error; - if (negotiation_requests_restart(context, ctx, ctx->err_padata)) { - ctx->have_restarted = 1; - k5_preauth_request_context_fini(context); -@@ -1441,9 +1444,10 @@ init_creds_step_reply(krb5_context context, - ctx->err_reply = NULL; - krb5_free_pa_data(context, ctx->err_padata); - ctx->err_padata = NULL; -- } else if (ctx->err_reply->error == KDC_ERR_PREAUTH_REQUIRED && -- retry) { -+ } else if ((reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED || -+ reply_code == KDC_ERR_PREAUTH_REQUIRED) && retry) { - /* reset the list of preauth types to try */ -+ k5_reset_preauth_types_tried(context); - krb5_free_pa_data(context, ctx->preauth_to_use); - ctx->preauth_to_use = ctx->err_padata; - ctx->err_padata = NULL; -@@ -1480,8 +1484,7 @@ init_creds_step_reply(krb5_context context, - code = 0; - } else { - /* error + no hints = give up */ -- code = (krb5_error_code)ctx->err_reply->error + -- ERROR_TABLE_BASE_krb5; -+ code = (krb5_error_code)reply_code + ERROR_TABLE_BASE_krb5; - } - } - diff --git a/SOURCES/krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch b/SOURCES/krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch deleted file mode 100644 index 2aa2b93..0000000 --- a/SOURCES/krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch +++ /dev/null @@ -1,22 +0,0 @@ -# Fix for RH Bug #1250154 ("[s390x, ppc64, ppc64le]: kadmind does not -# accept ACL if kadm5.acl does not end with EOL") -# The code "accidently" works on x86/AMD64 because declaring a variable -# |char| results in an |unsigned char| by default while most other platforms -# (e.g. { s390x, ppc64, ppc64le, ...} ) default to |signed char|. -# Lesson learned: Use lint(1) for development by default (saying that -# because Sun Studio lint(1) has found 38 more of these issues in -# krb1.13.2... ;-( ) -# Written by Roland Mainz ---- a/src/lib/kadm5/srv/server_acl.c -+++ b/src/lib/kadm5/srv/server_acl.c -@@ -115,7 +115,7 @@ - int byte; - byte = fgetc(fp); - acl_buf[i] = byte; -- if (byte == (char)EOF) { -+ if (byte == EOF) { - if (i > 0 && acl_buf[i-1] == '\\') - i--; - break; /* it gets nulled-out below */ - - diff --git a/SOURCES/krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch b/SOURCES/krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch deleted file mode 100644 index 72ee35b..0000000 --- a/SOURCES/krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch +++ /dev/null @@ -1,205 +0,0 @@ -# Note: This file contains TWO patches, first the fix for the original -# issue and then the valgrind fixes (modifed from the upstream commit -# to match krb5 1.13.2) -####################################################################### -#### Patch1: -From 50f426ac17a81ff5b7c212c24645b9874ea911f0 Mon Sep 17 00:00:00 2001 -From: Simo Sorce -Date: Mon, 17 Aug 2015 13:21:42 -0400 -Subject: [PATCH] Resolve krb5 GSS creds if time_rec is requested - -The code normally tries to defer credential acquisition to a later -time. However, if the application requests the lifetime, the code -needs to resolve the credential and return the actual expiration time. -Returning 0 would cause the application to think credentials are -expired. - -In the mechglue, pass through null time_rec pointers to the mech so -that the mech knows whether it was requested. In SPNEGO, pass through -time_rec to the mech when acquiring creds, via a new parameter to -get_available_mechs(). - -[ghudson@mit.edu: minor style changes; edit and expand commit message] - -ticket: 8235 (new) ---- -# Comments: -# - Added to fix RedHat bug #1252454 ('testsuite complains "Lifetime has -# increased by 32436 sec while 0 sec passed!", while rhel5-libkrb5 passes') -# - Original upstream URL https://github.com/krb5/krb5/commit/50f426ac17a81ff5b7c212c24645b9874ea911f0 ---- - src/lib/gssapi/krb5/acquire_cred.c | 9 ++++++++- - src/lib/gssapi/mechglue/g_acquire_cred.c | 14 +++++++++----- - src/lib/gssapi/spnego/spnego_mech.c | 15 ++++++++------- - 3 files changed, 25 insertions(+), 13 deletions(-) - -diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c -index 5bcfec9..6e83fb9 100644 ---- a/src/lib/gssapi/krb5/acquire_cred.c -+++ b/src/lib/gssapi/krb5/acquire_cred.c -@@ -825,8 +825,15 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, - if (code != 0) - goto krb_error_out; - -- if (time_rec) -+ if (time_rec) { -+ /* Resolve cred now to determine the expiration time. */ -+ ret = kg_cred_resolve(minor_status, context, (gss_cred_id_t)cred, -+ GSS_C_NO_NAME); -+ if (GSS_ERROR(ret)) -+ goto error_out; - *time_rec = (cred->expire > now) ? (cred->expire - now) : 0; -+ k5_mutex_unlock(&cred->lock); -+ } - } - - *minor_status = 0; -diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c -index ff250de..d29856c 100644 ---- a/src/lib/gssapi/mechglue/g_acquire_cred.c -+++ b/src/lib/gssapi/mechglue/g_acquire_cred.c -@@ -190,8 +190,9 @@ OM_uint32 * time_rec; - major = gss_add_cred_from(&tmpMinor, (gss_cred_id_t)creds, - desired_name, &mechs->elements[i], - cred_usage, time_req, time_req, -- cred_store, NULL, NULL, &initTimeOut, -- &acceptTimeOut); -+ cred_store, NULL, NULL, -+ time_rec ? &initTimeOut : NULL, -+ time_rec ? &acceptTimeOut : NULL); - if (major == GSS_S_COMPLETE) { - /* update the credential's time */ - if (cred_usage == GSS_C_ACCEPT) { -@@ -356,7 +357,7 @@ gss_add_cred_from(minor_status, input_cred_handle, - OM_uint32 *acceptor_time_rec; - { - OM_uint32 status, temp_minor_status; -- OM_uint32 time_req, time_rec; -+ OM_uint32 time_req, time_rec = 0, *time_recp = NULL; - gss_union_name_t union_name; - gss_union_cred_t new_union_cred, union_cred; - gss_name_t internal_name = GSS_C_NO_NAME; -@@ -447,15 +448,18 @@ gss_add_cred_from(minor_status, input_cred_handle, - if (status != GSS_S_COMPLETE) - goto errout; - -+ if (initiator_time_rec != NULL || acceptor_time_rec != NULL) -+ time_recp = &time_rec; -+ - if (mech->gss_acquire_cred_from) { - status = mech->gss_acquire_cred_from(minor_status, internal_name, - time_req, target_mechs, - cred_usage, cred_store, &cred, -- NULL, &time_rec); -+ NULL, time_recp); - } else if (cred_store == GSS_C_NO_CRED_STORE) { - status = mech->gss_acquire_cred(minor_status, internal_name, time_req, - target_mechs, cred_usage, &cred, NULL, -- &time_rec); -+ time_recp); - } else { - return GSS_S_UNAVAILABLE; - } -diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c -index 8ade245..f3d5f09 100644 ---- a/src/lib/gssapi/spnego/spnego_mech.c -+++ b/src/lib/gssapi/spnego/spnego_mech.c -@@ -96,7 +96,8 @@ static gss_OID_set get_mech_set(OM_uint32 *, unsigned char **, unsigned int); - static OM_uint32 get_req_flags(unsigned char **, OM_uint32, OM_uint32 *); - static OM_uint32 get_available_mechs(OM_uint32 *, gss_name_t, gss_cred_usage_t, - gss_const_key_value_set_t, -- gss_cred_id_t *, gss_OID_set *); -+ gss_cred_id_t *, gss_OID_set *, -+ OM_uint32 *); - static OM_uint32 get_negotiable_mechs(OM_uint32 *, spnego_gss_cred_id_t, - gss_cred_usage_t, gss_OID_set *); - static void release_spnego_ctx(spnego_gss_ctx_id_t *); -@@ -399,7 +400,7 @@ spnego_gss_acquire_cred_from(OM_uint32 *minor_status, - */ - status = get_available_mechs(minor_status, desired_name, - cred_usage, cred_store, &mcred, -- &amechs); -+ &amechs, time_rec); - - if (actual_mechs && amechs != GSS_C_NULL_OID_SET) { - (void) gssint_copy_oid_set(&tmpmin, amechs, actual_mechs); -@@ -2009,7 +2010,7 @@ spnego_gss_inquire_cred( - GSS_C_BOTH, - GSS_C_NO_CRED_STORE, - &creds, -- mechanisms); -+ mechanisms, NULL); - if (status != GSS_S_COMPLETE) { - dsyslog("Leaving inquire_cred\n"); - return (status); -@@ -2637,7 +2638,7 @@ spnego_gss_acquire_cred_with_password(OM_uint32 *minor_status, - - status = get_available_mechs(minor_status, desired_name, - cred_usage, GSS_C_NO_CRED_STORE, -- NULL, &amechs); -+ NULL, &amechs, NULL); - if (status != GSS_S_COMPLETE) - goto cleanup; - -@@ -3006,7 +3007,7 @@ static OM_uint32 - get_available_mechs(OM_uint32 *minor_status, - gss_name_t name, gss_cred_usage_t usage, - gss_const_key_value_set_t cred_store, -- gss_cred_id_t *creds, gss_OID_set *rmechs) -+ gss_cred_id_t *creds, gss_OID_set *rmechs, OM_uint32 *time_rec) - { - unsigned int i; - int found = 0; -@@ -3060,7 +3061,7 @@ get_available_mechs(OM_uint32 *minor_status, - GSS_C_INDEFINITE, - *rmechs, usage, - cred_store, creds, -- &goodmechs, NULL); -+ &goodmechs, time_rec); - - /* - * Drop the old list in favor of the new -@@ -3110,7 +3111,7 @@ get_negotiable_mechs(OM_uint32 *minor_status, spnego_gss_cred_id_t spcred, - credptr = (usage == GSS_C_INITIATE) ? &creds : NULL; - ret = get_available_mechs(minor_status, GSS_C_NO_NAME, usage, - GSS_C_NO_CRED_STORE, credptr, -- rmechs); -+ rmechs, NULL); - gss_release_cred(&tmpmin, &creds); - return (ret); - } -####################################################################### -#### Patch2: -From 042e9fc95a662acb54dc9168749c6725f17ae34a Mon Sep 17 00:00:00 2001 -From: Simo Sorce -Date: Fri, 21 Aug 2015 12:16:07 -0400 -Subject: [PATCH] Keep valgrind happy after time_rec change - -In gss_acquire_cred_from(), initialize initTimeOut and acceptTimeOut -so valgrind does not complain. All these values are ignored if -time_rec is NULL, so not having those variables initialized is -harmless, but it is annoying to get noise in the valgrind output. - -[ghudson@mit.edu: clarify commit message] - -ticket: 8235 ---- -# Comments: -# - modifed by Roland Mainz to match krb5 1.13.2 ---- - src/lib/gssapi/mechglue/g_acquire_cred.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c -index d29856c..9bd500b 100644 ---- a/src/lib/gssapi/mechglue/g_acquire_cred.c -+++ b/src/lib/gssapi/mechglue/g_acquire_cred.c -@@ -133,7 +133,7 @@ OM_uint32 * time_rec; - { - OM_uint32 major = GSS_S_FAILURE, tmpMinor; - OM_uint32 first_major = GSS_S_COMPLETE, first_minor = 0; -- OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE; -+ OM_uint32 initTimeOut = 0, acceptTimeOut = 0, outTime = GSS_C_INDEFINITE; - gss_OID_set mechs = GSS_C_NO_OID_SET; - unsigned int i; - gss_union_cred_t creds = NULL; diff --git a/SOURCES/krb5-1.14.1-selinux-label.patch b/SOURCES/krb5-1.14.1-selinux-label.patch new file mode 100644 index 0000000..e3585c7 --- /dev/null +++ b/SOURCES/krb5-1.14.1-selinux-label.patch @@ -0,0 +1,1065 @@ +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 new file mode 100644 index 0000000..e42bf86 --- /dev/null +++ b/SOURCES/krb5-1.14.1.tar.gz.asc @@ -0,0 +1,14 @@ +-----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 new file mode 100644 index 0000000..0fb965c --- /dev/null +++ b/SOURCES/krb5-1.14.2-log_file_mode.patch @@ -0,0 +1,63 @@ +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 new file mode 100644 index 0000000..b3e9af6 --- /dev/null +++ b/SOURCES/krb5-1.14.2-skip_unnecessary_mech_inquire_cred.patch @@ -0,0 +1,79 @@ +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 new file mode 100644 index 0000000..0a47bf0 --- /dev/null +++ b/SOURCES/krb5-1.14.3-fix_otp_as_key.patch @@ -0,0 +1,50 @@ +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 new file mode 100644 index 0000000..9016c88 --- /dev/null +++ b/SOURCES/krb5-1.14.3-krad-recv.patch @@ -0,0 +1,44 @@ +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 new file mode 100644 index 0000000..356f2c7 --- /dev/null +++ b/SOURCES/krb5-1.14.3-ksu_root_prompt.patch @@ -0,0 +1,43 @@ +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 new file mode 100644 index 0000000..fa412aa --- /dev/null +++ b/SOURCES/krb5-1.14.4-CVE-2016-3120.patch @@ -0,0 +1,57 @@ +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 new file mode 100644 index 0000000..c6693c4 --- /dev/null +++ b/SOURCES/krb5-1.14.4-Fix-responder-without-preauth.patch @@ -0,0 +1,86 @@ +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 new file mode 100644 index 0000000..a34faad --- /dev/null +++ b/SOURCES/krb5-1.14.4-SNI-HTTP-Host.patch @@ -0,0 +1,108 @@ +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 new file mode 100644 index 0000000..9a61843 --- /dev/null +++ b/SOURCES/krb5-1.15-NTLM_SPNEGO.patch @@ -0,0 +1,97 @@ +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-fix_t_kprop.patch b/SOURCES/krb5-1.15-fix_t_kprop.patch new file mode 100644 index 0000000..c43fdbe --- /dev/null +++ b/SOURCES/krb5-1.15-fix_t_kprop.patch @@ -0,0 +1,51 @@ +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 new file mode 100644 index 0000000..dc9db7a --- /dev/null +++ b/SOURCES/krb5-1.15-hide_deperecated_on_indicate.patch @@ -0,0 +1,89 @@ +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 new file mode 100644 index 0000000..c96a851 --- /dev/null +++ b/SOURCES/krb5-1.15-kadmin-kprop-port-test.patch @@ -0,0 +1,32 @@ +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 new file mode 100644 index 0000000..2f5f6e8 --- /dev/null +++ b/SOURCES/krb5-1.15-kadmin-kprop-port.patch @@ -0,0 +1,111 @@ +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 new file mode 100644 index 0000000..f17e495 --- /dev/null +++ b/SOURCES/krb5-1.15-kprop-debug-argument-order.patch @@ -0,0 +1,26 @@ +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 new file mode 100644 index 0000000..854bddd --- /dev/null +++ b/SOURCES/krb5-1.15-kprop-iprop-default_realm-tests.patch @@ -0,0 +1,319 @@ +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 new file mode 100644 index 0000000..d7c1242 --- /dev/null +++ b/SOURCES/krb5-1.15-kprop-kpropd-realm.patch @@ -0,0 +1,366 @@ +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-CVE-2015-8629.patch b/SOURCES/krb5-CVE-2015-8629.patch deleted file mode 100644 index 2eb0edd..0000000 --- a/SOURCES/krb5-CVE-2015-8629.patch +++ /dev/null @@ -1,48 +0,0 @@ -From df17a1224a3406f57477bcd372c61e04c0e5a5bb Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Fri, 8 Jan 2016 12:45:25 -0500 -Subject: [PATCH 1/3] Verify decoded kadmin C strings [CVE-2015-8629] - -In xdr_nullstring(), check that the decoded string is terminated with -a zero byte and does not contain any internal zero bytes. - -CVE-2015-8629: - -In all versions of MIT krb5, an authenticated attacker can cause -kadmind to read beyond the end of allocated memory by sending a string -without a terminating zero byte. Information leakage may be possible -for an attacker with permission to modify the database. - - CVSSv2 Vector: AV:N/AC:H/Au:S/C:P/I:N/A:N/E:POC/RL:OF/RC:C - -ticket: 8341 (new) -target_version: 1.14-next -target_version: 1.13-next -tags: pullup ---- - src/lib/kadm5/kadm_rpc_xdr.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c -index 2bef858..ba67084 100644 ---- a/src/lib/kadm5/kadm_rpc_xdr.c -+++ b/src/lib/kadm5/kadm_rpc_xdr.c -@@ -64,7 +64,14 @@ bool_t xdr_nullstring(XDR *xdrs, char **objp) - return FALSE; - } - } -- return (xdr_opaque(xdrs, *objp, size)); -+ if (!xdr_opaque(xdrs, *objp, size)) -+ return FALSE; -+ /* Check that the unmarshalled bytes are a C string. */ -+ if ((*objp)[size - 1] != '\0') -+ return FALSE; -+ if (memchr(*objp, '\0', size - 1) != NULL) -+ return FALSE; -+ return TRUE; - - case XDR_ENCODE: - if (size != 0) --- -2.7.0.rc3 - diff --git a/SOURCES/krb5-CVE-2015-8630.patch b/SOURCES/krb5-CVE-2015-8630.patch deleted file mode 100644 index 7908969..0000000 --- a/SOURCES/krb5-CVE-2015-8630.patch +++ /dev/null @@ -1,78 +0,0 @@ -From b863de7fbf080b15e347a736fdda0a82d42f4f6b Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Fri, 8 Jan 2016 12:52:28 -0500 -Subject: [PATCH 2/3] Check for null kadm5 policy name [CVE-2015-8630] - -In kadm5_create_principal_3() and kadm5_modify_principal(), check for -entry->policy being null when KADM5_POLICY is included in the mask. - -CVE-2015-8630: - -In MIT krb5 1.12 and later, an authenticated attacker with permission -to modify a principal entry can cause kadmind to dereference a null -pointer by supplying a null policy value but including KADM5_POLICY in -the mask. - - CVSSv2 Vector: AV:N/AC:H/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C - -ticket: 8342 (new) -target_version: 1.14-next -target_version: 1.13-next -tags: pullup ---- - src/lib/kadm5/srv/svr_principal.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c -index 5b95fa3..1d4365c 100644 ---- a/src/lib/kadm5/srv/svr_principal.c -+++ b/src/lib/kadm5/srv/svr_principal.c -@@ -395,6 +395,8 @@ kadm5_create_principal_3(void *server_handle, - /* - * Argument sanity checking, and opening up the DB - */ -+ if (entry == NULL) -+ return EINVAL; - if(!(mask & KADM5_PRINCIPAL) || (mask & KADM5_MOD_NAME) || - (mask & KADM5_MOD_TIME) || (mask & KADM5_LAST_PWD_CHANGE) || - (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) || -@@ -403,12 +405,12 @@ kadm5_create_principal_3(void *server_handle, - return KADM5_BAD_MASK; - if ((mask & KADM5_KEY_DATA) && entry->n_key_data != 0) - return KADM5_BAD_MASK; -+ if((mask & KADM5_POLICY) && entry->policy == NULL) -+ return KADM5_BAD_MASK; - if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR)) - return KADM5_BAD_MASK; - if((mask & ~ALL_PRINC_MASK)) - return KADM5_BAD_MASK; -- if (entry == NULL) -- return EINVAL; - - /* - * Check to see if the principal exists -@@ -643,6 +645,8 @@ kadm5_modify_principal(void *server_handle, - - krb5_clear_error_message(handle->context); - -+ if(entry == NULL) -+ return EINVAL; - if((mask & KADM5_PRINCIPAL) || (mask & KADM5_LAST_PWD_CHANGE) || - (mask & KADM5_MOD_TIME) || (mask & KADM5_MOD_NAME) || - (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) || -@@ -651,10 +655,10 @@ kadm5_modify_principal(void *server_handle, - return KADM5_BAD_MASK; - if((mask & ~ALL_PRINC_MASK)) - return KADM5_BAD_MASK; -+ if((mask & KADM5_POLICY) && entry->policy == NULL) -+ return KADM5_BAD_MASK; - if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR)) - return KADM5_BAD_MASK; -- if(entry == (kadm5_principal_ent_t) NULL) -- return EINVAL; - if (mask & KADM5_TL_DATA) { - tl_data_orig = entry->tl_data; - while (tl_data_orig) { --- -2.7.0.rc3 - diff --git a/SOURCES/krb5-CVE-2015-8631.patch b/SOURCES/krb5-CVE-2015-8631.patch deleted file mode 100644 index cd5efd5..0000000 --- a/SOURCES/krb5-CVE-2015-8631.patch +++ /dev/null @@ -1,573 +0,0 @@ -From 83ed75feba32e46f736fcce0d96a0445f29b96c2 Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Fri, 8 Jan 2016 13:16:54 -0500 -Subject: [PATCH 3/3] Fix leaks in kadmin server stubs [CVE-2015-8631] - -In each kadmind server stub, initialize the client_name and -server_name variables, and release them in the cleanup handler. Many -of the stubs will otherwise leak the client and server name if -krb5_unparse_name() fails. Also make sure to free the prime_arg -variables in rename_principal_2_svc(), or we can leak the first one if -unparsing the second one fails. Discovered by Simo Sorce. - -CVE-2015-8631: - -In all versions of MIT krb5, an authenticated attacker can cause -kadmind to leak memory by supplying a null principal name in a request -which uses one. Repeating these requests will eventually cause -kadmind to exhaust all available memory. - - CVSSv2 Vector: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C - -ticket: 8343 (new) -target_version: 1.14-next -target_version: 1.13-next -tags: pullup ---- - src/kadmin/server/server_stubs.c | 151 ++++++++++++++++++++------------------- - 1 file changed, 77 insertions(+), 74 deletions(-) - -diff --git a/src/kadmin/server/server_stubs.c b/src/kadmin/server/server_stubs.c -index 1879dc6..6ac797e 100644 ---- a/src/kadmin/server/server_stubs.c -+++ b/src/kadmin/server/server_stubs.c -@@ -334,7 +334,8 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - restriction_t *rp; -@@ -382,10 +383,10 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - } - free(prime_arg); -- gss_release_buffer(&minor_stat, &client_name); -- gss_release_buffer(&minor_stat, &service_name); - - exit_func: -+ gss_release_buffer(&minor_stat, &client_name); -+ gss_release_buffer(&minor_stat, &service_name); - free_server_handle(handle); - return &ret; - } -@@ -395,7 +396,8 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - restriction_t *rp; -@@ -444,10 +446,10 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - } - free(prime_arg); -- gss_release_buffer(&minor_stat, &client_name); -- gss_release_buffer(&minor_stat, &service_name); - - exit_func: -+ gss_release_buffer(&minor_stat, &client_name); -+ gss_release_buffer(&minor_stat, &service_name); - free_server_handle(handle); - return &ret; - } -@@ -457,8 +459,8 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -501,10 +503,10 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp) - - } - free(prime_arg); -- gss_release_buffer(&minor_stat, &client_name); -- gss_release_buffer(&minor_stat, &service_name); - - exit_func: -+ gss_release_buffer(&minor_stat, &client_name); -+ gss_release_buffer(&minor_stat, &service_name); - free_server_handle(handle); - return &ret; - } -@@ -514,8 +516,8 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - restriction_t *rp; -@@ -559,9 +561,9 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - } - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -570,10 +572,9 @@ generic_ret * - rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; -- char *prime_arg1, -- *prime_arg2; -- gss_buffer_desc client_name, -- service_name; -+ char *prime_arg1 = NULL, *prime_arg2 = NULL; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - restriction_t *rp; -@@ -655,11 +656,11 @@ rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - - } -+exit_func: - free(prime_arg1); - free(prime_arg2); - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -669,8 +670,8 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp) - { - static gprinc_ret ret; - char *prime_arg, *funcname; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -719,9 +720,9 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - } - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -731,8 +732,8 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp) - { - static gprincs_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -777,9 +778,9 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - - } -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -789,8 +790,8 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -840,9 +841,9 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp) - } - - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -852,8 +853,8 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -909,9 +910,9 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp) - } - - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -921,8 +922,8 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -969,9 +970,9 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp) - } - - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -981,8 +982,8 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1029,9 +1030,9 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp) - } - - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1041,8 +1042,8 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1092,9 +1093,9 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp) - } - - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1106,8 +1107,8 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp) - krb5_keyblock *k; - int nkeys; - char *prime_arg, *funcname; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1164,9 +1165,9 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - } - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1178,8 +1179,8 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp) - krb5_keyblock *k; - int nkeys; - char *prime_arg, *funcname; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1241,9 +1242,9 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - } - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1253,8 +1254,8 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1295,9 +1296,9 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp) - if (errmsg != NULL) - krb5_free_error_message(handle->context, errmsg); - } -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1307,8 +1308,8 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1347,9 +1348,9 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp) - if (errmsg != NULL) - krb5_free_error_message(handle->context, errmsg); - } -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1359,8 +1360,8 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1400,9 +1401,9 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp) - if (errmsg != NULL) - krb5_free_error_message(handle->context, errmsg); - } -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1413,8 +1414,8 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp) - static gpol_ret ret; - kadm5_ret_t ret2; - char *prime_arg, *funcname; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_principal_ent_rec caller_ent; - kadm5_server_handle_t handle; -@@ -1475,9 +1476,9 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp) - log_unauth(funcname, prime_arg, - &client_name, &service_name, rqstp); - } -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - -@@ -1488,8 +1489,8 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp) - { - static gpols_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1531,9 +1532,9 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp) - if (errmsg != NULL) - krb5_free_error_message(handle->context, errmsg); - } -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1541,7 +1542,8 @@ exit_func: - getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) - { - static getprivs_ret ret; -- gss_buffer_desc client_name, service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1571,9 +1573,9 @@ getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) - if (errmsg != NULL) - krb5_free_error_message(handle->context, errmsg); - -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1583,7 +1585,8 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg, *funcname; -- gss_buffer_desc client_name, service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - -@@ -1629,9 +1632,9 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - } - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1641,8 +1644,8 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp) - { - static gstrings_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1688,9 +1691,9 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - } - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1700,8 +1703,8 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp) - { - static generic_ret ret; - char *prime_arg; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - OM_uint32 minor_stat; - kadm5_server_handle_t handle; - const char *errmsg = NULL; -@@ -1744,9 +1747,9 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp) - krb5_free_error_message(handle->context, errmsg); - } - free(prime_arg); -+exit_func: - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); --exit_func: - free_server_handle(handle); - return &ret; - } -@@ -1754,8 +1757,8 @@ exit_func: - generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) - { - static generic_ret ret; -- gss_buffer_desc client_name, -- service_name; -+ gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; -+ gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; - kadm5_server_handle_t handle; - OM_uint32 minor_stat; - const char *errmsg = NULL; -@@ -1797,10 +1800,10 @@ generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) - rqstp->rq_cred.oa_flavor); - if (errmsg != NULL) - krb5_free_error_message(NULL, errmsg); -- gss_release_buffer(&minor_stat, &client_name); -- gss_release_buffer(&minor_stat, &service_name); - - exit_func: -+ gss_release_buffer(&minor_stat, &client_name); -+ gss_release_buffer(&minor_stat, &service_name); - return(&ret); - } - --- -2.7.0.rc3 - diff --git a/SOURCES/krb5-CVE-2016-3119.patch b/SOURCES/krb5-CVE-2016-3119.patch new file mode 100644 index 0000000..2624d57 --- /dev/null +++ b/SOURCES/krb5-CVE-2016-3119.patch @@ -0,0 +1,41 @@ +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 new file mode 100644 index 0000000..fa1c532 --- /dev/null +++ b/SOURCES/krb5-acquire_cred_interposer.patch @@ -0,0 +1,222 @@ +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 9f81bd8..7ecb9f1 100644 --- a/SOURCES/krb5-kadm5clntmit_libsoname_version_downgrade.patch +++ b/SOURCES/krb5-kadm5clntmit_libsoname_version_downgrade.patch @@ -1,10 +1,13 @@ +This patch is a hack so that we can rebase krb5 without breaking all +of our stricter dependents. + --- a/src/lib/kadm5/clnt/Makefile.in +++ b/src/lib/kadm5/clnt/Makefile.in @@ -3,7 +3,7 @@ LOCALINCLUDES = -I$(BUILDTOP)/include/kadm5 LIBBASE=kadm5clnt_mit --LIBMAJOR=9 +-LIBMAJOR=10 +LIBMAJOR=8 LIBMINOR=0 STOBJLISTS=../OBJS.ST OBJS.ST diff --git a/SOURCES/krb5-kvno-230379.patch b/SOURCES/krb5-kvno-230379.patch index ea9b69f..46eda22 100644 --- a/SOURCES/krb5-kvno-230379.patch +++ b/SOURCES/krb5-kvno-230379.patch @@ -8,6 +8,8 @@ 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. +[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) @@ -43,11 +45,11 @@ 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 @@ - higher than that. Short-term workaround: only compare - the low 8 bits. */ - -- if (new_entry.vno == (kvno & 0xff)) { -+ if (new_entry.vno == (kvno & 0xff) || new_entry.vno == IGNORE_VNO) { + * Otherwise, remember that we were here so we can return the right + * error, and free the new. + */ +- if (new_entry.vno == kvno) { ++ if (new_entry.vno == kvno || new_entry.vno == IGNORE_VNO) { krb5_kt_free_entry(context, &cur_entry); cur_entry = new_entry; - break; + if (new_entry.vno == kvno) diff --git a/SOURCES/krb5-tests_use_libs_from_build.patch b/SOURCES/krb5-tests_use_libs_from_build.patch deleted file mode 100644 index 4538b1d..0000000 --- a/SOURCES/krb5-tests_use_libs_from_build.patch +++ /dev/null @@ -1,96 +0,0 @@ -# -# krb5-tests_use_libs_from_build.patch - patch to ensure the tests -# in the upstream sources use the libraries from the local tree -# and not those from the underlying build system. -3 -# Originally repoted as RedHat Bug #1164304 ("Upstream unit tests loads -# the installed shared libraries instead the ones from the build") -# -# -# Description of problem: -# krb5-1.12.2/src/lib/kadm5/unit-test fails (segfaults) when -# krb5-pkinit is installed on the sysytem. -# Monitoring via audit showed that unit tests from this directory -# loads pkinit.so from the installed package and not the one that -# was built. -# On top of that, monitoring showed that libs from the installed -# krb5-libs (whatever version installed) are loaded too. -# This questions the effectiveness of upstream testing. -# -# Version-Release number of selected component (if applicable): -# krb5-libs-1.12.2-8.el7 -# -# How reproducible: -# always -# -# Steps to Reproduce: -# -# # rpm -qa krb5\* -# krb5-devel-1.11.3-49.el7.ppc64 -# krb5-libs-1.11.3-49.el7.ppc64 -# krb5-pkinit-1.11.3-49.el7.ppc64 -# # -# # rpm -ivh krb5-1.12.2-8.el7.src.rpm -# ... snip ... -# # rpmbuild -bc ~/rpmbuild/SPECS/krb5.spec -# ... snip ... -# # -# # cd ~/rpmbuild/BUILD/krb5-1.12.2/src/ -# # make runenv.py -# LD_LIBRARY_PATH=`echo -L./lib | sed -e "s/-L//g" -e "s/ /:/g"`; export LD_LIBRARY_PATH; \ -# for i in LD_LIBRARY_PATH; do \ -# eval echo 'env['\\\'$i\\\''] = '\\\'\$$i\\\'; \ -# done > pyrunenv.vals -# echo "proxy_tls_impl = 'openssl'" >> pyrunenv.vals -# echo 'env = {}' > runenv.py -# cat pyrunenv.vals >> runenv.py -# # cd lib/kadm5/unit-test/ -# # make check -# .. snip ... -# KINIT=../../../clients/kinit/kinit \ -# KDESTROY=../../../clients/kdestroy/kdestroy \ -# KADMIN_LOCAL=../../../kadmin/cli/kadmin.local \ -# PRIOCNTL_HACK=0 VALGRIND="" \ -# -# WARNING: Couldn't find the global config file. -# WARNING: Couldn't find tool init file -# Test Run By root on Fri Nov 14 10:30:35 2014 -# Native configuration is powerpc64-redhat-linux-gnu -# -# === api tests === -# -# Schedule of variations: -# unix -# -# Running target unix -# Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target. -# Using /usr/share/dejagnu/config/unix.exp as generic interface file for target. -# Using ./config/unix.exp as tool-and-target-specific interface file. -# Running ./api.2/crte-policy.exp ... -# FAIL: create-policy 1: eof -# ERROR: create-policy 1: unexpected failure in init -# ERROR: create-policy 2: unexpected failure in init -# ERROR: create-policy 3: unexpected failure in init -# -diff -ur krb5/src/kadmin/testing/proto/krb5.conf.proto krb5/src/kadmin/testing/proto/krb5.conf.proto ---- krb5/src/kadmin/testing/proto/krb5.conf.proto 2014-11-14 10:16:22.106948323 -0500 -+++ krb5/src/kadmin/testing/proto/krb5.conf.proto 2014-11-14 10:14:16.955948323 -0500 -@@ -2,6 +2,7 @@ - default_realm = __REALM__ - default_keytab_name = FILE:__K5ROOT__/v5srvtab - dns_fallback = no -+ plugin_base_dir = __PLUGIN_DIR__ - - [realms] - __REALM__ = { -diff -ur krb5/src/kadmin/testing/scripts/start_servers krb5/src/kadmin/testing/scripts/start_servers ---- krb5/src/kadmin/testing/scripts/start_servers 2014-08-11 18:46:27.000000000 -0400 -+++ krb5/src/kadmin/testing/scripts/start_servers 2014-11-14 10:14:56.409948323 -0500 -@@ -40,6 +40,7 @@ - -e "s/__KDCHOST__/$hostname/g" \ - -e "s/__LOCALHOST__/$localname/g" \ - -e "s#__MODDIR__#$TOP/../plugins/kdb#g"\ -+ -e "s#__PLUGIN_DIR__#$TOP/../plugins#g"\ - < $STESTDIR/proto/krb5.conf.proto > $K5ROOT/krb5.conf - - # Using /usr/ucb/rsh and getting rid of "-k $REALM" until we get diff --git a/SOURCES/krb5.conf b/SOURCES/krb5.conf index 471c4a1..77d794a 100644 --- a/SOURCES/krb5.conf +++ b/SOURCES/krb5.conf @@ -1,3 +1,6 @@ +# Configuration snippets may be placed in this directory as well +includedir /etc/krb5.conf.d/ + [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log diff --git a/SPECS/krb5.spec b/SPECS/krb5.spec index 716ccde..36ac156 100644 --- a/SPECS/krb5.spec +++ b/SPECS/krb5.spec @@ -1,47 +1,20 @@ -%global WITH_LDAP 1 %global WITH_DIRSRV 1 -%if 0%{?fedora} >= 17 || 0%{?rhel} > 6 -# These next two *will* change. -%global WITH_OPENSSL 1 -%global WITH_NSS 0 -%global WITH_SYSVERTO 1 -%else -%global WITH_OPENSSL 1 -%global WITH_NSS 0 -%global WITH_SYSVERTO 0 -%endif -# The "move everything to /usr" feature landed in Fedora 17, but we didn't -# catch up until the Fedora 18 development cycle, at which point we found -# that some packages were hard-coding paths. -%if 0%{?fedora} > 17 || 0%{?rhel} > 6 -%global separate_usr 0 -%else -%global separate_usr 1 -%endif -# Systemd landed in Fedora 15, but this package was cut over for Fedora 16. -%if 0%{?fedora} >= 16 || 0%{?rhel} > 6 -%global WITH_SYSTEMD 1 -%else -%global WITH_SYSTEMD 0 -%endif + # Set this so that find-lang.sh will recognize the .po files. %global gettext_domain mit-krb5 + # Guess where the -libs subpackage's docs are going to go. %define libsdocdir %{?_pkgdocdir:%(echo %{_pkgdocdir} | sed -e s,krb5,krb5-libs,g)}%{!?_pkgdocdir:%{_docdir}/%{name}-libs-%{version}} + # Figure out where the default ccache lives and how we set it. -%if 0%{?fedora} > 18 && 0%{?fedora} < 20 -%global compile_default_ccache_name 1 -%global compiled_default_ccache_name DIR:/run/user/%%{uid}/krb5cc -%endif -%if 0%{?fedora} >= 20 || 0%{?rhel} > 6 %global configure_default_ccache_name 1 %global configured_default_ccache_name KEYRING:persistent:%%{uid} -%endif Summary: The Kerberos network authentication system Name: krb5 -Version: 1.13.2 -Release: 12%{?dist} +Version: 1.14.1 +Release: 26%{?dist} + # - Maybe we should explode from the now-available-to-everybody tarball instead? # http://web.mit.edu/kerberos/dist/krb5/1.13/krb5-1.13.2-signed.tar # - The sources below are stored in a lookaside cache. Upload with @@ -49,10 +22,7 @@ Release: 12%{?dist} # remove, otherwise you can't go back or branch from a previous point) Source0: krb5-%{version}.tar.gz Source1: krb5-%{version}.tar.gz.asc -# Use a dummy krb5-%{version}-pdf.pax.xz the first time through, then -# $ pax -wv -x ustar build-pdf/*.pdf | xz -9 >"krb5-%{version}-pdf.pax.xz.new" # -# after the build phase finishes. -Source3: krb5-%{version}-pdf.pax.xz +Source3: krb5-%{version}-pdfs.tar Source2: kprop.service Source4: kadmin.service Source5: krb5kdc.service @@ -73,7 +43,7 @@ Source37: kadmind.init Source38: krb5kdc.init Source39: krb5-krb5kdc.conf -BuildRequires: cmake pax xz +BuildRequires: cmake xz # Carry this locally until it's available in a packaged form. Source100: nss_wrapper-0.0-20140204195100.git3d58327.tar.xz Source101: noport.c @@ -85,38 +55,41 @@ 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.13-selinux-label.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 -Patch319: krb5-kadm5clntmit_libsoname_version_downgrade.patch - -Patch140: krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch -Patch143: krb5-tests_use_libs_from_build.patch -Patch144: krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch -Patch145: krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad.patch -Patch146: krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch -Patch147: krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch -Patch148: krb5-1.13.3-client_referrals.patch -Patch149: krb5-1.13.3-client_referrals_test.patch -Patch150: krb5-CVE-2015-8629.patch -Patch151: krb5-CVE-2015-8630.patch -Patch152: krb5-CVE-2015-8631.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 License: MIT URL: http://web.mit.edu/kerberos/www/ Group: System Environment/Libraries BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, bison, flex, gawk, gettext, pkgconfig, sed -%if 0%{?fedora} >= 12 || 0%{?rhel} >= 6 BuildRequires: libcom_err-devel, libedit-devel, libss-devel -%endif BuildRequires: gzip, ncurses-devel BuildRequires: python-sphinx, texlive-pdftex -# The texlive package got a lot more complicated here. -%if 0%{?fedora} > 17 || 0%{?rhel} > 6 + # Taken from \usepackage directives produced by sphinx: BuildRequires: tex(babel.sty) BuildRequires: tex(bookmark.sty) @@ -134,25 +107,21 @@ BuildRequires: tex(titlesec.sty) BuildRequires: tex(threeparttable.sty) BuildRequires: tex(wrapfig.sty) BuildRequires: tex(report.cls) -%else -BuildRequires: texlive-texmf, texlive-texmf-latex -%endif + # Typical fonts, and the commands which we need to have present. BuildRequires: texlive, texlive-latex, texlive-texmf-fonts BuildRequires: /usr/bin/pdflatex /usr/bin/makeindex BuildRequires: keyutils, keyutils-libs-devel >= 1.5.8 BuildRequires: libselinux-devel BuildRequires: pam-devel -%if %{WITH_SYSTEMD} BuildRequires: systemd-units -%endif # For the test framework. BuildRequires: perl, dejagnu, tcl-devel BuildRequires: net-tools, rpcbind -%if 0%{?fedora} >= 13 || 0%{?rhel} > 6 BuildRequires: hostname BuildRequires: iproute -%endif + +# someday... %if 0%{?fedora} >= 9 BuildRequires: python-pyrad %endif @@ -162,18 +131,9 @@ BuildRequires: yasm %endif %endif -%if %{WITH_LDAP} BuildRequires: openldap-devel -%endif -%if %{WITH_OPENSSL} || %{WITH_NSS} BuildRequires: openssl-devel >= 0.9.8 -%endif -%if %{WITH_NSS} -BuildRequires: nss-devel >= 3.13 -%endif -%if %{WITH_SYSVERTO} BuildRequires: libverto-devel -%endif %description Kerberos V5 is a trusted-third-party network authentication system, @@ -184,9 +144,8 @@ practice of sending passwords over the network in unencrypted form. Summary: Development files needed to compile Kerberos 5 programs Group: Development/Libraries Requires: %{name}-libs%{?_isa} = %{version}-%{release} -%if 0%{?fedora} >= 12 || 0%{?rhel} >= 6 +Requires: libkadm5%{?_isa} = %{version}-%{release} Requires: libcom_err-devel -%endif Requires: keyutils-libs-devel, libselinux-devel Requires: libverto-devel @@ -197,13 +156,8 @@ contains the header files and libraries needed for compiling Kerberos to install this package. %package libs -Summary: The shared libraries used by Kerberos 5 +Summary: The non-admin shared libraries used by Kerberos 5 Group: System Environment/Libraries -%if 0%{?rhel} == 6 -# Some of the older libsmbclient builds here incorrectly called -# krb5_locate_kdc(), which was mistakenly exported in 1.9. -Conflicts: libsmbclient < 3.5.10-124 -%endif Requires: coreutils, gawk, grep, sed Requires: keyutils-libs >= 1.5.8 @@ -216,33 +170,16 @@ Kerberos, you need to install this package. Group: System Environment/Daemons Summary: The KDC and related programs for Kerberos 5 Requires: %{name}-libs%{?_isa} = %{version}-%{release} -Requires(post): chkconfig -%if %{WITH_SYSTEMD} -Requires(post): systemd-sysv Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units -%else -Requires(preun): chkconfig -# portreserve is used by init scripts for kadmind, kpropd, and krb5kdc -Requires: portreserve -%endif -Requires(post): initscripts -Requires(postun): initscripts -# we need 'status -l' to work, and that option was added in 8.99 -Requires: initscripts >= 8.99-1 -# used by the triggers -Requires: chkconfig # we drop files in its directory, but we don't want to own that directory Requires: logrotate -Requires(preun): initscripts # we specify /usr/share/dict/words as the default dict_file in kdc.conf Requires: /usr/share/dict/words -%if %{WITH_SYSVERTO} # for run-time, and for parts of the test suite BuildRequires: libverto-module-base Requires: libverto-module-base -%endif %ifarch x86_64 Obsoletes: krb5-server-1.11.3-49.el7.i686 %endif @@ -252,6 +189,7 @@ Obsoletes: krb5-server-1.11.3-49.el7.ppc %ifarch s390x Obsoletes: krb5-server-1.11.3-49.el7.s390 %endif +Requires: libkadm5%{?_isa} = %{version}-%{release} %description server Kerberos is a network authentication system. The krb5-server package @@ -265,6 +203,7 @@ Group: System Environment/Daemons Summary: The LDAP storage plugin for the Kerberos 5 KDC Requires: %{name}-server%{?_isa} = %{version}-%{release} Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: libkadm5%{?_isa} = %{version}-%{release} %ifarch x86_64 Obsoletes: krb5-server-ldap-1.11.3-49.el7.i686 %endif @@ -286,6 +225,7 @@ realm, you need to install this package. Summary: Kerberos 5 programs for use on workstations Group: System Environment/Base Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: libkadm5%{?_isa} = %{version}-%{release} # mktemp is used by krb5-send-pr Requires: coreutils @@ -295,29 +235,29 @@ package contains the basic Kerberos programs (kinit, klist, kdestroy, kpasswd). If your network uses Kerberos, this package should be installed on every workstation. -%if 0%{?fedora} >= 17 || 0%{?rhel} > 6 %package pkinit -%else -%package pkinit-openssl -%endif Summary: The PKINIT module for Kerberos 5 Group: System Environment/Libraries Requires: %{name}-libs%{?_isa} = %{version}-%{release} -%if 0%{?fedora} >= 17 || 0%{?rhel} >= 6 Obsoletes: krb5-pkinit-openssl < %{version}-%{release} Provides: krb5-pkinit-openssl = %{version}-%{release} -%endif -%if 0%{?fedora} >= 17 || 0%{?rhel} > 6 %description pkinit -%else -%description pkinit-openssl -%endif Kerberos is a network authentication system. The krb5-pkinit package contains the PKINIT plugin, which allows clients to obtain initial credentials from a KDC using a private key and a certificate. +%package -n libkadm5 +Summary: Kerberos 5 Administrative libraries +Group: System Environment/Base +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +%description -n libkadm5 +Kerberos is a network authentication system. The libkadm5 package +contains the libkadm5clnt and libkadm5serv shared objects, for use +ONLY by kerberos itself. Do not depend on this package. + %prep %setup -q -a 3 -a 100 -a 102 ln NOTICE LICENSE @@ -342,22 +282,28 @@ chmod u+x src/util/paste-kdcproxy.py %patch129 -p1 -b .run_user_0 %patch134 -p1 -b .kpasswdtest - -%patch319 -p1 -b .krb5-kadm5clntmit_libsoname_version_downgrade - -%patch140 -p1 -b .krb5-1.14-support-kdc_err_more_preauth_data_required -%patch143 -p1 -b .krb5-tests_use_libs_from_build -%patch144 -p1 -b .krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial -%patch145 -p1 -b .krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad -%patch146 -p1 -b .krb5-1.14-resolve_krb5_gss_creds_if_time_rec_is_requested -%patch147 -p1 -b .krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char - -%patch148 -p1 -b .krb5-1.13.3-client_referrals -%patch149 -p1 -b .krb5-1.13.3-client_referrals_test - -%patch150 -p1 -b .CVE-2015-8629 -%patch151 -p1 -b .CVE-2015-8630 -%patch152 -p1 -b .CVE-2015-8631 +%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 # Take the execute bit off of documentation. chmod -x doc/krb5-protocol/*.txt doc/ccapi/*.html @@ -409,10 +355,7 @@ sed -i -e s,7778,`expr "$PORT" + 1`,g $cfg # Go ahead and supply tcl info, because configure doesn't know how to find it. source %{_libdir}/tclConfig.sh pushd src -# Keep the old default if the package is built against older releases. -%if 0%{?compile_default_ccache_name} -DEFCCNAME=%{compiled_default_ccache_name}; export DEFCCNAME -%endif + # Set this so that configure will have a value even if the current version of # autoconf doesn't set one. runstatedir=%{_localstatedir}/run; export runstatedir @@ -438,30 +381,14 @@ CPPFLAGS="`echo $DEFINES $INCLUDES`" --with-netlib=-lresolv \ --with-tcl \ --enable-dns-for-realm \ -%if %{WITH_LDAP} --with-ldap \ %if %{WITH_DIRSRV} --with-dirsrv-account-locking \ %endif -%endif -%if %{WITH_OPENSSL} || %{WITH_NSS} --enable-pkinit \ -%else - --disable-pkinit \ -%endif -%if %{WITH_OPENSSL} --with-pkinit-crypto-impl=openssl \ --with-tls-impl=openssl \ -%endif -%if %{WITH_NSS} - --with-crypto-impl=nss \ - --without-tls-impl \ -%endif -%if %{WITH_SYSVERTO} --with-system-verto \ -%else - --without-system-verto \ -%endif --with-pam \ --with-selinux # Now build it. @@ -487,9 +414,8 @@ sphinx-build -a -b latex -t pathsubs doc build-pdf for pdf in admin appdev basic build plugindev user ; do test -s build-pdf/$pdf.pdf || make -C build-pdf done -# new krb5-%{version}-pdf.pax.xz, see above -pax -wv -x ustar build-pdf/*.pdf | xz -9 >"krb5-%{version}-pdf.pax.xz.new" -# false +# new krb5-%{version}-pdf +tar -cf "krb5-%{version}-pdfs.tar.new" build-pdf/*.pdf # Build the test wrappers. pushd nss_wrapper/build @@ -546,6 +472,9 @@ mkdir -p $RPM_BUILD_ROOT%{_var}/kerberos/krb5/user mkdir -p $RPM_BUILD_ROOT/etc install -pm 644 %{SOURCE6} $RPM_BUILD_ROOT/etc/krb5.conf +# Default include on this directory +mkdir -p $RPM_BUILD_ROOT/etc/krb5.conf.d + # Parent of configuration file for list of loadable GSS mechs ("mechs"). This # location is not relative to sysconfdir, but is hard-coded in g_initialize.c. mkdir -m 755 -p $RPM_BUILD_ROOT/etc/gss @@ -566,7 +495,6 @@ grep default_ccache_name $RPM_BUILD_ROOT/etc/krb5.conf %endif # Server init scripts (krb5kdc,kadmind,kpropd) and their sysconfig files. -%if %{WITH_SYSTEMD} mkdir -p $RPM_BUILD_ROOT%{_unitdir} for unit in \ %{SOURCE5}\ @@ -586,28 +514,6 @@ done mkdir -p $RPM_BUILD_ROOT/%{_tmpfilesdir} install -pm 644 %{SOURCE39} $RPM_BUILD_ROOT/%{_tmpfilesdir}/ mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/run/krb5kdc -%else -mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d -for init in \ - %{SOURCE36}\ - %{SOURCE37} \ - %{SOURCE38} ; do - # In the past, the init script was supposed to be named after the - # service that the started daemon provided. Changing their names - # is an upgrade-time problem I'm in no hurry to deal with. - service=`basename ${init} .init` - install -pm 755 ${init} \ - $RPM_BUILD_ROOT/etc/rc.d/init.d/${service%d} -done -# portreserve configuration files. -mkdir -p $RPM_BUILD_ROOT/etc/portreserve -for portreserve in \ - %{SOURCE31} \ - %{SOURCE32} ; do - install -pm 644 ${portreserve} \ - $RPM_BUILD_ROOT/etc/portreserve/`basename ${portreserve} .portreserve` -done -%endif mkdir -p $RPM_BUILD_ROOT/etc/sysconfig for sysconfig in \ @@ -657,23 +563,6 @@ if [[ "$(< $RPM_BUILD_ROOT%{_bindir}/krb5-config )" == *redhat-hardened-ld* ]] ; exit 1 fi -%if %{separate_usr} -# Move specific libraries from %%{_libdir} to /%%{_lib}, and fixup the symlinks. -touch $RPM_BUILD_ROOT/rootfile -rellibdir=.. -while ! test -r $RPM_BUILD_ROOT/%{_libdir}/${rellibdir}/rootfile ; do - rellibdir=../${rellibdir} -done -rm -f -- $RPM_BUILD_ROOT/rootfile -mkdir -p $RPM_BUILD_ROOT/%{_lib} -for library in libgssapi_krb5 libgssrpc libk5crypto libkrb5 libkrb5support ; do - mv $RPM_BUILD_ROOT/%{_libdir}/${library}.so.* $RPM_BUILD_ROOT/%{_lib}/ - pushd $RPM_BUILD_ROOT/%{_libdir} - ln -fs ${rellibdir}/%{_lib}/${library}.so.*.* ${library}.so - popd -done -%endif - # Install processed man pages. for section in 1 5 8 ; do install -m 644 build-man/*.${section} \ @@ -684,6 +573,14 @@ done # since we don't have a man page for it, just drop it. rm -- $RPM_BUILD_ROOT/%{_sbindir}/krb5-send-pr +# These files are already packaged elsewhere +rm -f -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/kdc.conf" +rm -f -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/krb5.conf" +rm -f -- "$RPM_BUILD_ROOT/%{_docdir}/krb5-libs/examples/services.append" + +# This is only needed for tests +rm -- "$RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/preauth/test.so" + %find_lang %{gettext_domain} %clean @@ -744,78 +641,33 @@ fi %postun server-ldap -p /sbin/ldconfig %post server -# Remove the init script for older servers. -[ -x /etc/rc.d/init.d/krb5server ] && /sbin/chkconfig --del krb5server -%if %{WITH_SYSTEMD} -if [ $1 -eq 1 ] ; then - # Initial installation - /bin/systemctl daemon-reload >/dev/null 2>&1 || : -fi -%else -# Install the new ones. -/sbin/chkconfig --add krb5kdc -/sbin/chkconfig --add kadmin -/sbin/chkconfig --add kprop -%endif +# assert sanity. A cleaner solution probably exists but it is opaque. +/bin/systemctl daemon-reload exit 0 %preun server if [ "$1" -eq "0" ] ; then -%if %{WITH_SYSTEMD} /bin/systemctl --no-reload disable krb5kdc.service > /dev/null 2>&1 || : /bin/systemctl --no-reload disable kadmin.service > /dev/null 2>&1 || : /bin/systemctl --no-reload disable kprop.service > /dev/null 2>&1 || : /bin/systemctl stop krb5kdc.service > /dev/null 2>&1 || : /bin/systemctl stop kadmin.service > /dev/null 2>&1 || : /bin/systemctl stop kprop.service > /dev/null 2>&1 || : -%else - /sbin/chkconfig --del krb5kdc - /sbin/chkconfig --del kadmin - /sbin/chkconfig --del kprop - /sbin/service krb5kdc stop > /dev/null 2>&1 || : - /sbin/service kadmin stop > /dev/null 2>&1 || : - /sbin/service kprop stop > /dev/null 2>&1 || : -%endif fi exit 0 %postun server -%if %{WITH_SYSTEMD} /bin/systemctl daemon-reload >/dev/null 2>&1 || : if [ "$1" -ge 1 ] ; then /bin/systemctl try-restart krb5kdc.service >/dev/null 2>&1 || : /bin/systemctl try-restart kadmin.service >/dev/null 2>&1 || : /bin/systemctl try-restart kprop.service >/dev/null 2>&1 || : fi -%else -if [ "$1" -ge 1 ] ; then - /sbin/service krb5kdc condrestart > /dev/null 2>&1 || : - /sbin/service kadmin condrestart > /dev/null 2>&1 || : - /sbin/service kprop condrestart > /dev/null 2>&1 || : -fi -%endif exit 0 -%if %{WITH_SYSTEMD} -%triggerun server -- krb5-server < 1.9.1-13 -# Save the current service runlevel info -# User must manually run -# systemd-sysv-convert --apply krb5kdc -# systemd-sysv-convert --apply kadmin -# systemd-sysv-convert --apply kprop -# to migrate them to systemd targets -/usr/bin/systemd-sysv-convert --save krb5kdc >/dev/null 2>&1 ||: -/usr/bin/systemd-sysv-convert --save kadmin >/dev/null 2>&1 ||: -/usr/bin/systemd-sysv-convert --save kprop >/dev/null 2>&1 ||: - -# Run these because the SysV package being removed won't do them -/sbin/chkconfig --del krb5kdc >/dev/null 2>&1 || : -/sbin/chkconfig --del kadmin >/dev/null 2>&1 || : -/sbin/chkconfig --del kprop >/dev/null 2>&1 || : -/bin/systemctl try-restart krb5kdc.service >/dev/null 2>&1 || : -/bin/systemctl try-restart kadmin.service >/dev/null 2>&1 || : -/bin/systemctl try-restart kprop.service >/dev/null 2>&1 || : -%endif +%post -n libkadm5 -p /sbin/ldconfig + +%postun -n libkadm5 -p /sbin/ldconfig %files workstation %defattr(-,root,root,-) @@ -855,19 +707,11 @@ exit 0 %defattr(-,root,root,-) %docdir %{_mandir} %doc build-pdf/admin.pdf build-pdf/build.pdf -%if %{WITH_SYSTEMD} %{_unitdir}/krb5kdc.service %{_unitdir}/kadmin.service %{_unitdir}/kprop.service %{_tmpfilesdir}/krb5-krb5kdc.conf %dir %{_localstatedir}/run/krb5kdc -%else -/etc/rc.d/init.d/krb5kdc -/etc/rc.d/init.d/kadmin -/etc/rc.d/init.d/kprop -%config(noreplace) /etc/portreserve/kerberos-adm -%config(noreplace) /etc/portreserve/krb5_prop -%endif %config(noreplace) /etc/sysconfig/krb5kdc %config(noreplace) /etc/sysconfig/kadmin %config(noreplace) /etc/logrotate.d/krb5kdc @@ -884,6 +728,7 @@ exit 0 %dir %{_libdir}/krb5/plugins/preauth %dir %{_libdir}/krb5/plugins/authdata %{_libdir}/krb5/plugins/preauth/otp.so +%{_libdir}/krb5/plugins/kdb/db2.so # KDC binaries and configuration. %{_mandir}/man5/kadm5.acl.5* @@ -912,7 +757,6 @@ exit 0 %{_sbindir}/sserver %{_mandir}/man8/sserver.8* -%if %{WITH_LDAP} %files server-ldap %defattr(-,root,root,-) %docdir %{_mandir} @@ -927,7 +771,6 @@ exit 0 %{_libdir}/libkdb_ldap.so.* %{_mandir}/man8/kdb5_ldap_util.8.gz %{_sbindir}/kdb5_ldap_util -%endif %files libs -f %{gettext_domain}.lang %defattr(-,root,root,-) @@ -938,55 +781,29 @@ exit 0 # These are hard-coded, not-dependent-on-the-configure-script paths. %dir /etc/gss %dir /etc/gss/mech.d -%verify(not md5 size mtime) %config(noreplace) /etc/krb5.conf +%dir /etc/krb5.conf.d +%config(noreplace) /etc/krb5.conf /%{_mandir}/man5/.k5identity.5* /%{_mandir}/man5/.k5login.5* /%{_mandir}/man5/k5identity.5* /%{_mandir}/man5/k5login.5* /%{_mandir}/man5/krb5.conf.5* -%if %{separate_usr} -/%{_lib}/libgssapi_krb5.so.* -/%{_lib}/libgssrpc.so.* -/%{_lib}/libk5crypto.so.* -%else %{_libdir}/libgssapi_krb5.so.* %{_libdir}/libgssrpc.so.* %{_libdir}/libk5crypto.so.* -%endif -%{_libdir}/libkadm5clnt_mit.so.* -%{_libdir}/libkadm5srv_mit.so.* %{_libdir}/libkdb5.so.* %{_libdir}/libkrad.so.* -%if %{separate_usr} -/%{_lib}/libkrb5.so.* -/%{_lib}/libkrb5support.so.* -%else %{_libdir}/libkrb5.so.* %{_libdir}/libkrb5support.so.* -%endif %dir %{_libdir}/krb5 %dir %{_libdir}/krb5/plugins %dir %{_libdir}/krb5/plugins/* %{_libdir}/krb5/plugins/tls/k5tls.so -%{_libdir}/krb5/plugins/kdb/db2.so %dir %{_var}/kerberos %dir %{_var}/kerberos/krb5 %dir %{_var}/kerberos/krb5/user -%if ! %{WITH_SYSVERTO} -%{_libdir}/libverto-k5ev.so -%{_libdir}/libverto-k5ev.so.* -# These really shouldn't be here, but until we have a system copy of libverto, -# don't force people who are using libverto to install the KDC just to get the -# shared library. Not that there are any development headers, but anyway. -%{_libdir}/libverto.so -%{_libdir}/libverto.so.* -%endif -%if 0%{?fedora} >= 17 || 0%{?rhel} > 6 %files pkinit -%else -%files pkinit-openssl -%endif %defattr(-,root,root,-) %dir %{_libdir}/krb5 %dir %{_libdir}/krb5/plugins @@ -1003,10 +820,6 @@ exit 0 %{_libdir}/libgssapi_krb5.so %{_libdir}/libgssrpc.so %{_libdir}/libk5crypto.so -%{_libdir}/libkadm5clnt.so -%{_libdir}/libkadm5clnt_mit.so -%{_libdir}/libkadm5srv.so -%{_libdir}/libkadm5srv_mit.so %{_libdir}/libkdb5.so %{_libdir}/libkrad.so %{_libdir}/libkrb5.so @@ -1030,12 +843,136 @@ exit 0 %{_sbindir}/gss-server %{_sbindir}/uuserver +%files -n libkadm5 +%defattr(-,root,root,-) +%{_libdir}/libkadm5clnt.so +%{_libdir}/libkadm5clnt_mit.so +%{_libdir}/libkadm5srv.so +%{_libdir}/libkadm5srv_mit.so +%{_libdir}/libkadm5clnt_mit.so.* +%{_libdir}/libkadm5srv_mit.so.* %changelog +* Wed Aug 17 2016 Robbie Harwood - 1.14.1-26 +- Use responder in non-preauth AS reqs +- Resolves: #1363690 + +* Wed Aug 17 2016 Robbie Harwood - 1.14.1-25 +- Fix bad debug_log() call in selinux handling +- Resolves: #1292153 + +* Wed Aug 10 2016 Robbie Harwood - 1.14.1-24 +- Fix KKDCPP with TLS SNI by always presenting "Host:" header +- Resolves: #1364993 + +* Fri Aug 05 2016 Robbie Harwood - 1.14.1-23 +- Add dependency on libkadm5 to krb5-devel +- Resolves: #1347403 + +* Fri Jul 29 2016 Robbie Harwood - 1.14.1-22 +- Builders have new version of mock; adapt. +- Resolves: #1290239 + +* Fri Jul 29 2016 Robbie Harwood - 1.14.1-21 +- Fix CVE-2016-3120 +- Resolves: #1361504 + +* Wed Jul 20 2016 Robbie Harwood - 1.14.1-20 +- Make version dependencies on libkadm5 more explicit to appease rpmdiff +- Resolves: #1347403 + +* Wed Jul 20 2016 Robbie Harwood - 1.14.1-19 +- Add in upstream version of kprop port and tests +- Resolves: #1292795 + +* Wed Jun 29 2016 Robbie Harwood - 1.14.1-18 +- Fix incorrect recv() size calculation in libkrad +- Resolves: #1349042 + +* Wed Jun 15 2016 Robbie Harwood - 1.14.1-17 +- Separate out the kadm5 libs +- Resolves: #1347403 + +* Mon Jun 13 2016 Robbie Harwood - 1.14.1-16 +- Fix kprop/iprop handling of default realm +- Fix t_kprop.py +- Resolves: #1290561 +- Resolves: #1302967 +- Resolves: #1292795 + +* Thu Jun 02 2016 Robbie Harwood - 1.14.1-15 +- Fix SPNEGO with NTLM to conform to MS-SPNG section 3.3.5.1 +- Resolves: #1341726 + +* Sat May 28 2016 Robbie Harwood - 1.14.1-14 +- Do not indicate depricated mechanisms when requested +- Resolves: #1293908 + +* Fri May 27 2016 Robbie Harwood - 1.14.1-13 +- Fix OTP module incorrectly overwriting as_key +- Resolves: #1340304 + +* Wed May 25 2016 Robbie Harwood - 1.14.1-12 +- Fix CVE-2016-3119 (LDAP NULL dereference) +- Resolves: #1339562 + +* Thu Apr 28 2016 Robbie Harwood - 1.14.1-11 +- Make ksu not ask for password without -n +- Resolves: #1247261 + +* Wed Apr 20 2016 Robbie Harwood - 1.14.1-10 +- Frob kadm5 soname version so that the rebase does not break things +- Resolves: #1292153 + +* Tue Apr 19 2016 Robbie Harwood - 1.14.1-9 +- Revamp selinux patch to not leak memory +- Resolves: #1313457 + +* Mon Apr 11 2016 Robbie Harwood - 1.14.1-8 +- Add snippet support in /etc/krb5.conf.d +- Resolves: #1146945 + +* Fri Apr 08 2016 Robbie Harwood - 1.14.1-7 +- Skip unnecessary mech calls in gss_inquire_cred +- Resolves: #1314493 + +* Thu Apr 07 2016 Robbie Harwood - 1.14.1-6 +- Fix impersonate_name to work with interposers +- Resolves: #1284987 + +* Thu Apr 07 2016 Robbie Harwood - 1.14.1-5 +- Fix change tracking of krb5.conf +- Resolves: #1208243 + +* Tue Apr 05 2016 Robbie Harwood - 1.14.1-4 +- Ensure log files are not world-readable +- Resolves: #1256735 + +* Wed Mar 30 2016 Robbie Harwood - 1.14.1-3 +- Clean up initscript handling in spec file +- Resolves: #1283902 +- Resolves: #1183058 + +* Wed Mar 30 2016 Robbie Harwood - 1.14.1-2 +- Backport spec file changes from Fedora +- Resolves: #1290239 + +* Thu Mar 10 2016 Robbie Harwood - 1.14.1-1 +- Rebase to new upstream version 1.14.1 +- Remove pax logic +- Resolves: #1292153 +- Resolves: #1135427 +- Resolves: #1265509 +- Resolves: #1265510 +- Resolves: #1296241 + * Fri Feb 12 2016 Robbie Harwood - 1.13.2-12 -- Fix CVE-2015-8631, CVE-2015-8630, and CVE-2015-8629 - Remove obsolete trigger to enable building of package -- Resolves: #1306969 +- Resolves: #1306970 + +* Fri Feb 12 2016 Robbie Harwood - 1.13.2-11 +- Fix CVE-2015-8631, CVE-2015-8630, and CVE-2015-8629 +- Resolves: #1306970 * Fri Sep 04 2015 Robbie Harwood 1.13.2-9 - Add patch and test case for "KDC does not return proper