diff --git a/.cyrus-sasl.metadata b/.cyrus-sasl.metadata
new file mode 100644
index 0000000..82b591b
--- /dev/null
+++ b/.cyrus-sasl.metadata
@@ -0,0 +1 @@
+c9e6848d9cc6f9588e0e7a75423f9a3aed3f10db SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..07c8f97
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/cyrus-sasl-2.1.27-nodlcompatorsrp.tar.gz
diff --git a/SOURCES/autogen.sh b/SOURCES/autogen.sh
new file mode 100644
index 0000000..38e3be2
--- /dev/null
+++ b/SOURCES/autogen.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+test -n "$srcdir" || srcdir=`dirname "$0"`
+test -n "$srcdir" || srcdir=.
+
+olddir=`pwd`
+
+cd $srcdir
+
+(test -f configure.ac) || {
+	echo "*** ERROR: Directory "\`$srcdir\'" does not look like the top-level project directory ***"
+	exit 1
+}
+
+PKG_NAME=`autoconf --trace 'AC_INIT:$1' configure.ac`
+
+if [ "$#" = 0 -a "x$NOCONFIGURE" = "x" ]; then
+	echo "*** WARNING: I am going to run \`configure' with no arguments." >&2
+	echo "*** If you wish to pass any to it, please specify them on the" >&2
+	echo "*** \`$0\' command line." >&2
+	echo "" >&2
+fi
+
+aclocal --install || exit 1
+autoreconf --verbose --force --install -Wno-portability || exit 1
+
+cd $olddir
+if [ "$NOCONFIGURE" = "" ]; then
+	$srcdir/configure "$@" || exit 1
+
+	if [ "$1" = "--help" ]; then exit 0 else
+		echo "Now type \`make\' to compile $PKG_NAME" || exit 1
+	fi
+else
+	echo "Skipping configure process."
+fi
+
diff --git a/SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch b/SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch
new file mode 100644
index 0000000..1e414ff
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.20-saslauthd.conf-path.patch
@@ -0,0 +1,26 @@
+diff -up cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc.path cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc
+--- cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc.path	2015-10-15 15:44:43.000000000 +0200
++++ cyrus-sasl-2.1.27/saslauthd/saslauthd.mdoc	2015-11-20 15:05:30.421377527 +0100
+@@ -221,7 +221,7 @@ instead.
+ .Em (All platforms that support OpenLDAP 2.0 or higher)
+ .Pp
+ Authenticate against an ldap server.  The ldap configuration parameters are
+-read from /usr/local/etc/saslauthd.conf.  The location of this file can be
++read from /etc/saslauthd.conf.  The location of this file can be
+ changed with the -O parameter. See the LDAP_SASLAUTHD file included with the
+ distribution for the list of available parameters.
+ .It Li sia
+@@ -251,10 +251,10 @@ these ticket files can cause serious per
+ servers. (Kerberos
+ was never intended to be used in this manner, anyway.)
+ .Sh FILES
+-.Bl -tag -width "/var/run/saslauthd/mux"
+-.It Pa /var/run/saslauthd/mux
++.Bl -tag -width "/run/saslauthd/mux"
++.It Pa /run/saslauthd/mux
+ The default communications socket.
+-.It Pa /usr/local/etc/saslauthd.conf
++.It Pa /etc/saslauthd.conf
+ The default configuration file for ldap support.
+ .El
+ .Sh SEE ALSO
diff --git a/SOURCES/cyrus-sasl-2.1.21-sizes.patch b/SOURCES/cyrus-sasl-2.1.21-sizes.patch
new file mode 100644
index 0000000..6373924
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.21-sizes.patch
@@ -0,0 +1,119 @@
+diff -up cyrus-sasl-2.1.27/configure.ac.sizes cyrus-sasl-2.1.27/configure.ac
+--- cyrus-sasl-2.1.27/configure.ac.sizes	2015-11-18 09:46:24.000000000 +0100
++++ cyrus-sasl-2.1.27/configure.ac	2015-11-20 15:11:20.474588247 +0100
+@@ -1312,6 +1312,10 @@ AC_HEADER_STDC
+ AC_HEADER_DIRENT
+ AC_HEADER_SYS_WAIT
+ AC_CHECK_HEADERS(crypt.h des.h dlfcn.h fcntl.h limits.h malloc.h paths.h strings.h sys/file.h sys/time.h syslog.h unistd.h inttypes.h sys/uio.h sys/param.h sysexits.h stdarg.h varargs.h krb5.h)
++AC_CHECK_TYPES([long long, int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t],,,[
++#ifdef HAVE_INTTYPES_H
++#include <inttypes.h>
++#endif])
+ 
+ IPv6_CHECK_SS_FAMILY()
+ IPv6_CHECK_SA_LEN()
+diff -up cyrus-sasl-2.1.27/include/makemd5.c.sizes cyrus-sasl-2.1.27/include/makemd5.c
+--- cyrus-sasl-2.1.27/include/makemd5.c.sizes	2015-10-15 15:44:43.000000000 +0200
++++ cyrus-sasl-2.1.27/include/makemd5.c	2015-11-20 15:11:20.477588240 +0100
+@@ -82,12 +82,19 @@
+  */
+ 
+ 
++#ifdef HAVE_CONFIG_H
++#include "../config.h"
++#endif
+ 
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <ctype.h>
+ 
++#ifdef HAVE_INTTYPES_H
++#include <inttypes.h>
++#endif
++
+ 
+ static void
+ my_strupr(char *s)
+@@ -122,6 +129,18 @@ my_strupr(char *s)
+ static void
+ try_signed(FILE *f, int len)
+ {
++#ifdef HAVE_INT8_T
++    BITSIZE(int8_t);
++#endif
++#ifdef HAVE_INT16_T
++    BITSIZE(int16_t);
++#endif
++#ifdef HAVE_INT32_T
++    BITSIZE(int32_t);
++#endif
++#ifdef HAVE_INT64_T
++    BITSIZE(int64_t);
++#endif
+     BITSIZE(signed char);
+     BITSIZE(short);
+     BITSIZE(int);
+@@ -135,6 +154,18 @@ try_signed(FILE *f, int len)
+ static void
+ try_unsigned(FILE *f, int len)
+ {
++#ifdef HAVE_UINT8_T
++    BITSIZE(uint8_t);
++#endif
++#ifdef HAVE_UINT16_T
++    BITSIZE(uint16_t);
++#endif
++#ifdef HAVE_UINT32_T
++    BITSIZE(uint32_t);
++#endif
++#ifdef HAVE_UINT64_T
++    BITSIZE(uint64_t);
++#endif
+     BITSIZE(unsigned char);
+     BITSIZE(unsigned short);
+     BITSIZE(unsigned int);
+@@ -165,6 +196,11 @@ static int print_pre(FILE *f)
+ 	  "/* POINTER defines a generic pointer type */\n"
+ 	  "typedef unsigned char *POINTER;\n"
+ 	  "\n"
++#ifdef HAVE_INTTYPES_H
++	  "/* We try to define integer types for our use */\n"
++	  "#include <inttypes.h>\n"
++	  "\n"
++#endif
+ 	  );
+   return 1;
+ }
+@@ -212,31 +248,15 @@ int main(int argc, char **argv)
+ 
+   print_pre(f);
+ 
+-#ifndef HAVE_INT8_T
+     try_signed (f, 8);
+-#endif /* HAVE_INT8_T */
+-#ifndef HAVE_INT16_T
+     try_signed (f, 16);
+-#endif /* HAVE_INT16_T */
+-#ifndef HAVE_INT32_T
+     try_signed (f, 32);
+-#endif /* HAVE_INT32_T */
+-#ifndef HAVE_INT64_T
+     try_signed (f, 64);
+-#endif /* HAVE_INT64_T */
+ 
+-#ifndef HAVE_U_INT8_T
+     try_unsigned (f, 8);
+-#endif /* HAVE_INT8_T */
+-#ifndef HAVE_U_INT16_T
+     try_unsigned (f, 16);
+-#endif /* HAVE_U_INT16_T */
+-#ifndef HAVE_U_INT32_T
+     try_unsigned (f, 32);
+-#endif /* HAVE_U_INT32_T */
+-#ifndef HAVE_U_INT64_T
+     try_unsigned (f, 64);
+-#endif /* HAVE_U_INT64_T */
+ 
+     print_post(f);
+   
diff --git a/SOURCES/cyrus-sasl-2.1.23-man.patch b/SOURCES/cyrus-sasl-2.1.23-man.patch
new file mode 100644
index 0000000..21c63cd
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.23-man.patch
@@ -0,0 +1,24 @@
+diff -up cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8.man cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8
+--- cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8.man	2013-09-03 15:25:26.818042047 +0200
++++ cyrus-sasl-2.1.26/saslauthd/testsaslauthd.8	2013-09-03 15:25:26.818042047 +0200
+@@ -0,0 +1,20 @@
++.\"                                      Hey, EMACS: -*- nroff -*-
++.TH TESTSASLAUTHD 8 "14 October 2006"
++.SH NAME
++testsaslauthd \- test utility for the SASL authentication server
++.SH SYNOPSIS
++.B testsaslauthd
++.RI "[ " \(hyr " " realm " ] [ " \(hys " " servicename " ] [ " \(hyf " " socket " " path " ] [ " \(hyR " " repeatnum " ]"
++.SH DESCRIPTION
++This manual page documents briefly the
++.B testsaslauthd
++command.
++.PP
++.SH SEE ALSO
++.BR saslauthd (8).
++.br
++.SH AUTHOR
++testsaslauthd was written by Carnegie Mellon University.
++.PP
++This manual page was written by Roberto C. Sanchez <roberto@connexer.com>,
++for the Debian project (but may be used by others).
diff --git a/SOURCES/cyrus-sasl-2.1.25-no_rpath.patch b/SOURCES/cyrus-sasl-2.1.25-no_rpath.patch
new file mode 100644
index 0000000..3ff180c
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.25-no_rpath.patch
@@ -0,0 +1,20 @@
+diff -up cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath cyrus-sasl-2.1.25/m4/cyrus.m4
+--- cyrus-sasl-2.1.25/m4/cyrus.m4.no_rpath	2010-01-22 16:12:01.000000000 +0100
++++ cyrus-sasl-2.1.25/m4/cyrus.m4	2012-12-06 14:59:47.956102057 +0100
+@@ -32,14 +32,5 @@ AC_DEFUN([CMU_ADD_LIBPATH_TO], [
+ dnl runpath initialization
+ AC_DEFUN([CMU_GUESS_RUNPATH_SWITCH], [
+    # CMU GUESS RUNPATH SWITCH
+-  AC_CACHE_CHECK(for runpath switch, andrew_cv_runpath_switch, [
+-    # first, try -R
+-    SAVE_LDFLAGS="${LDFLAGS}"
+-    LDFLAGS="-R /usr/lib"
+-    AC_TRY_LINK([],[],[andrew_cv_runpath_switch="-R"], [
+-  	LDFLAGS="-Wl,-rpath,/usr/lib"
+-    AC_TRY_LINK([],[],[andrew_cv_runpath_switch="-Wl,-rpath,"],
+-    [andrew_cv_runpath_switch="none"])
+-    ])
+-  LDFLAGS="${SAVE_LDFLAGS}"
+-  ])])
++    andrew_runpath_switch="none"
++  ])
diff --git a/SOURCES/cyrus-sasl-2.1.26-md5global.patch b/SOURCES/cyrus-sasl-2.1.26-md5global.patch
new file mode 100644
index 0000000..605c8ec
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.26-md5global.patch
@@ -0,0 +1,24 @@
+diff -up cyrus-sasl-2.1.27/include/Makefile.am.md5global.h cyrus-sasl-2.1.27/include/Makefile.am
+--- cyrus-sasl-2.1.27/include/Makefile.am.md5global.h	2018-05-17 13:33:49.588368350 +0200
++++ cyrus-sasl-2.1.27/include/Makefile.am	2018-05-17 13:38:19.377316869 +0200
+@@ -49,20 +49,7 @@ saslinclude_HEADERS = hmac-md5.h md5.h m
+ 
+ noinst_PROGRAMS = makemd5
+ 
+-makemd5_SOURCES = makemd5.c
+-
+-makemd5$(BUILD_EXEEXT) $(makemd5_OBJECTS): CC=$(CC_FOR_BUILD)
+-makemd5$(BUILD_EXEEXT) $(makemd5_OBJECTS): CFLAGS=$(CFLAGS_FOR_BUILD)
+-makemd5$(BUILD_EXEEXT): LDFLAGS=$(LDFLAGS_FOR_BUILD)
+-
+-md5global.h: makemd5$(BUILD_EXEEXT) Makefile
+-	-rm -f $@
+-	./$< $@
+-
+-BUILT_SOURCES = md5global.h
+-
+ EXTRA_DIST = NTMakefile
+-DISTCLEANFILES = md5global.h
+ 
+ if MACOSX
+ framedir = /Library/Frameworks/SASL2.framework
diff --git a/SOURCES/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch b/SOURCES/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch
new file mode 100644
index 0000000..242b436
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch
@@ -0,0 +1,444 @@
+From aa8b6b2275fd14ba2cca3d2339ae61c7e7ddfa70 Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Tue, 5 May 2020 14:08:48 -0400
+Subject: [PATCH] Add Channel Binding support for GSSAPI/GSS-SPNEGO
+
+Backport of commit ids:
+829a6ed086432e26dafa9d1dcf892aef4c42cfbd
+944bd8a6205f840b105206ef83e8f6b9dff0138e
+
+Signed-off-by: Simo Sorce <simo@redhat.com>
+---
+ plugins/gssapi.c     | 30 +++++++++++---
+ tests/runtests.py    | 93 ++++++++++++++++++++++++++++++++++++++++----
+ tests/t_common.c     | 24 ++++++++----
+ tests/t_common.h     |  5 ++-
+ tests/t_gssapi_cli.c | 24 ++++++++++--
+ tests/t_gssapi_srv.c | 24 ++++++++++--
+ 6 files changed, 172 insertions(+), 28 deletions(-)
+
+diff --git a/plugins/gssapi.c b/plugins/gssapi.c
+index ff663da..5d900c5 100644
+--- a/plugins/gssapi.c
++++ b/plugins/gssapi.c
+@@ -830,7 +830,9 @@ gssapi_server_mech_authneg(context_t *text,
+     gss_buffer_desc name_without_realm;
+     gss_name_t client_name_MN = NULL, without = NULL;
+     gss_OID mech_type;
+-	
++    gss_channel_bindings_t bindings = GSS_C_NO_CHANNEL_BINDINGS;
++    struct gss_channel_bindings_struct cb = {0};
++
+     input_token = &real_input_token;
+     output_token = &real_output_token;
+     output_token->value = NULL; output_token->length = 0;
+@@ -902,6 +904,12 @@ gssapi_server_mech_authneg(context_t *text,
+ 	real_input_token.length = clientinlen;
+     }
+ 
++    if (params->cbinding != NULL) {
++        cb.application_data.length = params->cbinding->len;
++        cb.application_data.value = params->cbinding->data;
++        bindings = &cb;
++    }
++
+ 
+     GSS_LOCK_MUTEX_CTX(params->utils, text);
+     maj_stat =
+@@ -909,7 +917,7 @@ gssapi_server_mech_authneg(context_t *text,
+ 			       &(text->gss_ctx),
+ 			       server_creds,
+ 			       input_token,
+-			       GSS_C_NO_CHANNEL_BINDINGS,
++			       bindings,
+ 			       &text->client_name,
+ 			       &mech_type,
+ 			       output_token,
+@@ -1505,7 +1513,8 @@ static sasl_server_plug_t gssapi_server_plugins[] =
+ 	| SASL_SEC_PASS_CREDENTIALS,
+ 	SASL_FEAT_WANT_CLIENT_FIRST
+ 	| SASL_FEAT_ALLOWS_PROXY
+-	| SASL_FEAT_DONTUSE_USERPASSWD,	/* features */
++	| SASL_FEAT_DONTUSE_USERPASSWD
++	| SASL_FEAT_CHANNEL_BINDING,	/* features */
+ 	NULL,				/* glob_context */
+ 	&gssapi_server_mech_new,	/* mech_new */
+ 	&gssapi_server_mech_step,	/* mech_step */
+@@ -1529,6 +1538,7 @@ static sasl_server_plug_t gssapi_server_plugins[] =
+ 	SASL_FEAT_WANT_CLIENT_FIRST
+ 	| SASL_FEAT_ALLOWS_PROXY
+ 	| SASL_FEAT_DONTUSE_USERPASSWD
++	| SASL_FEAT_CHANNEL_BINDING
+ 	| SASL_FEAT_SUPPORTS_HTTP,	/* features */
+ 	&gss_spnego_oid,		/* glob_context */
+ 	&gssapi_server_mech_new,	/* mech_new */
+@@ -1662,6 +1672,8 @@ static int gssapi_client_mech_step(void *conn_context,
+     input_token->value = NULL; 
+     input_token->length = 0;
+     gss_cred_id_t client_creds = (gss_cred_id_t)params->gss_creds;
++    gss_channel_bindings_t bindings = GSS_C_NO_CHANNEL_BINDINGS;
++    struct gss_channel_bindings_struct cb = {0};
+ 
+     if (clientout)
+         *clientout = NULL;
+@@ -1777,6 +1789,12 @@ static int gssapi_client_mech_step(void *conn_context,
+ 	    req_flags = req_flags |  GSS_C_DELEG_FLAG;
+ 	}
+ 
++        if (params->cbinding != NULL) {
++            cb.application_data.length = params->cbinding->len;
++            cb.application_data.value = params->cbinding->data;
++            bindings = &cb;
++        }
++
+ 	GSS_LOCK_MUTEX_CTX(params->utils, text);
+ 	maj_stat = gss_init_sec_context(&min_stat,
+ 					client_creds, /* GSS_C_NO_CREDENTIAL */
+@@ -1785,7 +1803,7 @@ static int gssapi_client_mech_step(void *conn_context,
+ 					text->mech_type,
+ 					req_flags,
+ 					0,
+-					GSS_C_NO_CHANNEL_BINDINGS,
++					bindings,
+ 					input_token,
+ 					NULL,
+ 					output_token,
+@@ -2190,7 +2208,8 @@ static sasl_client_plug_t gssapi_client_plugins[] =
+ 	| SASL_SEC_PASS_CREDENTIALS,    /* security_flags */
+ 	SASL_FEAT_NEEDSERVERFQDN
+ 	| SASL_FEAT_WANT_CLIENT_FIRST
+-	| SASL_FEAT_ALLOWS_PROXY,	/* features */
++	| SASL_FEAT_ALLOWS_PROXY
++	| SASL_FEAT_CHANNEL_BINDING,	/* features */
+ 	gssapi_required_prompts,	/* required_prompts */
+ 	GSS_C_NO_OID,			/* glob_context */
+ 	&gssapi_client_mech_new,	/* mech_new */
+@@ -2213,6 +2232,7 @@ static sasl_client_plug_t gssapi_client_plugins[] =
+ 	SASL_FEAT_NEEDSERVERFQDN
+ 	| SASL_FEAT_WANT_CLIENT_FIRST
+ 	| SASL_FEAT_ALLOWS_PROXY
++	| SASL_FEAT_CHANNEL_BINDING
+ 	| SASL_FEAT_SUPPORTS_HTTP,	/* features */
+ 	gssapi_required_prompts,	/* required_prompts */
+ 	&gss_spnego_oid,		/* glob_context */
+diff --git a/tests/runtests.py b/tests/runtests.py
+index f645adf..fc9cf24 100755
+--- a/tests/runtests.py
++++ b/tests/runtests.py
+@@ -1,6 +1,7 @@
+ #!/usr/bin/python3
+ 
+ import argparse
++import base64
+ import os
+ import shutil
+ import signal
+@@ -126,14 +127,7 @@ def setup_kdc(testdir, env):
+ 
+     return kdc, env
+ 
+-
+-def gssapi_tests(testdir):
+-    """ SASL/GSSAPI Tests """
+-    env = setup_socket_wrappers(testdir)
+-    kdc, kenv = setup_kdc(testdir, env)
+-    #print("KDC: {}, ENV: {}".format(kdc, kenv))
+-    kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
+-
++def gssapi_basic_test(kenv):
+     try:
+         srv = subprocess.Popen(["../tests/t_gssapi_srv"],
+                                stdout=subprocess.PIPE,
+@@ -155,11 +149,94 @@ def gssapi_tests(testdir):
+                 srv.returncode, srv.stderr.read().decode('utf-8')))
+     except Exception as e:
+         print("FAIL: {}".format(e))
++        return
++
++    print("PASS: CLI({}) SRV({})".format(
++        cli.stdout.read().decode('utf-8').strip(),
++        srv.stdout.read().decode('utf-8').strip()))
++
++def gssapi_channel_binding_test(kenv):
++    try:
++        bindings = base64.b64encode("MATCHING CBS".encode('utf-8'))
++        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-c", bindings],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        srv.stdout.readline() # Wait for srv to say it is ready
++        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-c", bindings],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        try:
++            cli.wait(timeout=5)
++            srv.wait(timeout=5)
++        except Exception as e:
++            print("Failed on {}".format(e));
++            cli.kill()
++            srv.kill()
++        if cli.returncode != 0 or srv.returncode != 0:
++            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
++                cli.returncode, cli.stderr.read().decode('utf-8'),
++                srv.returncode, srv.stderr.read().decode('utf-8')))
++    except Exception as e:
++        print("FAIL: {}".format(e))
++        return
+ 
+     print("PASS: CLI({}) SRV({})".format(
+         cli.stdout.read().decode('utf-8').strip(),
+         srv.stdout.read().decode('utf-8').strip()))
+ 
++def gssapi_channel_binding_mismatch_test(kenv):
++    result = "FAIL"
++    try:
++        bindings = base64.b64encode("SRV CBS".encode('utf-8'))
++        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-c", bindings],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        srv.stdout.readline() # Wait for srv to say it is ready
++        bindings = base64.b64encode("CLI CBS".encode('utf-8'))
++        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-c", bindings],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        try:
++            cli.wait(timeout=5)
++            srv.wait(timeout=5)
++        except Exception as e:
++            print("Failed on {}".format(e));
++            cli.kill()
++            srv.kill()
++        if cli.returncode != 0 or srv.returncode != 0:
++            cli_err = cli.stderr.read().decode('utf-8').strip()
++            srv_err = srv.stderr.read().decode('utf-8').strip()
++            if "authentication failure" in srv_err:
++                result = "PASS"
++            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
++                cli.returncode, cli_err, srv.returncode, srv_err))
++    except Exception as e:
++        print("{}: {}".format(result, e))
++        return
++
++    print("FAIL: This test should fail [CLI({}) SRV({})]".format(
++        cli.stdout.read().decode('utf-8').strip(),
++        srv.stdout.read().decode('utf-8').strip()))
++
++def gssapi_tests(testdir):
++    """ SASL/GSSAPI Tests """
++    env = setup_socket_wrappers(testdir)
++    kdc, kenv = setup_kdc(testdir, env)
++    #print("KDC: {}, ENV: {}".format(kdc, kenv))
++    kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
++
++    print('GSSAPI BASIC:')
++    print('    ', end='')
++    gssapi_basic_test(kenv)
++
++    print('GSSAPI CHANNEL BINDING:')
++    print('    ', end='')
++    gssapi_channel_binding_test(kenv)
++
++    print('GSSAPI CHANNEL BINDING MISMTACH:')
++    print('    ', end='')
++    gssapi_channel_binding_mismatch_test(kenv)
++
+     os.killpg(kdc.pid, signal.SIGTERM)
+ 
+ 
+diff --git a/tests/t_common.c b/tests/t_common.c
+index 7168b2f..478e6a1 100644
+--- a/tests/t_common.c
++++ b/tests/t_common.c
+@@ -1,4 +1,5 @@
+-/* TBD, add (C) */
++/* Copyright (C) Simo Sorce <simo@redhat.com>
++ * See COPYING file for License */
+ 
+ #include <t_common.h>
+ 
+@@ -13,9 +14,6 @@ void send_string(int sd, const char *s, unsigned int l)
+ {
+     ssize_t ret;
+ 
+-fprintf(stderr, "s:%u ", l);
+-fflush(stderr);
+-
+     ret = send(sd, &l, sizeof(l), 0);
+     if (ret != sizeof(l)) s_error("send size", ret, sizeof(l), errno);
+ 
+@@ -34,8 +32,6 @@ void recv_string(int sd, char *buf, unsigned int *buflen)
+     if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
+ 
+     if (l == 0) {
+-fprintf(stderr, "r:0 ");
+-fflush(stderr);
+         *buflen = 0;
+         return;
+     }
+@@ -45,8 +41,6 @@ fflush(stderr);
+     ret = recv(sd, buf, l, 0);
+     if (ret != l) s_error("recv data", ret, l, errno);
+ 
+-fprintf(stderr, "r:%ld ", ret);
+-fflush(stderr);
+     *buflen = ret;
+ }
+ 
+@@ -65,4 +59,18 @@ int getpath(void *context __attribute__((unused)), const char **path)
+     return SASL_OK;
+ }
+ 
++void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in)
++{
++    unsigned len;
++    int r;
+ 
++    r = sasl_decode64(in, strlen(in), buf, max, &len);
++    if (r != SASL_OK) {
++        saslerr(r, "failed to parse channel bindings");
++        exit(-1);
++    }
++    cb->name = "TEST BINDINGS";
++    cb->critical = 0;
++    cb->data = (unsigned char *)buf;
++    cb->len = len;
++}
+diff --git a/tests/t_common.h b/tests/t_common.h
+index 4ee1976..a10def1 100644
+--- a/tests/t_common.h
++++ b/tests/t_common.h
+@@ -1,4 +1,5 @@
+-/* TBD, add (C) */
++/* Copyright (C) Simo Sorce <simo@redhat.com>
++ * See COPYING file for License */
+ 
+ #include "config.h"
+ 
+@@ -7,9 +8,11 @@
+ #include <sys/socket.h>
+ 
+ #include <sasl.h>
++#include <saslutil.h>
+ 
+ void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
+ void send_string(int sd, const char *s, unsigned int l);
+ void recv_string(int sd, char *buf, unsigned int *buflen);
+ void saslerr(int why, const char *what);
+ int getpath(void *context __attribute__((unused)), const char **path);
++void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
+diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
+index c833c05..a44a3f5 100644
+--- a/tests/t_gssapi_cli.c
++++ b/tests/t_gssapi_cli.c
+@@ -1,4 +1,5 @@
+-/* TBD, add (C) */
++/* Copyright (C) Simo Sorce <simo@redhat.com>
++ * See COPYING file for License */
+ 
+ #include "t_common.h"
+ 
+@@ -13,6 +14,7 @@
+ 
+ #include <arpa/inet.h>
+ #include <saslplug.h>
++#include <saslutil.h>
+ 
+ static int setup_socket(void)
+ {
+@@ -32,7 +34,7 @@ static int setup_socket(void)
+     return sock;
+ }
+ 
+-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
++int main(int argc, char *argv[])
+ {
+     sasl_callback_t callbacks[2] = {};
+     char buf[8192];
+@@ -40,8 +42,20 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+     sasl_conn_t *conn;
+     const char *data;
+     unsigned int len;
++    sasl_channel_binding_t cb = {0};
++    char cb_buf[256];
+     int sd;
+-    int r;
++    int c, r;
++
++    while ((c = getopt(argc, argv, "c:")) != EOF) {
++        switch (c) {
++        case 'c':
++            parse_cb(&cb, cb_buf, 256, optarg);
++            break;
++        default:
++            break;
++        }
++    }
+ 
+     /* initialize the sasl library */
+     callbacks[0].id = SASL_CB_GETPATH;
+@@ -60,6 +74,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+         exit(-1);
+     }
+ 
++    if (cb.name) {
++        sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
++    }
++
+     r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
+     if (r != SASL_OK && r != SASL_CONTINUE) {
+ 	saslerr(r, "starting SASL negotiation");
+diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
+index 29f538d..ef1217f 100644
+--- a/tests/t_gssapi_srv.c
++++ b/tests/t_gssapi_srv.c
+@@ -1,4 +1,5 @@
+-/* TBD, add (C) */
++/* Copyright (C) Simo Sorce <simo@redhat.com>
++ * See COPYING file for License */
+ 
+ #include "t_common.h"
+ 
+@@ -44,15 +45,28 @@ static int setup_socket(void)
+     return sd;
+ }
+ 
+-int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
++int main(int argc, char *argv[])
+ {
+     sasl_callback_t callbacks[2] = {};
+     char buf[8192];
+     sasl_conn_t *conn;
+     const char *data;
+     unsigned int len;
++    sasl_channel_binding_t cb = {0};
++    unsigned char cb_buf[256];
+     int sd;
+-    int r;
++    int c, r;
++
++    while ((c = getopt(argc, argv, "c:")) != EOF) {
++        switch (c) {
++        case 'c':
++            parse_cb(&cb, cb_buf, 256, optarg);
++            break;
++        default:
++            break;
++        }
++    }
++
+ 
+     /* initialize the sasl library */
+     callbacks[0].id = SASL_CB_GETPATH;
+@@ -72,6 +86,10 @@ int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
+         exit(-1);
+     }
+ 
++    if (cb.name) {
++        sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
++    }
++
+     sd = setup_socket();
+ 
+     len = 8192;
+-- 
+2.18.2
+
diff --git a/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch b/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch
new file mode 100644
index 0000000..2f6a35c
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch
@@ -0,0 +1,641 @@
+From 82e299e970461c153a036bb1fbc84e808f926e12 Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Tue, 5 May 2020 14:06:57 -0400
+Subject: [PATCH] Add basic test infrastructure
+
+First test is for SASL/GSSAPI
+
+Backport of upstream commit id:
+18ff41d5d18f61c2ded7235dad1d9618aa84784b
+
+Signed-off-by: Simo Sorce <simo@redhat.com>
+---
+ Makefile.am          |   2 +-
+ configure.ac         |   3 +-
+ tests/Makefile.am    |  79 +++++++++++++++++++
+ tests/runtests.py    | 179 +++++++++++++++++++++++++++++++++++++++++++
+ tests/t_common.c     |  68 ++++++++++++++++
+ tests/t_common.h     |  15 ++++
+ tests/t_gssapi_cli.c |  95 +++++++++++++++++++++++
+ tests/t_gssapi_srv.c | 111 +++++++++++++++++++++++++++
+ 8 files changed, 550 insertions(+), 2 deletions(-)
+ create mode 100644 tests/Makefile.am
+ create mode 100755 tests/runtests.py
+ create mode 100644 tests/t_common.c
+ create mode 100644 tests/t_common.h
+ create mode 100644 tests/t_gssapi_cli.c
+ create mode 100644 tests/t_gssapi_srv.c
+
+diff --git a/Makefile.am b/Makefile.am
+index 83dae6f..fc24509 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -70,7 +70,7 @@ else
+ INSTALLOSX = 
+ endif
+ 
+-SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD)
++SUBDIRS=include sasldb common lib plugins utils $(PWC) $(SAM) $(JAV) $(SAD) tests
+ EXTRA_DIST=config doc docsrc win32 mac dlcompat-20010505 NTMakefile \
+     INSTALL.TXT libsasl2.pc.in
+ 
+diff --git a/configure.ac b/configure.ac
+index ca5936a..c1d2182 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1575,7 +1575,8 @@ java/javax/Makefile
+ java/javax/security/Makefile
+ java/javax/security/auth/Makefile
+ java/javax/security/auth/callback/Makefile
+-pwcheck/Makefile)
++pwcheck/Makefile
++tests/Makefile)
+ 
+ AC_MSG_NOTICE([
+ 
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+new file mode 100644
+index 0000000..1edf010
+--- /dev/null
++++ b/tests/Makefile.am
+@@ -0,0 +1,79 @@
++# Makefile.am -- automake input for cyrus-sasl tests
++# Simo Sorce
++#
++################################################################
++# Copyright (c) 2000 Carnegie Mellon University.  All rights reserved.
++#
++# Redistribution and use in source and binary forms, with or without
++# modification, are permitted provided that the following conditions
++# are met:
++#
++# 1. Redistributions of source code must retain the above copyright
++#    notice, this list of conditions and the following disclaimer.
++#
++# 2. Redistributions in binary form must reproduce the above copyright
++#    notice, this list of conditions and the following disclaimer in
++#    the documentation and/or other materials provided with the
++#    distribution.
++#
++# 3. The name "Carnegie Mellon University" must not be used to
++#    endorse or promote products derived from this software without
++#    prior written permission. For permission or any other legal
++#    details, please contact
++#      Office of Technology Transfer
++#      Carnegie Mellon University
++#      5000 Forbes Avenue
++#      Pittsburgh, PA  15213-3890
++#      (412) 268-4387, fax: (412) 268-7395
++#      tech-transfer@andrew.cmu.edu
++#
++# 4. Redistributions of any form whatsoever must retain the following
++#    acknowledgment:
++#    "This product includes software developed by Computing Services
++#     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
++#
++# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
++# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
++# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
++# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
++# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
++# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++#
++################################################################
++
++AM_CPPFLAGS=-I$(top_srcdir)/include -DPLUGINDIR='"${top_srcdir}/plugins/.libs"'
++
++COMMON_LDADD = ../lib/libsasl2.la $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET)
++
++t_gssapi_cli_SOURCES = \
++	t_common.c \
++	t_gssapi_cli.c
++
++t_gssapi_cli_LDADD = $(COMMON_LDADD)
++
++t_gssapi_srv_SOURCES = \
++	t_common.c \
++	t_gssapi_srv.c
++
++t_gssapi_srv_LDADD = $(COMMON_LDADD)
++
++check_PROGRAMS = \
++	t_gssapi_cli \
++	t_gssapi_srv \
++	$(NULL)
++
++noinst_PROGRAMS = $(check_PROGRAMS)
++
++EXTRA_DIST = \
++	runtests.py \
++	$(NULL)
++
++all: $(check_PROGRAMS)
++
++check:
++if MACOSX
++# skip Mac OSX for now
++else
++	$(srcdir)/runtests.py $(CHECKARGS)
++endif
+diff --git a/tests/runtests.py b/tests/runtests.py
+new file mode 100755
+index 0000000..f645adf
+--- /dev/null
++++ b/tests/runtests.py
+@@ -0,0 +1,179 @@
++#!/usr/bin/python3
++
++import argparse
++import os
++import shutil
++import signal
++import subprocess
++import time
++from string import Template
++
++
++def setup_socket_wrappers(testdir):
++    """ Try to set up socket wrappers """
++    wrapdir = os.path.join(testdir, 'w')
++    os.makedirs(wrapdir)
++
++    wrappers = subprocess.Popen(['pkg-config', '--exists', 'socket_wrapper'])
++    wrappers.wait()
++    if wrappers.returncode != 0:
++        raise Exception('Socket Wrappers not available')
++
++    wrappers = subprocess.Popen(['pkg-config', '--exists', 'nss_wrapper'])
++    wrappers.wait()
++    if wrappers.returncode != 0:
++        raise Exception('NSS Wrappers not available')
++
++    hosts = os.path.join(wrapdir, 'hosts')
++    with open(hosts, 'w+') as conffile:
++        conffile.write('127.0.0.9 host.realm.test')
++
++    return {'LD_PRELOAD': 'libsocket_wrapper.so libnss_wrapper.so',
++            'SOCKET_WRAPPER_DIR': wrapdir,
++            'SOCKET_WRAPPER_DEFAULT_IFACE': '9',
++            'NSS_WRAPPER_HOSTNAME': 'host.realm.test',
++            'NSS_WRAPPER_HOSTS': hosts}
++
++
++KERBEROS_CONF = '''
++[libdefaults]
++  default_realm = REALM.TEST
++  dns_lookup_realm = false
++  dns_lookup_kdc = false
++  rdns = false
++  ticket_lifetime = 24h
++  forwardable = yes
++  default_ccache_name = FILE://${TESTDIR}/ccache
++  udp_preference_limit = 1
++
++[domain_realm]
++  .realm.test = REALM.TEST
++  realm.test = REALM.TEST
++
++[realms]
++ REALM.TEST = {
++  kdc = 127.0.0.9
++  admin_server = 127.0.0.9
++  acl_file = ${TESTDIR}/kadm.acl
++  dict_file = /usr/share/dict/words
++  admin_keytab = ${TESTDIR}/kadm.keytab
++  database_name = ${TESTDIR}/kdc.db
++  key_stash_file = ${TESTDIR}/kdc.stash
++ }
++
++[kdcdefaults]
++ kdc_ports = 88
++ kdc_tcp_ports = 88
++
++[logging]
++  kdc = FILE:${TESTDIR}/kdc.log
++  admin_server = FILE:${TESTDIR}/kadm.log
++  default = FILE:${TESTDIR}/krb5.log
++'''
++
++
++def setup_kdc(testdir, env):
++    """ Setup KDC and start process """
++    krbconf = os.path.join(testdir, 'krb.conf')
++    env['KRB5_CONFIG'] = krbconf
++
++    kenv = {'KRB5_KDC_PROFILE': krbconf,
++            'PATH': '/sbin:/bin:/usr/sbin:/usr/bin'}
++    kenv.update(env)
++
++    # KDC/KRB5 CONFIG
++    templ = Template(KERBEROS_CONF)
++    text = templ.substitute({'TESTDIR': testdir})
++    with open(krbconf, 'w+') as conffile:
++        conffile.write(text)
++
++    testlog = os.path.join(testdir, 'kdc.log')
++    log = open(testlog, 'a')
++
++    subprocess.check_call([
++        "kdb5_util", "create",
++        "-r", "REALM.TEST", "-s", "-P", "password"
++        ], stdout=log, stderr=log, env=kenv, timeout=5)
++
++    kdc = subprocess.Popen(['krb5kdc', '-n'], env=kenv, preexec_fn=os.setsid)
++    time.sleep(5)
++
++    # Add a user and genrate a keytab
++    keytab = os.path.join(testdir, "user.keytab")
++    subprocess.check_call([
++        "kadmin.local", "-q",
++        "addprinc -randkey user"
++        ], stdout=log, stderr=log, env=kenv, timeout=5)
++
++    subprocess.check_call([
++        "kadmin.local", "-q",
++        "ktadd -k {} user".format(keytab)
++        ], stdout=log, stderr=log, env=kenv, timeout=5)
++    env['KRB5_CLIENT_KTNAME'] = keytab
++
++    # Add a service and genrate a keytab
++    keytab = os.path.join(testdir, "test.keytab")
++    subprocess.check_call([
++        "kadmin.local", "-q",
++        "addprinc -randkey test/host.realm.test"
++        ], stdout=log, stderr=log, env=kenv, timeout=5)
++
++    subprocess.check_call([
++        "kadmin.local", "-q",
++        "ktadd -k {} test/host.realm.test".format(keytab)
++        ], stdout=log, stderr=log, env=kenv, timeout=5)
++    env['KRB5_KTNAME'] = keytab
++
++    return kdc, env
++
++
++def gssapi_tests(testdir):
++    """ SASL/GSSAPI Tests """
++    env = setup_socket_wrappers(testdir)
++    kdc, kenv = setup_kdc(testdir, env)
++    #print("KDC: {}, ENV: {}".format(kdc, kenv))
++    kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
++
++    try:
++        srv = subprocess.Popen(["../tests/t_gssapi_srv"],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        srv.stdout.readline() # Wait for srv to say it is ready
++        cli = subprocess.Popen(["../tests/t_gssapi_cli"],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        try:
++            cli.wait(timeout=5)
++            srv.wait(timeout=5)
++        except Exception as e:
++            print("Failed on {}".format(e));
++            cli.kill()
++            srv.kill()
++        if cli.returncode != 0 or srv.returncode != 0:
++            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
++                cli.returncode, cli.stderr.read().decode('utf-8'),
++                srv.returncode, srv.stderr.read().decode('utf-8')))
++    except Exception as e:
++        print("FAIL: {}".format(e))
++
++    print("PASS: CLI({}) SRV({})".format(
++        cli.stdout.read().decode('utf-8').strip(),
++        srv.stdout.read().decode('utf-8').strip()))
++
++    os.killpg(kdc.pid, signal.SIGTERM)
++
++
++if __name__ == "__main__":
++
++    P = argparse.ArgumentParser(description='Cyrus SASL Tests')
++    P.add_argument('--testdir', default=os.path.join(os.getcwd(), '.tests'),
++                   help="Directory for running tests")
++    A = vars(P.parse_args())
++
++    T = A['testdir']
++
++    if os.path.exists(T):
++        shutil.rmtree(T)
++    os.makedirs(T)
++
++    gssapi_tests(T)
+diff --git a/tests/t_common.c b/tests/t_common.c
+new file mode 100644
+index 0000000..7168b2f
+--- /dev/null
++++ b/tests/t_common.c
+@@ -0,0 +1,68 @@
++/* TBD, add (C) */
++
++#include <t_common.h>
++
++void s_error(const char *hdr, ssize_t ret, ssize_t len, int err)
++{
++    fprintf(stderr, "%s l:%ld/%ld [%d] %s",
++            hdr, ret, len, err, strerror(err));
++    exit(-1);
++}
++
++void send_string(int sd, const char *s, unsigned int l)
++{
++    ssize_t ret;
++
++fprintf(stderr, "s:%u ", l);
++fflush(stderr);
++
++    ret = send(sd, &l, sizeof(l), 0);
++    if (ret != sizeof(l)) s_error("send size", ret, sizeof(l), errno);
++
++    if (l == 0) return;
++
++    ret = send(sd, s, l, 0);
++    if (ret != l) s_error("send data", ret, l, errno);
++}
++
++void recv_string(int sd, char *buf, unsigned int *buflen)
++{
++    unsigned int l;
++    ssize_t ret;
++
++    ret = recv(sd, &l, sizeof(l), MSG_WAITALL);
++    if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
++
++    if (l == 0) {
++fprintf(stderr, "r:0 ");
++fflush(stderr);
++        *buflen = 0;
++        return;
++    }
++
++    if (*buflen < l) s_error("recv len", l, *buflen, E2BIG);
++
++    ret = recv(sd, buf, l, 0);
++    if (ret != l) s_error("recv data", ret, l, errno);
++
++fprintf(stderr, "r:%ld ", ret);
++fflush(stderr);
++    *buflen = ret;
++}
++
++void saslerr(int why, const char *what)
++{
++    fprintf(stderr, "%s: %s", what, sasl_errstring(why, NULL, NULL));
++}
++
++int getpath(void *context __attribute__((unused)), const char **path)
++{
++    if (! path) {
++        return SASL_BADPARAM;
++    }
++
++    *path = PLUGINDIR;
++    return SASL_OK;
++}
++
++
+diff --git a/tests/t_common.h b/tests/t_common.h
+new file mode 100644
+index 0000000..4ee1976
+--- /dev/null
++++ b/tests/t_common.h
+@@ -0,0 +1,15 @@
++/* TBD, add (C) */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <sys/socket.h>
++
++#include <sasl.h>
++
++void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
++void send_string(int sd, const char *s, unsigned int l);
++void recv_string(int sd, char *buf, unsigned int *buflen);
++void saslerr(int why, const char *what);
++int getpath(void *context __attribute__((unused)), const char **path);
+diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
+new file mode 100644
+index 0000000..c833c05
+--- /dev/null
++++ b/tests/t_gssapi_cli.c
+@@ -0,0 +1,95 @@
++/* TBD, add (C) */
++
++#include "t_common.h"
++
++#include <stdlib.h>
++#include <stdarg.h>
++#include <ctype.h>
++#include <string.h>
++
++#ifdef HAVE_UNISTD_H
++#include <unistd.h>
++#endif
++
++#include <arpa/inet.h>
++#include <saslplug.h>
++
++static int setup_socket(void)
++{
++    struct sockaddr_in addr;
++    int sock, ret;
++
++    sock = socket(AF_INET, SOCK_STREAM, 0);
++    if (sock < 0) s_error("socket", 0, 0, errno);
++
++    addr.sin_family = AF_INET;
++    addr.sin_addr.s_addr = inet_addr("127.0.0.9");
++    addr.sin_port = htons(9000);
++
++    ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
++    if (ret != 0) s_error("connect", 0, 0, errno);
++
++    return sock;
++}
++
++int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
++{
++    sasl_callback_t callbacks[2] = {};
++    char buf[8192];
++    const char *chosenmech;
++    sasl_conn_t *conn;
++    const char *data;
++    unsigned int len;
++    int sd;
++    int r;
++
++    /* initialize the sasl library */
++    callbacks[0].id = SASL_CB_GETPATH;
++    callbacks[0].proc = (sasl_callback_ft)&getpath;
++    callbacks[0].context = NULL;
++    callbacks[1].id = SASL_CB_LIST_END;
++    callbacks[1].proc = NULL;
++    callbacks[1].context = NULL;
++
++    r = sasl_client_init(callbacks);
++    if (r != SASL_OK) exit(-1);
++
++    r = sasl_client_new("test", "host.realm.test", NULL, NULL, NULL, 0, &conn);
++    if (r != SASL_OK) {
++        saslerr(r, "allocating connection state");
++        exit(-1);
++    }
++
++    r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
++    if (r != SASL_OK && r != SASL_CONTINUE) {
++	saslerr(r, "starting SASL negotiation");
++	printf("\n%s\n", sasl_errdetail(conn));
++	exit(-1);
++    }
++
++    sd = setup_socket();
++
++    while (r == SASL_CONTINUE) {
++        send_string(sd, data, len);
++        len = 8192;
++        recv_string(sd, buf, &len);
++
++	r = sasl_client_step(conn, buf, len, NULL, &data, &len);
++	if (r != SASL_OK && r != SASL_CONTINUE) {
++	    saslerr(r, "performing SASL negotiation");
++	    printf("\n%s\n", sasl_errdetail(conn));
++	    exit(-1);
++        }
++    }
++
++    if (r != SASL_OK) exit(-1);
++
++    if (len > 0) {
++        send_string(sd, data, len);
++    }
++
++    fprintf(stdout, "DONE\n");
++    fflush(stdout);
++    return 0;
++}
++
+diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
+new file mode 100644
+index 0000000..29f538d
+--- /dev/null
++++ b/tests/t_gssapi_srv.c
+@@ -0,0 +1,111 @@
++/* TBD, add (C) */
++
++#include "t_common.h"
++
++#include <stdlib.h>
++#include <stdarg.h>
++#include <ctype.h>
++#include <string.h>
++
++#ifdef HAVE_UNISTD_H
++#include <unistd.h>
++#endif
++
++#include <arpa/inet.h>
++#include <saslplug.h>
++
++static int setup_socket(void)
++{
++    struct sockaddr_in addr;
++    int sock, ret, sd;
++
++    sock = socket(AF_INET, SOCK_STREAM, 0);
++    if (sock < 0) s_error("socket", 0, 0, errno);
++
++    addr.sin_family = AF_INET;
++    addr.sin_addr.s_addr = inet_addr("127.0.0.9");
++    addr.sin_port = htons(9000);
++
++    ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
++    if (ret != 0) s_error("bind", 0, 0, errno);
++
++    ret = listen(sock, 1);
++    if (ret != 0) s_error("listen", 0, 0, errno);
++
++    /* signal we are ready */
++    fprintf(stdout, "READY\n");
++    fflush(stdout);
++
++    /* block until the client connects */
++    sd = accept(sock, NULL, NULL);
++    if (sd < 0) s_error("accept", 0, 0, errno);
++
++    close(sock);
++    return sd;
++}
++
++int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
++{
++    sasl_callback_t callbacks[2] = {};
++    char buf[8192];
++    sasl_conn_t *conn;
++    const char *data;
++    unsigned int len;
++    int sd;
++    int r;
++
++    /* initialize the sasl library */
++    callbacks[0].id = SASL_CB_GETPATH;
++    callbacks[0].proc = (sasl_callback_ft)&getpath;
++    callbacks[0].context = NULL;
++    callbacks[1].id = SASL_CB_LIST_END;
++    callbacks[1].proc = NULL;
++    callbacks[1].context = NULL;
++
++    r = sasl_server_init(callbacks, "t_gssapi_srv");
++    if (r != SASL_OK) exit(-1);
++
++    r = sasl_server_new("test", "host.realm.test", NULL, NULL, NULL,
++                        callbacks, 0, &conn);
++    if (r != SASL_OK) {
++        saslerr(r, "allocating connection state");
++        exit(-1);
++    }
++
++    sd = setup_socket();
++
++    len = 8192;
++    recv_string(sd, buf, &len);
++
++    r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
++    if (r != SASL_OK && r != SASL_CONTINUE) {
++	saslerr(r, "starting SASL negotiation");
++	printf("\n%s\n", sasl_errdetail(conn));
++	exit(-1);
++    }
++
++    while (r == SASL_CONTINUE) {
++        send_string(sd, data, len);
++        len = 8192;
++        recv_string(sd, buf, &len);
++
++	r = sasl_server_step(conn, buf, len, &data, &len);
++	if (r != SASL_OK && r != SASL_CONTINUE) {
++	    saslerr(r, "performing SASL negotiation");
++	    printf("\n%s\n", sasl_errdetail(conn));
++	    exit(-1);
++	}
++
++    }
++
++    if (r != SASL_OK) exit(-1);
++
++    if (len > 0) {
++        send_string(sd, data, len);
++    }
++
++    fprintf(stdout, "DONE\n");
++    fflush(stdout);
++    return 0;
++}
++
+-- 
+2.18.2
+
diff --git a/SOURCES/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch b/SOURCES/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch
new file mode 100644
index 0000000..c8c4a79
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch
@@ -0,0 +1,435 @@
+From 49e965f41257a0ed299c58a7cf1c120ddf944aaa Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Tue, 5 May 2020 14:51:36 -0400
+Subject: [PATCH] Add support for setting max ssf 0 to GSS-SPNEGO
+
+Bacport form this proposed PR (still open at bacport time):
+https://github.com/cyrusimap/cyrus-sasl/pull/603
+
+Signed-off-by: Simo Sorce <simo@redhat.com>
+---
+ m4/sasl2.m4          | 13 +++++++
+ plugins/gssapi.c     | 44 ++++++++++++++++++++-
+ tests/runtests.py    | 91 ++++++++++++++++++++++++++++++++++++++++----
+ tests/t_common.c     | 13 ++++---
+ tests/t_common.h     |  3 +-
+ tests/t_gssapi_cli.c | 25 ++++++++++--
+ tests/t_gssapi_srv.c | 28 +++++++++++---
+ 7 files changed, 194 insertions(+), 23 deletions(-)
+
+diff --git a/m4/sasl2.m4 b/m4/sasl2.m4
+index 56e0504..6effe99 100644
+--- a/m4/sasl2.m4
++++ b/m4/sasl2.m4
+@@ -287,6 +287,19 @@ if test "$gssapi" != no; then
+   AC_CHECK_FUNCS(gss_oid_equal)
+   LIBS="$cmu_save_LIBS"
+ 
++  cmu_save_LIBS="$LIBS"
++  LIBS="$LIBS $GSSAPIBASE_LIBS"
++  if test "$ac_cv_header_gssapi_gssapi_krb5_h" = "yes"; then
++    AC_CHECK_DECL(GSS_KRB5_CRED_NO_CI_FLAGS_X,
++                  [AC_DEFINE(HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X,1,
++                             [Define if your GSSAPI implementation supports GSS_KRB5_CRED_NO_CI_FLAGS_X])],,
++                  [
++                    AC_INCLUDES_DEFAULT
++                    #include <gssapi/gssapi_krb5.h>
++                    ])
++  fi
++  LIBS="$cmu_save_LIBS"
++
+   cmu_save_LIBS="$LIBS"
+   LIBS="$LIBS $GSSAPIBASE_LIBS"
+   AC_CHECK_FUNCS(gss_get_name_attribute)
+diff --git a/plugins/gssapi.c b/plugins/gssapi.c
+index 5d900c5..7480316 100644
+--- a/plugins/gssapi.c
++++ b/plugins/gssapi.c
+@@ -1783,7 +1783,49 @@ static int gssapi_client_mech_step(void *conn_context,
+ 		/* We want to try for privacy */
+ 		req_flags |= GSS_C_CONF_FLAG;
+ 	    }
+-	}
++#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
++        /* The krb5 mechanism automatically adds INTEG and CONF flags even when
++         * not specified, this has the effect of rendering explicit requests
++         * of no confidentiality and integrity via setting maxssf 0 moot.
++         * However to interoperate with Windows machines it needs to be
++         * possible to unset these flags as Windows machines refuse to allow
++         * two layers (say TLS and GSSAPI) to both provide these services.
++         * So if we do not suppress these flags a SASL/GSS-SPNEGO negotiation
++         * over, say, LDAPS will fail against Windows Servers */
++	} else if (params->props.max_ssf == 0) {
++            gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
++            if (client_creds == GSS_C_NO_CREDENTIAL) {
++                gss_OID_set_desc mechs = { 0 };
++                gss_OID_set desired_mechs = GSS_C_NO_OID_SET;
++                if (text->mech_type != GSS_C_NO_OID) {
++                    mechs.count = 1;
++                    mechs.elements = text->mech_type;
++                    desired_mechs = &mechs;
++                }
++
++                maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME,
++                                            GSS_C_INDEFINITE, desired_mechs,
++                                            GSS_C_INITIATE,
++                                            &text->client_creds, NULL, NULL);
++                if (GSS_ERROR(maj_stat)) {
++                    sasl_gss_seterror(text->utils, maj_stat, min_stat);
++                    sasl_gss_free_context_contents(text);
++                    return SASL_FAIL;
++                }
++                client_creds = text->client_creds;
++            }
++
++            maj_stat = gss_set_cred_option(&min_stat, &client_creds,
++                                           (gss_OID)GSS_KRB5_CRED_NO_CI_FLAGS_X,
++                                            &empty_buffer);
++            if (GSS_ERROR(maj_stat)) {
++                sasl_gss_seterror(text->utils, maj_stat, min_stat);
++                sasl_gss_free_context_contents(text);
++                return SASL_FAIL;
++            }
++#endif
++        }
++
+ 
+ 	if (params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) {
+ 	    req_flags = req_flags |  GSS_C_DELEG_FLAG;
+diff --git a/tests/runtests.py b/tests/runtests.py
+index fc9cf24..4106401 100755
+--- a/tests/runtests.py
++++ b/tests/runtests.py
+@@ -6,6 +6,7 @@ import os
+ import shutil
+ import signal
+ import subprocess
++import sys
+ import time
+ from string import Template
+ 
+@@ -149,11 +150,12 @@ def gssapi_basic_test(kenv):
+                 srv.returncode, srv.stderr.read().decode('utf-8')))
+     except Exception as e:
+         print("FAIL: {}".format(e))
+-        return
++        return 1
+ 
+     print("PASS: CLI({}) SRV({})".format(
+         cli.stdout.read().decode('utf-8').strip(),
+         srv.stdout.read().decode('utf-8').strip()))
++    return 0
+ 
+ def gssapi_channel_binding_test(kenv):
+     try:
+@@ -178,11 +180,12 @@ def gssapi_channel_binding_test(kenv):
+                 srv.returncode, srv.stderr.read().decode('utf-8')))
+     except Exception as e:
+         print("FAIL: {}".format(e))
+-        return
++        return 1
+ 
+     print("PASS: CLI({}) SRV({})".format(
+         cli.stdout.read().decode('utf-8').strip(),
+         srv.stdout.read().decode('utf-8').strip()))
++    return 0
+ 
+ def gssapi_channel_binding_mismatch_test(kenv):
+     result = "FAIL"
+@@ -212,11 +215,70 @@ def gssapi_channel_binding_mismatch_test(kenv):
+                 cli.returncode, cli_err, srv.returncode, srv_err))
+     except Exception as e:
+         print("{}: {}".format(result, e))
+-        return
++        return 0
+ 
+     print("FAIL: This test should fail [CLI({}) SRV({})]".format(
+         cli.stdout.read().decode('utf-8').strip(),
+         srv.stdout.read().decode('utf-8').strip()))
++    return 1
++
++def gss_spnego_basic_test(kenv):
++    try:
++        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N"],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        srv.stdout.readline() # Wait for srv to say it is ready
++        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N"],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        try:
++            cli.wait(timeout=5)
++            srv.wait(timeout=5)
++        except Exception as e:
++            print("Failed on {}".format(e));
++            cli.kill()
++            srv.kill()
++        if cli.returncode != 0 or srv.returncode != 0:
++            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
++                cli.returncode, cli.stderr.read().decode('utf-8'),
++                srv.returncode, srv.stderr.read().decode('utf-8')))
++    except Exception as e:
++        print("FAIL: {}".format(e))
++        return 1
++
++    print("PASS: CLI({}) SRV({})".format(
++        cli.stdout.read().decode('utf-8').strip(),
++        srv.stdout.read().decode('utf-8').strip()))
++    return 0
++
++def gss_spnego_zeromaxssf_test(kenv):
++    try:
++        srv = subprocess.Popen(["../tests/t_gssapi_srv", "-N", "-z"],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        srv.stdout.readline() # Wait for srv to say it is ready
++        cli = subprocess.Popen(["../tests/t_gssapi_cli", "-N", "-z"],
++                               stdout=subprocess.PIPE,
++                               stderr=subprocess.PIPE, env=kenv)
++        try:
++            cli.wait(timeout=5)
++            srv.wait(timeout=5)
++        except Exception as e:
++            print("Failed on {}".format(e));
++            cli.kill()
++            srv.kill()
++        if cli.returncode != 0 or srv.returncode != 0:
++            raise Exception("CLI ({}): {} --> SRV ({}): {}".format(
++                cli.returncode, cli.stderr.read().decode('utf-8'),
++                srv.returncode, srv.stderr.read().decode('utf-8')))
++    except Exception as e:
++        print("FAIL: {}".format(e))
++        return 1
++
++    print("PASS: CLI({}) SRV({})".format(
++        cli.stdout.read().decode('utf-8').strip(),
++        srv.stdout.read().decode('utf-8').strip()))
++    return 0
+ 
+ def gssapi_tests(testdir):
+     """ SASL/GSSAPI Tests """
+@@ -225,20 +287,32 @@ def gssapi_tests(testdir):
+     #print("KDC: {}, ENV: {}".format(kdc, kenv))
+     kenv['KRB5_TRACE'] = os.path.join(testdir, 'trace.log')
+ 
++    err = 0
++
+     print('GSSAPI BASIC:')
+     print('    ', end='')
+-    gssapi_basic_test(kenv)
++    err += gssapi_basic_test(kenv)
+ 
+     print('GSSAPI CHANNEL BINDING:')
+     print('    ', end='')
+-    gssapi_channel_binding_test(kenv)
++    err += gssapi_channel_binding_test(kenv)
+ 
+     print('GSSAPI CHANNEL BINDING MISMTACH:')
+     print('    ', end='')
+-    gssapi_channel_binding_mismatch_test(kenv)
++    err += gssapi_channel_binding_mismatch_test(kenv)
++
++    print('GSS-SPNEGO BASIC:')
++    print('    ', end='')
++    err += gss_spnego_basic_test(kenv)
++
++    print('GSS-SPNEGO 0 MAXSSF:')
++    print('    ', end='')
++    err += gss_spnego_zeromaxssf_test(kenv)
+ 
+     os.killpg(kdc.pid, signal.SIGTERM)
+ 
++    return err
++
+ 
+ if __name__ == "__main__":
+ 
+@@ -253,4 +327,7 @@ if __name__ == "__main__":
+         shutil.rmtree(T)
+     os.makedirs(T)
+ 
+-    gssapi_tests(T)
++    err = gssapi_tests(T)
++    if err != 0:
++        print('{} test(s) FAILED'.format(err))
++        sys.exit(-1)
+diff --git a/tests/t_common.c b/tests/t_common.c
+index 478e6a1..f56098e 100644
+--- a/tests/t_common.c
++++ b/tests/t_common.c
+@@ -23,20 +23,21 @@ void send_string(int sd, const char *s, unsigned int l)
+     if (ret != l) s_error("send data", ret, l, errno);
+ }
+ 
+-void recv_string(int sd, char *buf, unsigned int *buflen)
++void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof)
+ {
++    unsigned int bufsize = *buflen;
+     unsigned int l;
+     ssize_t ret;
+ 
++    *buflen = 0;
++
+     ret = recv(sd, &l, sizeof(l), MSG_WAITALL);
++    if (allow_eof && ret == 0) return;
+     if (ret != sizeof(l)) s_error("recv size", ret, sizeof(l), errno);
+ 
+-    if (l == 0) {
+-        *buflen = 0;
+-        return;
+-    }
++    if (l == 0) return;
+ 
+-    if (*buflen < l) s_error("recv len", l, *buflen, E2BIG);
++    if (bufsize < l) s_error("recv len", l, bufsize, E2BIG);
+ 
+     ret = recv(sd, buf, l, 0);
+     if (ret != l) s_error("recv data", ret, l, errno);
+diff --git a/tests/t_common.h b/tests/t_common.h
+index a10def1..be24a53 100644
+--- a/tests/t_common.h
++++ b/tests/t_common.h
+@@ -4,6 +4,7 @@
+ #include "config.h"
+ 
+ #include <errno.h>
++#include <stdbool.h>
+ #include <stdio.h>
+ #include <sys/socket.h>
+ 
+@@ -12,7 +13,7 @@
+ 
+ void s_error(const char *hdr, ssize_t ret, ssize_t len, int err);
+ void send_string(int sd, const char *s, unsigned int l);
+-void recv_string(int sd, char *buf, unsigned int *buflen);
++void recv_string(int sd, char *buf, unsigned int *buflen, bool allow_eof);
+ void saslerr(int why, const char *what);
+ int getpath(void *context __attribute__((unused)), const char **path);
+ void parse_cb(sasl_channel_binding_t *cb, char *buf, unsigned max, char *in);
+diff --git a/tests/t_gssapi_cli.c b/tests/t_gssapi_cli.c
+index a44a3f5..d9eafe1 100644
+--- a/tests/t_gssapi_cli.c
++++ b/tests/t_gssapi_cli.c
+@@ -46,12 +46,21 @@ int main(int argc, char *argv[])
+     char cb_buf[256];
+     int sd;
+     int c, r;
++    const char *sasl_mech = "GSSAPI";
++    bool spnego = false;
++    bool zeromaxssf = false;
+ 
+-    while ((c = getopt(argc, argv, "c:")) != EOF) {
++    while ((c = getopt(argc, argv, "c:zN")) != EOF) {
+         switch (c) {
+         case 'c':
+             parse_cb(&cb, cb_buf, 256, optarg);
+             break;
++        case 'z':
++            zeromaxssf = true;
++            break;
++        case 'N':
++            spnego = true;
++            break;
+         default:
+             break;
+         }
+@@ -78,7 +87,17 @@ int main(int argc, char *argv[])
+         sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
+     }
+ 
+-    r = sasl_client_start(conn, "GSSAPI", NULL, &data, &len, &chosenmech);
++    if (spnego) {
++        sasl_mech = "GSS-SPNEGO";
++    }
++
++    if (zeromaxssf) {
++        /* set all security properties to 0 including maxssf */
++        sasl_security_properties_t secprops = { 0 };
++        sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
++    }
++
++    r = sasl_client_start(conn, sasl_mech, NULL, &data, &len, &chosenmech);
+     if (r != SASL_OK && r != SASL_CONTINUE) {
+ 	saslerr(r, "starting SASL negotiation");
+ 	printf("\n%s\n", sasl_errdetail(conn));
+@@ -90,7 +109,7 @@ int main(int argc, char *argv[])
+     while (r == SASL_CONTINUE) {
+         send_string(sd, data, len);
+         len = 8192;
+-        recv_string(sd, buf, &len);
++        recv_string(sd, buf, &len, false);
+ 
+ 	r = sasl_client_step(conn, buf, len, NULL, &data, &len);
+ 	if (r != SASL_OK && r != SASL_CONTINUE) {
+diff --git a/tests/t_gssapi_srv.c b/tests/t_gssapi_srv.c
+index ef1217f..448a218 100644
+--- a/tests/t_gssapi_srv.c
++++ b/tests/t_gssapi_srv.c
+@@ -56,12 +56,21 @@ int main(int argc, char *argv[])
+     unsigned char cb_buf[256];
+     int sd;
+     int c, r;
++    const char *sasl_mech = "GSSAPI";
++    bool spnego = false;
++    bool zeromaxssf = false;
+ 
+-    while ((c = getopt(argc, argv, "c:")) != EOF) {
++    while ((c = getopt(argc, argv, "c:zN")) != EOF) {
+         switch (c) {
+         case 'c':
+             parse_cb(&cb, cb_buf, 256, optarg);
+             break;
++        case 'z':
++            zeromaxssf = true;
++            break;
++        case 'N':
++            spnego = true;
++            break;
+         default:
+             break;
+         }
+@@ -90,12 +99,22 @@ int main(int argc, char *argv[])
+         sasl_setprop(conn, SASL_CHANNEL_BINDING, &cb);
+     }
+ 
++    if (spnego) {
++        sasl_mech = "GSS-SPNEGO";
++    }
++
++    if (zeromaxssf) {
++        /* set all security properties to 0 including maxssf */
++        sasl_security_properties_t secprops = { 0 };
++        sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
++    }
++
+     sd = setup_socket();
+ 
+     len = 8192;
+-    recv_string(sd, buf, &len);
++    recv_string(sd, buf, &len, false);
+ 
+-    r = sasl_server_start(conn, "GSSAPI", buf, len, &data, &len);
++    r = sasl_server_start(conn, sasl_mech, buf, len, &data, &len);
+     if (r != SASL_OK && r != SASL_CONTINUE) {
+ 	saslerr(r, "starting SASL negotiation");
+ 	printf("\n%s\n", sasl_errdetail(conn));
+@@ -105,7 +124,7 @@ int main(int argc, char *argv[])
+     while (r == SASL_CONTINUE) {
+         send_string(sd, data, len);
+         len = 8192;
+-        recv_string(sd, buf, &len);
++        recv_string(sd, buf, &len, true);
+ 
+ 	r = sasl_server_step(conn, buf, len, &data, &len);
+ 	if (r != SASL_OK && r != SASL_CONTINUE) {
+@@ -113,7 +132,6 @@ int main(int argc, char *argv[])
+ 	    printf("\n%s\n", sasl_errdetail(conn));
+ 	    exit(-1);
+ 	}
+-
+     }
+ 
+     if (r != SASL_OK) exit(-1);
+-- 
+2.18.2
+
diff --git a/SOURCES/cyrus-sasl-2.1.27-CVE-2019-19906.patch b/SOURCES/cyrus-sasl-2.1.27-CVE-2019-19906.patch
new file mode 100644
index 0000000..ad278aa
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.27-CVE-2019-19906.patch
@@ -0,0 +1,29 @@
+From bcb6c06ec17728f7c9c492dc257b1e541a6830da Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Tue, 5 May 2020 14:41:06 -0400
+Subject: [PATCH] CVE-2019-19906
+
+Backport of commit id:
+dcc9f51cbd4ed622cfb0f9b1c141eb2ffe3b12f1
+
+Signed-off-by: Simo Sorce <simo@redhat.com>
+---
+ lib/common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/common.c b/lib/common.c
+index bc3bf1d..9969d6a 100644
+--- a/lib/common.c
++++ b/lib/common.c
+@@ -190,7 +190,7 @@ int _sasl_add_string(char **out, size_t *alloclen,
+ 
+   if (add==NULL) add = "(null)";
+ 
+-  addlen=strlen(add); /* only compute once */
++  addlen=strlen(add)+1; /* only compute once */
+   if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK)
+     return SASL_NOMEM;
+ 
+-- 
+2.18.2
+
diff --git a/SOURCES/cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch b/SOURCES/cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch
new file mode 100644
index 0000000..d5e1334
--- /dev/null
+++ b/SOURCES/cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch
@@ -0,0 +1,42 @@
+From ec070b2e83a4ee698c08d6d68c205aea4d90b0bb Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Tue, 5 May 2020 14:31:10 -0400
+Subject: [PATCH] Emit debug log only in case of errors
+
+Backport of commit id:
+ccc5e547d4b40ee2b182a9945f8f6cc10b4fdf48
+
+Signed-off-by: Simo Sorce <simo@redhat.com>
+---
+ plugins/gssapi.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/plugins/gssapi.c b/plugins/gssapi.c
+index 7480316..6bcd78e 100644
+--- a/plugins/gssapi.c
++++ b/plugins/gssapi.c
+@@ -1444,9 +1444,6 @@ gssapi_server_mech_step(void *conn_context,
+ 
+     if (text == NULL) return SASL_BADPROT;
+ 
+-    params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
+-		       "GSSAPI server step %d\n", text->state);
+-
+     switch (text->state) {
+ 
+     case SASL_GSSAPI_STATE_AUTHNEG:
+@@ -1496,8 +1493,10 @@ gssapi_server_mech_step(void *conn_context,
+ 	}
+ 
+ 	oparams->doneflag = 1;
++    } else {
++        params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
++		           "GSSAPI server step failed: %d\n", text->state);
+     }
+-    
+     return ret;
+ }
+ 
+-- 
+2.18.2
+
diff --git a/SOURCES/cyrus-sasl-pr559-RC4-openssl.patch b/SOURCES/cyrus-sasl-pr559-RC4-openssl.patch
new file mode 100644
index 0000000..1993639
--- /dev/null
+++ b/SOURCES/cyrus-sasl-pr559-RC4-openssl.patch
@@ -0,0 +1,155 @@
+From 8aa9ae816ddf66921b4a8a0f422517e6f2e55ac6 Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Wed, 27 Mar 2019 14:29:08 -0400
+Subject: [PATCH] Use Openssl RC4 when available
+
+Signed-off-by: Simo Sorce <simo@redhat.com>
+---
+ configure.ac        |   5 +--
+ plugins/digestmd5.c | 107 +++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 108 insertions(+), 4 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 388f5d02..cfdee4a2 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1102,12 +1102,11 @@ AC_ARG_WITH(configdir, [   --with-configdir=DIR    set the directory where confi
+ AC_SUBST(configdir)
+ 
+-dnl look for rc4 libraries. we accept the CMU one or one from openSSL
+-AC_ARG_WITH(rc4, [  --with-rc4              use internal rc4 routines [[yes]] ],
++AC_ARG_WITH(rc4, [  --with-rc4              use rc4 routines [[yes]] ],
+ 	with_rc4=$withval,
+ 	with_rc4=yes)
+ 
+ if test "$with_rc4" != no; then
+-    AC_DEFINE(WITH_RC4,[],[Use internal RC4 implementation?])
++    AC_DEFINE(WITH_RC4,[],[Use RC4])
+ fi
+ 
+ building_for_macosx=no
+diff --git a/plugins/digestmd5.c b/plugins/digestmd5.c
+index df35093d..c6b54317 100644
+--- a/plugins/digestmd5.c
++++ b/plugins/digestmd5.c
+@@ -1117,6 +1117,111 @@ static void free_des(context_t *text)
+ #endif /* WITH_DES */
+ 
+ #ifdef WITH_RC4
++#ifdef HAVE_OPENSSL
++#include <openssl/evp.h>
++
++static void free_rc4(context_t *text)
++{
++    if (text->cipher_enc_context) {
++        EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_enc_context);
++        text->cipher_enc_context = NULL;
++    }
++    if (text->cipher_dec_context) {
++        EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)text->cipher_dec_context);
++        text->cipher_dec_context = NULL;
++    }
++}
++
++static int init_rc4(context_t *text,
++		    unsigned char enckey[16],
++		    unsigned char deckey[16])
++{
++    EVP_CIPHER_CTX *ctx;
++    int rc;
++
++    ctx = EVP_CIPHER_CTX_new();
++    if (ctx == NULL) return SASL_NOMEM;
++
++    rc = EVP_EncryptInit_ex(ctx, EVP_rc4(), NULL, enckey, NULL);
++    if (rc != 1) return SASL_FAIL;
++
++    text->cipher_enc_context = (void *)ctx;
++
++    ctx = EVP_CIPHER_CTX_new();
++    if (ctx == NULL) return SASL_NOMEM;
++
++    rc = EVP_DecryptInit_ex(ctx, EVP_rc4(), NULL, deckey, NULL);
++    if (rc != 1) return SASL_FAIL;
++
++    text->cipher_dec_context = (void *)ctx;
++
++    return SASL_OK;
++}
++
++static int dec_rc4(context_t *text,
++		   const char *input,
++		   unsigned inputlen,
++		   unsigned char digest[16] __attribute__((unused)),
++		   char *output,
++		   unsigned *outputlen)
++{
++    int len;
++    int rc;
++
++    /* decrypt the text part & HMAC */
++    rc = EVP_DecryptUpdate((EVP_CIPHER_CTX *)text->cipher_dec_context,
++                           (unsigned char *)output, &len,
++                           (const unsigned char *)input, inputlen);
++    if (rc != 1) return SASL_FAIL;
++
++    *outputlen = len;
++
++    rc = EVP_DecryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_dec_context,
++                             (unsigned char *)output + len, &len);
++    if (rc != 1) return SASL_FAIL;
++
++    *outputlen += len;
++
++    /* subtract the HMAC to get the text length */
++    *outputlen -= 10;
++
++    return SASL_OK;
++}
++
++static int enc_rc4(context_t *text,
++		   const char *input,
++		   unsigned inputlen,
++		   unsigned char digest[16],
++		   char *output,
++		   unsigned *outputlen)
++{
++    int len;
++    int rc;
++    /* encrypt the text part */
++    rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
++                           (unsigned char *)output, &len,
++                           (const unsigned char *)input, inputlen);
++    if (rc != 1) return SASL_FAIL;
++
++    *outputlen = len;
++
++    /* encrypt the `MAC part */
++    rc = EVP_EncryptUpdate((EVP_CIPHER_CTX *)text->cipher_enc_context,
++                           (unsigned char *)output + *outputlen, &len,
++                           digest, 10);
++    if (rc != 1) return SASL_FAIL;
++
++    *outputlen += len;
++
++    rc = EVP_EncryptFinal_ex((EVP_CIPHER_CTX *)text->cipher_enc_context,
++                             (unsigned char *)output + *outputlen, &len);
++    if (rc != 1) return SASL_FAIL;
++
++    *outputlen += len;
++
++    return SASL_OK;
++}
++#else
+ /* quick generic implementation of RC4 */
+ struct rc4_context_s {
+     unsigned char sbox[256];
+@@ -1296,7 +1401,7 @@ static int enc_rc4(context_t *text,
+     
+     return SASL_OK;
+ }
+-
++#endif /* HAVE_OPENSSL */
+ #endif /* WITH_RC4 */
+ 
+ struct digest_cipher available_ciphers[] =
diff --git a/SOURCES/make-no-dlcompatorsrp-tarball.sh b/SOURCES/make-no-dlcompatorsrp-tarball.sh
new file mode 100755
index 0000000..a0a3245
--- /dev/null
+++ b/SOURCES/make-no-dlcompatorsrp-tarball.sh
@@ -0,0 +1,41 @@
+#!/bin/bash -e
+#
+#  See ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/ for unmodified sources.
+#
+
+tmppath=`mktemp -d ${TMPDIR:-/tmp}/make-no-dlcompat-tarball-XXXXXX`
+if test -z "$tmppath" ; then
+	echo Error creating temporary directory.
+	exit 1
+fi
+trap "rm -fr $tmppath" EXIT
+
+initialdir=`pwd`
+
+for tarball in ${initialdir}/cyrus-sasl-*.tar.{gz,bz2} ; do
+	if ! test -s "$tarball" ; then
+		continue
+	fi
+	rm -fr $tmppath/*
+	pushd $tmppath > /dev/null
+	case "$tarball" in
+	*nodlcompat*)
+		: Do nothing.
+		;;
+	*.gz)
+		gzip  -dc "$tarball" | tar xf -
+		rm -fr cyrus-sasl-*/dlcompat*
+		rm -fr cyrus-sasl-*/plugins/srp*
+		tar cf - * | gzip  -9c > \
+		$initialdir/`basename $tarball .tar.gz`-nodlcompatorsrp.tar.gz
+		;;
+	*.bz2)
+		bzip2 -dc "$tarball" | tar xf -
+		rm -fr cyrus-sasl-*/dlcompat*
+		rm -fr cyrus-sasl-*/plugins/srp*
+		tar cf - * | bzip2 -9c > \
+		$initialdir/`basename $tarball .tar.bz2`-nodlcompatorsrp.tar.bz2
+		;;
+	esac
+	popd > /dev/null
+done
diff --git a/SOURCES/sasl-mechlist.c b/SOURCES/sasl-mechlist.c
new file mode 100644
index 0000000..680e983
--- /dev/null
+++ b/SOURCES/sasl-mechlist.c
@@ -0,0 +1,99 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "sasl.h"
+
+static int
+my_getopt(void *context, const char *plugin_name,
+	  const char *option, const char **result, unsigned *len)
+{
+	if (result) {
+		*result = NULL;
+#if 0
+		fprintf(stderr, "Getopt plugin=%s%s%s/option=%s%s%s -> ",
+			plugin_name ? "\"" : "",
+			plugin_name ? plugin_name : "(null)",
+			plugin_name ? "\"" : "",
+			option ? "\"" : "",
+			option ? option : "(null)",
+			option ? "\"" : "");
+		fprintf(stderr, "'%s'.\n", *result ? *result : "");
+#endif
+	}
+	if (len) {
+		*len = 0;
+	}
+	return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+	int ret, i;
+	const char *mechs, **globals;
+	sasl_callback_t callbacks[] = {
+		{SASL_CB_GETOPT, my_getopt, NULL},
+		{SASL_CB_LIST_END},
+	};
+	sasl_conn_t *connection;
+	char hostname[512];
+
+	if ((argc > 1) && (argv[1][0] == '-')) {
+		fprintf(stderr, "Usage: %s [appname [hostname] ]\n", argv[0]);
+		return 0;
+	}
+
+	ret = sasl_server_init(callbacks, argc > 1 ? argv[1] : "sasl-mechlist");
+	if (ret != SASL_OK) {
+		fprintf(stderr, "Error in sasl_server_init(): %s\n",
+			sasl_errstring(ret, NULL, NULL));
+	}
+
+	connection = NULL;
+	strcpy(hostname, "localhost");
+	gethostname(hostname, sizeof(hostname));
+	ret = sasl_server_new(argc > 2 ? argv[2] : "host",
+			      hostname,
+			      NULL,
+			      NULL,
+			      NULL,
+			      callbacks,
+			      0,
+			      &connection);
+	if (ret != SASL_OK) {
+		fprintf(stderr, "Error in sasl_server_new(): %s\n",
+			sasl_errstring(ret, NULL, NULL));
+	}
+
+	ret = sasl_listmech(connection,
+			    getenv("USER") ? getenv("USER") : "root",
+			    "Available mechanisms: ",
+			    ",",
+			    "\n",
+			    &mechs,
+			    NULL,
+			    NULL);
+	if (ret != SASL_OK) {
+		fprintf(stderr, "Error in sasl_listmechs(): %s\n",
+			sasl_errstring(ret, NULL, NULL));
+	} else {
+		fprintf(stdout, "%s", mechs);
+	}
+
+	globals = sasl_global_listmech();
+	for (i = 0; (globals != NULL) && (globals[i] != NULL); i++) {
+		if (i == 0) {
+			fprintf(stdout, "Library supports: ");
+		}
+		fprintf(stdout, "%s", globals[i]);
+		if (globals[i + 1] != NULL) {
+			fprintf(stdout, ",");
+		} else {
+			fprintf(stdout, "\n");
+		}
+	}
+
+	return 0;
+}
diff --git a/SOURCES/saslauthd.service b/SOURCES/saslauthd.service
new file mode 100644
index 0000000..c7c7eca
--- /dev/null
+++ b/SOURCES/saslauthd.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=SASL authentication daemon.
+
+[Service]
+Type=forking
+PIDFile=/run/saslauthd/saslauthd.pid
+EnvironmentFile=/etc/sysconfig/saslauthd
+ExecStart=/usr/sbin/saslauthd -m $SOCKETDIR -a $MECH $FLAGS
+RuntimeDirectory=saslauthd
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/saslauthd.sysconfig b/SOURCES/saslauthd.sysconfig
new file mode 100644
index 0000000..5413c36
--- /dev/null
+++ b/SOURCES/saslauthd.sysconfig
@@ -0,0 +1,11 @@
+# Directory in which to place saslauthd's listening socket, pid file, and so
+# on.  This directory must already exist.
+SOCKETDIR=/run/saslauthd
+
+# Mechanism to use when checking passwords.  Run "saslauthd -v" to get a list
+# of which mechanism your installation was compiled with the ablity to use.
+MECH=pam
+
+# Additional flags to pass to saslauthd on the command line.  See saslauthd(8)
+# for the list of accepted flags.
+FLAGS=
diff --git a/SPECS/cyrus-sasl.spec b/SPECS/cyrus-sasl.spec
new file mode 100644
index 0000000..e667c2c
--- /dev/null
+++ b/SPECS/cyrus-sasl.spec
@@ -0,0 +1,1157 @@
+%global username    saslauth
+%global hint        Saslauthd user
+%global homedir     /run/saslauthd
+
+%global _plugindir2 %{_libdir}/sasl2
+%global bootstrap_cyrus_sasl 0
+
+Summary: The Cyrus SASL library
+Name: cyrus-sasl
+Version: 2.1.27
+Release: 5%{?dist}
+License: BSD with advertising
+Group: System Environment/Libraries
+# Source0 originally comes from https://www.cyrusimap.org/releases/;
+# make-no-dlcompatorsrp-tarball.sh removes the "dlcompat" subdirectory and builds a
+# new tarball.
+Source0: cyrus-sasl-%{version}-nodlcompatorsrp.tar.gz
+Source5: saslauthd.service
+Source7: sasl-mechlist.c
+Source9: saslauthd.sysconfig
+Source10: make-no-dlcompatorsrp-tarball.sh
+# From upstream git, required for reconfigure after applying patches to configure.ac
+# https://raw.githubusercontent.com/cyrusimap/cyrus-sasl/master/autogen.sh
+Source11: autogen.sh
+URL: https://www.cyrusimap.org/sasl/
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Patch11: cyrus-sasl-2.1.25-no_rpath.patch
+Patch15: cyrus-sasl-2.1.20-saslauthd.conf-path.patch
+Patch23: cyrus-sasl-2.1.23-man.patch
+Patch24: cyrus-sasl-2.1.21-sizes.patch
+Patch49: cyrus-sasl-2.1.26-md5global.patch
+Patch60: cyrus-sasl-pr559-RC4-openssl.patch
+Patch830: cyrus-sasl-2.1.27-CVE-2019-19906.patch
+Patch831: cyrus-sasl-2.1.27-Add-basic-test-infrastructure.patch
+Patch832: cyrus-sasl-2.1.27-Add-Channel-Binding-support-for-GSSAPI-GSS-SPNEGO.patch
+Patch833: cyrus-sasl-2.1.27-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO.patch
+Patch834: cyrus-sasl-2.1.27-Emit-debug-log-only-in-case-of-errors.patch
+
+Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildRequires: autoconf, automake, libtool, gdbm-devel, groff
+BuildRequires: krb5-devel >= 1.2.2, openssl-devel, pam-devel, pkgconfig
+BuildRequires: mariadb-connector-c-devel, postgresql-devel, zlib-devel
+BuildRequires: libdb-devel
+%if ! %{bootstrap_cyrus_sasl}
+BuildRequires: openldap-devel
+%endif
+#build reqs for make check
+BuildRequires: python36 nss_wrapper socket_wrapper krb5-server
+%{?systemd_requires}
+Requires(post): chkconfig
+Requires(pre): /usr/sbin/useradd /usr/sbin/groupadd
+Requires(postun): /usr/sbin/userdel /usr/sbin/groupdel
+Requires: /sbin/nologin
+Requires: systemd >= 211
+Provides: user(%username)
+Provides: group(%username)
+
+
+%description
+The %{name} package contains the Cyrus implementation of SASL.
+SASL is the Simple Authentication and Security Layer, a method for
+adding authentication support to connection-based protocols.
+
+%package lib
+Group: System Environment/Libraries
+Summary: Shared libraries needed by applications which use Cyrus SASL
+
+%description lib
+The %{name}-lib package contains shared libraries which are needed by
+applications which use the Cyrus SASL library.
+
+%package devel
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: pkgconfig
+Group: Development/Libraries
+Summary: Files needed for developing applications with Cyrus SASL
+
+%description devel
+The %{name}-devel package contains files needed for developing and
+compiling applications which use the Cyrus SASL library.
+
+%package gssapi
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Group: System Environment/Libraries
+Summary: GSSAPI authentication support for Cyrus SASL
+
+%description gssapi
+The %{name}-gssapi package contains the Cyrus SASL plugins which
+support GSSAPI authentication. GSSAPI is commonly used for Kerberos
+authentication.
+
+%package plain
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Group: System Environment/Libraries
+Summary: PLAIN and LOGIN authentication support for Cyrus SASL
+
+%description plain
+The %{name}-plain package contains the Cyrus SASL plugins which support
+PLAIN and LOGIN authentication schemes.
+
+%package md5
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Group: System Environment/Libraries
+Summary: CRAM-MD5 and DIGEST-MD5 authentication support for Cyrus SASL
+
+%description md5
+The %{name}-md5 package contains the Cyrus SASL plugins which support
+CRAM-MD5 and DIGEST-MD5 authentication schemes.
+
+%package ntlm
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Group: System Environment/Libraries
+Summary: NTLM authentication support for Cyrus SASL
+
+%description ntlm
+The %{name}-ntlm package contains the Cyrus SASL plugin which supports
+the NTLM authentication scheme.
+
+# This would more appropriately be named cyrus-sasl-auxprop-sql.
+%package sql
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Group: System Environment/Libraries
+Summary: SQL auxprop support for Cyrus SASL
+
+%description sql
+The %{name}-sql package contains the Cyrus SASL plugin which supports
+using a RDBMS for storing shared secrets.
+
+%if ! %{bootstrap_cyrus_sasl}
+# This was *almost* named cyrus-sasl-auxprop-ldapdb, but that's a lot of typing.
+%package ldap
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Group: System Environment/Libraries
+Summary: LDAP auxprop support for Cyrus SASL
+
+%description ldap
+The %{name}-ldap package contains the Cyrus SASL plugin which supports using
+a directory server, accessed using LDAP, for storing shared secrets.
+%endif
+
+%package scram
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Group: System Environment/Libraries
+Summary: SCRAM auxprop support for Cyrus SASL
+
+%description scram
+The %{name}-scram package contains the Cyrus SASL plugin which supports
+the SCRAM authentication scheme.
+
+%package gs2
+Requires: %{name}-lib%{?_isa} = %{version}-%{release}
+Group: System Environment/Libraries
+Summary: GS2 support for Cyrus SASL
+
+%description gs2
+The %{name}-gs2 package contains the Cyrus SASL plugin which supports
+the GS2 authentication scheme.
+
+###
+
+
+%prep
+%setup -q -n cyrus-sasl-%{version}
+%patch11 -p1 -b .no_rpath
+%patch15 -p1 -b .path
+%patch23 -p1 -b .man
+%patch24 -p1 -b .sizes
+%patch49 -p1 -b .md5global.h
+%patch60 -p1 -b .openssl_rc4
+%patch830 -p1 -b .CVE-2019-19906
+%patch831 -p1 -b .tests
+%patch832 -p1 -b .gssapi_cbs
+%patch833 -p1 -b .maxssf0
+%patch834 -p1 -b .nolog
+
+%build
+# reconfigure
+cp %{SOURCE11} ./
+rm configure aclocal.m4 config/ltmain.sh Makefile.in
+export NOCONFIGURE=yes
+sh autogen.sh
+
+# Find Kerberos.
+krb5_prefix=`krb5-config --prefix`
+if test x$krb5_prefix = x%{_prefix} ; then
+        krb5_prefix=
+else
+        CPPFLAGS="-I${krb5_prefix}/include $CPPFLAGS"; export CPPFLAGS
+        LDFLAGS="-L${krb5_prefix}/%{_lib} $LDFLAGS"; export LDFLAGS
+fi
+
+# Find OpenSSL.
+LIBS="-lcrypt"; export LIBS
+if pkg-config openssl ; then
+        CPPFLAGS="`pkg-config --cflags-only-I openssl` $CPPFLAGS"; export CPPFLAGS
+        LDFLAGS="`pkg-config --libs-only-L openssl` $LDFLAGS"; export LDFLAGS
+fi
+
+# Find the MySQL libraries used needed by the SQL auxprop plugin.
+INC_DIR="`mysql_config --include`"
+if test x"$INC_DIR" != "x-I%{_includedir}"; then
+        CPPFLAGS="$INC_DIR $CPPFLAGS"; export CPPFLAGS
+fi
+LIB_DIR="`mysql_config --libs | sed -e 's,-[^L][^ ]*,,g' -e 's,^ *,,' -e 's, *$,,' -e 's,  *, ,g'`"
+if test x"$LIB_DIR" != "x-L%{_libdir}"; then
+        LDFLAGS="$LIB_DIR $LDFLAGS"; export LDFLAGS
+fi
+
+# Find the PostgreSQL libraries used needed by the SQL auxprop plugin.
+INC_DIR="-I`pg_config --includedir`"
+if test x"$INC_DIR" != "x-I%{_includedir}"; then
+        CPPFLAGS="$INC_DIR $CPPFLAGS"; export CPPFLAGS
+fi
+LIB_DIR="-L`pg_config --libdir`"
+if test x"$LIB_DIR" != "x-L%{_libdir}"; then
+        LDFLAGS="$LIB_DIR $LDFLAGS"; export LDFLAGS
+fi
+
+# Patch config.sub to support ppc64p7 subarch (Fedora specific)
+# This is similar to what the config.sub from automake has
+for i in `find . -name config.sub`; do
+  perl -pi -e "s/ppc64-\*/ppc64-\* \| ppc64p7-\*/" $i
+done
+
+CFLAGS="$RPM_OPT_FLAGS $CFLAGS $CPPFLAGS -fPIC -pie -Wl,-z,relro -Wl,-z,now"; export CFLAGS
+LDFLAGS="$LDFLAGS -pie -Wl,-z,now"; export LDFLAGS
+
+echo "$CFLAGS"
+echo "$CPPFLAGS"
+echo "$LDFLAGS"
+
+%configure \
+        --enable-shared --disable-static \
+        --disable-java \
+        --with-plugindir=%{_plugindir2} \
+        --with-configdir=%{_plugindir2}:%{_sysconfdir}/sasl2 \
+        --disable-krb4 \
+        --enable-gssapi${krb5_prefix:+=${krb5_prefix}} \
+        --with-gss_impl=mit \
+        --with-rc4 \
+        --with-dblib=berkeley \
+        --with-bdb=db \
+        --with-saslauthd=/run/saslauthd --without-pwcheck \
+%if ! %{bootstrap_cyrus_sasl}
+        --with-ldap \
+%endif
+        --with-devrandom=/dev/urandom \
+        --enable-anon \
+        --enable-cram \
+        --enable-digest \
+        --enable-ntlm \
+        --enable-plain \
+        --enable-login \
+        --enable-alwaystrue \
+        --enable-httpform \
+        --disable-otp \
+%if ! %{bootstrap_cyrus_sasl}
+        --enable-ldapdb \
+%endif
+        --enable-sql --with-mysql=yes --with-pgsql=yes \
+        --without-sqlite \
+        "$@"
+        # --enable-auth-sasldb -- EXPERIMENTAL
+make sasldir=%{_plugindir2}
+make -C saslauthd testsaslauthd
+make -C sample
+
+# Build a small program to list the available mechanisms, because I need it.
+pushd lib
+../libtool --mode=link %{__cc} -o sasl2-shared-mechlist -I../include $CFLAGS %{SOURCE7} $LDFLAGS ./libsasl2.la
+
+
+%install
+test "$RPM_BUILD_ROOT" != "/" && rm -rf $RPM_BUILD_ROOT
+
+make install DESTDIR=$RPM_BUILD_ROOT sasldir=%{_plugindir2}
+make install DESTDIR=$RPM_BUILD_ROOT sasldir=%{_plugindir2} -C plugins
+
+install -m755 -d $RPM_BUILD_ROOT%{_bindir}
+./libtool --mode=install \
+install -m755 sample/client $RPM_BUILD_ROOT%{_bindir}/sasl2-sample-client
+./libtool --mode=install \
+install -m755 sample/server $RPM_BUILD_ROOT%{_bindir}/sasl2-sample-server
+./libtool --mode=install \
+install -m755 saslauthd/testsaslauthd $RPM_BUILD_ROOT%{_sbindir}/testsaslauthd
+
+# Install the saslauthd mdoc page in the expected location.  Sure, it's not
+# really a man page, but groff seems to be able to cope with it.
+install -m755 -d $RPM_BUILD_ROOT%{_mandir}/man8/
+install -m644 -p saslauthd/saslauthd.mdoc $RPM_BUILD_ROOT%{_mandir}/man8/saslauthd.8
+install -m644 -p saslauthd/testsaslauthd.8 $RPM_BUILD_ROOT%{_mandir}/man8/testsaslauthd.8
+
+# Install the init script for saslauthd and the init script's config file.
+install -m755 -d $RPM_BUILD_ROOT/etc/rc.d/init.d $RPM_BUILD_ROOT/etc/sysconfig
+install -d -m755 $RPM_BUILD_ROOT/%{_unitdir}
+install -m644 -p %{SOURCE5} $RPM_BUILD_ROOT/%{_unitdir}/saslauthd.service
+install -m644 -p %{SOURCE9} $RPM_BUILD_ROOT/etc/sysconfig/saslauthd
+
+# Install the config dirs if they're not already there.
+install -m755 -d $RPM_BUILD_ROOT/%{_sysconfdir}/sasl2
+install -m755 -d $RPM_BUILD_ROOT/%{_plugindir2}
+
+# Provide an easy way to query the list of available mechanisms.
+./libtool --mode=install \
+install -m755 lib/sasl2-shared-mechlist $RPM_BUILD_ROOT/%{_sbindir}/
+
+# Remove unpackaged files from the buildroot.
+rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/libotp.*
+rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/*.a
+rm -f $RPM_BUILD_ROOT%{_libdir}/sasl2/*.la
+rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
+rm -f $RPM_BUILD_ROOT%{_mandir}/cat8/saslauthd.8
+
+%check
+make check %{?_smp_mflags}
+
+%pre
+getent group %{username} >/dev/null || groupadd -g 76 -r %{username}
+getent passwd %{username} >/dev/null || useradd -r -g %{username} -d %{homedir} -s /sbin/nologin -c "%{hint}" %{username}
+
+%post
+%systemd_post saslauthd.service
+
+%preun
+%systemd_preun saslauthd.service
+
+%postun
+%systemd_postun_with_restart saslauthd.service
+
+%triggerun -n cyrus-sasl -- cyrus-sasl < 2.1.23-32
+/usr/bin/systemd-sysv-convert --save saslauthd >/dev/null 2>&1 || :
+/sbin/chkconfig --del saslauthd >/dev/null 2>&1 || :
+/bin/systemctl try-restart saslauthd.service >/dev/null 2>&1 || :
+
+%post lib -p /sbin/ldconfig
+%postun lib -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root)
+%doc saslauthd/LDAP_SASLAUTHD
+%{_mandir}/man8/*
+%{_sbindir}/pluginviewer
+%{_sbindir}/saslauthd
+%{_sbindir}/testsaslauthd
+%config(noreplace) /etc/sysconfig/saslauthd
+%{_unitdir}/saslauthd.service
+%ghost /run/saslauthd
+
+%files lib
+%defattr(-,root,root)
+%license COPYING
+%doc AUTHORS doc/html/*.html
+%{_libdir}/libsasl*.so.*
+%dir %{_sysconfdir}/sasl2
+%dir %{_plugindir2}/
+%{_plugindir2}/*anonymous*.so*
+%{_plugindir2}/*sasldb*.so*
+%{_sbindir}/saslpasswd2
+%{_sbindir}/sasldblistusers2
+
+%files plain
+%defattr(-,root,root)
+%{_plugindir2}/*plain*.so*
+%{_plugindir2}/*login*.so*
+
+%if ! %{bootstrap_cyrus_sasl}
+%files ldap
+%defattr(-,root,root)
+%{_plugindir2}/*ldapdb*.so*
+%endif
+
+%files md5
+%defattr(-,root,root)
+%{_plugindir2}/*crammd5*.so*
+%{_plugindir2}/*digestmd5*.so*
+
+%files ntlm
+%defattr(-,root,root)
+%{_plugindir2}/*ntlm*.so*
+
+%files sql
+%defattr(-,root,root)
+%{_plugindir2}/*sql*.so*
+
+%files gssapi
+%defattr(-,root,root)
+%{_plugindir2}/*gssapi*.so*
+
+%files scram
+%defattr(-,root,root)
+%{_plugindir2}/libscram.so*
+
+%files gs2
+%defattr(-,root,root)
+%{_plugindir2}/libgs2.so*
+
+%files devel
+%defattr(-,root,root)
+%{_bindir}/sasl2-sample-client
+%{_bindir}/sasl2-sample-server
+%{_includedir}/*
+%{_libdir}/libsasl*.*so
+%{_libdir}/pkgconfig/*.pc
+%{_mandir}/man3/*
+%{_sbindir}/sasl2-shared-mechlist
+
+%changelog
+* Tue May  5 2020 Simo Sorce <simo@redhat.com> - 2.1.27-5
+- Reduce excessive GSSAPI plugin logging
+- Resolves: rhbz#1274734
+
+* Tue May  5 2020 Simo Sorce <simo@redhat.com> - 2.1.27-4
+- Add support for setting maxssf=0 in GSS-SPNEGO
+- Resolves: rhbz#1822133
+
+* Tue May  5 2020 Simo Sorce <simo@redhat.com> - 2.1.27-3
+- Backport GSSAPI Channel Bindings support
+- Resolves: rhbz#1817054
+
+* Tue May  5 2020 Simo Sorce <simo@redhat.com> - 2.1.27-2
+- Backport fix for CVE-2019-19906
+- Resolves: rhbz#1804036
+
+* Fri Jun 14 2019 Simo Sorce <simo@redhat.com> - 2.1.27-1
+- Rc7 to final source
+- Resovles bz#1618744
+
+* Thu Jun 13 2019 Simo Sorce <simo@redhat.com> - 2.1.27-0.4rc7
+- Add patch form Upstream PR559 to use RC4 implementation from OpenSSL
+- Resolves bz#1618744
+- Fix multilib issue bz#1663120
+
+* Mon Jul 30 2018 Florian Weimer <fweimer@redhat.com> - 2.1.27-0.3rc7
+- Rebuild with fixed binutils
+
+* Wed Jul 25 2018 Petr Kubat <pkubat@redhat.com> - 2.1.27-0.2rc7
+- Rebuilt for gdbm
+
+* Mon Mar 05 2018 Jakub Jelen <jjelen@redhat.com> - 2.1.27-0.1rc7
+- New upstream (pre-)release
+- Import LDFLAGS from redhat-rpm-config (#1548437)
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.26-37
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Sat Jan 20 2018 Björn Esser <besser82@fedoraproject.org> - 2.1.26-36
+- Rebuilt for switch to libxcrypt
+
+* Mon Oct 23 2017 Jakub Jelen <jjelen@redhat.com> - 2.1.26-35
+- Use mariadb-connector-c-devel instead of mysql-devel (#1493620)
+
+* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.26-34
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.26-33
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Wed Apr 19 2017 Jakub Jelen <jjelen@redhat.com> - 2.1.26-32
+- Add missing patch for separate mutexes per connection in GSSAPI
+
+* Tue Apr 18 2017 Jakub Jelen <jjelen@redhat.com> - 2.1.26-31
+- Allow cyrus sasl to get the ssf from gssapi
+
+* Wed Apr 12 2017 Petr Šabata <contyk@redhat.com> - 2.1.26-30
+- Removing the obsolete scriptlet /sbin/service dependency
+
+* Tue Mar 07 2017 Jakub Jelen <jjelen@redhat.com> - 2.1.26-29
+- Fix GSS SPNEGO support (#1421663)
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.26-28
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Mon Nov 07 2016 Jakub Jelen <jjelen@redhat.com> - 2.1.26-27
+- Add support for OpenSSL 1.1.0
+
+* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.26-26.2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Thu Jul 16 2015 Jakub Jelen <jjelen@redhat.com> 2.1.26-25.2
+- Revert tmpfiles.d and use new systemd feature RuntimeDirectory
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.26-24
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Fri May 29 2015 Jakub Jelen <jjelen@redhat.com> 2.1.26-23
+- Add ability to handle logging in gssapi plugin (#1187097)
+
+* Mon Mar 16 2015 Jakub Jelen <jjelen@redhat.com> 2.1.26-22
+- Rever "Do not leak memory in plugin_common.c ..." due the breakage of svn (#1202364)
+
+* Thu Mar 12 2015 Jakub Jelen <jjelen@redhat.com> 2.1.26-21
+- Add and Document ability to run saslauthd as non-root user, fix tpmfiles ownership (#1189203)
+- Do not leak memory in sample server (#852755)
+- Do not leak memory in plugin_common.c for password callback (#1191183)
+- Cleanup spec file: tmpfiles.d macros and tab/space
+
+* Wed Feb 04 2015 Petr Lautrbach <plautrba@redhat.com> 2.1.26-20
+- Change the ownership of /run/saslauth to saslauth:saslauth (#1189203)
+
+* Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.26-19
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Fri Jul 11 2014 Tom Callaway <spot@fedoraproject.org> - 2.1.26-18
+- fix license handling
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.26-17
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Sun Jan 19 2014 Ville Skyttä <ville.skytta@iki.fi> - 2.1.26-16
+- Don't order service after syslog.target.
+
+* Fri Nov 15 2013 Petr Lautrbach <plautrba@redhat.com> 2.1.26-15
+- Treat SCRAM-SHA-1/DIGEST-MD5 as more secure than PLAIN (#970718)
+- improve configuration error message
+
+* Fri Nov 01 2013 Petr Lautrbach <plautrba@redhat.com> 2.1.26-14
+- revert upstream commit 080e51c7fa0421eb2f0210d34cf0ac48a228b1e9 (#984079)
+
+* Tue Oct 15 2013 Karsten Hopp <karsten@redhat.com> 2.1.26-13
+- add ppc64p7 subarch support in config.sub (Fedora only)
+
+* Mon Sep 09 2013 Petr Lautrbach <plautrba@redhat.com> 2.1.26-12
+- build with RPM_OPT_FLAGS <ville.skytta@iki.fi> (#1005535)
+
+* Tue Sep 03 2013 Petr Lautrbach <plautrba@redhat.com> 2.1.26-11
+- fix hardening for /usr/sbin/saslauthd
+- add testsaslauthd.8 man page to the package
+- use static md5global.h file
+
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.26-10
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Mon Jun 24 2013 Petr Lautrbach <plautrba@redhat.com> 2.1.26-9
+- detect gsskrb5_register_acceptor_identity macro <nalin@redhat.com> (#976538)
+
+* Tue Jun 04 2013 Karsten Hopp <karsten@redhat.com> 2.1.26-8
+- disable incorrect check for MkLinux to allow building with shared libraries on PPC
+
+* Tue May 21 2013 Petr Lautrbach <plautrba@redhat.com> 2.1.26-7
+- fix the spec file in order to build the cyrus-sasl-sql plugin
+  with support for PostgreSQL and MySQL
+
+* Thu Feb 21 2013 Petr Lautrbach <plautrba@redhat.com> 2.1.26-6
+- don't include system sasl2 library needed for rebuilds after rebase
+
+* Mon Feb 11 2013 Petr Lautrbach <plautrba@redhat.com> 2.1.26-5
+- enable full relro and PIE compiler flags for saslauthd
+
+* Fri Feb 01 2013 Petr Lautrbach <plautrba@redhat.com> 2.1.26-4
+- fix library symlinks
+
+* Thu Jan 31 2013 Rex Dieter <rdieter@fedoraproject.org> 2.1.26-3
+- actually apply size_t patch (#906519)
+
+* Thu Jan 31 2013 Rex Dieter <rdieter@fedoraproject.org> 2.1.26-2
+- sasl.h: +#include<sys/types.h> for missing size_t type (#906519)
+- tighten subpkg deps via %%?_isa
+
+* Thu Dec 20 2012 Petr Lautrbach <plautrba@redhat.com> 2.1.26-1
+- update to 2.1.26
+- fix segfaults in sasl_gss_encode (#886140)
+
+* Mon Dec 10 2012 Petr Lautrbach <plautrba@redhat.com> 2.1.25-2
+- always use the current external Berkeley DB when linking
+
+* Fri Dec 07 2012 Petr Lautrbach <plautrba@redhat.com> 2.1.25-1
+- update to 2.1.25
+- add cyrus-sasl-scram and cyrus-sasl-gs2 packages
+
+* Fri Sep 14 2012 Petr Lautrbach <plautrba@redhat.com> 2.1.23-36
+- replace scriptlets with systemd macros (#856666)
+
+* Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.23-35
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Jul 17 2012 Petr Lautrbach <plautrba@redhat.com> 2.1.23-34
+- move /etc/tmpfiles.d/saslauthd.conf to /usr/lib/tmpfiles.d/saslauthd.conf (#840193)
+
+* Wed Jun 20 2012 Petr Lautrbach <plautrba@redhat.com> 2.1.23-33
+- properly deal with crypt() returning NULL (#816250)
+- use fixed gid 76 for saslauth
+
+* Mon Apr 16 2012 Jindrich Novy <jnovy@redhat.com> 2.1.23-32
+- re-enable libdb support and utilities
+
+* Wed Apr 04 2012 Jindrich Novy <jnovy@redhat.com> 2.1.23-31
+- temporarily disable libdb support to resolve cyrus-sasl
+  chicken and egg build problem against libdb
+
+* Tue Apr 03 2012 Jindrich Novy <jnovy@redhat.com> 2.1.23-30
+- rebuild against new libdb
+
+* Wed Feb 08 2012 Petr Lautrbach <plautrba@redhat.com> 2.1.23-29
+- Change saslauth user homedir to /run/saslauthd (#752889)
+- Change all /var/run/ to /run/
+- DAEMONOPTS are not supported any more in systemd units
+
+* Mon Jan 09 2012 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 2.1.23-28
+- Ship with sasl_pwcheck_method: alwaystrue
+
+* Mon Dec 12 2011 Petr Lautrbach <plautrba@redhat.com> 2.1.23-27
+- remove support for logging of the remote host via PAM (#759334)
+- fix systemd files (#750436)
+
+* Wed Aug 10 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-26
+- Add partial relro support for libraries
+
+* Mon Jul 25 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-25
+- Add support for berkeley db 5
+
+* Wed Jun 29 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-23
+- Migrate the package to full native systemd unit files, according to the Fedora
+  packaging guidelines.
+
+* Wed Jun  1 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-22
+- repair rimap support (more packets in response)
+
+* Wed May 25 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-21
+- repair ntlm support
+
+* Mon May 23 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-20
+- add logging of the remote host via PAM
+
+* Thu Apr 28 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-19
+- temporarilly revert systemd units
+
+* Tue Apr 26 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-18
+- update scriptlets
+
+* Fri Apr 22 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-17
+- Add systemd units
+
+* Wed Mar 23 2011 Tomas Mraz <tmraz@redhat.com> - 2.1.23-16
+- Rebuilt with new mysqlclient
+
+* Fri Feb 25 2011 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-15
+- set correct license tag
+- add ghost to /var/run/saslauthd
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.23-14
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Fri Apr  9 2010 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-13
+- Add /etc/tmpfiles.d element (#662734)
+
+* Fri Apr  9 2010 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-12
+- Update init script to impeach pid file
+
+* Thu Mar 11 2010 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-11
+- Update pre post preun and postun scripts (#572399)
+
+* Wed Mar 10 2010 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-10
+- Rewrite spec file, make corect CFLAGS, CPPFLAGS and LDFLAGS
+
+* Mon Feb 22 2010 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-9
+- solve race condition (#566875)
+
+* Wed Feb 17 2010 Stepan Kasal <skasal@redhat.com> - 2.1.23-8
+- improve m4 quoting to fix saslauthd/configure (#566088)
+- call autotools in build, not in prep
+
+* Fri Feb  5 2010 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-7
+- Add man page to testtcpauthd (#526189)
+
+* Fri Oct 16 2009 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-6
+- Create the saslauth user according to fedora packaging guide
+
+* Thu Sep 24 2009 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-5
+- Repair initscript to make condrestart working properly (#522103)
+
+* Wed Sep 23 2009 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-3
+- Add possibility to run the saslauth without root privilegies (#185614)
+
+* Fri Aug 21 2009 Tomas Mraz <tmraz@redhat.com> - 2.1.23-2
+- rebuilt with new openssl
+
+* Fri Aug  7 2009 Jan F. Chadima <jchadima@redhat.com> - 2.1.23-1
+- update to 2.1.23
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.22-25
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Mon May 11 2009 Jan F. Chadima <jchadima@redhat.com> - 2.1.22-24
+- repair sasl_encode64 nul termination (#487251)
+
+* Thu Apr 16 2009 Robert Scheck <robert@fedoraproject.org> - 2.1.22-23
+- Don't build the krb4 plugin as krb5 1.7 will drop it (#225974 #c6)
+
+* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.22-22
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Fri Feb  6 2009 Tomas Mraz <tmraz@redhat.com> - 2.1.22-21
+- fix build with gcc-4.4
+
+* Fri Jan 23 2009 Tomas Mraz <tmraz@redhat.com> - 2.1.22-20
+- set LDAP_OPT_TIMEOUT (#326452)
+- provide LSB compatible init script (#246900)
+
+* Fri Sep 26 2008 Tomas Mraz <tmraz@redhat.com> - 2.1.22-19
+- always use the current external db4 when linking,
+  thanks to Dan Horak for the original patch (#464098)
+
+* Wed Sep 10 2008 Tomas Mraz <tmraz@redhat.com> - 2.1.22-18
+- fix most critical build warnings (#433583)
+- use external db4
+
+* Fri Aug 29 2008 Tomas Mraz <tmraz@redhat.com> - 2.1.22-17
+- always link against the internal db4 (#459163)
+- rediff patches for no fuzz
+
+* Wed Jul  9 2008 Tomas Mraz <tmraz@redhat.com> - 2.1.22-16
+- update internal db4 (#449737)
+
+* Tue Jul  1 2008 Tomas Mraz <tmraz@redhat.com> - 2.1.22-15
+- drop reload from initscript help (#448154)
+- fix hang in rimap auth method (#438533)
+- build the krb4 plugin (#154675)
+
+* Fri May 23 2008 Dennis Gilmore <dennis@ausil.us> - 2.1.22-14
+- make it so that bootstrap actually works
+
+* Thu May 22 2008 Tom "spot" Callaway <tcallawa@redhat.com> - 2.1.22-13.1
+- minor release bump for sparc rebuild
+
+* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 2.1.22-13
+- Autorebuild for GCC 4.3
+
+* Thu Feb 14 2008 Steve Conklin <sconklin@redhat.com> - 2.1.22-12
+- rebuild for gcc4.3
+
+* Fri Jan 25 2008 Steve Conklin <sconklin@redhat.com> - 2.1.22-11
+- Cleanup after merge review bz #225673
+- no longer mark /etc/rc.d/init.d/saslauthd as config file
+- removed -x permissions on include files
+- added devel package dependency on cyrus-sasl
+- removed some remaining .la files that were being delivered
+
+* Wed Dec 05 2007 Release Engineering <rel-eng at fedoraproject dot org> - 2.1.22-10
+ - Rebuild for deps
+
+* Wed Nov  7 2007 Steve Conklin <sconklin@redhat.com> - 2.1.22-9
+- Fixed a typo in the spec file
+
+* Wed Nov  7 2007 Steve Conklin <sconklin@redhat.com> - 2.1.22-8
+- Removed srp plugin source and added dist to NVR
+
+* Tue Sep 18 2007 Steve Conklin <sconklin@redhat.com> 2.1.22-7
+- use db4 version 4.6.19 bz#249737
+
+* Mon Feb 26 2007 Nalin Dahyabhai <nalin@redhat.com> 2.1.22-6
+- install config files and init scripts using -p
+- pull in patch to build with current automake (#229010, Jacek Konieczny
+  and Robert Scheck)
+- remove prereq on ldconfig, RPM should pick it up based on the -libs
+  scriptlets
+- pull in patch to correctly detect gsskrb5_register_acceptor_identity
+  (#200892, Mirko Streckenbach)
+- move sasldb auxprop modules into the -lib subpackage, so that we'll pick
+  it up for multilib systems
+
+* Thu Feb 22 2007 Nalin Dahyabhai <nalin@redhat.com>
+- pull CVS fix for not tripping over extra commas in digest-md5
+  challenges (#229640)
+
+* Fri Feb 16 2007 Nalin Dahyabhai <nalin@redhat.com>
+- remove static build, which is no longer a useful option because not all of
+  our dependencies are available as static libraries
+- drop patches which were needed to keep static builds going
+- drop gssapi-generic patch due to lack of interest
+- update the bundled copy of db to 4.5.20 (#229012)
+- drop dbconverter-2, as we haven't bundled v1 libraries since FC4
+
+* Tue Dec  5 2006 Nalin Dahyabhai <nalin@redhat.com> 2.1.22-5
+- rebuild
+- add 'authentication' or 'auxprop' to summaries for plugin packages to
+  better indicate what the plugin provides
+- switch from automake 1.9 to automake 1.7
+
+* Fri Sep 29 2006 Nalin Dahyabhai <nalin@redhat.com> 2.1.22-4
+- rebuild without 'dlcompat' bits (#206119)
+
+* Mon Jul 17 2006 Nalin Dahyabhai <nalin@redhat.com> 2.1.22-3
+- rebuild
+
+* Tue Jun 20 2006 Nalin Dahyabhai <nalin@redhat.com> 2.1.22-2
+- fix a typo in sasl_client_start(3) (#196066)
+
+* Mon May 22 2006 Nalin Dahyabhai <nalin@redhat.com> 2.1.22-1
+- update to 2.1.22, adding pluginviewer to %%{_sbindir}
+
+* Tue May 16 2006 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-12
+- add conditionalized build dependency on openldap-devel (#191855)
+- patch md5global.h to be the same on all architectures
+
+* Thu Apr 27 2006 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-11
+- add unapplied patch which makes the DIGEST-MD5 plugin omit the realm
+  argument when the environment has $CYRUS_SASL_DIGEST_MD5_OMIT_REALM set to a
+  non-zero value, for testing purposes
+- add missing buildrequires on zlib-devel (#190113)
+
+* Mon Feb 20 2006 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-10
+- add missing buildrequires on gdbm-devel (Karsten Hopp)
+
+* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 2.1.21-9.2
+- bump again for double-long bug on ppc(64)
+
+* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 2.1.21-9.1
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Mon Dec 19 2005 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-9
+- use --as-needed to avoid linking dbconverter-2 with SQL libraries, which
+  it doesn't use because it manipulates files directly (#173321)
+
+* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
+- rebuilt
+
+* Mon Nov 14 2005 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-8
+- rebuild with new OpenLDAP, overriding the version checks to assume that
+  2.3.11 is acceptable
+- remove a lingering patch for 1.x which we no longer use
+
+* Sat Nov 12 2005 Tom Lane <tgl@redhat.com> 2.1.21-7
+- Rebuild due to mysql update.
+
+* Tue Nov  8 2005 Tomas Mraz <tmraz@redhat.com> 2.1.21-6
+- rebuilt with new openssl
+
+* Fri Sep  9 2005 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-5
+- add missing buildrequires: on groff (#163032)
+
+* Thu Sep  1 2005 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-4
+- move the ldapdb auxprop support into a subpackage (#167300)
+  (note: the ldap password check support in saslauthd doesn't use auxprop)
+
+* Tue Aug 30 2005 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-3
+- correct a use of uninitialized memory in the bundled libdb (Arjan van de Ven)
+
+* Mon Aug 29 2005 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-2
+- move the ANONYMOUS mech plugin to the -lib subpackage so that multilib
+  systems can use it without installing the main package
+- build the static libraries without sql auxprop support
+
+* Mon Aug 29 2005 Nalin Dahyabhai <nalin@redhat.com> 2.1.21-1
+- update to 2.1.21
+- turn off compilation of libsasl v1 (finally)
+- explicitly disable sqlite to avoid the build warning
+- change the default mechanism which is set for saslauthd from "shadow" to
+  "pam" (#159194)
+- split the shared library up from saslauthd so that multilib systems don't
+  have to pull in every dependency of saslauthd for the compat arch (#166749)
+
+* Wed Apr 13 2005 Nalin Dahyabhai <nalin@redhat.com> 2.1.20-5
+- rebuild with new deps
+
+* Tue Mar  1 2005 Nalin Dahyabhai <nalin@redhat.com> 2.1.20-4
+- rebuild with new deps
+
+* Thu Nov 11 2004 Jeff Johnson <jbj@jbj.org> 2.1.20-3
+- rebuild against db-4.3.21.
+
+* Thu Nov 11 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.20-2
+- build with mysql-devel instead of mysqlclient10
+
+* Mon Nov  1 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.20-1
+- build with mysqlclient10 instead of mysql-devel
+
+* Wed Oct 27 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.20-0
+- update to 2.1.20, including the fix for CAN-2004-0884
+
+* Tue Oct  5 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.19-3
+- use notting's fix for incorrect patch for CAN-2004-0884 for 1.5.28
+
+* Tue Oct  5 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.19-2
+- don't trust the environment in setuid/setgid contexts (CAN-2004-0884, #134660)
+
+* Thu Aug 19 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.19-1
+- rebuild (the 2.1.19 changelog for fixing a buffer overflow referred to a CVS
+  revision between 2.1.18 and 2.1.19)
+
+* Mon Jul 19 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.19-0
+- update to 2.1.19, maybe for update
+
+* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Mon Jun  7 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.18-4
+- enable sql auxprop support in a subpackage
+- include LDAP_SASLAUTHD documentation file (#124830)
+
+* Fri Jun  4 2004 Nalin Dahyabhai <nalin@redhat.com>
+- turn on ntlm in a subpackage
+
+* Thu May 13 2004 Thomas Woerner <twoerner@redhat.com> 2.1.18-3
+- removed rpath
+
+* Tue Mar 16 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.18-2
+- turn on building of libsasl v1 again
+
+* Fri Mar 12 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.18-1
+- update to 2.1.18
+- saslauthd's ldap code is no longer marked experimental, so we build it
+
+* Mon Mar  8 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.17-4
+- rebuild
+
+* Tue Mar 02 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Fri Feb 13 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Tue Feb  3 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.17-2
+- include default /etc/sysconfig/saslauthd configuration file for the init
+  script (#114868)
+
+* Thu Jan 29 2004 Nalin Dahyabhai <nalin@redhat.com>
+- drop saslauthd_version patch for libsasl2
+
+* Thu Jan 29 2004 Nalin Dahyabhai <nalin@redhat.com>
+- add a saslauthd_version option to libsasl's saslauthd client and teach it to
+  do the right thing
+- enable the saslauthd client code in libsasl version 1 (it's still going away!)
+- add saslauthd1-checkpass/saslauthd2-checkpass for testing the above change
+
+* Wed Jan  7 2004 Nalin Dahyabhai <nalin@redhat.com> 2.1.17-1
+- forcibly disable otp and sql plugins at compile-time
+
+* Fri Dec 19 2003 Nalin Dahyabhai <nalin@redhat.com>
+- update to 2.1.17, forcing the gssapi plugin to be shared now, as before
+- use a bundled libdb (#112215)
+- build static-with-all-plugins and normal-shared libsasl versions
+- add sasl2-{shared,static}-mechlist for very basic sanity checking
+- make inclusion of sasl1 stuffs conditional, because it's so going away
+
+* Sat Dec 13 2003 Jeff Johnson <jbj@jbj.org> 2.1.15-7
+- rebuild against db-4.2.52.
+
+* Thu Oct 23 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.15-6
+- use /dev/urandom instead of /dev/random for SASL2 (docs indicate that this is
+  safe if you aren't using OTP or SRP, and we build neither); SASL1 appears to
+  use it to seed the libc RNG only (#103378)
+
+* Mon Oct 20 2003 Nalin Dahyabhai <nalin@redhat.com>
+- obey RPM_OPT_FLAGS again when krb5_prefix != %%{_prefix}
+
+* Fri Oct 17 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.15-5
+- install saslauthd's mdoc page instead of the pre-formatted man page, which
+  would get formatted again
+
+* Thu Sep 25 2003 Jeff Johnson <jbj@jbj.org> 2.1.15-5
+- rebuild against db-4.2.42.
+
+* Mon Sep 15 2003 Nalin Dahyabhai <nalin@redhat.com>
+- include testsaslauthd
+- note in the README that the saslauthd protocol is different for v1 and v2,
+  so v1's clients can't talk to the v2 server
+
+* Thu Aug 21 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.15-4
+- rebuild
+
+* Thu Aug 21 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.15-3
+- add logic to build with gssapi libs in either /usr or /usr/kerberos
+
+* Mon Jul 21 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.15-2
+- rebuild
+
+* Tue Jul 15 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.15-1
+- update to 2.1.15
+
+* Mon Jul 14 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.14-1
+- update to 2.1.14
+
+* Wed Jun 04 2003 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Fri May  9 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.13-3
+- change -m argument to saslauthd to be a directory instead of a path
+
+* Thu May  8 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.13-2
+- link libsasl2 with -lpthread to ensure that the sasldb plug-in can always
+  be loaded
+
+* Tue Apr 29 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.13-1
+- update to 2.1.13
+
+* Wed Jan 22 2003 Tim Powers <timp@redhat.com>
+- rebuilt
+
+* Tue Jan  7 2003 Nalin Dahyabhai <nalin@redhat.com> 2.1.10-3
+- rebuild
+
+* Thu Dec 12 2002 Nalin Dahyabhai <nalin@redhat.com>
+- consider either des_cbc_encrypt or DES_cbc_encrypt to be sufficient when
+  searching for a DES implementation in libcrypto
+- pull in CPPFLAGS and LDFLAGS from openssl's pkg-config data, if it exists
+
+* Mon Dec  9 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.10-2
+- rebuild
+
+* Mon Dec  9 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.10-1
+- update to 2.1.10, fixing buffer overflows in libsasl2 noted by Timo Sirainen
+
+* Tue Nov 12 2002 Tim Powers <timp@redhat.com> 2.1.7-5
+- remove files from $RPM_BUILD_ROOT that we don't intend to include
+
+* Wed Oct  9 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.7-4
+- update to SASLv1 to final 1.5.28
+
+* Fri Sep 13 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.7-3
+- rebuild, overriding sasldir when running make so that on multilib systems
+  applications will be able to load modules for the right arch
+
+* Mon Sep  2 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.7-2
+- include dbconverter-2 (#68741)
+
+* Fri Aug  9 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.7-1
+- update to 2.1.7, fixing a race condition in digest-md5
+
+* Wed Jul 17 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.6-1
+- update to 2.1.6 and 1.5.28
+
+* Fri Jun 21 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Thu Jun 13 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.5-1
+- update to 2.1.5
+
+* Mon Jun 10 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.4-1
+- update to 2.1.4
+
+* Sun May 26 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Thu May 16 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.2-1
+- modify to build with db 4.x
+
+* Thu Apr 18 2002 Nalin Dahyabhai <nalin@redhat.com>
+- update cyrus-sasl 2 to 2.1.2
+- change buildreq to db3-devel
+
+* Tue Feb 12 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.1-3
+- suppress output to stdout/stderr in %%postun
+
+* Sun Feb 10 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.1-2
+- configure sasldb2 to use berkeley DB instead of gdbm
+
+* Wed Feb  6 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.1-1
+- update to 2.1.1
+
+* Thu Jan 31 2002 Nalin Dahyabhai <nalin@redhat.com> 2.1.0-1
+- marge 1.5.24 back in, making a note that it should be removed at some
+  point in the future
+
+* Wed Jan 30 2002 Nalin Dahyabhai <nalin@redhat.com>
+- update to 2.1.0, which is designed to be installed in parallel with cyrus sasl
+  1.x, so fork the package and rename it to cyrus-sasl2
+- add the sasldb auxprop plugin to the main package
+- add disabled-by-default saslauthd init script
+- move the .la files for plugins into their respective packages -- they're
+  needed by the library
+
+* Wed Jan 23 2002 Nalin Dahyabhai <nalin@redhat.com> 1.5.24-24
+- free ride through the build system
+
+* Fri Nov  2 2001 Nalin Dahyabhai <nalin@redhat.com> 1.5.24-23
+- patch to fix possible syslog format-string vulnerability 
+
+* Mon Oct 29 2001 Nalin Dahyabhai <nalin@redhat.com> 1.5.24-22
+- add pam-devel as a buildprereq
+
+* Wed Aug 29 2001 Nalin Dahyabhai <nalin@redhat.com> 1.5.24-21
+- include sample programs in the -devel subpackage, prefixing their names
+  with "sasl-" to reduce future potential naming conflicts
+
+* Tue Aug 14 2001 Nalin Dahyabhai <nalin@redhat.com> 1.5.24-20
+- build without -ggdb
+
+* Fri Aug  3 2001 Nalin Dahyabhai <nalin@redhat.com>
+- add gdbm-devel as a build dependency (#44990)
+- split off CRAM-MD5 and DIGEST-MD5 into a subpackage of their own (#43079,
+  and dialogs with David L. Parsley)
+
+* Fri Apr 27 2001 Nalin Dahyabhai <nalin@redhat.com>
+- split out the PLAIN and LOGIN mechanisms into their own package (this allows
+  an administrator to disable them by simply removing the package)
+
+* Fri Jan 19 2001 Nalin Dahyabhai <nalin@redhat.com>
+- rebuild in new environment
+
+* Wed Dec  6 2000 Nalin Dahyabhai <nalin@redhat.com>
+- fix gssapi-over-tls
+
+* Fri Oct 27 2000 Nalin Dahyabhai <nalin@redhat.com>
+- enable static libraries, but always build with -fPIC
+
+* Wed Oct 25 2000 Nalin Dahyabhai <nalin@redhat.com>
+- make sure the version of 1.5.24 in the package matches the masters (#18968)
+
+* Mon Oct  9 2000 Nalin Dahyabhai <nalin@redhat.com>
+- re-add the libsasl.so symlink to the -devel package (oops)
+
+* Fri Oct  6 2000 Nalin Dahyabhai <nalin@redhat.com>
+- move .so files for modules to their respective packages -- they're not -devel
+  links meant for use by ld anyway
+
+* Thu Oct  5 2000 Nalin Dahyabhai <nalin@redhat.com>
+- split off -devel subpackage
+- add a -gssapi subpackage for the gssapi plugins
+
+* Wed Aug 16 2000 Nalin Dahyabhai <nalin@redhat.com>
+- fix the summary text
+
+* Sun Aug 13 2000 Nalin Dahyabhai <nalin@redhat.com>
+- re-enable arcfour and CRAM
+
+* Fri Aug  4 2000 Nalin Dahyabhai <nalin@redhat.com>
+- force use of gdbm for database files to avoid DB migration weirdness
+- enable login mechanism
+- disable gssapi until it can coexist peacefully with non-gssapi setups
+- actually do a make in the build section (#15410)
+
+* Fri Jul 21 2000 Nalin Dahyabhai <nalin@redhat.com>
+- update to 1.5.24
+
+* Wed Jul 12 2000 Prospector <bugzilla@redhat.com>
+- automatic rebuild
+
+* Tue Jun 27 2000 Nalin Dahyabhai <nalin@redhat.com>
+- rebuild in new environment (release 3)
+
+* Mon Jun 19 2000 Nalin Dahyabhai <nalin@redhat.com>
+- don't muck with syslogd in post
+- remove patch for db-3.0 wackiness, no longer needed
+
+* Thu Jun  8 2000 Nalin Dahyabhai <nalin@redhat.com>
+- FHS cleanup
+- don't strip anything by default
+
+* Fri Feb 11 2000 Tim Powers <timp@redhat.com>
+- fixed man pages not being gzipped
+
+* Tue Nov 16 1999 Tim Powers <timp@redhat.com>
+- incorporated changes from Mads Kiilerich
+- release number is 1, not mk1
+
+* Wed Nov 10 1999 Mads Kiilerich <mads@kiilerich.com>
+- updated to sasl 1.5.11
+- configure --disable-krb4 --without-rc4 --disable-cram 
+  because of missing libraries and pine having cram as default...
+- handle changing libsasl.so versions
+
+* Mon Aug 30 1999 Tim Powers <timp@redhat.com>
+- changed group
+
+* Fri Aug 13 1999 Tim Powers <timp@redhat.com>
+- first build for Powertools