diff --git a/SOURCES/openldap-cbinding-Add-channel-binding-support.patch b/SOURCES/openldap-cbinding-Add-channel-binding-support.patch
new file mode 100644
index 0000000..bc4ee65
--- /dev/null
+++ b/SOURCES/openldap-cbinding-Add-channel-binding-support.patch
@@ -0,0 +1,291 @@
+From ca310ebff44f10739fd75aff437c7676e089b134 Mon Sep 17 00:00:00 2001
+From: Howard Chu <hyc@openldap.org>
+Date: Mon, 26 Aug 2013 23:31:48 -0700
+Subject: [PATCH] Add channel binding support
+
+Currently only implemented for OpenSSL.
+Needs an option to set the criticality flag.
+---
+ include/ldap_pvt.h           |  1 +
+ libraries/libldap/cyrus.c    | 22 ++++++++++++++++++++++
+ libraries/libldap/ldap-int.h |  1 +
+ libraries/libldap/ldap-tls.h |  2 ++
+ libraries/libldap/tls2.c     |  7 +++++++
+ libraries/libldap/tls_g.c    |  7 +++++++
+ libraries/libldap/tls_m.c    |  7 +++++++
+ libraries/libldap/tls_o.c    | 16 ++++++++++++++++
+ servers/slapd/connection.c   |  8 ++++++++
+ servers/slapd/sasl.c         | 18 ++++++++++++++++++
+ servers/slapd/slap.h         |  1 +
+ 11 files changed, 90 insertions(+)
+
+diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h
+index 871e7c180..fdc9d2de3 100644
+--- a/include/ldap_pvt.h
++++ b/include/ldap_pvt.h
+@@ -430,6 +430,7 @@ LDAP_F (int) ldap_pvt_tls_get_my_dn LDAP_P(( void *ctx, struct berval *dn,
+ LDAP_F (int) ldap_pvt_tls_get_peer_dn LDAP_P(( void *ctx, struct berval *dn,
+ 	LDAPDN_rewrite_dummy *func, unsigned flags ));
+ LDAP_F (int) ldap_pvt_tls_get_strength LDAP_P(( void *ctx ));
++LDAP_F (int) ldap_pvt_tls_get_unique LDAP_P(( void *ctx, struct berval *buf, int is_server ));
+ 
+ LDAP_END_DECL
+ 
+diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c
+index 28c241b0b..a57292800 100644
+--- a/libraries/libldap/cyrus.c
++++ b/libraries/libldap/cyrus.c
+@@ -369,6 +369,10 @@ int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
+ 		lc->lconn_sasl_sockctx = NULL;
+ 		lc->lconn_sasl_authctx = NULL;
+ 	}
++	if( lc->lconn_sasl_cbind ) {
++		ldap_memfree( lc->lconn_sasl_cbind );
++		lc->lconn_sasl_cbind = NULL;
++	}
+ 
+ 	return LDAP_SUCCESS;
+ }
+@@ -482,6 +486,24 @@ ldap_int_sasl_bind(
+ 
+ 			(void) ldap_int_sasl_external( ld, ld->ld_defconn, authid.bv_val, fac );
+ 			LDAP_FREE( authid.bv_val );
++#ifdef SASL_CHANNEL_BINDING	/* 2.1.25+ */
++			{
++				char cbinding[64];
++				struct berval cbv = { sizeof(cbinding), cbinding };
++				if ( ldap_pvt_tls_get_unique( ssl, &cbv, 0 )) {
++					sasl_channel_binding_t *cb = ldap_memalloc( sizeof(*cb) +
++						cbv.bv_len);
++					cb->name = "ldap";
++					cb->critical = 0;
++					cb->data = (char *)(cb+1);
++					cb->len = cbv.bv_len;
++					memcpy( cb->data, cbv.bv_val, cbv.bv_len );
++					sasl_setprop( ld->ld_defconn->lconn_sasl_authctx,
++						SASL_CHANNEL_BINDING, cb );
++					ld->ld_defconn->lconn_sasl_cbind = cb;
++				}
++			}
++#endif
+ 		}
+ #endif
+ 
+diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
+index 37c342e26..1915ecab4 100644
+--- a/libraries/libldap/ldap-int.h
++++ b/libraries/libldap/ldap-int.h
+@@ -305,6 +305,7 @@ typedef struct ldap_conn {
+ #ifdef HAVE_CYRUS_SASL
+ 	void		*lconn_sasl_authctx;	/* context for bind */
+ 	void		*lconn_sasl_sockctx;	/* for security layer */
++	void		*lconn_sasl_cbind;		/* for channel binding */
+ #endif
+ #ifdef HAVE_GSSAPI
+ 	void		*lconn_gss_ctx;		/* gss_ctx_id_t */
+diff --git a/libraries/libldap/ldap-tls.h b/libraries/libldap/ldap-tls.h
+index 75661c005..1eb5ae47e 100644
+--- a/libraries/libldap/ldap-tls.h
++++ b/libraries/libldap/ldap-tls.h
+@@ -41,6 +41,7 @@ typedef char *(TI_session_errmsg)(tls_session *s, int rc, char *buf, size_t len
+ typedef int (TI_session_dn)(tls_session *sess, struct berval *dn);
+ typedef int (TI_session_chkhost)(LDAP *ld, tls_session *s, const char *name_in);
+ typedef int (TI_session_strength)(tls_session *sess);
++typedef int (TI_session_unique)(tls_session *sess, struct berval *buf, int is_server);
+ 
+ typedef void (TI_thr_init)(void);
+ 
+@@ -64,6 +65,7 @@ typedef struct tls_impl {
+ 	TI_session_dn *ti_session_peer_dn;
+ 	TI_session_chkhost *ti_session_chkhost;
+ 	TI_session_strength *ti_session_strength;
++	TI_session_unique *ti_session_unique;
+ 
+ 	Sockbuf_IO *ti_sbio;
+ 
+diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
+index e11d1a8a3..957e73c03 100644
+--- a/libraries/libldap/tls2.c
++++ b/libraries/libldap/tls2.c
+@@ -981,6 +981,13 @@ ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func,
+ 		rc = ldap_X509dn2bv(&der_dn, dn, (LDAPDN_rewrite_func *)func, flags );
+ 	return rc;
+ }
++
++int
++ldap_pvt_tls_get_unique( void *s, struct berval *buf, int is_server )
++{
++	tls_session *session = s;
++	return tls_imp->ti_session_unique( session, buf, is_server );
++}
+ #endif /* HAVE_TLS */
+ 
+ int
+diff --git a/libraries/libldap/tls_g.c b/libraries/libldap/tls_g.c
+index ed1f8f1cb..dfdc35da4 100644
+--- a/libraries/libldap/tls_g.c
++++ b/libraries/libldap/tls_g.c
+@@ -780,6 +780,12 @@ tlsg_session_strength( tls_session *session )
+ 	return gnutls_cipher_get_key_size( c ) * 8;
+ }
+ 
++static int
++tlsg_session_unique( tls_session *sess, struct berval *buf, int is_server)
++{
++	return 0;
++}
++
+ /* suites is a string of colon-separated cipher suite names. */
+ static int
+ tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites )
+@@ -1110,6 +1116,7 @@ tls_impl ldap_int_tls_impl = {
+ 	tlsg_session_peer_dn,
+ 	tlsg_session_chkhost,
+ 	tlsg_session_strength,
++	tlsg_session_unique,
+ 
+ 	&tlsg_sbio,
+ 
+diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
+index 072d41d56..240bd9ff6 100644
+--- a/libraries/libldap/tls_m.c
++++ b/libraries/libldap/tls_m.c
+@@ -2838,6 +2838,12 @@ tlsm_session_strength( tls_session *session )
+ 	return rc ? 0 : keySize;
+ }
+ 
++static int
++tlsm_session_unique( tls_session *sess, struct berval *buf, int is_server)
++{
++	return 0;
++}
++
+ /*
+  * TLS support for LBER Sockbufs
+  */
+@@ -3266,6 +3272,7 @@ tls_impl ldap_int_tls_impl = {
+ 	tlsm_session_peer_dn,
+ 	tlsm_session_chkhost,
+ 	tlsm_session_strength,
++	tlsm_session_unique,
+ 
+ 	&tlsm_sbio,
+ 
+diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
+index 3c077f895..2ecee465b 100644
+--- a/libraries/libldap/tls_o.c
++++ b/libraries/libldap/tls_o.c
+@@ -676,6 +676,21 @@ tlso_session_strength( tls_session *sess )
+ 	return SSL_CIPHER_get_bits(SSL_get_current_cipher(s), NULL);
+ }
+ 
++static int
++tlso_session_unique( tls_session *sess, struct berval *buf, int is_server)
++{
++	tlso_session *s = (tlso_session *)sess;
++
++	/* Usually the client sends the finished msg. But if the
++	 * session was resumed, the server sent the msg.
++	 */
++	if (SSL_session_reused(s) ^ !is_server)
++		buf->bv_len = SSL_get_finished(s, buf->bv_val, buf->bv_len);
++	else
++		buf->bv_len = SSL_get_peer_finished(s, buf->bv_val, buf->bv_len);
++	return buf->bv_len;
++}
++
+ /*
+  * TLS support for LBER Sockbufs
+  */
+@@ -1283,6 +1298,7 @@ tls_impl ldap_int_tls_impl = {
+ 	tlso_session_peer_dn,
+ 	tlso_session_chkhost,
+ 	tlso_session_strength,
++	tlso_session_unique,
+ 
+ 	&tlso_sbio,
+ 
+diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
+index e34703cb3..bc2b8a4d0 100644
+--- a/servers/slapd/connection.c
++++ b/servers/slapd/connection.c
+@@ -406,6 +406,7 @@ Connection * connection_init(
+ 		c->c_sasl_sockctx = NULL;
+ 		c->c_sasl_extra = NULL;
+ 		c->c_sasl_bindop = NULL;
++		c->c_sasl_cbind = NULL;
+ 
+ 		c->c_sb = ber_sockbuf_alloc( );
+ 
+@@ -451,6 +452,7 @@ Connection * connection_init(
+ 	assert( c->c_sasl_sockctx == NULL );
+ 	assert( c->c_sasl_extra == NULL );
+ 	assert( c->c_sasl_bindop == NULL );
++	assert( c->c_sasl_cbind == NULL );
+ 	assert( c->c_currentber == NULL );
+ 	assert( c->c_writewaiter == 0);
+ 	assert( c->c_writers == 0);
+@@ -1408,6 +1410,12 @@ connection_read( ber_socket_t s, conn_readinfo *cri )
+ 			    c->c_connid, (int) s, c->c_tls_ssf, c->c_ssf, 0 );
+ 			slap_sasl_external( c, c->c_tls_ssf, &authid );
+ 			if ( authid.bv_val ) free( authid.bv_val );
++			{
++				char cbinding[64];
++				struct berval cbv = { sizeof(cbinding), cbinding };
++				if ( ldap_pvt_tls_get_unique( ssl, &cbv, 1 ))
++					slap_sasl_cbinding( c, &cbv );
++			}
+ 		} else if ( rc == 1 && ber_sockbuf_ctrl( c->c_sb,
+ 			LBER_SB_OPT_NEEDS_WRITE, NULL )) {	/* need to retry */
+ 			slapd_set_write( s, 1 );
+diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c
+index 0bd6259be..57907d79b 100644
+--- a/servers/slapd/sasl.c
++++ b/servers/slapd/sasl.c
+@@ -1503,6 +1503,21 @@ int slap_sasl_external(
+ 	return LDAP_SUCCESS;
+ }
+ 
++int slap_sasl_cbinding( Connection *conn, struct berval *cbv )
++{
++#ifdef SASL_CHANNEL_BINDING
++	sasl_channel_binding_t *cb = ch_malloc( sizeof(*cb) + cbv->bv_len );;
++	cb->name = "ldap";
++	cb->critical = 0;
++	cb->data = (char *)(cb+1);
++	cb->len = cbv->bv_len;
++	memcpy( cb->data, cbv->bv_val, cbv->bv_len );
++	sasl_setprop( conn->c_sasl_authctx, SASL_CHANNEL_BINDING, cb );
++	conn->c_sasl_cbind = cb;
++#endif
++	return LDAP_SUCCESS;
++}
++
+ int slap_sasl_reset( Connection *conn )
+ {
+ 	return LDAP_SUCCESS;
+@@ -1568,6 +1583,9 @@ int slap_sasl_close( Connection *conn )
+ 	free( conn->c_sasl_extra );
+ 	conn->c_sasl_extra = NULL;
+ 
++	free( conn->c_sasl_cbind );
++	conn->c_sasl_cbind = NULL;
++
+ #elif defined(SLAP_BUILTIN_SASL)
+ 	SASL_CTX *ctx = conn->c_sasl_authctx;
+ 	if( ctx ) {
+diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
+index 09c1854f8..4b3bbd12e 100644
+--- a/servers/slapd/slap.h
++++ b/servers/slapd/slap.h
+@@ -2910,6 +2910,7 @@ struct Connection {
+ 	void	*c_sasl_authctx;	/* SASL authentication context */
+ 	void	*c_sasl_sockctx;	/* SASL security layer context */
+ 	void	*c_sasl_extra;		/* SASL session extra stuff */
++	void	*c_sasl_cbind;		/* SASL channel binding */
+ 	Operation	*c_sasl_bindop;	/* set to current op if it's a bind */
+ 
+ #ifdef LDAP_X_TXN
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-Convert-test077-to-LDIF-config.patch b/SOURCES/openldap-cbinding-Convert-test077-to-LDIF-config.patch
new file mode 100644
index 0000000..4bf9b63
--- /dev/null
+++ b/SOURCES/openldap-cbinding-Convert-test077-to-LDIF-config.patch
@@ -0,0 +1,167 @@
+From 59bdc8158f51fc22cc3c6d6dd2db9e5aa4bcfdc4 Mon Sep 17 00:00:00 2001
+From: Ryan Tandy <ryan@nardis.ca>
+Date: Mon, 27 Apr 2020 23:24:16 -0700
+Subject: [PATCH] Convert test077 to LDIF config
+
+---
+ tests/data/slapd-sasl-gssapi.conf | 68 -------------------------------
+ tests/scripts/defines.sh          |  1 -
+ tests/scripts/test077-sasl-gssapi | 35 +++++++++++++---
+ 3 files changed, 30 insertions(+), 74 deletions(-)
+ delete mode 100644 tests/data/slapd-sasl-gssapi.conf
+
+diff --git a/tests/data/slapd-sasl-gssapi.conf b/tests/data/slapd-sasl-gssapi.conf
+deleted file mode 100644
+index 29ab6040b..000000000
+--- a/tests/data/slapd-sasl-gssapi.conf
++++ /dev/null
+@@ -1,68 +0,0 @@
+-# stand-alone slapd config -- for testing (with indexing)
+-# $OpenLDAP$
+-## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+-##
+-## Copyright 1998-2020 The OpenLDAP Foundation.
+-## All rights reserved.
+-##
+-## Redistribution and use in source and binary forms, with or without
+-## modification, are permitted only as authorized by the OpenLDAP
+-## Public License.
+-##
+-## A copy of this license is available in the file LICENSE in the
+-## top-level directory of the distribution or, alternatively, at
+-## <http://www.OpenLDAP.org/license.html>.
+-
+-#
+-include		@SCHEMADIR@/core.schema
+-include		@SCHEMADIR@/cosine.schema
+-#
+-include		@SCHEMADIR@/corba.schema
+-include		@SCHEMADIR@/java.schema
+-include		@SCHEMADIR@/inetorgperson.schema
+-include		@SCHEMADIR@/misc.schema
+-include		@SCHEMADIR@/nis.schema
+-include		@SCHEMADIR@/openldap.schema
+-#
+-include		@SCHEMADIR@/duaconf.schema
+-include		@SCHEMADIR@/dyngroup.schema
+-
+-#
+-pidfile		@TESTDIR@/slapd.1.pid
+-argsfile	@TESTDIR@/slapd.1.args
+-
+-# SSL configuration
+-TLSCACertificateFile @TESTDIR@/tls/ca/certs/testsuiteCA.crt
+-TLSCertificateKeyFile @TESTDIR@/tls/private/localhost.key
+-TLSCertificateFile @TESTDIR@/tls/certs/localhost.crt
+-
+-#
+-rootdse 	@DATADIR@/rootdse.ldif
+-
+-#mod#modulepath	../servers/slapd/back-@BACKEND@/
+-#mod#moduleload	back_@BACKEND@.la
+-#monitormod#modulepath ../servers/slapd/back-monitor/
+-#monitormod#moduleload back_monitor.la
+-
+-
+-#######################################################################
+-# database definitions
+-#######################################################################
+-
+-database	@BACKEND@
+-suffix          "dc=example,dc=com"
+-rootdn          "cn=Manager,dc=example,dc=com"
+-rootpw          secret
+-#~null~#directory	@TESTDIR@/db.1.a
+-#indexdb#index		objectClass eq
+-#indexdb#index		mail eq
+-#ndb#dbname db_1_a
+-#ndb#include @DATADIR@/ndb.conf
+-
+-#monitor#database	monitor
+-
+-sasl-realm	@KRB5REALM@
+-sasl-host	localhost
+-
+-database	config
+-rootpw		secret
+diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh
+index f9e5578ee..a84fd0a65 100755
+--- a/tests/scripts/defines.sh
++++ b/tests/scripts/defines.sh
+@@ -114,7 +114,6 @@ REFSLAVECONF=$DATADIR/slapd-ref-slave.conf
+ SCHEMACONF=$DATADIR/slapd-schema.conf
+ TLSCONF=$DATADIR/slapd-tls.conf
+ TLSSASLCONF=$DATADIR/slapd-tls-sasl.conf
+-SASLGSSAPICONF=$DATADIR/slapd-sasl-gssapi.conf
+ GLUECONF=$DATADIR/slapd-glue.conf
+ REFINTCONF=$DATADIR/slapd-refint.conf
+ RETCODECONF=$DATADIR/slapd-retcode.conf
+diff --git a/tests/scripts/test077-sasl-gssapi b/tests/scripts/test077-sasl-gssapi
+index 20c414600..322df60a4 100755
+--- a/tests/scripts/test077-sasl-gssapi
++++ b/tests/scripts/test077-sasl-gssapi
+@@ -21,15 +21,40 @@ if test $WITH_SASL = no ; then
+         exit 0
+ fi
+ 
++CONFDIR=$TESTDIR/slapd.d
++CONFLDIF=$TESTDIR/slapd.ldif
++
+ mkdir -p $TESTDIR $DBDIR1 $CONFDIR
+ cp -r $DATADIR/tls $TESTDIR
++$SLAPPASSWD -g -n >$CONFIGPWF
+ 
+ echo "Starting KDC for SASL/GSSAPI tests..."
+ . $SRCDIR/scripts/setup_kdc.sh
+ 
+-echo "Running slapadd to build slapd database..."
+-. $CONFFILTER $BACKEND $MONITORDB < $SASLGSSAPICONF > $CONF1
+-$SLAPADD -f $CONF1 -l $LDIFORDERED
++echo "Configuring slapd..."
++cat > $CONFLDIF <<EOF
++dn: cn=config
++objectClass: olcGlobal
++cn: config
++olcSaslHost: localhost
++olcSaslRealm: $KRB5REALM
++olcTLSCACertificateFile: $TESTDIR/tls/ca/certs/testsuiteCA.crt
++olcTLSCertificateFile: $TESTDIR/tls/certs/localhost.crt
++olcTLSCertificateKeyFile: $TESTDIR/tls/private/localhost.key
++
++dn: cn=schema,cn=config
++objectClass: olcSchemaConfig
++cn: schema
++
++include: file://$ABS_SCHEMADIR/core.ldif
++
++dn: olcDatabase={0}config,cn=config
++objectClass: olcDatabaseConfig
++olcDatabase: {0}config
++olcRootPW:< file://$TESTDIR/configpw
++
++EOF
++$SLAPADD -F $CONFDIR -n 0 -l $CONFLDIF
+ RC=$?
+ if test $RC != 0 ; then
+ 	echo "slapadd failed ($RC)!"
+@@ -38,7 +63,7 @@ if test $RC != 0 ; then
+ fi
+ 
+ echo "Starting ldap:/// slapd on TCP/IP port $PORT1 and ldaps:/// slapd on $PORT2..."
+-$SLAPD -f $CONF1 -h "$URI1 $SURI2" -d $LVL $TIMING > $LOG1 2>&1 &
++$SLAPD -F $CONFDIR -h "$URI1 $SURI2" -d $LVL $TIMING > $LOG1 2>&1 &
+ PID=$!
+ if test $WAIT != 0 ; then
+     echo PID $PID
+@@ -151,7 +176,7 @@ else
+ 	for acb in "none" "tls-unique" "tls-endpoint" ; do
+ 
+ 		echo "Modifying slapd's olcSaslCBinding to ${acb} ..."
+-		$LDAPMODIFY -D cn=config -H $URI1 -w secret <<EOF > $TESTOUT 2>&1
++		$LDAPMODIFY -D cn=config -H $URI1 -y $CONFIGPWF <<EOF > $TESTOUT 2>&1
+ dn: cn=config
+ changetype: modify
+ replace: olcSaslCBinding
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-Fix-slaptest-in-test077.patch b/SOURCES/openldap-cbinding-Fix-slaptest-in-test077.patch
new file mode 100644
index 0000000..fc1e034
--- /dev/null
+++ b/SOURCES/openldap-cbinding-Fix-slaptest-in-test077.patch
@@ -0,0 +1,62 @@
+From e006994d83af9dcb7813a18253cf4e5beacee043 Mon Sep 17 00:00:00 2001
+From: Ryan Tandy <ryan@nardis.ca>
+Date: Sun, 26 Apr 2020 11:40:23 -0700
+Subject: [PATCH] Fix slaptest in test077
+
+The libtool wrapper scripts lose argv[0] when exec'ing the real binary.
+
+In the CI Docker container, where the build runs as root, this was
+actually starting a real slapd on the default port.
+
+Outside Docker, running as a non-root user, this slapd would just fail
+to start, and wouldn't convert the config either.
+
+Using "slapd -Tt" fixes the issue but also prints a warning from
+slaptest since the database hasn't been initialized yet.
+
+Dynamic config isn't actually used in this test script, so let's just
+run slapd off the config file directly.
+---
+ tests/scripts/test077-sasl-gssapi | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/tests/scripts/test077-sasl-gssapi b/tests/scripts/test077-sasl-gssapi
+index 19f665622..20c414600 100755
+--- a/tests/scripts/test077-sasl-gssapi
++++ b/tests/scripts/test077-sasl-gssapi
+@@ -21,22 +21,15 @@ if test $WITH_SASL = no ; then
+         exit 0
+ fi
+ 
+-SLAPTEST="$TESTWD/../servers/slapd/slaptest"
+-CONFDIR=$TESTDIR/slapd.d
+-
+ mkdir -p $TESTDIR $DBDIR1 $CONFDIR
+ cp -r $DATADIR/tls $TESTDIR
+ 
+-cd $TESTWD
+-
+-
+ echo "Starting KDC for SASL/GSSAPI tests..."
+ . $SRCDIR/scripts/setup_kdc.sh
+ 
+ echo "Running slapadd to build slapd database..."
+ . $CONFFILTER $BACKEND $MONITORDB < $SASLGSSAPICONF > $CONF1
+-$SLAPTEST -f $CONF1 -F $CONFDIR
+-$SLAPADD -F $CONFDIR -l $LDIFORDERED
++$SLAPADD -f $CONF1 -l $LDIFORDERED
+ RC=$?
+ if test $RC != 0 ; then
+ 	echo "slapadd failed ($RC)!"
+@@ -45,7 +38,7 @@ if test $RC != 0 ; then
+ fi
+ 
+ echo "Starting ldap:/// slapd on TCP/IP port $PORT1 and ldaps:/// slapd on $PORT2..."
+-$SLAPD -F $CONFDIR -h "$URI1 $SURI2" -d $LVL $TIMING > $LOG1 2>&1 &
++$SLAPD -f $CONF1 -h "$URI1 $SURI2" -d $LVL $TIMING > $LOG1 2>&1 &
+ PID=$!
+ if test $WAIT != 0 ; then
+     echo PID $PID
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-ITS-7398-add-LDAP_OPT_X_TLS_PEERCERT.patch b/SOURCES/openldap-cbinding-ITS-7398-add-LDAP_OPT_X_TLS_PEERCERT.patch
new file mode 100644
index 0000000..b0454f8
--- /dev/null
+++ b/SOURCES/openldap-cbinding-ITS-7398-add-LDAP_OPT_X_TLS_PEERCERT.patch
@@ -0,0 +1,220 @@
+NOTE: The patch has been adjusted to match the base code before backporting.
+
+From 16f8b0902c28b1eaab93ddf120ce40b89bcda8d1 Mon Sep 17 00:00:00 2001
+From: Howard Chu <hyc@openldap.org>
+Date: Tue, 10 Sep 2013 04:26:51 -0700
+Subject: [PATCH] ITS#7398 add LDAP_OPT_X_TLS_PEERCERT
+
+retrieve peer cert for an active TLS session
+---
+ doc/man/man3/ldap_get_option.3 |  8 ++++++++
+ include/ldap.h                 |  1 +
+ libraries/libldap/ldap-tls.h   |  2 ++
+ libraries/libldap/tls2.c       | 23 +++++++++++++++++++++++
+ libraries/libldap/tls_g.c      | 19 +++++++++++++++++++
+ libraries/libldap/tls_m.c      | 17 +++++++++++++++++
+ libraries/libldap/tls_o.c      | 16 ++++++++++++++++
+ 7 files changed, 86 insertions(+)
+
+diff --git a/doc/man/man3/ldap_get_option.3 b/doc/man/man3/ldap_get_option.3
+index e67de75e9..1bb55d357 100644
+--- a/doc/man/man3/ldap_get_option.3
++++ b/doc/man/man3/ldap_get_option.3
+@@ -732,6 +732,14 @@ A non-zero value pointed to by
+ .BR invalue
+ tells the library to create a context for a server.
+ .TP
++.B LDAP_OPT_X_TLS_PEERCERT
++Gets the peer's certificate in DER format from an established TLS session.
++.BR outvalue
++must be
++.BR "struct berval *" ,
++and the data it returns needs to be freed by the caller using
++.BR ldap_memfree (3).
++.TP
+ .B LDAP_OPT_X_TLS_PROTOCOL_MIN
+ Sets/gets the minimum protocol version.
+ .BR invalue
+diff --git a/include/ldap.h b/include/ldap.h
+index 4de3f7f32..97ca524d7 100644
+--- a/include/ldap.h
++++ b/include/ldap.h
+@@ -161,6 +161,7 @@ LDAP_BEGIN_DECL
+ #define LDAP_OPT_X_TLS_CRLFILE		0x6010	/* GNUtls only */
+ #define LDAP_OPT_X_TLS_PACKAGE		0x6011
+ #define LDAP_OPT_X_TLS_ECNAME		0x6012
++#define LDAP_OPT_X_TLS_PEERCERT		0x6015	/* read-only */
+ 
+ #define LDAP_OPT_X_TLS_NEVER	0
+ #define LDAP_OPT_X_TLS_HARD		1
+diff --git a/libraries/libldap/ldap-tls.h b/libraries/libldap/ldap-tls.h
+index 548814d7f..890d20dc7 100644
+--- a/libraries/libldap/ldap-tls.h
++++ b/libraries/libldap/ldap-tls.h
+@@ -43,6 +43,7 @@ typedef int (TI_session_dn)(tls_session *sess, struct berval *dn);
+ typedef int (TI_session_chkhost)(LDAP *ld, tls_session *s, const char *name_in);
+ typedef int (TI_session_strength)(tls_session *sess);
+ typedef int (TI_session_unique)(tls_session *sess, struct berval *buf, int is_server);
++typedef int (TI_session_peercert)(tls_session *s, struct berval *der);
+ 
+ typedef void (TI_thr_init)(void);
+ 
+@@ -69,6 +70,7 @@ typedef struct tls_impl {
+	TI_session_chkhost *ti_session_chkhost;
+	TI_session_strength *ti_session_strength;
+ 	TI_session_unique *ti_session_unique;
++	TI_session_peercert *ti_session_peercert;
+ 
+ 	Sockbuf_IO *ti_sbio;
+ 
+diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
+index 05fce3218..cbf73bdd5 100644
+--- a/libraries/libldap/tls2.c
++++ b/libraries/libldap/tls2.c
+@@ -718,6 +718,23 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
+ 	case LDAP_OPT_X_TLS_CONNECT_ARG:
+ 		*(void **)arg = lo->ldo_tls_connect_arg;
+ 		break;
++	case LDAP_OPT_X_TLS_PEERCERT: {
++		void *sess = NULL;
++		struct berval *bv = arg;
++		bv->bv_len = 0;
++		bv->bv_val = NULL;
++		if ( ld != NULL ) {
++			LDAPConn *conn = ld->ld_defconn;
++			if ( conn != NULL ) {
++				Sockbuf *sb = conn->lconn_sb;
++				sess = ldap_pvt_tls_sb_ctx( sb );
++				if ( sess != NULL )
++					return ldap_pvt_tls_get_peercert( sess, bv );
++			}
++		}
++		break;
++	}
++
+ 	default:
+ 		return -1;
+ 	}
+@@ -1050,6 +1066,13 @@ ldap_pvt_tls_get_unique( void *s, struct berval *buf, int is_server )
+ 	tls_session *session = s;
+ 	return tls_imp->ti_session_unique( session, buf, is_server );
+ }
++
++int
++ldap_pvt_tls_get_peercert( void *s, struct berval *der )
++{
++	tls_session *session = s;
++	return tls_imp->ti_session_peercert( session, der );
++}
+ #endif /* HAVE_TLS */
+ 
+ int
+diff --git a/libraries/libldap/tls_g.c b/libraries/libldap/tls_g.c
+index ce422387c..739680439 100644
+--- a/libraries/libldap/tls_g.c
++++ b/libraries/libldap/tls_g.c
+@@ -830,6 +830,24 @@ tlsg_session_unique( tls_session *sess, struct berval *buf, int is_server)
+ 	return 0;
+ }
+ 
++static int
++tlsg_session_peercert( tls_session *sess, struct berval *der )
++{
++	tlsg_session *s = (tlsg_session *)sess;
++	const gnutls_datum_t *peer_cert_list;
++	unsigned int list_size;
++
++	peer_cert_list = gnutls_certificate_get_peers( s->session, &list_size );
++	if (!peer_cert_list)
++		return -1;
++	der->bv_len = peer_cert_list[0].size;
++	der->bv_val = LDAP_MALLOC( der->bv_len );
++	if (!der->bv_val)
++		return -1;
++	memcpy(der->bv_val, peer_cert_list[0].data, der->bv_len);
++	return 0;
++}
++
+ /* suites is a string of colon-separated cipher suite names. */
+ static int
+ tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites )
+@@ -1166,6 +1184,7 @@ tls_impl ldap_int_tls_impl = {
+ 	tlsg_session_chkhost,
+ 	tlsg_session_strength,
+ 	tlsg_session_unique,
++	tlsg_session_peercert,
+ 
+ 	&tlsg_sbio,
+ 
+diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
+index 4bd9e63cb..36dc989ef 100644
+--- a/libraries/libldap/tls_m.c
++++ b/libraries/libldap/tls_m.c
+@@ -2891,6 +2891,22 @@ tlsm_session_unique( tls_session *sess, struct berval *buf, int is_server)
+ 	return 0;
+ }
+ 
++static int
++tlsm_session_peercert( tls_session *sess, struct berval *der )
++{
++	tlsm_session *s = (tlsm_session *)sess;
++	CERTCertificate *cert;
++	cert = SSL_PeerCertificate( s );
++	if (!cert)
++		return -1;
++	der->bv_len = cert->derCert.len;
++	der->bv_val = LDAP_MALLOC( der->bv_len );
++	if (!der->bv_val)
++		return -1;
++	memcpy( der->bv_val, cert->derCert.data, der->bv_len );
++	return 0;
++}
++
+ /*
+  * TLS support for LBER Sockbufs
+  */
+@@ -3322,6 +3338,7 @@ tls_impl ldap_int_tls_impl = {
+ 	tlsm_session_chkhost,
+ 	tlsm_session_strength,
+ 	tlsm_session_unique,
++	tlsm_session_peercert,
+ 
+ 	&tlsm_sbio,
+ 
+diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
+index 6288456d3..1fa50392f 100644
+--- a/libraries/libldap/tls_o.c
++++ b/libraries/libldap/tls_o.c
+@@ -721,6 +721,21 @@ tlso_session_unique( tls_session *sess, struct berval *buf, int is_server)
+ 	return buf->bv_len;
+ }
+ 
++static int
++tlso_session_peercert( tls_session *sess, struct berval *der )
++{
++	tlso_session *s = (tlso_session *)sess;
++	unsigned char *ptr;
++	X509 *x = SSL_get_peer_certificate(s);
++	der->bv_len = i2d_X509(x, NULL);
++	der->bv_val = LDAP_MALLOC(der->bv_len);
++	if ( !der->bv_val )
++		return -1;
++	ptr = der->bv_val;
++	i2d_X509(x, &ptr);
++	return 0;
++}
++
+ /*
+  * TLS support for LBER Sockbufs
+  */
+@@ -1229,6 +1244,7 @@ tls_impl ldap_int_tls_impl = {
+ 	tlso_session_chkhost,
+ 	tlso_session_strength,
+ 	tlso_session_unique,
++	tlso_session_peercert,
+ 
+ 	&tlso_sbio,
+ 
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-ITS-8573-Add-missing-URI-variables-for-tests.patch b/SOURCES/openldap-cbinding-ITS-8573-Add-missing-URI-variables-for-tests.patch
new file mode 100644
index 0000000..71cfbf0
--- /dev/null
+++ b/SOURCES/openldap-cbinding-ITS-8573-Add-missing-URI-variables-for-tests.patch
@@ -0,0 +1,70 @@
+From 465b1c5972eef1d4e60eb98ae3776d33e270853d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= <okuznik@symas.com>
+Date: Fri, 15 Jun 2018 15:12:28 +0100
+Subject: [PATCH] ITS#8573 Add missing URI variables for tests
+
+---
+ tests/scripts/conf.sh    | 18 ++++++++++++++++++
+ tests/scripts/defines.sh |  7 +++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/tests/scripts/conf.sh b/tests/scripts/conf.sh
+index fe5e60509..02629f190 100755
+--- a/tests/scripts/conf.sh
++++ b/tests/scripts/conf.sh
+@@ -75,6 +75,24 @@ sed -e "s/@BACKEND@/${BACKEND}/"			\
+ 	-e "s;@PORT4@;${PORT4};"			\
+ 	-e "s;@PORT5@;${PORT5};"			\
+ 	-e "s;@PORT6@;${PORT6};"			\
++	-e "s;@SURI1@;${SURI1};"			\
++	-e "s;@SURI2@;${SURI2};"			\
++	-e "s;@SURI3@;${SURI3};"			\
++	-e "s;@SURI4@;${SURI4};"			\
++	-e "s;@SURI5@;${SURI5};"			\
++	-e "s;@SURI6@;${SURI6};"			\
++	-e "s;@URIP1@;${URIP1};"			\
++	-e "s;@URIP2@;${URIP2};"			\
++	-e "s;@URIP3@;${URIP3};"			\
++	-e "s;@URIP4@;${URIP4};"			\
++	-e "s;@URIP5@;${URIP5};"			\
++	-e "s;@URIP6@;${URIP6};"			\
++	-e "s;@SURIP1@;${SURIP1};"			\
++	-e "s;@SURIP2@;${SURIP2};"			\
++	-e "s;@SURIP3@;${SURIP3};"			\
++	-e "s;@SURIP4@;${SURIP4};"			\
++	-e "s;@SURIP5@;${SURIP5};"			\
++	-e "s;@SURIP6@;${SURIP6};"			\
+ 	-e "s/@SASL_MECH@/${SASL_MECH}/"		\
+ 	-e "s;@TESTDIR@;${TESTDIR};"			\
+ 	-e "s;@TESTWD@;${TESTWD};"			\
+diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh
+index 2c9e8f76a..9816034f9 100755
+--- a/tests/scripts/defines.sh
++++ b/tests/scripts/defines.sh
+@@ -223,16 +223,23 @@ URIP2="ldap://${LOCALIP}:$PORT2/"
+ URI3="ldap://${LOCALHOST}:$PORT3/"
+ URIP3="ldap://${LOCALIP}:$PORT3/"
+ URI4="ldap://${LOCALHOST}:$PORT4/"
++URIP4="ldap://${LOCALIP}:$PORT4/"
+ URI5="ldap://${LOCALHOST}:$PORT5/"
++URIP5="ldap://${LOCALIP}:$PORT5/"
+ URI6="ldap://${LOCALHOST}:$PORT6/"
++URIP6="ldap://${LOCALIP}:$PORT6/"
+ SURI1="ldaps://${LOCALHOST}:$PORT1/"
+ SURIP1="ldaps://${LOCALIP}:$PORT1/"
+ SURI2="ldaps://${LOCALHOST}:$PORT2/"
+ SURIP2="ldaps://${LOCALIP}:$PORT2/"
+ SURI3="ldaps://${LOCALHOST}:$PORT3/"
++SURIP3="ldaps://${LOCALIP}:$PORT3/"
+ SURI4="ldaps://${LOCALHOST}:$PORT4/"
++SURIP4="ldaps://${LOCALIP}:$PORT4/"
+ SURI5="ldaps://${LOCALHOST}:$PORT5/"
++SURIP5="ldaps://${LOCALIP}:$PORT5/"
+ SURI6="ldaps://${LOCALHOST}:$PORT6/"
++SURIP6="ldaps://${LOCALIP}:$PORT6/"
+ 
+ # LDIF
+ LDIF=$DATADIR/test.ldif
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-ITS-8573-TLS-option-test-suite.patch b/SOURCES/openldap-cbinding-ITS-8573-TLS-option-test-suite.patch
new file mode 100644
index 0000000..2a7e4b0
--- /dev/null
+++ b/SOURCES/openldap-cbinding-ITS-8573-TLS-option-test-suite.patch
@@ -0,0 +1,2108 @@
+From eb087e0861f207858a4e08c72836a86f26d9701c Mon Sep 17 00:00:00 2001
+From: Quanah Gibson-Mount <quanah@openldap.org>
+Date: Thu, 14 Jun 2018 16:12:59 +0100
+Subject: [PATCH] ITS#8573 TLS option test suite
+
+---
+ configure                                     |   4 +
+ configure.in                                  |   4 +
+ tests/data/slapd-tls-sasl.conf                |  65 ++
+ tests/data/slapd-tls.conf                     |  61 ++
+ tests/data/tls/ca/certs/testsuiteCA.crt       |  16 +
+ tests/data/tls/ca/private/testsuiteCA.key     |  16 +
+ .../tls/certs/bjensen@mailgw.example.com.crt  |  16 +
+ tests/data/tls/certs/localhost.crt            |  16 +
+ tests/data/tls/conf/openssl.cnf               | 129 ++++
+ tests/data/tls/create-crt.sh                  |  78 +++
+ .../private/bjensen@mailgw.example.com.key    |  16 +
+ tests/data/tls/private/localhost.key          |  16 +
+ tests/run.in                                  |   3 +-
+ tests/scripts/defines.sh                      |  21 +-
+ tests/scripts/test067-tls                     | 140 +++++
+ tests/scripts/test068-sasl-tls-external       | 102 ++++
+ .../test069-delta-multimaster-starttls        | 574 ++++++++++++++++++
+ tests/scripts/test070-delta-multimaster-ldaps | 571 +++++++++++++++++
+ 18 files changed, 1846 insertions(+), 2 deletions(-)
+ create mode 100644 tests/data/slapd-tls-sasl.conf
+ create mode 100644 tests/data/slapd-tls.conf
+ create mode 100644 tests/data/tls/ca/certs/testsuiteCA.crt
+ create mode 100644 tests/data/tls/ca/private/testsuiteCA.key
+ create mode 100644 tests/data/tls/certs/bjensen@mailgw.example.com.crt
+ create mode 100644 tests/data/tls/certs/localhost.crt
+ create mode 100644 tests/data/tls/conf/openssl.cnf
+ create mode 100755 tests/data/tls/create-crt.sh
+ create mode 100644 tests/data/tls/private/bjensen@mailgw.example.com.key
+ create mode 100644 tests/data/tls/private/localhost.key
+ create mode 100755 tests/scripts/test067-tls
+ create mode 100755 tests/scripts/test068-sasl-tls-external
+ create mode 100755 tests/scripts/test069-delta-multimaster-starttls
+ create mode 100755 tests/scripts/test070-delta-multimaster-ldaps
+
+diff --git a/configure b/configure
+index 16d4ab884..29b7ad91d 100755
+--- a/configure
++++ b/configure
+@@ -761,6 +761,7 @@ AUTH_LIBS
+ LIBSLAPI
+ SLAPI_LIBS
+ MODULES_LIBS
++WITH_TLS_TYPE
+ TLS_LIBS
+ SASL_LIBS
+ KRB5_LIBS
+@@ -5223,6 +5224,7 @@ KRB4_LIBS=
+ KRB5_LIBS=
+ SASL_LIBS=
+ TLS_LIBS=
++WITH_TLS_TYPE=
+ MODULES_LIBS=
+ SLAPI_LIBS=
+ LIBSLAPI=
+@@ -15701,6 +15703,7 @@ fi
+ 		if test $have_openssl = yes ; then
+ 			ol_with_tls=openssl
+ 			ol_link_tls=yes
++			WITH_TLS_TYPE=openssl
+ 
+ 
+ $as_echo "#define HAVE_OPENSSL 1" >>confdefs.h
+@@ -15835,6 +15838,7 @@ fi
+ 			if test $have_gnutls = yes ; then
+ 				ol_with_tls=gnutls
+ 				ol_link_tls=yes
++				WITH_TLS_TYPE=gnutls
+ 
+ 				TLS_LIBS="-lgnutls"
+ 
+diff --git a/configure.in b/configure.in
+index ee25a4a90..60c446096 100644
+--- a/configure.in
++++ b/configure.in
+@@ -610,6 +610,7 @@ KRB4_LIBS=
+ KRB5_LIBS=
+ SASL_LIBS=
+ TLS_LIBS=
++WITH_TLS_TYPE=
+ MODULES_LIBS=
+ SLAPI_LIBS=
+ LIBSLAPI=
+@@ -1210,6 +1211,7 @@ if test $ol_with_tls = openssl || test $ol_with_tls = auto ; then
+ 		if test $have_openssl = yes ; then
+ 			ol_with_tls=openssl
+ 			ol_link_tls=yes
++			WITH_TLS_TYPE=openssl
+ 
+ 			AC_DEFINE(HAVE_OPENSSL, 1, 
+ 				[define if you have OpenSSL])
+@@ -1250,6 +1252,7 @@ if test $ol_link_tls = no ; then
+ 			if test $have_gnutls = yes ; then
+ 				ol_with_tls=gnutls
+ 				ol_link_tls=yes
++				WITH_TLS_TYPE=gnutls
+ 
+ 				TLS_LIBS="-lgnutls"
+ 
+@@ -3261,6 +3264,7 @@ AC_SUBST(KRB4_LIBS)
+ AC_SUBST(KRB5_LIBS)
+ AC_SUBST(SASL_LIBS)
+ AC_SUBST(TLS_LIBS)
++AC_SUBST(WITH_TLS_TYPE)
+ AC_SUBST(MODULES_LIBS)
+ AC_SUBST(SLAPI_LIBS)
+ AC_SUBST(LIBSLAPI)
+diff --git a/tests/data/slapd-tls-sasl.conf b/tests/data/slapd-tls-sasl.conf
+new file mode 100644
+index 000000000..f4bb0773e
+--- /dev/null
++++ b/tests/data/slapd-tls-sasl.conf
+@@ -0,0 +1,65 @@
++# stand-alone slapd config -- for testing (with indexing)
++# $OpenLDAP$
++## This work is part of OpenLDAP Software <http://www.openldap.org/>.
++##
++## Copyright 1998-2017 The OpenLDAP Foundation.
++## All rights reserved.
++##
++## Redistribution and use in source and binary forms, with or without
++## modification, are permitted only as authorized by the OpenLDAP
++## Public License.
++##
++## A copy of this license is available in the file LICENSE in the
++## top-level directory of the distribution or, alternatively, at
++## <http://www.OpenLDAP.org/license.html>.
++
++#
++include		@SCHEMADIR@/core.schema
++include		@SCHEMADIR@/cosine.schema
++#
++include		@SCHEMADIR@/corba.schema
++include		@SCHEMADIR@/java.schema
++include		@SCHEMADIR@/inetorgperson.schema
++include		@SCHEMADIR@/misc.schema
++include		@SCHEMADIR@/nis.schema
++include		@SCHEMADIR@/openldap.schema
++#
++include		@SCHEMADIR@/duaconf.schema
++include		@SCHEMADIR@/dyngroup.schema
++include		@SCHEMADIR@/ppolicy.schema
++
++#
++pidfile		@TESTDIR@/slapd.1.pid
++argsfile	@TESTDIR@/slapd.1.args
++
++# SSL configuration
++TLSCACertificateFile @TESTDIR@/tls/ca/certs/testsuiteCA.crt
++TLSCertificateKeyFile @TESTDIR@/tls/private/localhost.key
++TLSCertificateFile @TESTDIR@/tls/certs/localhost.crt
++TLSVerifyClient hard
++
++#
++rootdse 	@DATADIR@/rootdse.ldif
++
++#mod#modulepath	../servers/slapd/back-@BACKEND@/
++#mod#moduleload	back_@BACKEND@.la
++#monitormod#modulepath ../servers/slapd/back-monitor/
++#monitormod#moduleload back_monitor.la
++
++authz-regexp "email=([^,]*),cn=[^,]*,ou=OpenLDAP,o=OpenLDAP Foundation,st=CA,c=US" ldap:///ou=People,dc=example,dc=com??sub?(mail=$1)
++
++#######################################################################
++# database definitions
++#######################################################################
++
++database	@BACKEND@
++suffix          "dc=example,dc=com"
++rootdn          "cn=Manager,dc=example,dc=com"
++rootpw          secret
++#~null~#directory	@TESTDIR@/db.1.a
++#indexdb#index		objectClass eq
++#indexdb#index		mail eq
++#ndb#dbname db_1_a
++#ndb#include @DATADIR@/ndb.conf
++
++#monitor#database	monitor
+diff --git a/tests/data/slapd-tls.conf b/tests/data/slapd-tls.conf
+new file mode 100644
+index 000000000..6a7785557
+--- /dev/null
++++ b/tests/data/slapd-tls.conf
+@@ -0,0 +1,61 @@
++# stand-alone slapd config -- for testing (with indexing)
++# $OpenLDAP$
++## This work is part of OpenLDAP Software <http://www.openldap.org/>.
++##
++## Copyright 1998-2017 The OpenLDAP Foundation.
++## All rights reserved.
++##
++## Redistribution and use in source and binary forms, with or without
++## modification, are permitted only as authorized by the OpenLDAP
++## Public License.
++##
++## A copy of this license is available in the file LICENSE in the
++## top-level directory of the distribution or, alternatively, at
++## <http://www.OpenLDAP.org/license.html>.
++
++#
++include		@SCHEMADIR@/core.schema
++include		@SCHEMADIR@/cosine.schema
++#
++include		@SCHEMADIR@/corba.schema
++include		@SCHEMADIR@/java.schema
++include		@SCHEMADIR@/inetorgperson.schema
++include		@SCHEMADIR@/misc.schema
++include		@SCHEMADIR@/nis.schema
++include		@SCHEMADIR@/openldap.schema
++#
++include		@SCHEMADIR@/duaconf.schema
++include		@SCHEMADIR@/dyngroup.schema
++include		@SCHEMADIR@/ppolicy.schema
++
++#
++pidfile		@TESTDIR@/slapd.1.pid
++argsfile	@TESTDIR@/slapd.1.args
++
++# SSL configuration
++TLSCertificateKeyFile @TESTDIR@/tls/private/localhost.key
++TLSCertificateFile @TESTDIR@/tls/certs/localhost.crt
++
++#
++rootdse 	@DATADIR@/rootdse.ldif
++
++#mod#modulepath	../servers/slapd/back-@BACKEND@/
++#mod#moduleload	back_@BACKEND@.la
++#monitormod#modulepath ../servers/slapd/back-monitor/
++#monitormod#moduleload back_monitor.la
++
++#######################################################################
++# database definitions
++#######################################################################
++
++database	@BACKEND@
++suffix          "dc=example,dc=com"
++rootdn          "cn=Manager,dc=example,dc=com"
++rootpw          secret
++#~null~#directory	@TESTDIR@/db.1.a
++#indexdb#index		objectClass eq
++#indexdb#index		mail eq
++#ndb#dbname db_1_a
++#ndb#include @DATADIR@/ndb.conf
++
++#monitor#database	monitor
+diff --git a/tests/data/tls/ca/certs/testsuiteCA.crt b/tests/data/tls/ca/certs/testsuiteCA.crt
+new file mode 100644
+index 000000000..7458e7461
+--- /dev/null
++++ b/tests/data/tls/ca/certs/testsuiteCA.crt
+@@ -0,0 +1,16 @@
++-----BEGIN CERTIFICATE-----
++MIICgjCCAeugAwIBAgIJAJGJtO9oGgLiMA0GCSqGSIb3DQEBCwUAMFkxCzAJBgNV
++BAYTAlVTMQswCQYDVQQIDAJDQTEcMBoGA1UECgwTT3BlbkxEQVAgRm91bmRhdGlv
++bjEfMB0GA1UECwwWT3BlbkxEQVAgVGVzdCBTdWl0ZSBDQTAgFw0xNzAxMTkyMDI0
++NTFaGA8yNTE4MDIwMjIwMjQ1MVowWTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNB
++MRwwGgYDVQQKDBNPcGVuTERBUCBGb3VuZGF0aW9uMR8wHQYDVQQLDBZPcGVuTERB
++UCBUZXN0IFN1aXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3xcMd
++rvEPxIzZ0FnGVfk6sLXW//4UbBZmmsHSNT7UDNpL301QrsOaATyiOMSPHxmQoLPb
++lYOtTCPaHN9/KIHoCnEQ6tJRe30okA0DFnZvSH5jAm9E2QvsXMVXU5XIi9dZTNdL
++6jwRajPQP3YfK+PyrtIqc0IvhB4Ori39vrFLpQIDAQABo1AwTjAdBgNVHQ4EFgQU
++7fEPwfVJESrieK5MzzjBSK8xEfIwHwYDVR0jBBgwFoAU7fEPwfVJESrieK5MzzjB
++SK8xEfIwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQBtXLZWW6ZKZux/
++wk7uLNZl01kPJUBiI+yMU5uY5PgOph1CpaUXp3QftCb0yRQ2g5d0CNYI5DyXuHws
++ZSZRFF8SRwm3AogkMzYKenPF5m2OXSpvOMdnlbbFmIJnvwUfKhtinw+r0zvW8I8Q
++aL52EFPS0o3tiAJXS82U2wrQdJ0YEw==
++-----END CERTIFICATE-----
+diff --git a/tests/data/tls/ca/private/testsuiteCA.key b/tests/data/tls/ca/private/testsuiteCA.key
+new file mode 100644
+index 000000000..2e14d7033
+--- /dev/null
++++ b/tests/data/tls/ca/private/testsuiteCA.key
+@@ -0,0 +1,16 @@
++-----BEGIN PRIVATE KEY-----
++MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALfFwx2u8Q/EjNnQ
++WcZV+Tqwtdb//hRsFmaawdI1PtQM2kvfTVCuw5oBPKI4xI8fGZCgs9uVg61MI9oc
++338ogegKcRDq0lF7fSiQDQMWdm9IfmMCb0TZC+xcxVdTlciL11lM10vqPBFqM9A/
++dh8r4/Ku0ipzQi+EHg6uLf2+sUulAgMBAAECgYBDOb7kjuh0Iix8SXFt0ml3hMkg
++O0kQ43FWW2pnoT64h3MbqjY4O5YmMimiFi4hRPkvJPpma01eCapb0ZAYjhLm1bpf
++7Ey+724CEN3/DnorbQ3b/Fe2AVl4msJKEQFoercnaS9tFDPoijzH/quC2agH41tn
++rGWTpahq6JUIP6xkwQJBAPHJZVHGQ8P/5bGxqOkPLtjIfDLtAgInMxZgDjHhHw2f
++wGoeRrZ3J1yW0tnWtTXBN+5fKjCd6QpEvBmwhiZ+S+0CQQDCk1JBq64UotqeSWnk
++AmhRMyVs87P0DPW2Gg8y96Q3d5Rwmy65ITr4pf/xufcSkrTSObDLhfhRyJKz7W4l
++vjeZAkBq99CtZuugENxLyu+RfDgbjEb2OMjErxb49TISeyhD3MNBr3dVTk3Jtqg9
++27F7wKm/+bYuoA3zjwkwzFntOb7ZAkAY0Hz/DwwGabaD1U0B3SS8pk8xk+rxRu3X
++KX+iul5hDIkLy16sEYbZyyHXDCZsYfVZki3v5sgCdhfvhmozugyRAkBQgCeI8K1N
++I9rHrcMZUjVT/3AdjSu6xIM87Vv/oIzGUNaadnQONRaXZ+Kp5pv9j4B/18rPcQwL
+++b2qljWeZbGH
++-----END PRIVATE KEY-----
+diff --git a/tests/data/tls/certs/bjensen@mailgw.example.com.crt b/tests/data/tls/certs/bjensen@mailgw.example.com.crt
+new file mode 100644
+index 000000000..93e3a0d39
+--- /dev/null
++++ b/tests/data/tls/certs/bjensen@mailgw.example.com.crt
+@@ -0,0 +1,16 @@
++-----BEGIN CERTIFICATE-----
++MIICejCCAeOgAwIBAgIBADANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJVUzEL
++MAkGA1UECAwCQ0ExHDAaBgNVBAoME09wZW5MREFQIEZvdW5kYXRpb24xHzAdBgNV
++BAsMFk9wZW5MREFQIFRlc3QgU3VpdGUgQ0EwIBcNMTcwNTEwMjMxNjExWhgPMjUx
++ODA1MjQyMzE2MTFaMIGbMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExHDAaBgNV
++BAoME09wZW5MREFQIEZvdW5kYXRpb24xETAPBgNVBAsMCE9wZW5MREFQMSMwIQYD
++VQQDDBpiamVuc2VuQG1haWxndy5leGFtcGxlLmNvbTEpMCcGCSqGSIb3DQEJARYa
++YmplbnNlbkBtYWlsZ3cuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0A
++MIGJAoGBAMjb2C5VL+f/B/f2xJyhsdXeaGhWdABWqJlCiupk7QVPotpZphqJ2fKg
++QbX2w0sPazujt8hG96F2mBv49pHqzhSrKN70EA/E7b8d6ynjJpBU2P9ZgVlttnmU
++U++22BSuhthP5VQK7IqNyI7ZyQ4hFzuqb/XrHD1VCDo/Z/JAkw7jAgMBAAGjDTAL
++MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADgYEAmAQhIIKqjC13rtAGEQHV/pKn
++wOnLbNOumODqM+0MkEfqXXtR6eNGres2RNAtCJ5fqqDBTQCTqRzIt67cqdlJle2f
++7vXYm8Y6NgxHwG+N1y7S0Xf+oo7/BJ+YJTLF7CLJuPNRqILWvXGlcNDcM1nekeKo
++4DnnYQBDnq48VORVX94=
++-----END CERTIFICATE-----
+diff --git a/tests/data/tls/certs/localhost.crt b/tests/data/tls/certs/localhost.crt
+new file mode 100644
+index 000000000..194cb119d
+--- /dev/null
++++ b/tests/data/tls/certs/localhost.crt
+@@ -0,0 +1,16 @@
++-----BEGIN CERTIFICATE-----
++MIICgzCCAeygAwIBAgIBADANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJVUzEL
++MAkGA1UECAwCQ0ExHDAaBgNVBAoME09wZW5MREFQIEZvdW5kYXRpb24xHzAdBgNV
++BAsMFk9wZW5MREFQIFRlc3QgU3VpdGUgQ0EwIBcNMTcwNTEwMjMxNjExWhgPMjUx
++ODA1MjQyMzE2MTFaMGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEcMBoGA1UE
++CgwTT3BlbkxEQVAgRm91bmRhdGlvbjEcMBoGA1UECwwTT3BlbkxEQVAgVGVzdCBT
++dWl0ZTESMBAGA1UEAwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
++iQKBgQDutp3GaZXGSm7joDm1TYI+dhBAuL1+O+oJlmZL10GX/oHqc8WNobvuZGH4
++7H8mQf7zWwJQWxL805oBDMPi2ncgha5ydaVsf4rBZATpweji04vd+672qtR/dGgv
++8Re5G3ZFYWxUv8nb/DJojG601V2Ye/K3rf+Xwa9u4Q9EJqIivwIDAQABo0gwRjAJ
++BgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A
++AAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADgYEAYItH9TDh/lqG
++8XcBPi0bzGaUPkGlDY615xvsVCflnsfRqLKP/dCfi1GjaDajEmE874pvnmmZfwxl
++0MRTqnhEmFdqjPzVSVKCeNQYWGr3wzKwI7qrhTLMg3Tz98Sz0+HUY8G9fwsNekAR
++GjeZB1FxqDGHjxBq2O828iejw28bSz4=
++-----END CERTIFICATE-----
+diff --git a/tests/data/tls/conf/openssl.cnf b/tests/data/tls/conf/openssl.cnf
+new file mode 100644
+index 000000000..a3c8ad9f6
+--- /dev/null
++++ b/tests/data/tls/conf/openssl.cnf
+@@ -0,0 +1,129 @@
++HOME                    = .
++RANDFILE                = $ENV::HOME/.rnd
++
++oid_section             = new_oids
++
++[ new_oids ]
++tsa_policy1 = 1.2.3.4.1
++tsa_policy2 = 1.2.3.4.5.6
++tsa_policy3 = 1.2.3.4.5.7
++
++[ ca ]
++default_ca      = CA_default            # The default ca section
++
++[ CA_default ]
++
++dir             = ./cruft		# Where everything is kept
++certs           = $dir/certs            # Where the issued certs are kept
++crl_dir         = $dir/crl              # Where the issued crl are kept
++database        = $dir/index.txt        # database index file.
++new_certs_dir   = $dir/certs         # default place for new certs.
++certificate     = $dir/cacert.pem       # The CA certificate
++serial          = $dir/serial           # The current serial number
++crlnumber       = $dir/crlnumber        # the current crl number
++crl             = $dir/crl.pem          # The current CRL
++private_key     = $dir/private/cakey.pem# The private key
++RANDFILE        = $dir/private/.rand    # private random number file
++x509_extensions = usr_cert              # The extentions to add to the cert
++name_opt        = ca_default            # Subject Name options
++cert_opt        = ca_default            # Certificate field options
++default_days    = 365                   # how long to certify for
++default_crl_days= 30                    # how long before next CRL
++default_md      = default               # use public key default MD
++preserve        = no                    # keep passed DN ordering
++policy          = policy_match
++
++[ policy_match ]
++countryName             = match
++stateOrProvinceName     = match
++organizationName        = match
++organizationalUnitName  = optional
++commonName              = supplied
++emailAddress            = optional
++
++[ policy_anything ]
++countryName             = optional
++stateOrProvinceName     = optional
++localityName            = optional
++organizationName        = optional
++organizationalUnitName  = optional
++commonName              = supplied
++emailAddress            = optional
++
++[ req ]
++default_bits            = 2048
++default_keyfile         = privkey.pem
++distinguished_name      = req_distinguished_name
++attributes              = req_attributes
++x509_extensions = v3_ca # The extentions to add to the self signed cert
++
++string_mask = utf8only
++
++[ req_distinguished_name ]
++basicConstraints=CA:FALSE
++
++[ req_attributes ]
++challengePassword               = A challenge password
++challengePassword_min           = 4
++challengePassword_max           = 20
++
++unstructuredName                = An optional company name
++
++[ usr_cert ]
++
++basicConstraints=CA:FALSE
++nsComment                       = "OpenSSL Generated Certificate"
++
++subjectKeyIdentifier=hash
++authorityKeyIdentifier=keyid,issuer
++
++[ v3_req ]
++
++basicConstraints = CA:FALSE
++keyUsage = nonRepudiation, digitalSignature, keyEncipherment
++subjectAltName = DNS:localhost,IP:127.0.0.1,IP:::1
++
++[ v3_ca ]
++subjectKeyIdentifier=hash
++authorityKeyIdentifier=keyid:always,issuer
++basicConstraints = CA:true
++
++[ crl_ext ]
++
++authorityKeyIdentifier=keyid:always
++
++[ proxy_cert_ext ]
++basicConstraints=CA:FALSE
++nsComment                       = "OpenSSL Generated Certificate"
++
++subjectKeyIdentifier=hash
++authorityKeyIdentifier=keyid,issuer
++proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
++
++[ tsa ]
++
++default_tsa = tsa_config1       # the default TSA section
++
++[ tsa_config1 ]
++
++dir             = ./demoCA              # TSA root directory
++serial          = $dir/tsaserial        # The current serial number (mandatory)
++crypto_device   = builtin               # OpenSSL engine to use for signing
++signer_cert     = $dir/tsacert.pem      # The TSA signing certificate
++                                        # (optional)
++certs           = $dir/cacert.pem       # Certificate chain to include in reply
++                                        # (optional)
++signer_key      = $dir/private/tsakey.pem # The TSA private key (optional)
++
++default_policy  = tsa_policy1           # Policy if request did not specify it
++                                        # (optional)
++other_policies  = tsa_policy2, tsa_policy3      # acceptable policies (optional)
++digests         = md5, sha1             # Acceptable message digests (mandatory)
++accuracy        = secs:1, millisecs:500, microsecs:100  # (optional)
++clock_precision_digits  = 0     # number of digits after dot. (optional)
++ordering                = yes   # Is ordering defined for timestamps?
++                                # (optional, default: no)
++tsa_name                = yes   # Must the TSA name be included in the reply?
++                                # (optional, default: no)
++ess_cert_id_chain       = no    # Must the ESS cert id chain be included?
++                                # (optional, default: no)
+diff --git a/tests/data/tls/create-crt.sh b/tests/data/tls/create-crt.sh
+new file mode 100755
+index 000000000..8c33a24fe
+--- /dev/null
++++ b/tests/data/tls/create-crt.sh
+@@ -0,0 +1,78 @@
++#!/bin/sh
++openssl=$(which openssl)
++
++if [ x"$openssl" = "x" ]; then
++echo "OpenSSL command line binary not found, skipping..."
++fi
++
++USAGE="$0 [-s] [-u <user@domain.com>]"
++SERVER=0
++USER=0
++EMAIL=
++
++while test $# -gt 0 ; do
++	case "$1" in
++		-s | -server)
++			SERVER=1;
++			shift;;
++		-u | -user)
++			if [ x"$2" = "x" ]; then
++				echo "User cert requires an email address as an argument"
++				exit;
++			fi
++			USER=1;
++			EMAIL="$2";
++			shift; shift;;
++		-)
++			shift;;
++		-*)
++			echo "$USAGE"; exit 1
++			;;
++		*)
++			break;;
++	esac
++done
++
++if [ $SERVER = 0 -a $USER = 0 ]; then
++	echo "$USAGE";
++	exit 1;
++fi
++
++rm -rf ./openssl.cnf cruft
++mkdir -p private certs cruft/private cruft/certs
++
++echo "00" > cruft/serial
++touch cruft/index.txt
++touch cruft/index.txt.attr
++hn=$(hostname -f)
++sed -e "s;@HOSTNAME@;$hn;" conf/openssl.cnf >  ./openssl.cnf
++
++if [ $SERVER = 1 ]; then
++	rm -rf private/localhost.key certs/localhost.crt
++
++	$openssl req -new -nodes -out localhost.csr -keyout private/localhost.key \
++		-newkey rsa:1024 -config ./openssl.cnf \
++		-subj "/CN=localhost/OU=OpenLDAP Test Suite/O=OpenLDAP Foundation/ST=CA/C=US" \
++		-batch > /dev/null 2>&1
++
++	$openssl ca -out certs/localhost.crt -notext -config ./openssl.cnf -days 183000 -in localhost.csr \
++		-keyfile ca/private/testsuiteCA.key -extensions v3_req -cert ca/certs/testsuiteCA.crt \
++		-batch >/dev/null 2>&1
++
++	rm -rf ./openssl.cnf ./localhost.csr cruft
++fi
++
++if [ $USER = 1 ]; then
++	rm -f certs/$EMAIL.crt private/$EMAIL.key $EMAIL.csr
++
++	$openssl req -new -nodes -out $EMAIL.csr -keyout private/$EMAIL.key \
++		-newkey rsa:1024 -config ./openssl.cnf \
++		-subj "/emailAddress=$EMAIL/CN=$EMAIL/OU=OpenLDAP/O=OpenLDAP Foundation/ST=CA/C=US" \
++		-batch >/dev/null 2>&1
++
++	$openssl ca -out certs/$EMAIL.crt -notext -config ./openssl.cnf -days 183000 -in $EMAIL.csr \
++		-keyfile ca/private/testsuiteCA.key -extensions req_distinguished_name \
++		-cert ca/certs/testsuiteCA.crt -batch >/dev/null 2>&1
++
++	rm -rf ./openssl.cnf ./$EMAIL.csr cruft
++fi
+diff --git a/tests/data/tls/private/bjensen@mailgw.example.com.key b/tests/data/tls/private/bjensen@mailgw.example.com.key
+new file mode 100644
+index 000000000..5f4625fd7
+--- /dev/null
++++ b/tests/data/tls/private/bjensen@mailgw.example.com.key
+@@ -0,0 +1,16 @@
++-----BEGIN PRIVATE KEY-----
++MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMjb2C5VL+f/B/f2
++xJyhsdXeaGhWdABWqJlCiupk7QVPotpZphqJ2fKgQbX2w0sPazujt8hG96F2mBv4
++9pHqzhSrKN70EA/E7b8d6ynjJpBU2P9ZgVlttnmUU++22BSuhthP5VQK7IqNyI7Z
++yQ4hFzuqb/XrHD1VCDo/Z/JAkw7jAgMBAAECgYEApDgKQadoaZd7nmJlUWJqEV+r
++oVK9uOEhK1zaUtV9bBA2J6uQQLZgORyJXQqJlT7f/3zVb6uGHr7lkkk03wxIu+3e
++nIi7or/Cw6KmxhgslsQamf/ujjeqRlij/4pJIpEYByme9SstfzMBFNWU4t+fguPg
++xXz6lvVZuNiYRWWuXxECQQDwakp31mNczqLPg8fuhdgixz7HCK5g6p4XDw+Cu9Ra
++EenuOJVlnwXdW+g5jooiV5RWhxbTO6ImtgbcBGoeLSbVAkEA1eEcifIzgSi8XODd
++9i6dCSMHKk4FgDRk2DJxRePLK2J1kt2bhOz/N1130fTargDWo8QiQAnd7RBOMJO/
++pGaq1wJAZ2afzrjzlWf+WFgqdmk0k4i0dHBEZ8Sg5/P/TNAyPeb0gRPvFXz2zcUI
++tTCcMrcOQsTpSUKdtB6YBqsTZRUwXQI/FbjHLTtr/7Ijb0tnP5l8WXE1SRajeGHZ
++3BtDZdW8zKszRbc8FEP9p6HWiXxUuVdcdUV2NQrLf0goqMZYsFm9AkBtV3URLS4D
++tw0VPr/TtzDx0UTJU5POdRcNrrpm233A0EyGNmLuM7y0iLxrvCIN9z0RVu7AeMBg
++36Ixj3L+5H18
++-----END PRIVATE KEY-----
+diff --git a/tests/data/tls/private/localhost.key b/tests/data/tls/private/localhost.key
+new file mode 100644
+index 000000000..8a24f69f8
+--- /dev/null
++++ b/tests/data/tls/private/localhost.key
+@@ -0,0 +1,16 @@
++-----BEGIN PRIVATE KEY-----
++MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAO62ncZplcZKbuOg
++ObVNgj52EEC4vX476gmWZkvXQZf+gepzxY2hu+5kYfjsfyZB/vNbAlBbEvzTmgEM
++w+LadyCFrnJ1pWx/isFkBOnB6OLTi937rvaq1H90aC/xF7kbdkVhbFS/ydv8MmiM
++brTVXZh78ret/5fBr27hD0QmoiK/AgMBAAECgYEA0gs5tNY/BaWFASGA5bj3u4Ij
++Nu/XPPX3Lsx54o3bl6RIKEYKNF91f4QweNmP39f+P596373jbTe7sOTMkBXu7qnf
++2B51VBJ72Uq92gO2VXImK+uuC6JdZfYTlX1QJkaR6mxhBl3KAgUeGUgbL0Xp9XeJ
++bVcPqDOpRyIlW/80EHECQQD6PWRkk+0H4EMRA3GAnMQv/+Cy+sqF0T0OBNsQ846q
++1hQhJfVvjgj2flmJZpH9zBTaqDn4grJDfQ9cViZwf4k7AkEA9DVNHPNVpkeToWrf
++3yH55Ya5WEAl/6oNsHlaSZ88SHCZGqY7hQrpjSycsEezmsnDeqfdVuO97G2nHC7U
++VdPUTQJAAq8r54RKs53tOj5+NjH4TMeC4oicKYlQDVlx/CGQszZuqthcZKDyaap7
++TWUDReStiJbrYEYOoXiy9HucF/LWRwJAQKeH9f06lN5oaJkKEmJFbg5ALew14z1b
++iHhofgtpg2hEMLkIEw4zjUvdZBJnq7h1R5j/0cxT8S+KybxgPSTrFQJBAPTrj7bP
++5M7tPyQtyFxhFhas6g4ZHz/D2yB7BL+hL3IiJf3fdWNcHTzBDFEgDOVjR/7CZ6L3
++b61hkjQZfbEg5cg=
++-----END PRIVATE KEY-----
+diff --git a/tests/run.in b/tests/run.in
+index 6c33d4d20..793e388c1 100644
+--- a/tests/run.in
++++ b/tests/run.in
+@@ -57,6 +57,7 @@ AC_valsort=valsort@BUILD_VALSORT@
+ # misc
+ AC_WITH_SASL=@WITH_SASL@
+ AC_WITH_TLS=@WITH_TLS@
++AC_TLS_TYPE=@WITH_TLS_TYPE@
+ AC_WITH_MODULES_ENABLED=@WITH_MODULES_ENABLED@
+ AC_ACI_ENABLED=aci@WITH_ACI_ENABLED@
+ AC_THREADS=threads@BUILD_THREAD@
+@@ -75,7 +76,7 @@ export AC_bdb AC_hdb AC_ldap AC_mdb AC_meta AC_monitor AC_null AC_relay AC_sql \
+ 	AC_refint AC_retcode AC_rwm AC_unique AC_syncprov AC_translucent \
+ 	AC_valsort \
+ 	AC_WITH_SASL AC_WITH_TLS AC_WITH_MODULES_ENABLED AC_ACI_ENABLED \
+-	AC_THREADS AC_LIBS_DYNAMIC
++	AC_THREADS AC_LIBS_DYNAMIC AC_WITH_TLS AC_TLS_TYPE
+ 
+ if test ! -x ../servers/slapd/slapd ; then
+ 	echo "Could not locate slapd(8)"
+diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh
+index a7dacebdd..2c9e8f76a 100755
+--- a/tests/scripts/defines.sh
++++ b/tests/scripts/defines.sh
+@@ -46,6 +46,9 @@ VALSORT=${AC_valsort-valsortno}
+ # misc
+ WITH_SASL=${AC_WITH_SASL-no}
+ USE_SASL=${SLAPD_USE_SASL-no}
++WITH_TLS=${AC_WITH_TLS-no}
++WITH_TLS_TYPE=${AC_TLS_TYPE-no}
++
+ ACI=${AC_ACI_ENABLED-acino}
+ THREADS=${AC_THREADS-threadsno}
+ SLEEP0=${SLEEP0-1}
+@@ -104,6 +107,8 @@ P2SRSLAVECONF=$DATADIR/slapd-syncrepl-slave-persist2.conf
+ P3SRSLAVECONF=$DATADIR/slapd-syncrepl-slave-persist3.conf
+ REFSLAVECONF=$DATADIR/slapd-ref-slave.conf
+ SCHEMACONF=$DATADIR/slapd-schema.conf
++TLSCONF=$DATADIR/slapd-tls.conf
++TLSSASLCONF=$DATADIR/slapd-tls-sasl.conf
+ GLUECONF=$DATADIR/slapd-glue.conf
+ REFINTCONF=$DATADIR/slapd-refint.conf
+ RETCODECONF=$DATADIR/slapd-retcode.conf
+@@ -164,6 +169,7 @@ SLURPLOG=$TESTDIR/slurp.log
+ CONFIGPWF=$TESTDIR/configpw
+ 
+ # args
++SASLARGS="-Q"
+ TOOLARGS="-x $LDAP_TOOLARGS"
+ TOOLPROTO="-P 3"
+ 
+@@ -186,7 +192,8 @@ BCMP="diff -iB"
+ CMPOUT=/dev/null
+ SLAPD="$TESTWD/../servers/slapd/slapd -s0"
+ LDAPPASSWD="$CLIENTDIR/ldappasswd $TOOLARGS"
+-LDAPSASLSEARCH="$CLIENTDIR/ldapsearch $TOOLPROTO $LDAP_TOOLARGS -LLL"
++LDAPSASLSEARCH="$CLIENTDIR/ldapsearch $SASLARGS $TOOLPROTO $LDAP_TOOLARGS -LLL"
++LDAPSASLWHOAMI="$CLIENTDIR/ldapwhoami $SASLARGS $LDAP_TOOLARGS"
+ LDAPSEARCH="$CLIENTDIR/ldapsearch $TOOLPROTO $TOOLARGS -LLL"
+ LDAPRSEARCH="$CLIENTDIR/ldapsearch $TOOLPROTO $TOOLARGS"
+ LDAPDELETE="$CLIENTDIR/ldapdelete $TOOLPROTO $TOOLARGS"
+@@ -201,6 +208,7 @@ LDIFFILTER=$PROGDIR/ldif-filter
+ SLAPDMTREAD=$PROGDIR/slapd-mtread
+ LVL=${SLAPD_DEBUG-0x4105}
+ LOCALHOST=localhost
++LOCALIP=127.0.0.1
+ BASEPORT=${SLAPD_BASEPORT-9010}
+ PORT1=`expr $BASEPORT + 1`
+ PORT2=`expr $BASEPORT + 2`
+@@ -209,11 +217,22 @@ PORT4=`expr $BASEPORT + 4`
+ PORT5=`expr $BASEPORT + 5`
+ PORT6=`expr $BASEPORT + 6`
+ URI1="ldap://${LOCALHOST}:$PORT1/"
++URIP1="ldap://${LOCALIP}:$PORT1/"
+ URI2="ldap://${LOCALHOST}:$PORT2/"
++URIP2="ldap://${LOCALIP}:$PORT2/"
+ URI3="ldap://${LOCALHOST}:$PORT3/"
++URIP3="ldap://${LOCALIP}:$PORT3/"
+ URI4="ldap://${LOCALHOST}:$PORT4/"
+ URI5="ldap://${LOCALHOST}:$PORT5/"
+ URI6="ldap://${LOCALHOST}:$PORT6/"
++SURI1="ldaps://${LOCALHOST}:$PORT1/"
++SURIP1="ldaps://${LOCALIP}:$PORT1/"
++SURI2="ldaps://${LOCALHOST}:$PORT2/"
++SURIP2="ldaps://${LOCALIP}:$PORT2/"
++SURI3="ldaps://${LOCALHOST}:$PORT3/"
++SURI4="ldaps://${LOCALHOST}:$PORT4/"
++SURI5="ldaps://${LOCALHOST}:$PORT5/"
++SURI6="ldaps://${LOCALHOST}:$PORT6/"
+ 
+ # LDIF
+ LDIF=$DATADIR/test.ldif
+diff --git a/tests/scripts/test067-tls b/tests/scripts/test067-tls
+new file mode 100755
+index 000000000..2b245f5f5
+--- /dev/null
++++ b/tests/scripts/test067-tls
+@@ -0,0 +1,140 @@
++#! /bin/sh
++# $OpenLDAP$
++## This work is part of OpenLDAP Software <http://www.openldap.org/>.
++##
++## Copyright 1998-2017 The OpenLDAP Foundation.
++## All rights reserved.
++##
++## Redistribution and use in source and binary forms, with or without
++## modification, are permitted only as authorized by the OpenLDAP
++## Public License.
++##
++## A copy of this license is available in the file LICENSE in the
++## top-level directory of the distribution or, alternatively, at
++## <http://www.OpenLDAP.org/license.html>.
++
++echo "running defines.sh"
++. $SRCDIR/scripts/defines.sh
++
++if test $WITH_TLS = no ; then
++        echo "TLS support not available, test skipped"
++        exit 0
++fi
++
++mkdir -p $TESTDIR $DBDIR1
++cp -r $DATADIR/tls $TESTDIR
++
++cd $TESTWD
++
++echo "Starting ldap:/// slapd on TCP/IP port $PORT1 and ldaps:/// slapd on $PORT2..."
++. $CONFFILTER $BACKEND $MONITORDB < $TLSCONF > $CONF1
++$SLAPD -f $CONF1 -h "$URI1 $SURI2" -d $LVL $TIMING > $LOG1 2>&1 &
++PID=$!
++if test $WAIT != 0 ; then
++    echo PID $PID
++    read foo
++fi
++KILLPIDS="$PID"
++
++sleep 1
++
++for i in 0 1 2 3 4 5; do
++	$LDAPSEARCH -s base -b "" -H $URI1 \
++		'objectclass=*' > /dev/null 2>&1
++        RC=$?
++        if test $RC = 0 ; then
++                break
++        fi
++        echo "Waiting 5 seconds for slapd to start..."
++        sleep 5
++done
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++echo -n "Using ldapsearch with startTLS with no server cert validation...."
++$LDAPSEARCH -o tls_reqcert=never -ZZ -b "" -s base -H $URIP1 \
++	'@extensibleObject' > $SEARCHOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapsearch (startTLS) failed ($RC)!"
++	exit $RC
++else
++	echo "success"
++fi
++
++echo -n "Using ldapsearch with startTLS with hard require cert...."
++$LDAPSEARCH -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -o tls_reqcert=hard -ZZ -b "" -s base -H $URIP1 \
++	'@extensibleObject' > $SEARCHOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapsearch (startTLS) failed ($RC)!"
++	exit $RC
++else
++	echo "success"
++fi
++
++if test $WITH_TLS_TYPE = openssl ; then
++	echo -n "Using ldapsearch with startTLS and specific protocol version...."
++	$LDAPSEARCH -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -o tls_reqcert=hard -o tls_protocol_min=3.3 -ZZ -b "" -s base -H $URIP1 \
++		'@extensibleObject' > $SEARCHOUT 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "ldapsearch (protocol-min) failed ($RC)!"
++		exit $RC
++	else
++		echo "success"
++	fi
++fi
++
++echo -n "Using ldapsearch on $SURI2 with no server cert validation..."
++$LDAPSEARCH -o tls_reqcert=never -b "cn=Subschema" -s base -H $SURIP2 \
++	'(&(objectClasses=top)(objectClasses=2.5.6.0))' cn objectClass \
++	>> $SEARCHOUT  2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapsearch (ldaps) failed($RC)!"
++	exit $RC
++else
++	echo "success"
++fi
++
++echo -n "Using ldapsearch on $SURI2 with reqcert HARD and no CA cert.  Should fail..."
++$LDAPSEARCH -o tls_reqcert=hard -b "cn=Subschema" -s base -H $SURIP2 \
++	'(&(objectClasses=top)(objectClasses=2.5.6.0))' cn objectClass \
++	>> $SEARCHOUT  2>&1
++RC=$?
++if test $RC = 0 ; then
++	echo "ldapsearch (ldaps) succeeded when it should have failed($RC)!"
++	exit 1
++else
++	echo "failed correctly with error code ($RC)"
++fi
++
++echo -n "Using ldapsearch on $SURI2 with CA cert and reqcert HARD..."
++$LDAPSEARCH -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -o tls_reqcert=hard -b "cn=Subschema" -s base -H $SURIP2 \
++	'(&(objectClasses=top)(objectClasses=2.5.6.0))' cn objectClass \
++	>> $SEARCHOUT  2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapsearch (ldaps) failed ($RC)!"
++	exit $RC
++else
++	echo "success"
++fi
++
++test $KILLSERVERS != no && kill -HUP $KILLPIDS
++
++if test $RC != 0 ; then
++	echo ">>>>> Test failed"
++else
++	echo ">>>>> Test succeeded"
++	RC=0
++fi
++
++test $KILLSERVERS != no && wait
++
++exit $RC
+diff --git a/tests/scripts/test068-sasl-tls-external b/tests/scripts/test068-sasl-tls-external
+new file mode 100755
+index 000000000..dcbc50fd4
+--- /dev/null
++++ b/tests/scripts/test068-sasl-tls-external
+@@ -0,0 +1,102 @@
++#! /bin/sh
++# $OpenLDAP$
++## This work is part of OpenLDAP Software <http://www.openldap.org/>.
++##
++## Copyright 1998-2017 The OpenLDAP Foundation.
++## All rights reserved.
++##
++## Redistribution and use in source and binary forms, with or without
++## modification, are permitted only as authorized by the OpenLDAP
++## Public License.
++##
++## A copy of this license is available in the file LICENSE in the
++## top-level directory of the distribution or, alternatively, at
++## <http://www.OpenLDAP.org/license.html>.
++
++echo "running defines.sh"
++. $SRCDIR/scripts/defines.sh
++
++if test $WITH_TLS = no ; then
++        echo "TLS support not available, test skipped"
++        exit 0
++fi
++
++mkdir -p $TESTDIR $DBDIR1
++cp -r $DATADIR/tls $TESTDIR
++
++cd $TESTWD
++
++echo "Running slapadd to build slapd database..."
++. $CONFFILTER $BACKEND $MONITORDB < $TLSSASLCONF > $CONF1
++$SLAPADD -f $CONF1 -l $LDIFORDERED
++RC=$?
++if test $RC != 0 ; then
++        echo "slapadd failed ($RC)!"
++        exit $RC
++fi
++
++echo "Starting ldap:/// slapd on TCP/IP port $PORT1 and ldaps:/// slapd on $PORT2..."
++$SLAPD -f $CONF1 -h "$URI1 $SURI2" -d $LVL $TIMING > $LOG1 2>&1 &
++PID=$!
++if test $WAIT != 0 ; then
++    echo PID $PID
++    read foo
++fi
++KILLPIDS="$PID"
++
++sleep 1
++
++for i in 0 1 2 3 4 5; do
++	$LDAPSEARCH -s base -b "" -H $URI1 \
++		'objectclass=*' > /dev/null 2>&1
++        RC=$?
++        if test $RC = 0 ; then
++                break
++        fi
++        echo "Waiting 5 seconds for slapd to start..."
++        sleep 5
++done
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++echo -n "Using ldapwhoami with SASL/EXTERNAL...."
++$LDAPSASLWHOAMI -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -o tls_reqcert=hard \
++	-o tls_cert=$TESTDIR/tls/certs/bjensen@mailgw.example.com.crt -o tls_key=$TESTDIR/tls/private/bjensen@mailgw.example.com.key -ZZ -Y EXTERNAL -H $URIP1 \
++	> $TESTOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapwhoami (startTLS) failed ($RC)!"
++	exit $RC
++else
++	echo "success"
++fi
++
++echo -n "Validating mapped SASL ID..."
++echo 'dn:cn=barbara jensen,ou=information technology division,ou=people,dc=example,dc=com' > $TESTDIR/dn.out
++$CMP $TESTDIR/dn.out $TESTOUT > $CMPOUT
++
++RC=$?
++if test $RC != 0 ; then
++	echo "Comparison failed"
++	test $KILLSERVERS != no && kill -HUP $PID
++	exit $RC
++else
++	echo "success"
++fi
++
++test $KILLSERVERS != no && kill -HUP $KILLPIDS
++
++if test $RC != 0 ; then
++	echo ">>>>> Test failed"
++else
++	echo ">>>>> Test succeeded"
++	RC=0
++fi
++
++test $KILLSERVERS != no && wait
++
++exit $RC
+diff --git a/tests/scripts/test069-delta-multimaster-starttls b/tests/scripts/test069-delta-multimaster-starttls
+new file mode 100755
+index 000000000..2dfbb30a1
+--- /dev/null
++++ b/tests/scripts/test069-delta-multimaster-starttls
+@@ -0,0 +1,574 @@
++#! /bin/sh
++# $OpenLDAP$
++## This work is part of OpenLDAP Software <http://www.openldap.org/>.
++##
++## Copyright 1998-2017 The OpenLDAP Foundation.
++## All rights reserved.
++##
++## Redistribution and use in source and binary forms, with or without
++## modification, are permitted only as authorized by the OpenLDAP
++## Public License.
++##
++## A copy of this license is available in the file LICENSE in the
++## top-level directory of the distribution or, alternatively, at
++## <http://www.OpenLDAP.org/license.html>.
++
++echo "running defines.sh"
++. $SRCDIR/scripts/defines.sh
++
++if test $WITH_TLS = no ; then
++        echo "TLS support not available, test skipped"
++        exit 0
++fi
++
++if test $SYNCPROV = syncprovno; then
++	echo "Syncrepl provider overlay not available, test skipped"
++	exit 0
++fi
++if test $ACCESSLOG = accesslogno; then
++	echo "Accesslog overlay not available, test skipped"
++	exit 0
++fi
++
++MMR=2
++
++XDIR=$TESTDIR/srv
++TMP=$TESTDIR/tmp
++
++mkdir -p $TESTDIR
++cp -r $DATADIR/tls $TESTDIR
++
++$SLAPPASSWD -g -n >$CONFIGPWF
++
++if test x"$SYNCMODE" = x ; then
++	SYNCMODE=rp
++fi
++case "$SYNCMODE" in
++	ro)
++		SYNCTYPE="type=refreshOnly interval=00:00:00:03"
++		;;
++	rp)
++		SYNCTYPE="type=refreshAndPersist interval=00:00:00:03"
++		;;
++	*)
++		echo "unknown sync mode $SYNCMODE"
++		exit 1;
++		;;
++esac
++
++#
++# Test delta-sync mmr
++# - start servers
++# - configure over ldap
++# - populate over ldap
++# - configure syncrepl over ldap
++# - break replication
++# - modify each server separately
++# - restore replication
++# - compare results
++#
++
++nullExclude=""
++test $BACKEND = null && nullExclude="# "
++
++KILLPIDS=
++
++echo "Initializing server configurations..."
++n=1
++while [ $n -le $MMR ]; do
++
++DBDIR=${XDIR}$n/db
++CFDIR=${XDIR}$n/slapd.d
++
++mkdir -p ${XDIR}$n $DBDIR.1 $DBDIR.2 $CFDIR
++
++o=`expr 3 - $n`
++cat > $TMP <<EOF
++dn: cn=config
++objectClass: olcGlobal
++cn: config
++olcServerID: $n
++olcTLSCertificateFile: $TESTDIR/tls/certs/localhost.crt
++olcTLSCertificateKeyFile: $TESTDIR/tls/private/localhost.key
++
++EOF
++
++if [ "$SYNCPROV" = syncprovmod -o "$ACCESSLOG" = accesslogmod ]; then
++  cat <<EOF >> $TMP
++dn: cn=module,cn=config
++objectClass: olcModuleList
++cn: module
++olcModulePath: $TESTWD/../servers/slapd/overlays
++EOF
++  if [ "$SYNCPROV" = syncprovmod ]; then
++  echo "olcModuleLoad: syncprov.la" >> $TMP
++  fi
++  if [ "$ACCESSLOG" = accesslogmod ]; then
++  echo "olcModuleLoad: accesslog.la" >> $TMP
++  fi
++  echo "" >> $TMP
++fi
++
++if [ "$BACKENDTYPE" = mod ]; then
++cat <<EOF >> $TMP
++dn: cn=module,cn=config
++objectClass: olcModuleList
++cn: module
++olcModulePath: $TESTWD/../servers/slapd/back-$BACKEND
++olcModuleLoad: back_$BACKEND.la
++
++EOF
++fi
++MYURI=`eval echo '$URI'$n`
++PROVIDERURI=`eval echo '$URIP'$o`
++if test $INDEXDB = indexdb ; then
++INDEX1="olcDbIndex: objectClass,entryCSN,reqStart,reqDN,reqResult eq"
++INDEX2="olcDbIndex: objectClass,entryCSN,entryUUID eq"
++else
++INDEX1=
++INDEX2=
++fi
++cat >> $TMP <<EOF
++dn: cn=schema,cn=config
++objectclass: olcSchemaconfig
++cn: schema
++
++include: file://$ABS_SCHEMADIR/core.ldif
++
++include: file://$ABS_SCHEMADIR/cosine.ldif
++
++include: file://$ABS_SCHEMADIR/inetorgperson.ldif
++
++include: file://$ABS_SCHEMADIR/openldap.ldif
++
++include: file://$ABS_SCHEMADIR/nis.ldif
++
++dn: olcDatabase={0}config,cn=config
++objectClass: olcDatabaseConfig
++olcDatabase: {0}config
++olcRootPW:< file://$CONFIGPWF
++
++dn: olcDatabase={1}$BACKEND,cn=config
++objectClass: olcDatabaseConfig
++${nullExclude}objectClass: olc${BACKEND}Config
++olcDatabase: {1}$BACKEND
++olcSuffix: cn=log
++${nullExclude}olcDbDirectory: ${DBDIR}.1
++olcRootDN: $MANAGERDN
++$INDEX1
++
++dn: olcOverlay=syncprov,olcDatabase={1}$BACKEND,cn=config
++objectClass: olcOverlayConfig
++objectClass: olcSyncProvConfig
++olcOverlay: syncprov
++olcSpNoPresent: TRUE
++olcSpReloadHint: TRUE
++
++dn: olcDatabase={2}$BACKEND,cn=config
++objectClass: olcDatabaseConfig
++${nullExclude}objectClass: olc${BACKEND}Config
++olcDatabase: {2}$BACKEND
++olcSuffix: $BASEDN
++${nullExclude}olcDbDirectory: ${DBDIR}.2
++olcRootDN: $MANAGERDN
++olcRootPW: $PASSWD
++olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
++  credentials=$PASSWD searchbase="$BASEDN" $SYNCTYPE
++  retry="3 +" timeout=3 logbase="cn=log"
++  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
++  syncdata=accesslog tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt
++  starttls=critical
++olcMirrorMode: TRUE
++$INDEX2
++
++dn: olcOverlay=syncprov,olcDatabase={2}$BACKEND,cn=config
++objectClass: olcOverlayConfig
++objectClass: olcSyncProvConfig
++olcOverlay: syncprov
++
++dn: olcOverlay=accesslog,olcDatabase={2}$BACKEND,cn=config
++objectClass: olcOverlayConfig
++objectClass: olcAccessLogConfig
++olcOverlay: accesslog
++olcAccessLogDB: cn=log
++olcAccessLogOps: writes
++olcAccessLogSuccess: TRUE
++
++EOF
++$SLAPADD -F $CFDIR -n 0  -d-1< $TMP > $TESTOUT 2>&1
++PORT=`eval echo '$PORT'$n`
++echo "Starting server $n on TCP/IP port $PORT..."
++cd ${XDIR}${n}
++LOG=`eval echo '$LOG'$n`
++$SLAPD -F slapd.d -h $MYURI -d $LVL $TIMING > $LOG 2>&1 &
++PID=$!
++if test $WAIT != 0 ; then
++    echo PID $PID
++    read foo
++fi
++KILLPIDS="$PID $KILLPIDS"
++cd $TESTWD
++
++echo "Using ldapsearch to check that server $n is running..."
++for i in 0 1 2 3 4 5; do
++	$LDAPSEARCH -s base -b "" -H $MYURI \
++		'objectclass=*' > /dev/null 2>&1
++	RC=$?
++	if test $RC = 0 ; then
++		break
++	fi
++	echo "Waiting 5 seconds for slapd to start..."
++	sleep 5
++done
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++if [ $n = 1 ]; then
++echo "Using ldapadd for context on server 1..."
++$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD -f $LDIFORDEREDCP \
++	>> $TESTOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapadd failed for server $n database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++fi
++
++n=`expr $n + 1`
++done
++
++echo "Using ldapadd to populate server 1..."
++$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD -f $LDIFORDEREDNOCP \
++	>> $TESTOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapadd failed for server $n database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
++sleep $SLEEP1
++
++n=1
++while [ $n -le $MMR ]; do
++PORT=`expr $BASEPORT + $n`
++URI="ldap://${LOCALHOST}:$PORT/"
++
++echo "Using ldapsearch to read all the entries from server $n..."
++$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
++	'objectclass=*' > $TESTDIR/server$n.out 2>&1
++RC=$?
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed at server $n ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++$LDIFFILTER < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
++n=`expr $n + 1`
++done
++
++n=2
++while [ $n -le $MMR ]; do
++echo "Comparing retrieved entries from server 1 and server $n..."
++$CMP $MASTERFLT $TESTDIR/server$n.flt > $CMPOUT
++
++if test $? != 0 ; then
++	echo "test failed - server 1 and server $n databases differ"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit 1
++fi
++n=`expr $n + 1`
++done
++
++echo "Using ldapadd to populate server 2..."
++$LDAPADD -D "$MANAGERDN" -H $URI2 -w $PASSWD -f $LDIFADD1 \
++	>> $TESTOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapadd failed for server 2 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++THEDN="cn=James A Jones 2,ou=Alumni Association,ou=People,dc=example,dc=com"
++sleep 1
++for i in 1 2 3; do
++	$LDAPSEARCH -S "" -b "$THEDN" -H $URI1 \
++		-s base '(objectClass=*)' entryCSN > "${MASTEROUT}.$i" 2>&1
++	RC=$?
++
++	if test $RC = 0 ; then
++		break
++	fi
++
++	if test $RC != 32 ; then
++		echo "ldapsearch failed at slave ($RC)!"
++		test $KILLSERVERS != no && kill -HUP $KILLPIDS
++		exit $RC
++	fi
++
++	echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
++	sleep $SLEEP1
++done
++
++n=1
++while [ $n -le $MMR ]; do
++PORT=`expr $BASEPORT + $n`
++URI="ldap://${LOCALHOST}:$PORT/"
++
++echo "Using ldapsearch to read all the entries from server $n..."
++$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
++	'objectclass=*' > $TESTDIR/server$n.out 2>&1
++RC=$?
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed at server $n ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++$LDIFFILTER < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
++n=`expr $n + 1`
++done
++
++n=2
++while [ $n -le $MMR ]; do
++echo "Comparing retrieved entries from server 1 and server $n..."
++$CMP $MASTERFLT $TESTDIR/server$n.flt > $CMPOUT
++
++if test $? != 0 ; then
++	echo "test failed - server 1 and server $n databases differ"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit 1
++fi
++n=`expr $n + 1`
++done
++
++echo "Breaking replication between server 1 and 2..."
++n=1
++while [ $n -le $MMR ]; do
++o=`expr 3 - $n`
++MYURI=`eval echo '$URI'$n`
++PROVIDERURI=`eval echo '$URIP'$o`
++$LDAPMODIFY -D cn=config -H $MYURI -y $CONFIGPWF > $TESTOUT 2>&1 <<EOF
++dn: olcDatabase={2}$BACKEND,cn=config
++changetype: modify
++replace: olcSyncRepl
++olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
++  credentials=InvalidPw searchbase="$BASEDN" $SYNCTYPE
++  retry="3 +" timeout=3 logbase="cn=log"
++  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
++  syncdata=accesslog tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt
++  starttls=critical
++-
++replace: olcMirrorMode
++olcMirrorMode: TRUE
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server $n config ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++n=`expr $n + 1`
++done
++
++echo "Using ldapmodify to force conflicts between server 1 and 2..."
++$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++add: description
++description: Amazing
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 1 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -D "$MANAGERDN" -H $URI2 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++add: description
++description: Stupendous
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 2 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++delete: description
++description: Outstanding
++-
++add: description
++description: Mindboggling
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 1 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -D "$MANAGERDN" -H $URI2 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++delete: description
++description: OutStanding
++-
++add: description
++description: Bizarre
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 2 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++add: carLicense
++carLicense: 123-XYZ
++-
++add: employeeNumber
++employeeNumber: 32
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 1 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -D "$MANAGERDN" -H $URI2 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++add: employeeType
++employeeType: deadwood
++-
++add: employeeNumber
++employeeNumber: 64
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 2 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++replace: sn
++sn: Replaced later
++-
++replace: sn
++sn: Surname
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 1 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++echo "Restoring replication between server 1 and 2..."
++n=1
++while [ $n -le $MMR ]; do
++o=`expr 3 - $n`
++MYURI=`eval echo '$URI'$n`
++PROVIDERURI=`eval echo '$URIP'$o`
++$LDAPMODIFY -D cn=config -H $MYURI -y $CONFIGPWF > $TESTOUT 2>&1 <<EOF
++dn: olcDatabase={2}$BACKEND,cn=config
++changetype: modify
++replace: olcSyncRepl
++olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
++  credentials=$PASSWD searchbase="$BASEDN" $SYNCTYPE
++  retry="3 +" timeout=3 logbase="cn=log"
++  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
++  syncdata=accesslog tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt
++  starttls=critical
++-
++replace: olcMirrorMode
++olcMirrorMode: TRUE
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server $n config ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++n=`expr $n + 1`
++done
++
++echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
++sleep $SLEEP1
++
++n=1
++while [ $n -le $MMR ]; do
++PORT=`expr $BASEPORT + $n`
++URI="ldap://${LOCALHOST}:$PORT/"
++
++echo "Using ldapsearch to read all the entries from server $n..."
++$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
++	'objectclass=*' > $TESTDIR/server$n.out 2>&1
++RC=$?
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed at server $n ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++$LDIFFILTER -s a < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
++n=`expr $n + 1`
++done
++
++n=2
++while [ $n -le $MMR ]; do
++echo "Comparing retrieved entries from server 1 and server $n..."
++$CMP $MASTERFLT $TESTDIR/server$n.flt > $CMPOUT
++
++if test $? != 0 ; then
++	echo "test failed - server 1 and server $n databases differ"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit 1
++fi
++n=`expr $n + 1`
++done
++
++test $KILLSERVERS != no && kill -HUP $KILLPIDS
++
++echo ">>>>> Test succeeded"
++
++test $KILLSERVERS != no && wait
++
++exit 0
+diff --git a/tests/scripts/test070-delta-multimaster-ldaps b/tests/scripts/test070-delta-multimaster-ldaps
+new file mode 100755
+index 000000000..1024640ef
+--- /dev/null
++++ b/tests/scripts/test070-delta-multimaster-ldaps
+@@ -0,0 +1,571 @@
++#! /bin/sh
++# $OpenLDAP$
++## This work is part of OpenLDAP Software <http://www.openldap.org/>.
++##
++## Copyright 1998-2017 The OpenLDAP Foundation.
++## All rights reserved.
++##
++## Redistribution and use in source and binary forms, with or without
++## modification, are permitted only as authorized by the OpenLDAP
++## Public License.
++##
++## A copy of this license is available in the file LICENSE in the
++## top-level directory of the distribution or, alternatively, at
++## <http://www.OpenLDAP.org/license.html>.
++
++echo "running defines.sh"
++. $SRCDIR/scripts/defines.sh
++
++if test $WITH_TLS = no ; then
++        echo "TLS support not available, test skipped"
++        exit 0
++fi
++
++if test $SYNCPROV = syncprovno; then
++	echo "Syncrepl provider overlay not available, test skipped"
++	exit 0
++fi
++if test $ACCESSLOG = accesslogno; then
++	echo "Accesslog overlay not available, test skipped"
++	exit 0
++fi
++
++MMR=2
++
++XDIR=$TESTDIR/srv
++TMP=$TESTDIR/tmp
++
++mkdir -p $TESTDIR
++cp -r $DATADIR/tls $TESTDIR
++
++$SLAPPASSWD -g -n >$CONFIGPWF
++
++if test x"$SYNCMODE" = x ; then
++	SYNCMODE=rp
++fi
++case "$SYNCMODE" in
++	ro)
++		SYNCTYPE="type=refreshOnly interval=00:00:00:03"
++		;;
++	rp)
++		SYNCTYPE="type=refreshAndPersist interval=00:00:00:03"
++		;;
++	*)
++		echo "unknown sync mode $SYNCMODE"
++		exit 1;
++		;;
++esac
++
++#
++# Test delta-sync mmr
++# - start servers
++# - configure over ldap
++# - populate over ldap
++# - configure syncrepl over ldap
++# - break replication
++# - modify each server separately
++# - restore replication
++# - compare results
++#
++
++nullExclude=""
++test $BACKEND = null && nullExclude="# "
++
++KILLPIDS=
++
++echo "Initializing server configurations..."
++n=1
++while [ $n -le $MMR ]; do
++
++DBDIR=${XDIR}$n/db
++CFDIR=${XDIR}$n/slapd.d
++
++mkdir -p ${XDIR}$n $DBDIR.1 $DBDIR.2 $CFDIR
++
++o=`expr 3 - $n`
++cat > $TMP <<EOF
++dn: cn=config
++objectClass: olcGlobal
++cn: config
++olcServerID: $n
++olcTLSCertificateFile: $TESTDIR/tls/certs/localhost.crt
++olcTLSCertificateKeyFile: $TESTDIR/tls/private/localhost.key
++
++EOF
++
++if [ "$SYNCPROV" = syncprovmod -o "$ACCESSLOG" = accesslogmod ]; then
++  cat <<EOF >> $TMP
++dn: cn=module,cn=config
++objectClass: olcModuleList
++cn: module
++olcModulePath: $TESTWD/../servers/slapd/overlays
++EOF
++  if [ "$SYNCPROV" = syncprovmod ]; then
++  echo "olcModuleLoad: syncprov.la" >> $TMP
++  fi
++  if [ "$ACCESSLOG" = accesslogmod ]; then
++  echo "olcModuleLoad: accesslog.la" >> $TMP
++  fi
++  echo "" >> $TMP
++fi
++
++if [ "$BACKENDTYPE" = mod ]; then
++cat <<EOF >> $TMP
++dn: cn=module,cn=config
++objectClass: olcModuleList
++cn: module
++olcModulePath: $TESTWD/../servers/slapd/back-$BACKEND
++olcModuleLoad: back_$BACKEND.la
++
++EOF
++fi
++MYURI=`eval echo '$SURIP'$n`
++PROVIDERURI=`eval echo '$SURIP'$o`
++if test $INDEXDB = indexdb ; then
++INDEX1="olcDbIndex: objectClass,entryCSN,reqStart,reqDN,reqResult eq"
++INDEX2="olcDbIndex: objectClass,entryCSN,entryUUID eq"
++else
++INDEX1=
++INDEX2=
++fi
++cat >> $TMP <<EOF
++dn: cn=schema,cn=config
++objectclass: olcSchemaconfig
++cn: schema
++
++include: file://$ABS_SCHEMADIR/core.ldif
++
++include: file://$ABS_SCHEMADIR/cosine.ldif
++
++include: file://$ABS_SCHEMADIR/inetorgperson.ldif
++
++include: file://$ABS_SCHEMADIR/openldap.ldif
++
++include: file://$ABS_SCHEMADIR/nis.ldif
++
++dn: olcDatabase={0}config,cn=config
++objectClass: olcDatabaseConfig
++olcDatabase: {0}config
++olcRootPW:< file://$CONFIGPWF
++
++dn: olcDatabase={1}$BACKEND,cn=config
++objectClass: olcDatabaseConfig
++${nullExclude}objectClass: olc${BACKEND}Config
++olcDatabase: {1}$BACKEND
++olcSuffix: cn=log
++${nullExclude}olcDbDirectory: ${DBDIR}.1
++olcRootDN: $MANAGERDN
++$INDEX1
++
++dn: olcOverlay=syncprov,olcDatabase={1}$BACKEND,cn=config
++objectClass: olcOverlayConfig
++objectClass: olcSyncProvConfig
++olcOverlay: syncprov
++olcSpNoPresent: TRUE
++olcSpReloadHint: TRUE
++
++dn: olcDatabase={2}$BACKEND,cn=config
++objectClass: olcDatabaseConfig
++${nullExclude}objectClass: olc${BACKEND}Config
++olcDatabase: {2}$BACKEND
++olcSuffix: $BASEDN
++${nullExclude}olcDbDirectory: ${DBDIR}.2
++olcRootDN: $MANAGERDN
++olcRootPW: $PASSWD
++olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
++  credentials=$PASSWD searchbase="$BASEDN" $SYNCTYPE
++  retry="3 +" timeout=3 logbase="cn=log"
++  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
++  syncdata=accesslog tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt
++olcMirrorMode: TRUE
++$INDEX2
++
++dn: olcOverlay=syncprov,olcDatabase={2}$BACKEND,cn=config
++objectClass: olcOverlayConfig
++objectClass: olcSyncProvConfig
++olcOverlay: syncprov
++
++dn: olcOverlay=accesslog,olcDatabase={2}$BACKEND,cn=config
++objectClass: olcOverlayConfig
++objectClass: olcAccessLogConfig
++olcOverlay: accesslog
++olcAccessLogDB: cn=log
++olcAccessLogOps: writes
++olcAccessLogSuccess: TRUE
++
++EOF
++$SLAPADD -F $CFDIR -n 0  -d-1< $TMP > $TESTOUT 2>&1
++PORT=`eval echo '$PORT'$n`
++echo "Starting server $n on TCP/IP port $PORT..."
++cd ${XDIR}${n}
++LOG=`eval echo '$LOG'$n`
++$SLAPD -F slapd.d -h $MYURI -d $LVL $TIMING > $LOG 2>&1 &
++PID=$!
++if test $WAIT != 0 ; then
++    echo PID $PID
++    read foo
++fi
++KILLPIDS="$PID $KILLPIDS"
++cd $TESTWD
++
++echo "Using ldapsearch to check that server $n is running..."
++for i in 0 1 2 3 4 5; do
++	$LDAPSEARCH -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -s base -b "" -H $MYURI \
++		'objectclass=*' > /dev/null 2>&1
++	RC=$?
++	if test $RC = 0 ; then
++		break
++	fi
++	echo "Waiting 5 seconds for slapd to start..."
++	sleep 5
++done
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++if [ $n = 1 ]; then
++echo "Using ldapadd for context on server 1..."
++$LDAPADD -D "$MANAGERDN" -H $SURIP1 -w $PASSWD -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -f $LDIFORDEREDCP \
++	>> $TESTOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapadd failed for server $n database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++fi
++
++n=`expr $n + 1`
++done
++
++echo "Using ldapadd to populate server 1..."
++$LDAPADD -D "$MANAGERDN" -H $SURIP1 -w $PASSWD -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -f $LDIFORDEREDNOCP \
++	>> $TESTOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapadd failed for server $n database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
++sleep $SLEEP1
++
++n=1
++while [ $n -le $MMR ]; do
++PORT=`expr $BASEPORT + $n`
++URI="ldaps://${LOCALIP}:$PORT/"
++
++echo "Using ldapsearch to read all the entries from server $n..."
++$LDAPSEARCH -S "" -b "$BASEDN" -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D "$MANAGERDN" -H $URI -w $PASSWD  \
++	'objectclass=*' > $TESTDIR/server$n.out 2>&1
++RC=$?
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed at server $n ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++$LDIFFILTER < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
++n=`expr $n + 1`
++done
++
++n=2
++while [ $n -le $MMR ]; do
++echo "Comparing retrieved entries from server 1 and server $n..."
++$CMP $MASTERFLT $TESTDIR/server$n.flt > $CMPOUT
++
++if test $? != 0 ; then
++	echo "test failed - server 1 and server $n databases differ"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit 1
++fi
++n=`expr $n + 1`
++done
++
++echo "Using ldapadd to populate server 2..."
++$LDAPADD -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D "$MANAGERDN" -H $SURIP2 -w $PASSWD -f $LDIFADD1 \
++	>> $TESTOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapadd failed for server 2 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++THEDN="cn=James A Jones 2,ou=Alumni Association,ou=People,dc=example,dc=com"
++sleep 1
++for i in 1 2 3; do
++	$LDAPSEARCH -S "" -b "$THEDN" -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -H $SURIP1 \
++		-s base '(objectClass=*)' entryCSN > "${MASTEROUT}.$i" 2>&1
++	RC=$?
++
++	if test $RC = 0 ; then
++		break
++	fi
++
++	if test $RC != 32 ; then
++		echo "ldapsearch failed at slave ($RC)!"
++		test $KILLSERVERS != no && kill -HUP $KILLPIDS
++		exit $RC
++	fi
++
++	echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
++	sleep $SLEEP1
++done
++
++n=1
++while [ $n -le $MMR ]; do
++PORT=`expr $BASEPORT + $n`
++URI="ldaps://${LOCALIP}:$PORT/"
++
++echo "Using ldapsearch to read all the entries from server $n..."
++$LDAPSEARCH -S "" -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
++	'objectclass=*' > $TESTDIR/server$n.out 2>&1
++RC=$?
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed at server $n ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++$LDIFFILTER < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
++n=`expr $n + 1`
++done
++
++n=2
++while [ $n -le $MMR ]; do
++echo "Comparing retrieved entries from server 1 and server $n..."
++$CMP $MASTERFLT $TESTDIR/server$n.flt > $CMPOUT
++
++if test $? != 0 ; then
++	echo "test failed - server 1 and server $n databases differ"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit 1
++fi
++n=`expr $n + 1`
++done
++
++echo "Breaking replication between server 1 and 2..."
++n=1
++while [ $n -le $MMR ]; do
++o=`expr 3 - $n`
++MYURI=`eval echo '$SURIP'$n`
++PROVIDERURI=`eval echo '$SURIP'$o`
++$LDAPMODIFY -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D cn=config -H $MYURI -y $CONFIGPWF > $TESTOUT 2>&1 <<EOF
++dn: olcDatabase={2}$BACKEND,cn=config
++changetype: modify
++replace: olcSyncRepl
++olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
++  credentials=InvalidPw searchbase="$BASEDN" $SYNCTYPE
++  retry="3 +" timeout=3 logbase="cn=log"
++  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
++  syncdata=accesslog tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt
++-
++replace: olcMirrorMode
++olcMirrorMode: TRUE
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server $n config ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++n=`expr $n + 1`
++done
++
++echo "Using ldapmodify to force conflicts between server 1 and 2..."
++$LDAPMODIFY -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D "$MANAGERDN" -H $SURIP1 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++add: description
++description: Amazing
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 1 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D "$MANAGERDN" -H $SURIP2 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++add: description
++description: Stupendous
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 2 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D "$MANAGERDN" -H $SURIP1 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++delete: description
++description: Outstanding
++-
++add: description
++description: Mindboggling
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 1 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D "$MANAGERDN" -H $SURIP2 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++delete: description
++description: OutStanding
++-
++add: description
++description: Bizarre
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 2 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D "$MANAGERDN" -H $SURIP1 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++add: carLicense
++carLicense: 123-XYZ
++-
++add: employeeNumber
++employeeNumber: 32
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 1 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D "$MANAGERDN" -H $SURIP2 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++add: employeeType
++employeeType: deadwood
++-
++add: employeeNumber
++employeeNumber: 64
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 2 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPMODIFY -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -D "$MANAGERDN" -H $SURIP1 -w $PASSWD \
++	>> $TESTOUT 2>&1 << EOF
++dn: $THEDN
++changetype: modify
++replace: sn
++sn: Replaced later
++-
++replace: sn
++sn: Surname
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server 1 database ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++echo "Restoring replication between server 1 and 2..."
++n=1
++while [ $n -le $MMR ]; do
++o=`expr 3 - $n`
++MYURI=`eval echo '$SURIP'$n`
++PROVIDERURI=`eval echo '$SURIP'$o`
++$LDAPMODIFY -D cn=config -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -H $MYURI -y $CONFIGPWF > $TESTOUT 2>&1 <<EOF
++dn: olcDatabase={2}$BACKEND,cn=config
++changetype: modify
++replace: olcSyncRepl
++olcSyncRepl: rid=001 provider=$PROVIDERURI binddn="$MANAGERDN" bindmethod=simple
++  credentials=$PASSWD searchbase="$BASEDN" $SYNCTYPE
++  retry="3 +" timeout=3 logbase="cn=log"
++  logfilter="(&(objectclass=auditWriteObject)(reqresult=0))"
++  syncdata=accesslog tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt
++-
++replace: olcMirrorMode
++olcMirrorMode: TRUE
++
++EOF
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapmodify failed for server $n config ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++n=`expr $n + 1`
++done
++
++echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
++sleep $SLEEP1
++
++n=1
++while [ $n -le $MMR ]; do
++PORT=`expr $BASEPORT + $n`
++URI="ldaps://${LOCALIP}:$PORT/"
++
++echo "Using ldapsearch to read all the entries from server $n..."
++$LDAPSEARCH -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI -w $PASSWD  \
++	'objectclass=*' > $TESTDIR/server$n.out 2>&1
++RC=$?
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed at server $n ($RC)!"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++$LDIFFILTER -s a < $TESTDIR/server$n.out > $TESTDIR/server$n.flt
++n=`expr $n + 1`
++done
++
++n=2
++while [ $n -le $MMR ]; do
++echo "Comparing retrieved entries from server 1 and server $n..."
++$CMP $MASTERFLT $TESTDIR/server$n.flt > $CMPOUT
++
++if test $? != 0 ; then
++	echo "test failed - server 1 and server $n databases differ"
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit 1
++fi
++n=`expr $n + 1`
++done
++
++test $KILLSERVERS != no && kill -HUP $KILLPIDS
++
++echo ">>>>> Test succeeded"
++
++test $KILLSERVERS != no && wait
++
++exit 0
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-ITS-8573-allow-all-libldap-options-in-tools-o-option.patch b/SOURCES/openldap-cbinding-ITS-8573-allow-all-libldap-options-in-tools-o-option.patch
new file mode 100644
index 0000000..2a288fa
--- /dev/null
+++ b/SOURCES/openldap-cbinding-ITS-8573-allow-all-libldap-options-in-tools-o-option.patch
@@ -0,0 +1,582 @@
+NOTE: The patch has been adjusted to match the base code before backporting.
+
+From 8a259e3df16def3f05828f355e98a5089cd6e6d0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= <ondra@openldap.org>
+Date: Thu, 14 Jun 2018 16:14:15 +0100
+Subject: [PATCH] ITS#8573 allow all libldap options in tools -o option
+
+---
+ clients/tools/common.c     |  15 ++-
+ doc/devel/args             |   2 +-
+ doc/man/man1/ldapcompare.1 |   9 +-
+ doc/man/man1/ldapdelete.1  |   9 +-
+ doc/man/man1/ldapexop.1    |   9 +-
+ doc/man/man1/ldapmodify.1  |   9 +-
+ doc/man/man1/ldapmodrdn.1  |   9 +-
+ doc/man/man1/ldappasswd.1  |   9 +-
+ doc/man/man1/ldapsearch.1  |   9 +-
+ doc/man/man1/ldapwhoami.1  |  13 ++-
+ doc/man/man8/slapcat.8     |   2 +-
+ include/ldap_pvt.h         |   5 +
+ libraries/libldap/init.c   | 231 ++++++++++++++++++++++---------------
+ servers/slapd/slapcommon.c |   5 +-
+ 14 files changed, 200 insertions(+), 136 deletions(-)
+
+diff --git a/clients/tools/common.c b/clients/tools/common.c
+index 1cd8a2c1b..b1edffdaf 100644
+--- a/clients/tools/common.c
++++ b/clients/tools/common.c
+@@ -374,9 +374,9 @@ N_("  -I         use SASL Interactive mode\n"),
+ N_("  -n         show what would be done but don't actually do it\n"),
+ N_("  -N         do not use reverse DNS to canonicalize SASL host name\n"),
+ N_("  -O props   SASL security properties\n"),
+-N_("  -o <opt>[=<optparam>] general options\n"),
++N_("  -o <opt>[=<optparam>] any libldap ldap.conf options, plus\n"),
++N_("             ldif_wrap=<width> (in columns, or \"no\" for no wrapping)\n"),
+ N_("             nettimeout=<timeout> (in seconds, or \"none\" or \"max\")\n"),
+-N_("             ldif-wrap=<width> (in columns, or \"no\" for no wrapping)\n"),
+ N_("  -p port    port on LDAP server\n"),
+ N_("  -Q         use SASL Quiet mode\n"),
+ N_("  -R realm   SASL realm\n"),
+@@ -838,6 +838,11 @@ tool_args( int argc, char **argv )
+ 			if ( (cvalue = strchr( control, '=' )) != NULL ) {
+ 				*cvalue++ = '\0';
+ 			}
++			for ( next=control; *next; next++ ) {
++				if ( *next == '-' ) {
++					*next = '_';
++				}
++			}
+ 
+ 			if ( strcasecmp( control, "nettimeout" ) == 0 ) {
+ 				if( nettimeout.tv_sec != -1 ) {
+@@ -867,7 +872,7 @@ tool_args( int argc, char **argv )
+ 	 				exit( EXIT_FAILURE );
+  				}
+ 
+-			} else if ( strcasecmp( control, "ldif-wrap" ) == 0 ) {
++			} else if ( strcasecmp( control, "ldif_wrap" ) == 0 ) {
+ 				if ( cvalue == 0 ) {
+ 					ldif_wrap = LDIF_LINE_WIDTH;
+ 
+@@ -878,13 +883,13 @@ tool_args( int argc, char **argv )
+ 					unsigned int u;
+ 					if ( lutil_atou( &u, cvalue ) ) {
+ 						fprintf( stderr,
+-							_("Unable to parse ldif-wrap=\"%s\"\n"), cvalue );
++							_("Unable to parse ldif_wrap=\"%s\"\n"), cvalue );
+ 		 				exit( EXIT_FAILURE );
+ 					}
+ 					ldif_wrap = (ber_len_t)u;
+ 				}
+ 
+-			} else {
++			} else if ( ldap_pvt_conf_option( control, cvalue, 1 ) ) {
+ 				fprintf( stderr, "Invalid general option name: %s\n",
+ 					control );
+ 				usage();
+diff --git a/doc/devel/args b/doc/devel/args
+index 9796fe528..c5aa02f11 100644
+--- a/doc/devel/args
++++ b/doc/devel/args
+@@ -28,7 +28,7 @@ ldapwhoami       * DE**HI**  NO QR  UVWXYZ   def*h*** *nop*    vwxy
+ 	-h host
+ 	-n no-op
+ 	-N no (SASLprep) normalization of simple bind password
+-	-o general options (currently nettimeout and ldif-wrap only)
++	-o general libldap options (plus ldif_wrap and nettimeout for backwards comp.)
+ 	-p port
+ 	-v verbose
+ 	-V version
+diff --git a/doc/man/man1/ldapcompare.1 b/doc/man/man1/ldapcompare.1
+index 9e66cd4b2..a0e58d7c3 100644
+--- a/doc/man/man1/ldapcompare.1
++++ b/doc/man/man1/ldapcompare.1
+@@ -186,13 +186,14 @@ Compare extensions:
+ .TP
+ .BI \-o \ opt \fR[= optparam \fR]
+ 
+-Specify general options.
+-
+-General options:
++Specify any
++.BR ldap.conf (5)
++option or one of the following:
+ .nf
+   nettimeout=<timeout>  (in seconds, or "none" or "max")
+-  ldif-wrap=<width>     (in columns, or "no" for no wrapping)
++  ldif_wrap=<width>     (in columns, or "no" for no wrapping)
+ .fi
++
+ .TP
+ .BI \-O \ security-properties
+ Specify SASL security properties.
+diff --git a/doc/man/man1/ldapdelete.1 b/doc/man/man1/ldapdelete.1
+index 394d35275..85dbf4360 100644
+--- a/doc/man/man1/ldapdelete.1
++++ b/doc/man/man1/ldapdelete.1
+@@ -192,13 +192,14 @@ Delete extensions:
+ .TP
+ .BI \-o \ opt \fR[= optparam \fR]
+ 
+-Specify general options.
+-
+-General options:
++Specify any
++.BR ldap.conf (5)
++option or one of the following:
+ .nf
+   nettimeout=<timeout>  (in seconds, or "none" or "max")
+-  ldif-wrap=<width>     (in columns, or "no" for no wrapping)
++  ldif_wrap=<width>     (in columns, or "no" for no wrapping)
+ .fi
++
+ .TP
+ .BI \-O \ security-properties
+ Specify SASL security properties.
+diff --git a/doc/man/man1/ldapexop.1 b/doc/man/man1/ldapexop.1
+index 503d681ca..26e1730a8 100644
+--- a/doc/man/man1/ldapexop.1
++++ b/doc/man/man1/ldapexop.1
+@@ -189,13 +189,14 @@ Specify general extensions.  \'!\' indicates criticality.
+ .TP
+ .BI \-o \ opt \fR[= optparam \fR]
+ 
+-Specify general options.
+-
+-General options:
++Specify any
++.BR ldap.conf (5)
++option or one of the following:
+ .nf
+   nettimeout=<timeout>  (in seconds, or "none" or "max")
+-  ldif-wrap=<width>     (in columns, or "no" for no wrapping)
++  ldif_wrap=<width>     (in columns, or "no" for no wrapping)
+ .fi
++
+ .TP
+ .BI \-O \ security-properties
+ Specify SASL security properties.
+diff --git a/doc/man/man1/ldapmodify.1 b/doc/man/man1/ldapmodify.1
+index 2792d460b..6c277d89c 100644
+--- a/doc/man/man1/ldapmodify.1
++++ b/doc/man/man1/ldapmodify.1
+@@ -255,13 +255,14 @@ Modify extensions:
+ .TP
+ .BI \-o \ opt \fR[= optparam \fR]]
+ 
+-Specify general options.
+-
+-General options:
++Specify any
++.BR ldap.conf (5)
++option or one of the following:
+ .nf
+   nettimeout=<timeout>  (in seconds, or "none" or "max")
+-  ldif-wrap=<width>     (in columns, or "no" for no wrapping)
++  ldif_wrap=<width>     (in columns, or "no" for no wrapping)
+ .fi
++
+ .TP
+ .BI \-O \ security-properties
+ Specify SASL security properties.
+diff --git a/doc/man/man1/ldapmodrdn.1 b/doc/man/man1/ldapmodrdn.1
+index 5d0f3fcd9..b24e500fe 100644
+--- a/doc/man/man1/ldapmodrdn.1
++++ b/doc/man/man1/ldapmodrdn.1
+@@ -186,13 +186,14 @@ Modrdn extensions:
+ .TP
+ .BI \-o \ opt \fR[= optparam \fR]
+ 
+-Specify general options.
+-
+-General options:
++Specify any
++.BR ldap.conf (5)
++option or one of the following:
+ .nf
+   nettimeout=<timeout>  (in seconds, or "none" or "max")
+-  ldif-wrap=<width>     (in columns, or "no" for no wrapping)
++  ldif_wrap=<width>     (in columns, or "no" for no wrapping)
+ .fi
++
+ .TP
+ .BI \-O \ security-properties
+ Specify SASL security properties.
+diff --git a/doc/man/man1/ldappasswd.1 b/doc/man/man1/ldappasswd.1
+index 36857ab8f..a2805e57b 100644
+--- a/doc/man/man1/ldappasswd.1
++++ b/doc/man/man1/ldappasswd.1
+@@ -188,13 +188,14 @@ Passwd Modify extensions:
+ .TP
+ .BI \-o \ opt \fR[= optparam \fR]]
+ 
+-Specify general options.
+-
+-General options:
++Specify any
++.BR ldap.conf (5)
++option or one of the following:
+ .nf
+   nettimeout=<timeout>  (in seconds, or "none" or "max")
+-  ldif-wrap=<width>     (in columns, or "no" for no wrapping)
++  ldif_wrap=<width>     (in columns, or "no" for no wrapping)
+ .fi
++
+ .TP
+ .BI \-O \ security-properties
+ Specify SASL security properties.
+diff --git a/doc/man/man1/ldapsearch.1 b/doc/man/man1/ldapsearch.1
+index 036ce6245..1914eafbf 100644
+--- a/doc/man/man1/ldapsearch.1
++++ b/doc/man/man1/ldapsearch.1
+@@ -332,13 +332,14 @@ Search extensions:
+ .TP
+ .BI \-o \ opt \fR[= optparam \fR]
+ 
+-Specify general options.
+-
+-General options:
++Specify any
++.BR ldap.conf (5)
++option or one of the following:
+ .nf
+   nettimeout=<timeout>  (in seconds, or "none" or "max")
+-  ldif-wrap=<width>     (in columns, or "no" for no wrapping)
++  ldif_wrap=<width>     (in columns, or "no" for no wrapping)
+ .fi
++
+ .TP
+ .BI \-O \ security-properties
+ Specify SASL security properties.
+diff --git a/doc/man/man1/ldapwhoami.1 b/doc/man/man1/ldapwhoami.1
+index 5912af5ba..2c8cfded2 100644
+--- a/doc/man/man1/ldapwhoami.1
++++ b/doc/man/man1/ldapwhoami.1
+@@ -143,13 +143,18 @@ WhoAmI extensions:
+ .TP
+ .BI \-o \ opt \fR[= optparam \fR]
+ 
+-Specify general options.
+-
+-General options:
++Specify any
++.BR ldap.conf (5)
++option or one of the following:
+ .nf
+   nettimeout=<timeout>  (in seconds, or "none" or "max")
+-  ldif-wrap=<width>     (in columns, or "no" for no wrapping)
++  ldif_wrap=<width>     (in columns, or "no" for no wrapping)
+ .fi
++
++.B -o
++option that can be passed here, check
++.BR ldap.conf (5)
++for details.
+ .TP
+ .BI \-O \ security-properties
+ Specify SASL security properties.
+diff --git a/doc/man/man8/slapcat.8 b/doc/man/man8/slapcat.8
+index 57c41deff..2085e9176 100644
+--- a/doc/man/man8/slapcat.8
++++ b/doc/man/man8/slapcat.8
+@@ -149,7 +149,7 @@ Possible generic options/values are:
+               syslog\-level=<level> (see `\-S' in slapd(8))
+               syslog\-user=<user>   (see `\-l' in slapd(8))
+ 
+-              ldif-wrap={no|<n>}
++              ldif_wrap={no|<n>}
+ 
+ .in
+ \fIn\fP is the number of columns allowed for the LDIF output
+diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h
+index 31f37277c..e86b032cb 100644
+--- a/include/ldap_pvt.h
++++ b/include/ldap_pvt.h
+@@ -326,6 +326,11 @@ struct ldifrecord;
+ LDAP_F ( int ) ldap_pvt_discard LDAP_P((
+ 	struct ldap *ld, ber_int_t msgid ));
+ 
++/* init.c */
++LDAP_F( int )
++ldap_pvt_conf_option LDAP_P((
++	char *cmd, char *opt, int userconf ));
++
+ /* messages.c */
+ LDAP_F( BerElement * )
+ ldap_get_message_ber LDAP_P((
+diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
+index 548d2c1cb..4a7e81bdb 100644
+--- a/libraries/libldap/init.c
++++ b/libraries/libldap/init.c
+@@ -147,6 +147,141 @@ static const struct ol_attribute {
+ #define MAX_LDAP_ATTR_LEN  sizeof("GSSAPI_ALLOW_REMOTE_PRINCIPAL")
+ #define MAX_LDAP_ENV_PREFIX_LEN 8
+ 
++static int
++ldap_int_conf_option(
++	struct ldapoptions *gopts,
++	char *cmd, char *opt, int userconf )
++{
++	int i;
++
++	for(i=0; attrs[i].type != ATTR_NONE; i++) {
++		void *p;
++
++		if( !userconf && attrs[i].useronly ) {
++			continue;
++		}
++
++		if(strcasecmp(cmd, attrs[i].name) != 0) {
++			continue;
++		}
++
++		switch(attrs[i].type) {
++		case ATTR_BOOL:
++			if((strcasecmp(opt, "on") == 0)
++				|| (strcasecmp(opt, "yes") == 0)
++				|| (strcasecmp(opt, "true") == 0))
++			{
++				LDAP_BOOL_SET(gopts, attrs[i].offset);
++
++			} else {
++				LDAP_BOOL_CLR(gopts, attrs[i].offset);
++			}
++
++			break;
++
++		case ATTR_INT: {
++			char *next;
++			long l;
++			p = &((char *) gopts)[attrs[i].offset];
++			l = strtol( opt, &next, 10 );
++			if ( next != opt && next[ 0 ] == '\0' ) {
++				* (int*) p = l;
++			}
++			} break;
++
++		case ATTR_KV: {
++				const struct ol_keyvalue *kv;
++
++				for(kv = attrs[i].data;
++					kv->key != NULL;
++					kv++) {
++
++					if(strcasecmp(opt, kv->key) == 0) {
++						p = &((char *) gopts)[attrs[i].offset];
++						* (int*) p = kv->value;
++						break;
++					}
++				}
++			} break;
++
++		case ATTR_STRING:
++			p = &((char *) gopts)[attrs[i].offset];
++			if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
++			* (char**) p = LDAP_STRDUP(opt);
++			break;
++		case ATTR_OPTION:
++			ldap_set_option( NULL, attrs[i].offset, opt );
++			break;
++		case ATTR_SASL:
++#ifdef HAVE_CYRUS_SASL
++			ldap_int_sasl_config( gopts, attrs[i].offset, opt );
++#endif
++			break;
++		case ATTR_GSSAPI:
++#ifdef HAVE_GSSAPI
++			ldap_int_gssapi_config( gopts, attrs[i].offset, opt );
++#endif
++			break;
++		case ATTR_TLS:
++#ifdef HAVE_TLS
++			ldap_int_tls_config( NULL, attrs[i].offset, opt );
++#endif
++			break;
++		case ATTR_OPT_TV: {
++			struct timeval tv;
++			char *next;
++			tv.tv_usec = 0;
++			tv.tv_sec = strtol( opt, &next, 10 );
++			if ( next != opt && next[ 0 ] == '\0' && tv.tv_sec > 0 ) {
++				(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&tv );
++			}
++			} break;
++		case ATTR_OPT_INT: {
++			long l;
++			char *next;
++			l = strtol( opt, &next, 10 );
++			if ( next != opt && next[ 0 ] == '\0' && l > 0 && (long)((int)l) == l ) {
++				int v = (int)l;
++				(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&v );
++			}
++			} break;
++		}
++
++		break;
++	}
++
++	if ( attrs[i].type == ATTR_NONE ) {
++		Debug( LDAP_DEBUG_TRACE, "ldap_int_tls_config: "
++				"unknown option '%s'",
++				cmd, 0, 0 );
++		return 1;
++	}
++
++	return 0;
++}
++
++int
++ldap_pvt_conf_option(
++	char *cmd, char *opt, int userconf )
++{
++	struct ldapoptions *gopts;
++	int rc = LDAP_OPT_ERROR;
++
++	/* Get pointer to global option structure */
++	gopts = LDAP_INT_GLOBAL_OPT();
++	if (NULL == gopts) {
++		return LDAP_NO_MEMORY;
++	}
++
++	if ( gopts->ldo_valid != LDAP_INITIALIZED ) {
++		ldap_int_initialize(gopts, NULL);
++		if ( gopts->ldo_valid != LDAP_INITIALIZED )
++			return LDAP_LOCAL_ERROR;
++	}
++
++	return ldap_int_conf_option( gopts, cmd, opt, userconf );
++}
++
+ static void openldap_ldap_init_w_conf(
+ 	const char *file, int userconf )
+ {
+@@ -212,101 +347,7 @@ static void openldap_ldap_init_w_conf(
+ 		while(isspace((unsigned char)*start)) start++;
+ 		opt = start;
+ 
+-		for(i=0; attrs[i].type != ATTR_NONE; i++) {
+-			void *p;
+-
+-			if( !userconf && attrs[i].useronly ) {
+-				continue;
+-			}
+-
+-			if(strcasecmp(cmd, attrs[i].name) != 0) {
+-				continue;
+-			}
+-
+-			switch(attrs[i].type) {
+-			case ATTR_BOOL:
+-				if((strcasecmp(opt, "on") == 0) 
+-					|| (strcasecmp(opt, "yes") == 0)
+-					|| (strcasecmp(opt, "true") == 0))
+-				{
+-					LDAP_BOOL_SET(gopts, attrs[i].offset);
+-
+-				} else {
+-					LDAP_BOOL_CLR(gopts, attrs[i].offset);
+-				}
+-
+-				break;
+-
+-			case ATTR_INT: {
+-				char *next;
+-				long l;
+-				p = &((char *) gopts)[attrs[i].offset];
+-				l = strtol( opt, &next, 10 );
+-				if ( next != opt && next[ 0 ] == '\0' ) {
+-					* (int*) p = l;
+-				}
+-				} break;
+-
+-			case ATTR_KV: {
+-					const struct ol_keyvalue *kv;
+-
+-					for(kv = attrs[i].data;
+-						kv->key != NULL;
+-						kv++) {
+-
+-						if(strcasecmp(opt, kv->key) == 0) {
+-							p = &((char *) gopts)[attrs[i].offset];
+-							* (int*) p = kv->value;
+-							break;
+-						}
+-					}
+-				} break;
+-
+-			case ATTR_STRING:
+-				p = &((char *) gopts)[attrs[i].offset];
+-				if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
+-				* (char**) p = LDAP_STRDUP(opt);
+-				break;
+-			case ATTR_OPTION:
+-				ldap_set_option( NULL, attrs[i].offset, opt );
+-				break;
+-			case ATTR_SASL:
+-#ifdef HAVE_CYRUS_SASL
+-			   	ldap_int_sasl_config( gopts, attrs[i].offset, opt );
+-#endif
+-				break;
+-			case ATTR_GSSAPI:
+-#ifdef HAVE_GSSAPI
+-				ldap_int_gssapi_config( gopts, attrs[i].offset, opt );
+-#endif
+-				break;
+-			case ATTR_TLS:
+-#ifdef HAVE_TLS
+-			   	ldap_int_tls_config( NULL, attrs[i].offset, opt );
+-#endif
+-				break;
+-			case ATTR_OPT_TV: {
+-				struct timeval tv;
+-				char *next;
+-				tv.tv_usec = 0;
+-				tv.tv_sec = strtol( opt, &next, 10 );
+-				if ( next != opt && next[ 0 ] == '\0' && tv.tv_sec > 0 ) {
+-					(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&tv );
+-				}
+-				} break;
+-			case ATTR_OPT_INT: {
+-				long l;
+-				char *next;
+-				l = strtol( opt, &next, 10 );
+-				if ( next != opt && next[ 0 ] == '\0' && l > 0 && (long)((int)l) == l ) {
+-					int v = (int)l;
+-					(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&v );
+-				}
+-				} break;
+-			}
+-
+-			break;
+-		}
++		ldap_int_conf_option( gopts, cmd, opt, userconf );
+ 	}
+ 
+ 	fclose(fp);
+diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c
+index 87ea0ea06..39384e5e9 100644
+--- a/servers/slapd/slapcommon.c
++++ b/servers/slapd/slapcommon.c
+@@ -228,7 +228,8 @@ parse_slapopt( int tool, int *mode )
+ 			break;
+ 		}
+ 
+-	} else if ( strncasecmp( optarg, "ldif-wrap", len ) == 0 ) {
++	} else if ( ( strncasecmp( optarg, "ldif_wrap", len ) == 0 ) ||
++			( strncasecmp( optarg, "ldif-wrap", len ) == 0 ) ) {
+ 		switch ( tool ) {
+ 		case SLAPCAT:
+ 			if ( strcasecmp( p, "no" ) == 0 ) {
+@@ -237,7 +238,7 @@ parse_slapopt( int tool, int *mode )
+ 			} else {
+ 				unsigned int u;
+ 				if ( lutil_atou( &u, p ) ) {
+-					Debug( LDAP_DEBUG_ANY, "unable to parse ldif-wrap=\"%s\".\n", p, 0, 0 );
++					Debug( LDAP_DEBUG_ANY, "unable to parse ldif_wrap=\"%s\".\n", p, 0, 0 );
+ 					return -1;
+ 				}
+ 				ldif_wrap = (ber_len_t)u;
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-ITS-9189_1-rework-sasl-cbinding-support.patch b/SOURCES/openldap-cbinding-ITS-9189_1-rework-sasl-cbinding-support.patch
new file mode 100644
index 0000000..1410482
--- /dev/null
+++ b/SOURCES/openldap-cbinding-ITS-9189_1-rework-sasl-cbinding-support.patch
@@ -0,0 +1,631 @@
+NOTE: The patch has been adjusted to match the base code before backporting.
+
+From 3cd50fa8b32a21040a9892e2a8a7a9dfc7541ce6 Mon Sep 17 00:00:00 2001
+From: Isaac Boukris <iboukris@gmail.com>
+Date: Tue, 14 Apr 2020 16:10:48 +0300
+Subject: [PATCH] ITS#9189 rework sasl-cbinding support
+
+Add LDAP_OPT_X_SASL_CBINDING option to define the binding type to use,
+defaults to "none".
+
+Add "tls-endpoint" binding type implementing "tls-server-end-point" from
+RCF 5929, which is compatible with Windows.
+
+Fix "tls-unique" to include the prefix in the bindings as per RFC 5056.
+---
+ doc/man/man3/ldap_get_option.3 |  16 +++++
+ doc/man/man5/ldap.conf.5       |   3 +
+ doc/man/man5/slapd-config.5    |   4 ++
+ doc/man/man5/slapd.conf.5      |   3 +
+ include/ldap.h                 |   5 ++
+ include/ldap_pvt.h             |   5 ++
+ libraries/libldap/cyrus.c      | 103 ++++++++++++++++++++++++++++-----
+ libraries/libldap/init.c       |   1 +
+ libraries/libldap/ldap-int.h   |   1 +
+ libraries/libldap/ldap-tls.h   |   2 +
+ libraries/libldap/tls2.c       |   7 +++
+ libraries/libldap/tls_g.c      |  59 +++++++++++++++++++
+ libraries/libldap/tls_o.c      |  45 ++++++++++++++
+ servers/slapd/bconfig.c        |  11 +++-
+ servers/slapd/config.c         |   1 +
+ servers/slapd/connection.c     |   9 +--
+ servers/slapd/proto-slap.h     |   4 +-
+ servers/slapd/sasl.c           |  27 ++++++---
+ 18 files changed, 274 insertions(+), 32 deletions(-)
+
+diff --git a/doc/man/man3/ldap_get_option.3 b/doc/man/man3/ldap_get_option.3
+index 4f03a01a3..fd1b3c91c 100644
+--- a/doc/man/man3/ldap_get_option.3
++++ b/doc/man/man3/ldap_get_option.3
+@@ -563,6 +563,22 @@ must be a
+ .BR "char **" .
+ Its content needs to be freed by the caller using
+ .BR ldap_memfree (3).
++.B LDAP_OPT_X_SASL_CBINDING
++Sets/gets the channel-binding type to use in SASL,
++one of
++.BR LDAP_OPT_X_SASL_CBINDING_NONE
++(the default),
++.BR LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE
++the "tls-unique" type from RCF 5929.
++.BR LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT
++the "tls-server-end-point" from RCF 5929, compatible with Windows.
++.BR invalue
++must be
++.BR "const int *" ;
++.BR outvalue
++must be
++.BR "int *" .
++.TP
+ .SH TCP OPTIONS
+ The TCP options are OpenLDAP specific.
+ Mainly intended for use with Linux, they may not be portable.
+diff --git a/doc/man/man5/ldap.conf.5 b/doc/man/man5/ldap.conf.5
+index 65ad40c1b..4974f8340 100644
+--- a/doc/man/man5/ldap.conf.5
++++ b/doc/man/man5/ldap.conf.5
+@@ -286,6 +286,9 @@ size allowed.  0 disables security layers.  The default is 65536.
+ .TP
+ .B SASL_NOCANON <on/true/yes/off/false/no>
+ Do not perform reverse DNS lookups to canonicalize SASL host names. The default is off.
++.TP
++.B SASL_CBINDING <none/tls-unique/tls-endpoint>
++The channel-binding type to use, see also LDAP_OPT_X_SASL_CBINDING. The default is none.
+ .SH GSSAPI OPTIONS
+ If OpenLDAP is built with Generic Security Services Application Programming Interface support,
+ there are more options you can specify.
+diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5
+index 18518a186..dc0ab769f 100644
+--- a/doc/man/man5/slapd-config.5
++++ b/doc/man/man5/slapd-config.5
+@@ -720,6 +720,10 @@ Used to specify the fully qualified domain name used for SASL processing.
+ .B olcSaslRealm: <realm>
+ Specify SASL realm.  Default is empty.
+ .TP
++.B olcSaslCbinding: none | tls-unique | tls-endpoint
++Specify the channel-binding type, see also LDAP_OPT_X_SASL_CBINDING.
++Default is none.
++.TP
+ .B olcSaslSecProps: <properties>
+ Used to specify Cyrus SASL security properties.
+ The
+diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5
+index f2094b7fd..73a151a70 100644
+--- a/doc/man/man5/slapd.conf.5
++++ b/doc/man/man5/slapd.conf.5
+@@ -914,6 +914,9 @@ The
+ property specifies the maximum security layer receive buffer
+ size allowed.  0 disables security layers.  The default is 65536.
+ .TP
++.B sasl\-cbinding none | tls-unique | tls-endpoint
++Specify the channel-binding type, see also LDAP_OPT_X_SASL_CBINDING.
++.TP
+ .B schemadn <dn>
+ Specify the distinguished name for the subschema subentry that
+ controls the entries on this server.  The default is "cn=Subschema".
+diff --git a/include/ldap.h b/include/ldap.h
+index 7b4fc9d64..9d5679ae8 100644
+--- a/include/ldap.h
++++ b/include/ldap.h
+@@ -186,6 +186,10 @@ LDAP_BEGIN_DECL
+ #define LDAP_OPT_X_TLS_PROTOCOL_TLS1_1		((3 << 8) + 2)
+ #define LDAP_OPT_X_TLS_PROTOCOL_TLS1_2		((3 << 8) + 3)
+ 
++#define LDAP_OPT_X_SASL_CBINDING_NONE		0
++#define LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE	1
++#define LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT	2
++
+ /* OpenLDAP SASL options */
+ #define LDAP_OPT_X_SASL_MECH			0x6100
+ #define LDAP_OPT_X_SASL_REALM			0x6101
+@@ -201,6 +205,7 @@ LDAP_BEGIN_DECL
+ #define LDAP_OPT_X_SASL_NOCANON			0x610b
+ #define LDAP_OPT_X_SASL_USERNAME		0x610c /* read-only */
+ #define LDAP_OPT_X_SASL_GSS_CREDS		0x610d
++#define LDAP_OPT_X_SASL_CBINDING		0x610e
+ 
+ /* OpenLDAP GSSAPI options */
+ #define LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT      0x6200
+diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h
+index 783d280a5..01220d00a 100644
+--- a/include/ldap_pvt.h
++++ b/include/ldap_pvt.h
+@@ -262,6 +262,10 @@ LDAP_F (void *) ldap_pvt_sasl_mutex_new LDAP_P((void));
+ LDAP_F (int) ldap_pvt_sasl_mutex_lock LDAP_P((void *mutex));
+ LDAP_F (int) ldap_pvt_sasl_mutex_unlock LDAP_P((void *mutex));
+ LDAP_F (void) ldap_pvt_sasl_mutex_dispose LDAP_P((void *mutex));
++
++LDAP_F (int) ldap_pvt_sasl_cbinding_parse LDAP_P(( const char *arg ));
++LDAP_F (void *) ldap_pvt_sasl_cbinding LDAP_P(( void *ssl, int type,
++					        int is_server ));
+ #endif /* HAVE_CYRUS_SASL */
+ 
+ struct sockbuf; /* avoid pulling in <lber.h> */
+@@ -438,6 +442,7 @@ LDAP_F (int) ldap_pvt_tls_get_peer_dn LDAP_P(( void *ctx, struct berval *dn,
+ 	LDAPDN_rewrite_dummy *func, unsigned flags ));
+ LDAP_F (int) ldap_pvt_tls_get_strength LDAP_P(( void *ctx ));
+ LDAP_F (int) ldap_pvt_tls_get_unique LDAP_P(( void *ctx, struct berval *buf, int is_server ));
++LDAP_F (int) ldap_pvt_tls_get_endpoint LDAP_P(( void *ctx, struct berval *buf, int is_server ));
+ 
+ LDAP_END_DECL
+ 
+diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c
+index beb1cf4a0..4d4d5b3e3 100644
+--- a/libraries/libldap/cyrus.c
++++ b/libraries/libldap/cyrus.c
+@@ -372,6 +372,65 @@ int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
+ 	return LDAP_SUCCESS;
+ }
+ 
++int ldap_pvt_sasl_cbinding_parse( const char *arg )
++{
++	int i = -1;
++
++	if ( strcasecmp(arg, "none") == 0 )
++		i = LDAP_OPT_X_SASL_CBINDING_NONE;
++	else if ( strcasecmp(arg, "tls-unique") == 0 )
++		i = LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE;
++	else if ( strcasecmp(arg, "tls-endpoint") == 0 )
++		i = LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT;
++
++	return i;
++}
++
++void *ldap_pvt_sasl_cbinding( void *ssl, int type, int is_server )
++{
++#if defined(SASL_CHANNEL_BINDING) && defined(HAVE_TLS)
++	char unique_prefix[] = "tls-unique:";
++	char endpoint_prefix[] = "tls-server-end-point:";
++	char cbinding[ 64 ];
++	struct berval cbv = { 64, cbinding };
++	void *cb_data; /* used since cb->data is const* */
++	sasl_channel_binding_t *cb;
++	char *prefix;
++	int plen;
++
++	switch (type) {
++	case LDAP_OPT_X_SASL_CBINDING_NONE:
++		return NULL;
++	case LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE:
++		if ( !ldap_pvt_tls_get_unique( ssl, &cbv, is_server ))
++			return NULL;
++		prefix = unique_prefix;
++		plen = sizeof(unique_prefix) -1;
++		break;
++	case LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT:
++		if ( !ldap_pvt_tls_get_endpoint( ssl, &cbv, is_server ))
++			return NULL;
++		prefix = endpoint_prefix;
++		plen = sizeof(endpoint_prefix) -1;
++		break;
++	default:
++		return NULL;
++	}
++
++	cb = ldap_memalloc( sizeof(*cb) + plen + cbv.bv_len );
++	cb->len = plen + cbv.bv_len;
++	cb->data = cb_data = cb+1;
++	memcpy( cb_data, prefix, plen );
++	memcpy( cb_data + plen, cbv.bv_val, cbv.bv_len );
++	cb->name = "ldap";
++	cb->critical = 0;
++
++	return cb;
++#else
++	return NULL;
++#endif
++}
++
+ int
+ ldap_int_sasl_bind(
+ 	LDAP			*ld,
+@@ -497,17 +556,12 @@ ldap_int_sasl_bind(
+ 			(void) ldap_int_sasl_external( ld, ld->ld_defconn, authid.bv_val, fac );
+ 			LDAP_FREE( authid.bv_val );
+ #ifdef SASL_CHANNEL_BINDING	/* 2.1.25+ */
+-			{
+-				char cbinding[64];
+-				struct berval cbv = { sizeof(cbinding), cbinding };
+-				if ( ldap_pvt_tls_get_unique( ssl, &cbv, 0 )) {
+-					sasl_channel_binding_t *cb = ldap_memalloc( sizeof(*cb) +
+-						cbv.bv_len);
+-					cb->name = "ldap";
+-					cb->critical = 0;
+-					cb->data = (char *)(cb+1);
+-					cb->len = cbv.bv_len;
+-					memcpy( cb->data, cbv.bv_val, cbv.bv_len );
++			if ( ld->ld_defconn->lconn_sasl_cbind == NULL ) {
++				void *cb;
++				cb = ldap_pvt_sasl_cbinding( ssl,
++							     ld->ld_options.ldo_sasl_cbinding,
++							     0 );
++				if ( cb != NULL ) {
+ 					sasl_setprop( ld->ld_defconn->lconn_sasl_authctx,
+ 						SASL_CHANNEL_BINDING, cb );
+ 					ld->ld_defconn->lconn_sasl_cbind = cb;
+@@ -931,12 +983,20 @@ int ldap_pvt_sasl_secprops(
+ int
+ ldap_int_sasl_config( struct ldapoptions *lo, int option, const char *arg )
+ {
+-	int rc;
++	int rc, i;
+ 
+ 	switch( option ) {
+ 	case LDAP_OPT_X_SASL_SECPROPS:
+ 		rc = ldap_pvt_sasl_secprops( arg, &lo->ldo_sasl_secprops );
+ 		if( rc == LDAP_SUCCESS ) return 0;
++		break;
++	case LDAP_OPT_X_SASL_CBINDING:
++		i = ldap_pvt_sasl_cbinding_parse( arg );
++		if ( i >= 0 ) {
++			lo->ldo_sasl_cbinding = i;
++			return 0;
++		}
++		break;
+ 	}
+ 
+ 	return -1;
+@@ -1042,6 +1102,10 @@ ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
+ 			/* this option is write only */
+ 			return -1;
+ 
++		case LDAP_OPT_X_SASL_CBINDING:
++			*(int *)arg = ld->ld_options.ldo_sasl_cbinding;
++			break;
++
+ #ifdef SASL_GSS_CREDS
+ 		case LDAP_OPT_X_SASL_GSS_CREDS: {
+ 			sasl_conn_t *ctx;
+@@ -1143,6 +1207,17 @@ ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
+ 		return sc == LDAP_SUCCESS ? 0 : -1;
+ 		}
+ 
++	case LDAP_OPT_X_SASL_CBINDING:
++		if ( !arg ) return -1;
++		switch( *(int *) arg ) {
++		case LDAP_OPT_X_SASL_CBINDING_NONE:
++		case LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE:
++		case LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT:
++			ld->ld_options.ldo_sasl_cbinding = *(int *) arg;
++			return 0;
++		}
++		return -1;
++
+ #ifdef SASL_GSS_CREDS
+ 	case LDAP_OPT_X_SASL_GSS_CREDS: {
+ 		sasl_conn_t *ctx;
+diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
+index 3468ee249..dfe1ea9da 100644
+--- a/libraries/libldap/init.c
++++ b/libraries/libldap/init.c
+@@ -110,6 +110,7 @@ static const struct ol_attribute {
+ 		offsetof(struct ldapoptions, ldo_def_sasl_authzid)},
+ 	{0, ATTR_SASL,		"SASL_SECPROPS",	NULL,	LDAP_OPT_X_SASL_SECPROPS},
+ 	{0, ATTR_BOOL,		"SASL_NOCANON",	NULL,	LDAP_BOOL_SASL_NOCANON},
++	{0, ATTR_SASL,		"SASL_CBINDING",	NULL,	LDAP_OPT_X_SASL_CBINDING},
+ #endif
+ 
+ #ifdef HAVE_GSSAPI
+diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
+index 67e8bd6da..c6c6891a9 100644
+--- a/libraries/libldap/ldap-int.h
++++ b/libraries/libldap/ldap-int.h
+@@ -300,6 +300,7 @@ struct ldapoptions {
+ 
+ 	/* SASL Security Properties */
+ 	struct sasl_security_properties	ldo_sasl_secprops;
++	int ldo_sasl_cbinding;
+ #define LDAP_LDO_SASL_NULLARG ,0,0,0,0,{0}
+ #else
+ #define LDAP_LDO_SASL_NULLARG
+diff --git a/libraries/libldap/ldap-tls.h b/libraries/libldap/ldap-tls.h
+index efd51aaa2..9f01ddda1 100644
+--- a/libraries/libldap/ldap-tls.h
++++ b/libraries/libldap/ldap-tls.h
+@@ -42,6 +42,7 @@ typedef int (TI_session_dn)(tls_session *sess, struct berval *dn);
+ typedef int (TI_session_chkhost)(LDAP *ld, tls_session *s, const char *name_in);
+ typedef int (TI_session_strength)(tls_session *sess);
+ typedef int (TI_session_unique)(tls_session *sess, struct berval *buf, int is_server);
++typedef int (TI_session_endpoint)(tls_session *sess, struct berval *buf, int is_server);
+ typedef int (TI_session_peercert)(tls_session *s, struct berval *der);
+
+ typedef void (TI_thr_init)(void);
+@@ -69,6 +70,7 @@ typedef struct tls_impl {
+ 	TI_session_chkhost *ti_session_chkhost;
+ 	TI_session_strength *ti_session_strength;
+ 	TI_session_unique *ti_session_unique;
++	TI_session_endpoint *ti_session_endpoint;
+ 	TI_session_peercert *ti_session_peercert;
+ 
+ 	Sockbuf_IO *ti_sbio;
+diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
+index 79a651a38..72827a1a3 100644
+--- a/libraries/libldap/tls2.c
++++ b/libraries/libldap/tls2.c
+@@ -1200,6 +1200,13 @@ ldap_pvt_tls_get_unique( void *s, struct berval *buf, int is_server )
+ 	return tls_imp->ti_session_unique( session, buf, is_server );
+ }
+ 
++int
++ldap_pvt_tls_get_endpoint( void *s, struct berval *buf, int is_server )
++{
++	tls_session *session = s;
++	return tls_imp->ti_session_endpoint( session, buf, is_server );
++}
++
+ int
+ ldap_pvt_tls_get_peercert( void *s, struct berval *der )
+ {
+diff --git a/libraries/libldap/tls_g.c b/libraries/libldap/tls_g.c
+index 956a9ec90..ef0f44e20 100644
+--- a/libraries/libldap/tls_g.c
++++ b/libraries/libldap/tls_g.c
+@@ -729,6 +729,64 @@ tlsg_session_unique( tls_session *sess, struct berval *buf, int is_server)
+ 	return 0;
+ }
+ 
++static int
++tlsg_session_endpoint( tls_session *sess, struct berval *buf, int is_server )
++{
++	tlsg_session *s = (tlsg_session *)sess;
++	const gnutls_datum_t *cert_data;
++	gnutls_x509_crt_t server_cert;
++	gnutls_digest_algorithm_t md;
++	int sign_algo, md_len, rc;
++
++	if ( is_server )
++		cert_data = gnutls_certificate_get_ours( s->session );
++	else
++		cert_data = gnutls_certificate_get_peers( s->session, NULL );
++
++	if ( cert_data == NULL )
++		return 0;
++
++	rc = gnutls_x509_crt_init( &server_cert );
++	if ( rc != GNUTLS_E_SUCCESS )
++		return 0;
++
++	rc = gnutls_x509_crt_import( server_cert, cert_data, GNUTLS_X509_FMT_DER );
++	if ( rc != GNUTLS_E_SUCCESS ) {
++		gnutls_x509_crt_deinit( server_cert );
++		return 0;
++	}
++
++	sign_algo = gnutls_x509_crt_get_signature_algorithm( server_cert );
++	gnutls_x509_crt_deinit( server_cert );
++	if ( sign_algo <= GNUTLS_SIGN_UNKNOWN )
++		return 0;
++
++	md = gnutls_sign_get_hash_algorithm( sign_algo );
++	if ( md == GNUTLS_DIG_UNKNOWN )
++		return 0;
++
++	/* See RFC 5929 */
++	switch (md) {
++	case GNUTLS_DIG_NULL:
++	case GNUTLS_DIG_MD2:
++	case GNUTLS_DIG_MD5:
++	case GNUTLS_DIG_SHA1:
++		md = GNUTLS_DIG_SHA256;
++	}
++
++	md_len = gnutls_hash_get_len( md );
++	if ( md_len == 0 || md_len > buf->bv_len )
++		return 0;
++
++	rc = gnutls_hash_fast( md, cert_data->data, cert_data->size, buf->bv_val );
++	if ( rc != GNUTLS_E_SUCCESS )
++		return 0;
++
++	buf->bv_len = md_len;
++
++	return md_len;
++}
++
+ static int
+ tlsg_session_peercert( tls_session *sess, struct berval *der )
+ {
+@@ -1117,6 +1175,7 @@ tls_impl ldap_int_tls_impl = {
+ 	tlsg_session_chkhost,
+ 	tlsg_session_strength,
+ 	tlsg_session_unique,
++	tlsg_session_endpoint,
+ 	tlsg_session_peercert,
+ 
+ 	&tlsg_sbio,
+diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
+index cf97d7632..aa855d77a 100644
+--- a/libraries/libldap/tls_o.c
++++ b/libraries/libldap/tls_o.c
+@@ -858,6 +858,50 @@ tlso_session_unique( tls_session *sess, struct berval *buf, int is_server)
+ 	return buf->bv_len;
+ }
+ 
++static int
++tlso_session_endpoint( tls_session *sess, struct berval *buf, int is_server )
++{
++	tlso_session *s = (tlso_session *)sess;
++	const EVP_MD *md;
++	unsigned int md_len;
++	X509 *cert;
++
++	if ( buf->bv_len < EVP_MAX_MD_SIZE )
++		return 0;
++
++	if ( is_server )
++		cert = SSL_get_certificate( s );
++	else
++		cert = SSL_get_peer_certificate( s );
++
++	if ( cert == NULL )
++		return 0;
++
++#if OPENSSL_VERSION_NUMBER >= 0x10100000
++	md = EVP_get_digestbynid( X509_get_signature_nid( cert ));
++#else
++	md = EVP_get_digestbynid(OBJ_obj2nid( cert->sig_alg->algorithm ));
++#endif
++
++	/* See RFC 5929 */
++	if ( md == NULL ||
++	     md == EVP_md_null() ||
++#ifndef OPENSSL_NO_MD2
++	     md == EVP_md2() ||
++#endif
++	     md == EVP_md4() ||
++	     md == EVP_md5() ||
++	     md == EVP_sha1() )
++		md = EVP_sha256();
++
++	if ( !X509_digest( cert, md, buf->bv_val, &md_len ))
++		return 0;
++
++	buf->bv_len = md_len;
++
++	return md_len;
++}
++
+ static int
+ tlso_session_peercert( tls_session *sess, struct berval *der )
+ {
+@@ -1474,6 +1518,7 @@ tls_impl ldap_int_tls_impl = {
+ 	tlso_session_chkhost,
+ 	tlso_session_strength,
+ 	tlso_session_unique,
++	tlso_session_endpoint,
+ 	tlso_session_peercert,
+ 
+ 	&tlso_sbio,
+diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c
+index 6069ee203..4c90715be 100644
+--- a/servers/slapd/bconfig.c
++++ b/servers/slapd/bconfig.c
+@@ -630,6 +630,15 @@ static ConfigTable config_back_cf_table[] = {
+ #endif
+ 		"( OLcfgGlAt:89 NAME 'olcSaslAuxprops' "
+ 			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
++	{ "sasl-cbinding", NULL, 2, 2, 0,
++#ifdef HAVE_CYRUS_SASL
++		ARG_STRING, &sasl_cbinding,
++#else
++		ARG_IGNORED, NULL,
++#endif
++		"( OLcfgGlAt:100 NAME 'olcSaslCBinding' "
++			"EQUALITY caseIgnoreMatch "
++			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ 	{ "sasl-host", "host", 2, 2, 0,
+ #ifdef HAVE_CYRUS_SASL
+ 		ARG_STRING|ARG_UNIQUE, &sasl_host,
+@@ -948,7 +957,7 @@ static ConfigOCs cf_ocs[] = {
+ 		 "olcPluginLogFile $ olcReadOnly $ olcReferral $ "
+ 		 "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
+ 		 "olcRootDSE $ "
+-		 "olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
++		 "olcSaslAuxprops $ olcSaslCBinding $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
+ 		 "olcSecurity $ olcServerID $ olcSizeLimit $ "
+ 		 "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ "
+ 		 "olcTCPBuffer $ "
+diff --git a/servers/slapd/config.c b/servers/slapd/config.c
+index 060d3410f..3d713d4fb 100644
+--- a/servers/slapd/config.c
++++ b/servers/slapd/config.c
+@@ -73,6 +73,7 @@ char	*global_host = NULL;
+ struct berval global_host_bv = BER_BVNULL;
+ char	*global_realm = NULL;
+ char	*sasl_host = NULL;
++char	*sasl_cbinding = NULL;
+ char		**default_passwd_hash = NULL;
+ struct berval default_search_base = BER_BVNULL;
+ struct berval default_search_nbase = BER_BVNULL;
+diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
+index 5f11a0cf1..6d9bb8e85 100644
+--- a/servers/slapd/connection.c
++++ b/servers/slapd/connection.c
+@@ -1440,12 +1440,9 @@ connection_read( ber_socket_t s, conn_readinfo *cri )
+ 			    c->c_connid, (int) s, c->c_tls_ssf, c->c_ssf, 0 );
+ 			slap_sasl_external( c, c->c_tls_ssf, &authid );
+ 			if ( authid.bv_val ) free( authid.bv_val );
+-			{
+-				char cbinding[64];
+-				struct berval cbv = { sizeof(cbinding), cbinding };
+-				if ( ldap_pvt_tls_get_unique( ssl, &cbv, 1 ))
+-					slap_sasl_cbinding( c, &cbv );
+-			}
++
++			slap_sasl_cbinding( c, ssl );
++
+ 		} else if ( rc == 1 && ber_sockbuf_ctrl( c->c_sb,
+ 			LBER_SB_OPT_NEEDS_WRITE, NULL )) {	/* need to retry */
+ 			slapd_set_write( s, 1 );
+diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
+index b89fa836a..0790a8004 100644
+--- a/servers/slapd/proto-slap.h
++++ b/servers/slapd/proto-slap.h
+@@ -1681,8 +1681,7 @@ LDAP_SLAPD_F (int) slap_sasl_external( Connection *c,
+ 	slap_ssf_t ssf,	/* relative strength of external security */
+ 	struct berval *authid );	/* asserted authenication id */
+ 
+-LDAP_SLAPD_F (int) slap_sasl_cbinding( Connection *c,
+-	struct berval *cbv );
++LDAP_SLAPD_F (int) slap_sasl_cbinding( Connection *c, void *ssl );
+ 
+ LDAP_SLAPD_F (int) slap_sasl_reset( Connection *c );
+ LDAP_SLAPD_F (int) slap_sasl_close( Connection *c );
+@@ -2072,6 +2071,7 @@ LDAP_SLAPD_V (char *)	global_host;
+ LDAP_SLAPD_V (struct berval)	global_host_bv;
+ LDAP_SLAPD_V (char *)	global_realm;
+ LDAP_SLAPD_V (char *)	sasl_host;
++LDAP_SLAPD_V (char *)	sasl_cbinding;
+ LDAP_SLAPD_V (char *)	slap_sasl_auxprops;
+ LDAP_SLAPD_V (char **)	default_passwd_hash;
+ LDAP_SLAPD_V (int)		lber_debug;
+diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c
+index fc023904a..5cced358c 100644
+--- a/servers/slapd/sasl.c
++++ b/servers/slapd/sasl.c
+@@ -1320,6 +1320,8 @@ int slap_sasl_destroy( void )
+ #endif
+ 	free( sasl_host );
+ 	sasl_host = NULL;
++	free( sasl_cbinding );
++	sasl_cbinding = NULL;
+ 
+ 	return 0;
+ }
+@@ -1506,17 +1508,24 @@ int slap_sasl_external(
+ 	return LDAP_SUCCESS;
+ }
+ 
+-int slap_sasl_cbinding( Connection *conn, struct berval *cbv )
++int slap_sasl_cbinding( Connection *conn, void *ssl )
+ {
+ #ifdef SASL_CHANNEL_BINDING
+-	sasl_channel_binding_t *cb = ch_malloc( sizeof(*cb) + cbv->bv_len );;
+-	cb->name = "ldap";
+-	cb->critical = 0;
+-	cb->data = (char *)(cb+1);
+-	cb->len = cbv->bv_len;
+-	memcpy( cb->data, cbv->bv_val, cbv->bv_len );
+-	sasl_setprop( conn->c_sasl_authctx, SASL_CHANNEL_BINDING, cb );
+-	conn->c_sasl_cbind = cb;
++	void *cb;
++	int i;
++
++	if ( sasl_cbinding == NULL )
++		return LDAP_SUCCESS;
++
++	i = ldap_pvt_sasl_cbinding_parse( sasl_cbinding );
++	if ( i < 0 )
++		return LDAP_SUCCESS;
++
++	cb = ldap_pvt_sasl_cbinding( ssl, i, 1 );
++	if ( cb != NULL ) {
++		sasl_setprop( conn->c_sasl_authctx, SASL_CHANNEL_BINDING, cb );
++		conn->c_sasl_cbind = cb;
++	}
+ #endif
+ 	return LDAP_SUCCESS;
+ }
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-ITS-9189_2-add-channel-bindings-tests.patch b/SOURCES/openldap-cbinding-ITS-9189_2-add-channel-bindings-tests.patch
new file mode 100644
index 0000000..5478022
--- /dev/null
+++ b/SOURCES/openldap-cbinding-ITS-9189_2-add-channel-bindings-tests.patch
@@ -0,0 +1,190 @@
+From 7b0017ad49a2290ec26cbcdffded8a527799e981 Mon Sep 17 00:00:00 2001
+From: Isaac Boukris <iboukris@gmail.com>
+Date: Sat, 18 Apr 2020 16:30:03 +0200
+Subject: [PATCH] ITS#9189 add channel-bindings tests
+
+---
+ tests/data/slapd-sasl-gssapi.conf       |  3 +
+ tests/scripts/setup_kdc.sh              |  8 +++
+ tests/scripts/test068-sasl-tls-external | 22 +++++++
+ tests/scripts/test077-sasl-gssapi       | 83 ++++++++++++++++++++++++-
+ 4 files changed, 113 insertions(+), 3 deletions(-)
+
+diff --git a/tests/data/slapd-sasl-gssapi.conf b/tests/data/slapd-sasl-gssapi.conf
+index 611fc7097..29ab6040b 100644
+--- a/tests/data/slapd-sasl-gssapi.conf
++++ b/tests/data/slapd-sasl-gssapi.conf
+@@ -63,3 +63,6 @@ rootpw          secret
+ 
+ sasl-realm	@KRB5REALM@
+ sasl-host	localhost
++
++database	config
++rootpw		secret
+diff --git a/tests/scripts/setup_kdc.sh b/tests/scripts/setup_kdc.sh
+index 1cb784075..98bcd9f96 100755
+--- a/tests/scripts/setup_kdc.sh
++++ b/tests/scripts/setup_kdc.sh
+@@ -142,3 +142,11 @@ if test $RC != 0 ; then
+ 		exit 0
+ 	fi
+ fi
++
++HAVE_SASL_GSS_CBIND=no
++
++grep CHANNEL_BINDING $TESTDIR/plugin_out > /dev/null 2>&1
++RC=$?
++if test $RC = 0 ; then
++	HAVE_SASL_GSS_CBIND=yes
++fi
+diff --git a/tests/scripts/test068-sasl-tls-external b/tests/scripts/test068-sasl-tls-external
+index f647b1012..0b91aa197 100755
+--- a/tests/scripts/test068-sasl-tls-external
++++ b/tests/scripts/test068-sasl-tls-external
+@@ -88,6 +88,28 @@ else
+ 	echo "success"
+ fi
+ 
++# Exercise channel-bindings code in builds without SASL support
++for cb in "none" "tls-unique" "tls-endpoint" ; do
++
++	echo -n "Using ldapwhoami with SASL/EXTERNAL and SASL_CBINDING (${cb})...."
++
++	$LDAPSASLWHOAMI -o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt     \
++	-o tls_cert=$TESTDIR/tls/certs/bjensen@mailgw.example.com.crt           \
++	-o tls_key=$TESTDIR/tls/private/bjensen@mailgw.example.com.key          \
++	-o tls_reqcert=hard -o SASL_CBINDING=$cb -ZZ -Y EXTERNAL -H $URIP1      \
++	> $TESTOUT 2>&1
++
++	RC=$?
++	if test $RC != 0 ; then
++		echo "ldapwhoami failed ($RC)!"
++		test $KILLSERVERS != no && kill -HUP $PID
++		exit $RC
++	else
++		echo "success"
++	fi
++done
++
++
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ 
+ if test $RC != 0 ; then
+diff --git a/tests/scripts/test077-sasl-gssapi b/tests/scripts/test077-sasl-gssapi
+index 64abe16fe..19f665622 100755
+--- a/tests/scripts/test077-sasl-gssapi
++++ b/tests/scripts/test077-sasl-gssapi
+@@ -21,7 +21,10 @@ if test $WITH_SASL = no ; then
+         exit 0
+ fi
+ 
+-mkdir -p $TESTDIR $DBDIR1
++SLAPTEST="$TESTWD/../servers/slapd/slaptest"
++CONFDIR=$TESTDIR/slapd.d
++
++mkdir -p $TESTDIR $DBDIR1 $CONFDIR
+ cp -r $DATADIR/tls $TESTDIR
+ 
+ cd $TESTWD
+@@ -32,7 +35,8 @@ echo "Starting KDC for SASL/GSSAPI tests..."
+ 
+ echo "Running slapadd to build slapd database..."
+ . $CONFFILTER $BACKEND $MONITORDB < $SASLGSSAPICONF > $CONF1
+-$SLAPADD -f $CONF1 -l $LDIFORDERED
++$SLAPTEST -f $CONF1 -F $CONFDIR
++$SLAPADD -F $CONFDIR -l $LDIFORDERED
+ RC=$?
+ if test $RC != 0 ; then
+ 	echo "slapadd failed ($RC)!"
+@@ -41,7 +45,7 @@ if test $RC != 0 ; then
+ fi
+ 
+ echo "Starting ldap:/// slapd on TCP/IP port $PORT1 and ldaps:/// slapd on $PORT2..."
+-$SLAPD -f $CONF1 -h "$URI1 $SURI2" -d $LVL $TIMING > $LOG1 2>&1 &
++$SLAPD -F $CONFDIR -h "$URI1 $SURI2" -d $LVL $TIMING > $LOG1 2>&1 &
+ PID=$!
+ if test $WAIT != 0 ; then
+     echo PID $PID
+@@ -144,6 +148,79 @@ else
+ 	fi
+ fi
+ 
++if test $WITH_TLS = no ; then
++        echo "TLS support not available, skipping channe-binding test"
++elif test $HAVE_SASL_GSS_CBIND = no ; then
++        echo "SASL has no channel-binding support in GSSAPI, test skipped"
++else
++	echo "Testing SASL/GSSAPI with SASL_CBINDING..."
++
++	for acb in "none" "tls-unique" "tls-endpoint" ; do
++
++		echo "Modifying slapd's olcSaslCBinding to ${acb} ..."
++		$LDAPMODIFY -D cn=config -H $URI1 -w secret <<EOF > $TESTOUT 2>&1
++dn: cn=config
++changetype: modify
++replace: olcSaslCBinding
++olcSaslCBinding: ${acb}
++EOF
++		RC=$?
++		if test $RC != 0 ; then
++			echo "ldapmodify failed ($RC)!"
++			kill $KDCPROC
++			test $KILLSERVERS != no && kill -HUP $KILLPIDS
++			exit $RC
++		fi
++
++		for icb in "none" "tls-unique" "tls-endpoint" ; do
++
++			# The gnutls implemantation of "tls-unique" seems broken
++			if test $icb = "tls-unique" -o $acb = "tls-unique" ; then
++				if test $WITH_TLS_TYPE == gnutls  ; then
++					continue
++				fi
++			fi
++
++			fail="no"
++			if test $icb != $acb -a $acb != "none" ; then
++				# This currently fails in MIT, but it is planned to be
++				# fixed not to fail like in heimdal - avoid testing.
++				if test $icb = "none" ; then
++					continue
++				fi
++				# Otherwise unmatching bindings are expected to fail.
++				fail="yes"
++			fi
++
++			echo -n "Using ldapwhoami with SASL/GSSAPI and SASL_CBINDING "
++			echo -ne "(client: ${icb},\tserver: ${acb}): "
++
++			$LDAPSASLWHOAMI -N -Y GSSAPI -H $URI1 -ZZ -o tls_reqcert=allow	\
++			-o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt	\
++			-o SASL_CBINDING=$icb > $TESTOUT 2>&1
++
++			RC=$?
++			if test $RC != 0 ; then
++				if test $fail = "no" ; then
++					echo "test failed ($RC)!"
++					kill $KDCPROC
++					test $KILLSERVERS != no && kill -HUP $KILLPIDS
++					exit $RC
++				fi
++			elif test $fail = "yes" ; then
++				echo "failed: command succeeded unexpectedly."
++				kill $KDCPROC
++				test $KILLSERVERS != no && kill -HUP $KILLPIDS
++				exit 1
++			fi
++
++			echo "success"
++			RC=0
++		done
++	done
++fi
++
++
+ kill $KDCPROC
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ 
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-ITS-9189_3-initialize-ldo_sasl_cbinding-in-LDAP_LDO_SA.patch b/SOURCES/openldap-cbinding-ITS-9189_3-initialize-ldo_sasl_cbinding-in-LDAP_LDO_SA.patch
new file mode 100644
index 0000000..f8ee932
--- /dev/null
+++ b/SOURCES/openldap-cbinding-ITS-9189_3-initialize-ldo_sasl_cbinding-in-LDAP_LDO_SA.patch
@@ -0,0 +1,27 @@
+From 4cac398b19c21ad56949ef7e67e285c6c8e7ecea Mon Sep 17 00:00:00 2001
+From: Isaac Boukris <iboukris@gmail.com>
+Date: Thu, 23 Apr 2020 22:47:32 +0200
+Subject: [PATCH] ITS#9189 - initialize ldo_sasl_cbinding in
+ LDAP_LDO_SASL_NULLARG
+
+Reported-by: Ryan Tandy @ryan
+---
+ libraries/libldap/ldap-int.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
+index c6c6891a9..336448115 100644
+--- a/libraries/libldap/ldap-int.h
++++ b/libraries/libldap/ldap-int.h
+@@ -301,7 +301,7 @@ struct ldapoptions {
+ 	/* SASL Security Properties */
+ 	struct sasl_security_properties	ldo_sasl_secprops;
+ 	int ldo_sasl_cbinding;
+-#define LDAP_LDO_SASL_NULLARG ,0,0,0,0,{0}
++#define LDAP_LDO_SASL_NULLARG ,0,0,0,0,{0},0
+ #else
+ #define LDAP_LDO_SASL_NULLARG
+ #endif
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-Make-prototypes-available-where-needed.patch b/SOURCES/openldap-cbinding-Make-prototypes-available-where-needed.patch
new file mode 100644
index 0000000..534b418
--- /dev/null
+++ b/SOURCES/openldap-cbinding-Make-prototypes-available-where-needed.patch
@@ -0,0 +1,64 @@
+NOTE: The patch has been adjusted to match the base code before backporting.
+
+From cd914149a665167b2c5ae16baa0c438824588819 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= <ondra@openldap.org>
+Date: Tue, 19 Feb 2019 10:26:39 +0000
+Subject: [PATCH] Make prototypes available where needed
+
+---
+ libraries/libldap/tls2.c   | 3 +++
+ servers/slapd/config.c     | 1 +
+ servers/slapd/proto-slap.h | 4 ++++
+ 3 files changed, 8 insertions(+)
+
+diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
+index 1a96b62c3..869de2eb5 100644
+--- a/libraries/libldap/tls2.c
++++ b/libraries/libldap/tls2.c
+@@ -76,6 +76,9 @@ static oid_name oids[] = {
+ 
+ #ifdef HAVE_TLS
+ 
++LDAP_F(int) ldap_pvt_tls_check_hostname LDAP_P(( LDAP *ld, void *s, const char *name_in ));
++LDAP_F(int) ldap_pvt_tls_get_peercert LDAP_P(( void *s, struct berval *der ));
++
+ void
+ ldap_pvt_tls_ctx_free ( void *c )
+ {
+diff --git a/servers/slapd/config.c b/servers/slapd/config.c
+index 778365fd0..2816455a3 100644
+--- a/servers/slapd/config.c
++++ b/servers/slapd/config.c
+@@ -48,6 +48,7 @@
+ #endif
+ #include "lutil.h"
+ #include "lutil_ldap.h"
++#include "ldif.h"
+ #include "config.h"
+ 
+ #ifdef _WIN32
+diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
+index 4bfdcf930..e33e3b7d9 100644
+--- a/servers/slapd/proto-slap.h
++++ b/servers/slapd/proto-slap.h
+@@ -755,6 +755,7 @@ LDAP_SLAPD_F (int) bindconf_unparse LDAP_P((
+ LDAP_SLAPD_F (int) bindconf_tls_set LDAP_P((
+ 	slap_bindconf *bc, LDAP *ld ));
+ LDAP_SLAPD_F (void) bindconf_free LDAP_P(( slap_bindconf *bc ));
++LDAP_SLAPD_F (void) slap_client_keepalive LDAP_P(( LDAP *ld, slap_keepalive *sk ));
+ LDAP_SLAPD_F (int) slap_client_connect LDAP_P(( LDAP **ldp, slap_bindconf *sb ));
+ LDAP_SLAPD_F (int) config_generic_wrapper LDAP_P(( Backend *be,
+ 	const char *fname, int lineno, int argc, char **argv ));
+@@ -1683,6 +1684,9 @@ LDAP_SLAPD_F (int) slap_sasl_external( Connection *c,
+ 	slap_ssf_t ssf,	/* relative strength of external security */
+ 	struct berval *authid );	/* asserted authenication id */
+ 
++LDAP_SLAPD_F (int) slap_sasl_cbinding( Connection *c,
++	struct berval *cbv );
++
+ LDAP_SLAPD_F (int) slap_sasl_reset( Connection *c );
+ LDAP_SLAPD_F (int) slap_sasl_close( Connection *c );
+ 
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-Update-keys-to-RSA-4096.patch b/SOURCES/openldap-cbinding-Update-keys-to-RSA-4096.patch
new file mode 100644
index 0000000..288d7d0
--- /dev/null
+++ b/SOURCES/openldap-cbinding-Update-keys-to-RSA-4096.patch
@@ -0,0 +1,526 @@
+From 3ab98b2fc98843289c1833891518fb3b5b42dcd8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= <ondra@openldap.org>
+Date: Tue, 30 Oct 2018 15:42:35 +0000
+Subject: [PATCH] Update keys to RSA 4096
+
+---
+ tests/data/tls/ca/certs/testsuiteCA.crt       | 133 ++++++++++++++++--
+ tests/data/tls/ca/private/testsuiteCA.key     |  64 +++++++--
+ .../tls/certs/bjensen@mailgw.example.com.crt  |  44 ++++--
+ tests/data/tls/certs/localhost.crt            |  44 ++++--
+ tests/data/tls/conf/openssl.cnf               |   2 +-
+ tests/data/tls/create-crt.sh                  |   9 +-
+ .../private/bjensen@mailgw.example.com.key    |  64 +++++++--
+ tests/data/tls/private/localhost.key          |  64 +++++++--
+ 8 files changed, 336 insertions(+), 88 deletions(-)
+
+diff --git a/tests/data/tls/ca/certs/testsuiteCA.crt b/tests/data/tls/ca/certs/testsuiteCA.crt
+index 7458e7461..62c88acca 100644
+--- a/tests/data/tls/ca/certs/testsuiteCA.crt
++++ b/tests/data/tls/ca/certs/testsuiteCA.crt
+@@ -1,16 +1,121 @@
++Certificate:
++    Data:
++        Version: 3 (0x2)
++        Serial Number:
++            0b:43:f8:e9:ee:d3:38:37:92:db:19:65:d9:94:17:cc:70:45:d4:06
++        Signature Algorithm: sha256WithRSAEncryption
++        Issuer: C=US, ST=CA, O=OpenLDAP Foundation, OU=OpenLDAP Test Suite
++        Validity
++            Not Before: Oct 30 15:29:02 2018 GMT
++            Not After : Nov 13 15:29:02 2519 GMT
++        Subject: C=US, ST=CA, O=OpenLDAP Foundation, OU=OpenLDAP Test Suite
++        Subject Public Key Info:
++            Public Key Algorithm: rsaEncryption
++                RSA Public-Key: (4096 bit)
++                Modulus:
++                    00:be:e0:ff:36:89:65:c0:4e:46:e6:24:e8:3d:81:
++                    97:92:28:4b:11:c6:21:ac:28:14:31:b2:a3:64:24:
++                    62:61:24:bd:76:7b:9e:7c:3a:50:65:fa:97:f3:c5:
++                    9d:49:cc:61:3a:31:6f:0d:a4:d8:70:57:73:c8:c6:
++                    66:06:d0:59:3f:24:3b:56:5d:70:20:e4:51:2b:88:
++                    5e:f4:78:82:bc:55:b5:d5:5b:f6:e5:55:1f:3a:af:
++                    59:9f:b7:5d:72:70:fe:b6:a4:dd:4e:f9:d0:38:e8:
++                    15:14:c7:45:ed:5e:d3:4c:ee:02:34:3a:37:d8:75:
++                    f1:49:0d:f6:8a:7b:8c:87:39:c9:fb:f2:3a:96:57:
++                    cd:7c:18:a7:bb:35:de:d3:c4:79:57:20:48:07:b9:
++                    65:f6:bd:7b:01:5c:99:8a:92:35:7c:b7:e3:96:1c:
++                    6f:4c:47:42:c1:77:d6:62:49:0e:be:01:8f:c9:f4:
++                    64:68:4c:b0:ec:10:12:d0:0e:5f:67:0e:e8:a4:bd:
++                    df:9c:fb:5b:04:6f:3c:2a:35:1b:5a:ca:98:ba:f3:
++                    61:f4:3a:77:28:be:a3:63:f1:d6:94:0d:fb:a0:87:
++                    e3:a5:9f:56:b6:a6:6a:90:13:80:2a:2e:ae:fe:af:
++                    aa:e3:e7:d8:3b:2b:a3:52:4f:73:2d:12:aa:e2:a3:
++                    0c:aa:fb:11:40:86:68:de:be:2b:9b:36:19:9c:d7:
++                    d7:5e:13:21:c9:b3:34:6d:09:53:ff:a3:2e:92:f4:
++                    33:80:de:7a:47:1c:47:57:68:53:2a:db:73:6e:6d:
++                    fa:40:df:55:25:a1:fc:87:c4:86:ef:6e:16:ec:f8:
++                    48:35:f5:96:b3:55:ce:56:a9:6e:c1:8c:ea:32:85:
++                    26:ea:af:0c:92:24:05:e2:49:12:b7:07:8f:06:96:
++                    be:13:fa:ec:49:f7:d4:49:6f:b9:c7:6c:79:53:39:
++                    a3:89:c4:4a:92:66:b0:f3:0c:72:6d:50:3c:63:1f:
++                    f3:76:63:a8:aa:b7:fd:db:ef:98:b4:5b:49:b6:84:
++                    66:e5:fc:60:0b:c1:f7:b0:f7:84:68:7e:71:5d:ac:
++                    fc:a9:cb:f6:02:fc:86:d3:a7:c3:42:ef:ba:f4:1a:
++                    27:71:5d:22:f5:53:e1:a6:f4:a5:dc:31:38:45:0b:
++                    a1:6d:ab:9c:05:2e:87:8c:31:02:99:80:6d:3f:66:
++                    e8:8a:d7:64:4f:08:7e:2f:f0:1f:28:ff:85:57:22:
++                    ee:6a:a7:05:72:f8:cf:5d:07:c6:73:23:82:85:82:
++                    76:4e:36:8a:ec:ea:f1:53:1e:e0:77:d1:4a:9f:df:
++                    ec:87:91:0a:56:40:b7:23:19:fa:60:14:d0:f0:32:
++                    4d:11:39
++                Exponent: 65537 (0x10001)
++        X509v3 extensions:
++            X509v3 Subject Key Identifier: 
++                90:CF:51:1D:E8:08:D4:4C:34:70:71:6B:D2:0B:00:68:D9:FD:60:50
++            X509v3 Authority Key Identifier: 
++                keyid:90:CF:51:1D:E8:08:D4:4C:34:70:71:6B:D2:0B:00:68:D9:FD:60:50
++
++            X509v3 Basic Constraints: critical
++                CA:TRUE
++    Signature Algorithm: sha256WithRSAEncryption
++         0f:7f:a0:c5:3c:ac:dc:ed:8f:56:3e:64:89:e6:87:d0:ca:a5:
++         37:b8:0e:49:aa:93:d3:e5:ac:ff:54:24:91:07:1b:9c:dc:08:
++         e6:cc:15:53:be:85:4c:51:52:d3:88:d0:d8:c7:b7:98:40:41:
++         8a:a7:7a:4c:96:85:61:8c:98:76:f6:a3:2c:10:31:a1:d8:e6:
++         a7:4c:ec:c3:29:ad:04:8b:e3:f2:2d:4c:30:0d:a4:bc:c8:93:
++         d2:9b:88:1d:a4:25:eb:ff:9f:f2:d9:c5:3b:bf:51:91:71:06:
++         92:35:96:5c:ca:6d:d6:86:47:63:07:7f:37:35:53:68:e9:4e:
++         d0:d0:25:42:18:e0:00:9e:ca:f5:bd:b7:94:ee:99:51:44:3a:
++         0c:44:40:e3:87:e6:ce:6c:2b:3f:c1:01:6c:5c:32:d5:59:b5:
++         bd:25:a3:1a:ff:85:a5:89:9c:d8:24:4b:fa:59:99:5a:64:ab:
++         a1:d8:0f:c0:19:28:84:1e:89:c2:a1:15:4e:0f:7e:1f:bf:f8:
++         92:df:9f:1c:d5:4a:98:40:82:ee:41:1f:de:f7:25:11:fd:76:
++         0a:cf:37:40:bc:c2:2d:6a:ea:4a:0c:6d:b0:e6:75:37:b5:63:
++         a8:a1:c5:81:d0:84:c0:f3:e0:c3:5c:c4:9f:ec:3b:9f:8a:74:
++         ce:f0:cc:e3:e9:15:08:a0:ea:3e:a9:8e:bc:9a:01:00:96:fe:
++         37:6f:61:b5:2c:4b:1f:5d:d7:24:09:fe:bf:f4:77:47:e4:ee:
++         7c:ea:6b:67:84:ee:56:4f:5f:b9:b8:e4:db:70:e1:4a:b3:94:
++         4d:dd:52:45:05:4d:79:d4:7c:8b:9d:9b:6a:0b:73:9e:f3:0e:
++         d5:d5:46:da:b4:fb:4a:ea:5b:ab:8e:42:68:0e:96:cd:8a:6e:
++         35:a8:e6:1b:6a:ed:a8:9e:3c:cc:3b:44:54:b8:2d:ba:c7:83:
++         91:7c:70:40:0c:14:b8:21:7a:12:ac:8c:96:4c:94:a6:ee:fe:
++         cc:77:34:8e:e3:c3:c0:44:19:51:85:07:6c:d8:d1:2e:69:8d:
++         b1:0e:42:fb:e6:16:65:86:c6:e3:2f:a7:3f:b4:8e:4f:1c:83:
++         c4:0a:ae:a0:d9:17:fd:cf:a2:38:a1:9f:70:dc:5c:df:3c:07:
++         7b:64:01:ff:35:8c:45:43:e8:fa:a4:f6:c4:71:78:17:6e:6a:
++         7f:d1:6e:66:c6:89:33:3b:28:4a:76:bf:ca:29:05:51:07:98:
++         ce:63:62:25:61:7f:5e:c6:91:23:02:13:15:4f:fd:24:58:9d:
++         2d:ac:eb:cb:9a:c2:82:2f:50:5c:5a:16:bb:8c:bf:4d:66:2c:
++         6f:1c:c4:a9:28:e1:3d:4d
+ -----BEGIN CERTIFICATE-----
+-MIICgjCCAeugAwIBAgIJAJGJtO9oGgLiMA0GCSqGSIb3DQEBCwUAMFkxCzAJBgNV
+-BAYTAlVTMQswCQYDVQQIDAJDQTEcMBoGA1UECgwTT3BlbkxEQVAgRm91bmRhdGlv
+-bjEfMB0GA1UECwwWT3BlbkxEQVAgVGVzdCBTdWl0ZSBDQTAgFw0xNzAxMTkyMDI0
+-NTFaGA8yNTE4MDIwMjIwMjQ1MVowWTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNB
+-MRwwGgYDVQQKDBNPcGVuTERBUCBGb3VuZGF0aW9uMR8wHQYDVQQLDBZPcGVuTERB
+-UCBUZXN0IFN1aXRlIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3xcMd
+-rvEPxIzZ0FnGVfk6sLXW//4UbBZmmsHSNT7UDNpL301QrsOaATyiOMSPHxmQoLPb
+-lYOtTCPaHN9/KIHoCnEQ6tJRe30okA0DFnZvSH5jAm9E2QvsXMVXU5XIi9dZTNdL
+-6jwRajPQP3YfK+PyrtIqc0IvhB4Ori39vrFLpQIDAQABo1AwTjAdBgNVHQ4EFgQU
+-7fEPwfVJESrieK5MzzjBSK8xEfIwHwYDVR0jBBgwFoAU7fEPwfVJESrieK5MzzjB
+-SK8xEfIwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQBtXLZWW6ZKZux/
+-wk7uLNZl01kPJUBiI+yMU5uY5PgOph1CpaUXp3QftCb0yRQ2g5d0CNYI5DyXuHws
+-ZSZRFF8SRwm3AogkMzYKenPF5m2OXSpvOMdnlbbFmIJnvwUfKhtinw+r0zvW8I8Q
+-aL52EFPS0o3tiAJXS82U2wrQdJ0YEw==
++MIIFjzCCA3egAwIBAgIUC0P46e7TODeS2xll2ZQXzHBF1AYwDQYJKoZIhvcNAQEL
++BQAwVjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRwwGgYDVQQKDBNPcGVuTERB
++UCBGb3VuZGF0aW9uMRwwGgYDVQQLDBNPcGVuTERBUCBUZXN0IFN1aXRlMCAXDTE4
++MTAzMDE1MjkwMloYDzI1MTkxMTEzMTUyOTAyWjBWMQswCQYDVQQGEwJVUzELMAkG
++A1UECAwCQ0ExHDAaBgNVBAoME09wZW5MREFQIEZvdW5kYXRpb24xHDAaBgNVBAsM
++E09wZW5MREFQIFRlc3QgU3VpdGUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
++AoICAQC+4P82iWXATkbmJOg9gZeSKEsRxiGsKBQxsqNkJGJhJL12e558OlBl+pfz
++xZ1JzGE6MW8NpNhwV3PIxmYG0Fk/JDtWXXAg5FEriF70eIK8VbXVW/blVR86r1mf
++t11ycP62pN1O+dA46BUUx0XtXtNM7gI0OjfYdfFJDfaKe4yHOcn78jqWV818GKe7
++Nd7TxHlXIEgHuWX2vXsBXJmKkjV8t+OWHG9MR0LBd9ZiSQ6+AY/J9GRoTLDsEBLQ
++Dl9nDuikvd+c+1sEbzwqNRtaypi682H0OncovqNj8daUDfugh+Oln1a2pmqQE4Aq
++Lq7+r6rj59g7K6NST3MtEqriowyq+xFAhmjeviubNhmc19deEyHJszRtCVP/oy6S
++9DOA3npHHEdXaFMq23NubfpA31UlofyHxIbvbhbs+Eg19ZazVc5WqW7BjOoyhSbq
++rwySJAXiSRK3B48Glr4T+uxJ99RJb7nHbHlTOaOJxEqSZrDzDHJtUDxjH/N2Y6iq
++t/3b75i0W0m2hGbl/GALwfew94RofnFdrPypy/YC/IbTp8NC77r0GidxXSL1U+Gm
++9KXcMThFC6Ftq5wFLoeMMQKZgG0/ZuiK12RPCH4v8B8o/4VXIu5qpwVy+M9dB8Zz
++I4KFgnZONors6vFTHuB30Uqf3+yHkQpWQLcjGfpgFNDwMk0ROQIDAQABo1MwUTAd
++BgNVHQ4EFgQUkM9RHegI1Ew0cHFr0gsAaNn9YFAwHwYDVR0jBBgwFoAUkM9RHegI
++1Ew0cHFr0gsAaNn9YFAwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
++AgEAD3+gxTys3O2PVj5kieaH0MqlN7gOSaqT0+Ws/1QkkQcbnNwI5swVU76FTFFS
++04jQ2Me3mEBBiqd6TJaFYYyYdvajLBAxodjmp0zswymtBIvj8i1MMA2kvMiT0puI
++HaQl6/+f8tnFO79RkXEGkjWWXMpt1oZHYwd/NzVTaOlO0NAlQhjgAJ7K9b23lO6Z
++UUQ6DERA44fmzmwrP8EBbFwy1Vm1vSWjGv+FpYmc2CRL+lmZWmSrodgPwBkohB6J
++wqEVTg9+H7/4kt+fHNVKmECC7kEf3vclEf12Cs83QLzCLWrqSgxtsOZ1N7VjqKHF
++gdCEwPPgw1zEn+w7n4p0zvDM4+kVCKDqPqmOvJoBAJb+N29htSxLH13XJAn+v/R3
++R+TufOprZ4TuVk9fubjk23DhSrOUTd1SRQVNedR8i52bagtznvMO1dVG2rT7Supb
++q45CaA6WzYpuNajmG2rtqJ48zDtEVLgtuseDkXxwQAwUuCF6EqyMlkyUpu7+zHc0
++juPDwEQZUYUHbNjRLmmNsQ5C++YWZYbG4y+nP7SOTxyDxAquoNkX/c+iOKGfcNxc
++3zwHe2QB/zWMRUPo+qT2xHF4F25qf9FuZsaJMzsoSna/yikFUQeYzmNiJWF/XsaR
++IwITFU/9JFidLazry5rCgi9QXFoWu4y/TWYsbxzEqSjhPU0=
+ -----END CERTIFICATE-----
+diff --git a/tests/data/tls/ca/private/testsuiteCA.key b/tests/data/tls/ca/private/testsuiteCA.key
+index 2e14d7033..01a6614c1 100644
+--- a/tests/data/tls/ca/private/testsuiteCA.key
++++ b/tests/data/tls/ca/private/testsuiteCA.key
+@@ -1,16 +1,52 @@
+ -----BEGIN PRIVATE KEY-----
+-MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALfFwx2u8Q/EjNnQ
+-WcZV+Tqwtdb//hRsFmaawdI1PtQM2kvfTVCuw5oBPKI4xI8fGZCgs9uVg61MI9oc
+-338ogegKcRDq0lF7fSiQDQMWdm9IfmMCb0TZC+xcxVdTlciL11lM10vqPBFqM9A/
+-dh8r4/Ku0ipzQi+EHg6uLf2+sUulAgMBAAECgYBDOb7kjuh0Iix8SXFt0ml3hMkg
+-O0kQ43FWW2pnoT64h3MbqjY4O5YmMimiFi4hRPkvJPpma01eCapb0ZAYjhLm1bpf
+-7Ey+724CEN3/DnorbQ3b/Fe2AVl4msJKEQFoercnaS9tFDPoijzH/quC2agH41tn
+-rGWTpahq6JUIP6xkwQJBAPHJZVHGQ8P/5bGxqOkPLtjIfDLtAgInMxZgDjHhHw2f
+-wGoeRrZ3J1yW0tnWtTXBN+5fKjCd6QpEvBmwhiZ+S+0CQQDCk1JBq64UotqeSWnk
+-AmhRMyVs87P0DPW2Gg8y96Q3d5Rwmy65ITr4pf/xufcSkrTSObDLhfhRyJKz7W4l
+-vjeZAkBq99CtZuugENxLyu+RfDgbjEb2OMjErxb49TISeyhD3MNBr3dVTk3Jtqg9
+-27F7wKm/+bYuoA3zjwkwzFntOb7ZAkAY0Hz/DwwGabaD1U0B3SS8pk8xk+rxRu3X
+-KX+iul5hDIkLy16sEYbZyyHXDCZsYfVZki3v5sgCdhfvhmozugyRAkBQgCeI8K1N
+-I9rHrcMZUjVT/3AdjSu6xIM87Vv/oIzGUNaadnQONRaXZ+Kp5pv9j4B/18rPcQwL
+-+b2qljWeZbGH
++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
++yu/1yFXYTrmhD/P0+nJn1DfS5JljCJY=
+ -----END PRIVATE KEY-----
+diff --git a/tests/data/tls/certs/bjensen@mailgw.example.com.crt b/tests/data/tls/certs/bjensen@mailgw.example.com.crt
+index 93e3a0d39..eb0fc693f 100644
+--- a/tests/data/tls/certs/bjensen@mailgw.example.com.crt
++++ b/tests/data/tls/certs/bjensen@mailgw.example.com.crt
+@@ -1,16 +1,32 @@
+ -----BEGIN CERTIFICATE-----
+-MIICejCCAeOgAwIBAgIBADANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJVUzEL
+-MAkGA1UECAwCQ0ExHDAaBgNVBAoME09wZW5MREFQIEZvdW5kYXRpb24xHzAdBgNV
+-BAsMFk9wZW5MREFQIFRlc3QgU3VpdGUgQ0EwIBcNMTcwNTEwMjMxNjExWhgPMjUx
+-ODA1MjQyMzE2MTFaMIGbMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExHDAaBgNV
+-BAoME09wZW5MREFQIEZvdW5kYXRpb24xETAPBgNVBAsMCE9wZW5MREFQMSMwIQYD
+-VQQDDBpiamVuc2VuQG1haWxndy5leGFtcGxlLmNvbTEpMCcGCSqGSIb3DQEJARYa
+-YmplbnNlbkBtYWlsZ3cuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0A
+-MIGJAoGBAMjb2C5VL+f/B/f2xJyhsdXeaGhWdABWqJlCiupk7QVPotpZphqJ2fKg
+-QbX2w0sPazujt8hG96F2mBv49pHqzhSrKN70EA/E7b8d6ynjJpBU2P9ZgVlttnmU
+-U++22BSuhthP5VQK7IqNyI7ZyQ4hFzuqb/XrHD1VCDo/Z/JAkw7jAgMBAAGjDTAL
+-MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADgYEAmAQhIIKqjC13rtAGEQHV/pKn
+-wOnLbNOumODqM+0MkEfqXXtR6eNGres2RNAtCJ5fqqDBTQCTqRzIt67cqdlJle2f
+-7vXYm8Y6NgxHwG+N1y7S0Xf+oo7/BJ+YJTLF7CLJuPNRqILWvXGlcNDcM1nekeKo
+-4DnnYQBDnq48VORVX94=
++MIIFfDCCA2SgAwIBAgIBADANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJVUzEL
++MAkGA1UECAwCQ0ExHDAaBgNVBAoME09wZW5MREFQIEZvdW5kYXRpb24xHDAaBgNV
++BAsME09wZW5MREFQIFRlc3QgU3VpdGUwIBcNMTgxMDMwMTUzNzQwWhgPMjUxOTEx
++MTMxNTM3NDBaMIGbMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExHDAaBgNVBAoM
++E09wZW5MREFQIEZvdW5kYXRpb24xETAPBgNVBAsMCE9wZW5MREFQMSMwIQYDVQQD
++DBpiamVuc2VuQG1haWxndy5leGFtcGxlLmNvbTEpMCcGCSqGSIb3DQEJARYaYmpl
++bnNlbkBtYWlsZ3cuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
++ggIKAoICAQCcHBkHcUSKG4s7nKmcqZT3EoZkEgxoaMlpxUZtxBtO5ZXEfcpMaxuA
++7qkZvMJR8ws2u8TQU/18FhH4+0aZBefM0ExwqvGNJ8F0cTl3439DGNE+/psh5NWg
++qPYe/K3bAtSRtF7wDxF77eb2Yz0J3NIDxFrAbovfg0ydbt9pWJr5pDBvlqSdYu38
++kpIB5WENCEy77QK9GEGAlMVIRXneA5t2CKsljujRG1H5YJeS6qVAEdMllHZ6a0nN
++LxTdLe1qbZyRgEqRKgW5WcWrW46Co9CRDcFeMqoHdwAQsRdOGBivgkeYUST1yIms
++CbzlSRLC1dfj++2mzCMxoc3xpZNPyHyBuRgou8VqWpF2NuG+KS7QBtm1PVUhSAvR
++X9uQOnXnazQvlRfsaHQjGUKyhMUr5dcwpTqThW4BoqtStd6/097sZTZVWmsC+mzL
++twWkESVDU0tNg/czWLn56smV7DfPjFDDAV6eNcScFfD8w04aPdk8ODalW/wnsTjI
++LQuEBssrV1h8WblruWRU31Mn+mw9SA3tDfTk9sJiEyiTJh3B1DrEb+pIuk4vz5ui
++cNcYTXCfa5ZpPL608f7cWuG2GP8f5ug4PMKyRkh6qCt7BWrVgOheo1ZhjvrbmhI4
++yPXHATrCtYO1wqIyu9Yuirdg7WJD6npu8IV38VEgEBD3UFanY9xN7wIDAQABow0w
++CzAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQCq8VvpcoAgCK/D5yi/2puB
++LD7kYaVaSXxrUQBeLTmKERw3akpgW7QTGCNgM425VVaBQRPtv8YcX9OycUAylAA+
++7lzwdP95OJGnUOjQY4x4iRAwCPkpDCcnwc43c3WAyQb2S46aZJaWK4S0+RM3CmWH
++1Fzb6aODdnoBEKk0XgNrB6/teB+UWgtTSxWiY/HWiArDaZDPMAxqEK0hnB+b/sBD
++ZoBYnfnQXezylqbk9vkzTIbSVrv5ZZdQELOAnPuxUCFpYew1OGKcg+1twYKDHgBS
++s13zN03eMEnC/O4Z01dhu16vqdikdP+tJJrppjvZtJys0KIP24ltDnpA6h/3m/Cl
++U1eiTDgWO+SsfiL1K4gcTL1eLjnCBFfnHN5gfgAV5w5DaKzvKp7Qu8db4DtH+S4o
++W/MBKuaHHKWUPGksvFUiGNgE/XyDU4MK34/5ulzbrWmqb24pYAzm1MyjsdzmXObw
+++fzg6EDBB14cWA2hA7mSqnzkiW1pELVym6+uTaIlopSIFr8nNAimwLiY5QJNGYvd
++hgNNvOyUUO+nON3aHsC/rRMgar3eo7A9AkQJ6qKVvPR2h1317PJLuKaLfjbaCzNw
++iA3JSQjcwR2ydlSgKKN2d/XXm/G4PZ9tUcBY4Zngn0ViT0/m7MFy9qsiWG97+yaZ
++nYsN5WfwDZrtG24dTotxVQ==
+ -----END CERTIFICATE-----
+diff --git a/tests/data/tls/certs/localhost.crt b/tests/data/tls/certs/localhost.crt
+index 194cb119d..3aeae3c16 100644
+--- a/tests/data/tls/certs/localhost.crt
++++ b/tests/data/tls/certs/localhost.crt
+@@ -1,16 +1,32 @@
+ -----BEGIN CERTIFICATE-----
+-MIICgzCCAeygAwIBAgIBADANBgkqhkiG9w0BAQsFADBZMQswCQYDVQQGEwJVUzEL
+-MAkGA1UECAwCQ0ExHDAaBgNVBAoME09wZW5MREFQIEZvdW5kYXRpb24xHzAdBgNV
+-BAsMFk9wZW5MREFQIFRlc3QgU3VpdGUgQ0EwIBcNMTcwNTEwMjMxNjExWhgPMjUx
+-ODA1MjQyMzE2MTFaMGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEcMBoGA1UE
+-CgwTT3BlbkxEQVAgRm91bmRhdGlvbjEcMBoGA1UECwwTT3BlbkxEQVAgVGVzdCBT
+-dWl0ZTESMBAGA1UEAwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+-iQKBgQDutp3GaZXGSm7joDm1TYI+dhBAuL1+O+oJlmZL10GX/oHqc8WNobvuZGH4
+-7H8mQf7zWwJQWxL805oBDMPi2ncgha5ydaVsf4rBZATpweji04vd+672qtR/dGgv
+-8Re5G3ZFYWxUv8nb/DJojG601V2Ye/K3rf+Xwa9u4Q9EJqIivwIDAQABo0gwRjAJ
+-BgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8A
+-AAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADgYEAYItH9TDh/lqG
+-8XcBPi0bzGaUPkGlDY615xvsVCflnsfRqLKP/dCfi1GjaDajEmE874pvnmmZfwxl
+-0MRTqnhEmFdqjPzVSVKCeNQYWGr3wzKwI7qrhTLMg3Tz98Sz0+HUY8G9fwsNekAR
+-GjeZB1FxqDGHjxBq2O828iejw28bSz4=
++MIIFhTCCA22gAwIBAgIBADANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJVUzEL
++MAkGA1UECAwCQ0ExHDAaBgNVBAoME09wZW5MREFQIEZvdW5kYXRpb24xHDAaBgNV
++BAsME09wZW5MREFQIFRlc3QgU3VpdGUwIBcNMTgxMDMwMTUzNjMwWhgPMjUxOTEx
++MTMxNTM2MzBaMGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEcMBoGA1UECgwT
++T3BlbkxEQVAgRm91bmRhdGlvbjEcMBoGA1UECwwTT3BlbkxEQVAgVGVzdCBTdWl0
++ZTESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
++CgKCAgEA6Ud89ugah2oWY00q1g+M6NkpluewwvGq4tkMau1gq+Q5Biv61bubgdSA
++Z+Zkkxe3Sx0Zv7i5wldIN4wXqEDlMg2qhfzKDSNKUofc0z7FLMb0Cn46WqlciUCY
++VetHhBghGd+6fxOOz+x98FhiiAif+AdiUWBTKFFohWXo/9aiGgm0ueJj2NS3Eyac
++xOKoTcDd9TMsOJ2fMH2MlquArLobCvuphOrVbqBoeeol2SzFDDOW8ryPDzFGy5xh
++ZHkm/3sGIoDpDkDR0yhvBzn47qdLI5myc6Fj96s7S2xgqiqGXJW0D0FCfpUQXxfm
++ahz/Jdwl+hqs5Eg/aA+LE/7lmS7szo3zwJQ53ApdcaupHi4fU60wPVrdo29wLwDO
++hDuS+Oc1os1UyJt0T0a+zB4PIP2rxifyxI1iWmZFt7tJyLv1k7yMN7CLCWzsSy5P
++BZpGmHV9Wbvb660N6NzlFDMqnjJWDAr1BLoV4ywmpiWPhy/7JtKXFe1V3jT5MvGM
++26IOC+zCwwZVyEIIASeWepZDuto00Lqo7jOKSlLRmuhTX1ELK8xYX6ZU/fz0FwYn
++bLu6bI4mRGfbJ12fWYm5QMje2QAuvndfi759HUeuLl6TgmeQFgqFA/6Kkwoz0Ncb
++Kaaj+ByvLXfI4S3lvkwT26nOAt966fb1bsdkb8P52NdkqeSMk5cCAwEAAaNIMEYw
++CQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/
++AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUAA4ICAQCGQCs10hwY
++t5o3AWjU8oT8HWnLDsEzIvI/Z2dvtsFSOFotH14d8a7CdCKNiry8BbQ82A4sG/Xw
++0aVdP1EscxGhpJuMHG4Ph9PZBm31ZW2VoRHOEs7/Moi6G/1yldVxWUH/qXO00Dw9
++cEsiUQdPrPQDoVBKYAMuV15RP9b3iPpw3GY1EkIu+akGVziHFmFYUoU2gctiGIZ6
++6KiqBFvCP1Yvm3RSZ5t/Kv/jPMetAnCq+9JAUAodAh2+goBvUCAN9Itr/tEs98jq
++9d14J7gzIRDdNHKOLrRFmoMrTaDZNtqBe5jiMf0O55tgjv4BqN4w11M51bjY4umd
++GX+OXoBJG+MK7AZyaHPjHa1NMoLDOUhTvHb4zPNkPiVb8r3lYkQ4VCtre+4qqrEn
++cEt9KWGpHkoz4GSKn6uidQebdi4waexcGttsHbKPaKZqzYXAJ2bjFZnv85zPtpjO
++qxzqrMUruiCU7EfjGAdZ8S0lwjdMihznLATjKuwQkJ2mVg2HbLgxZu578FHTBOHW
++LjVIr/80auF4Ino9ocHpIwL/E4jpYQWP/Uv4KBHwkAktmUOwqyt0iysRaWy4Gp7S
++keBI9FoGtJ1Mq5M2tVINBzt1ESC3t03KqyY+/9r/IeY7A7yukC0YJnJ+HorfuQFf
++0//7DOEA58bRswyWTLOAjYMJHilTKOozSQ==
+ -----END CERTIFICATE-----
+diff --git a/tests/data/tls/conf/openssl.cnf b/tests/data/tls/conf/openssl.cnf
+index a3c8ad9f6..632cff11c 100644
+--- a/tests/data/tls/conf/openssl.cnf
++++ b/tests/data/tls/conf/openssl.cnf
+@@ -51,7 +51,7 @@ commonName              = supplied
+ emailAddress            = optional
+ 
+ [ req ]
+-default_bits            = 2048
++default_bits            = @KEY_BITS@
+ default_keyfile         = privkey.pem
+ distinguished_name      = req_distinguished_name
+ attributes              = req_attributes
+diff --git a/tests/data/tls/create-crt.sh b/tests/data/tls/create-crt.sh
+index 8c33a24fe..739f8eaf1 100755
+--- a/tests/data/tls/create-crt.sh
++++ b/tests/data/tls/create-crt.sh
+@@ -5,6 +5,9 @@ if [ x"$openssl" = "x" ]; then
+ echo "OpenSSL command line binary not found, skipping..."
+ fi
+ 
++KEY_BITS=4096
++KEY_TYPE=rsa:$KEY_BITS
++
+ USAGE="$0 [-s] [-u <user@domain.com>]"
+ SERVER=0
+ USER=0
+@@ -45,13 +48,13 @@ echo "00" > cruft/serial
+ touch cruft/index.txt
+ touch cruft/index.txt.attr
+ hn=$(hostname -f)
+-sed -e "s;@HOSTNAME@;$hn;" conf/openssl.cnf >  ./openssl.cnf
++sed -e "s;@HOSTNAME@;$hn;" -e "s;@KEY_BITS@;$KEY_BITS;" conf/openssl.cnf >  ./openssl.cnf
+ 
+ if [ $SERVER = 1 ]; then
+ 	rm -rf private/localhost.key certs/localhost.crt
+ 
+ 	$openssl req -new -nodes -out localhost.csr -keyout private/localhost.key \
+-		-newkey rsa:1024 -config ./openssl.cnf \
++		-newkey $KEY_TYPE -config ./openssl.cnf \
+ 		-subj "/CN=localhost/OU=OpenLDAP Test Suite/O=OpenLDAP Foundation/ST=CA/C=US" \
+ 		-batch > /dev/null 2>&1
+ 
+@@ -66,7 +69,7 @@ if [ $USER = 1 ]; then
+ 	rm -f certs/$EMAIL.crt private/$EMAIL.key $EMAIL.csr
+ 
+ 	$openssl req -new -nodes -out $EMAIL.csr -keyout private/$EMAIL.key \
+-		-newkey rsa:1024 -config ./openssl.cnf \
++		-newkey $KEY_TYPE -config ./openssl.cnf \
+ 		-subj "/emailAddress=$EMAIL/CN=$EMAIL/OU=OpenLDAP/O=OpenLDAP Foundation/ST=CA/C=US" \
+ 		-batch >/dev/null 2>&1
+ 
+diff --git a/tests/data/tls/private/bjensen@mailgw.example.com.key b/tests/data/tls/private/bjensen@mailgw.example.com.key
+index 5f4625fd7..e30e11586 100644
+--- a/tests/data/tls/private/bjensen@mailgw.example.com.key
++++ b/tests/data/tls/private/bjensen@mailgw.example.com.key
+@@ -1,16 +1,52 @@
+ -----BEGIN PRIVATE KEY-----
+-MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMjb2C5VL+f/B/f2
+-xJyhsdXeaGhWdABWqJlCiupk7QVPotpZphqJ2fKgQbX2w0sPazujt8hG96F2mBv4
+-9pHqzhSrKN70EA/E7b8d6ynjJpBU2P9ZgVlttnmUU++22BSuhthP5VQK7IqNyI7Z
+-yQ4hFzuqb/XrHD1VCDo/Z/JAkw7jAgMBAAECgYEApDgKQadoaZd7nmJlUWJqEV+r
+-oVK9uOEhK1zaUtV9bBA2J6uQQLZgORyJXQqJlT7f/3zVb6uGHr7lkkk03wxIu+3e
+-nIi7or/Cw6KmxhgslsQamf/ujjeqRlij/4pJIpEYByme9SstfzMBFNWU4t+fguPg
+-xXz6lvVZuNiYRWWuXxECQQDwakp31mNczqLPg8fuhdgixz7HCK5g6p4XDw+Cu9Ra
+-EenuOJVlnwXdW+g5jooiV5RWhxbTO6ImtgbcBGoeLSbVAkEA1eEcifIzgSi8XODd
+-9i6dCSMHKk4FgDRk2DJxRePLK2J1kt2bhOz/N1130fTargDWo8QiQAnd7RBOMJO/
+-pGaq1wJAZ2afzrjzlWf+WFgqdmk0k4i0dHBEZ8Sg5/P/TNAyPeb0gRPvFXz2zcUI
+-tTCcMrcOQsTpSUKdtB6YBqsTZRUwXQI/FbjHLTtr/7Ijb0tnP5l8WXE1SRajeGHZ
+-3BtDZdW8zKszRbc8FEP9p6HWiXxUuVdcdUV2NQrLf0goqMZYsFm9AkBtV3URLS4D
+-tw0VPr/TtzDx0UTJU5POdRcNrrpm233A0EyGNmLuM7y0iLxrvCIN9z0RVu7AeMBg
+-36Ixj3L+5H18
++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
++dH+lv5X1bTB18GK88ANpC2qLCKRJPCTx
+ -----END PRIVATE KEY-----
+diff --git a/tests/data/tls/private/localhost.key b/tests/data/tls/private/localhost.key
+index 8a24f69f8..99cb512c4 100644
+--- a/tests/data/tls/private/localhost.key
++++ b/tests/data/tls/private/localhost.key
+@@ -1,16 +1,52 @@
+ -----BEGIN PRIVATE KEY-----
+-MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAO62ncZplcZKbuOg
+-ObVNgj52EEC4vX476gmWZkvXQZf+gepzxY2hu+5kYfjsfyZB/vNbAlBbEvzTmgEM
+-w+LadyCFrnJ1pWx/isFkBOnB6OLTi937rvaq1H90aC/xF7kbdkVhbFS/ydv8MmiM
+-brTVXZh78ret/5fBr27hD0QmoiK/AgMBAAECgYEA0gs5tNY/BaWFASGA5bj3u4Ij
+-Nu/XPPX3Lsx54o3bl6RIKEYKNF91f4QweNmP39f+P596373jbTe7sOTMkBXu7qnf
+-2B51VBJ72Uq92gO2VXImK+uuC6JdZfYTlX1QJkaR6mxhBl3KAgUeGUgbL0Xp9XeJ
+-bVcPqDOpRyIlW/80EHECQQD6PWRkk+0H4EMRA3GAnMQv/+Cy+sqF0T0OBNsQ846q
+-1hQhJfVvjgj2flmJZpH9zBTaqDn4grJDfQ9cViZwf4k7AkEA9DVNHPNVpkeToWrf
+-3yH55Ya5WEAl/6oNsHlaSZ88SHCZGqY7hQrpjSycsEezmsnDeqfdVuO97G2nHC7U
+-VdPUTQJAAq8r54RKs53tOj5+NjH4TMeC4oicKYlQDVlx/CGQszZuqthcZKDyaap7
+-TWUDReStiJbrYEYOoXiy9HucF/LWRwJAQKeH9f06lN5oaJkKEmJFbg5ALew14z1b
+-iHhofgtpg2hEMLkIEw4zjUvdZBJnq7h1R5j/0cxT8S+KybxgPSTrFQJBAPTrj7bP
+-5M7tPyQtyFxhFhas6g4ZHz/D2yB7BL+hL3IiJf3fdWNcHTzBDFEgDOVjR/7CZ6L3
+-b61hkjQZfbEg5cg=
++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
++bcnWV4XIPIMbouL4132Ove+GukJlPA==
+ -----END PRIVATE KEY-----
+-- 
+2.26.2
+
diff --git a/SOURCES/openldap-cbinding-auth-add-SASL-GSSAPI-tests.patch b/SOURCES/openldap-cbinding-auth-add-SASL-GSSAPI-tests.patch
new file mode 100644
index 0000000..323d531
--- /dev/null
+++ b/SOURCES/openldap-cbinding-auth-add-SASL-GSSAPI-tests.patch
@@ -0,0 +1,487 @@
+From 8e3e85e329f5cbd989936b0df8a0ac06906a4824 Mon Sep 17 00:00:00 2001
+From: Isaac Boukris <iboukris@gmail.com>
+Date: Tue, 14 Apr 2020 16:19:05 +0300
+Subject: [PATCH] auth: add SASL/GSSAPI tests
+
+---
+ tests/data/krb5.conf              |  32 ++++++
+ tests/data/slapd-sasl-gssapi.conf |  65 ++++++++++++
+ tests/scripts/conf.sh             |   3 +
+ tests/scripts/defines.sh          |   5 +
+ tests/scripts/setup_kdc.sh        | 144 +++++++++++++++++++++++++++
+ tests/scripts/test077-sasl-gssapi | 159 ++++++++++++++++++++++++++++++
+ 6 files changed, 408 insertions(+)
+ create mode 100644 tests/data/krb5.conf
+ create mode 100644 tests/data/slapd-sasl-gssapi.conf
+ create mode 100755 tests/scripts/setup_kdc.sh
+ create mode 100755 tests/scripts/test077-sasl-gssapi
+
+diff --git a/tests/data/krb5.conf b/tests/data/krb5.conf
+new file mode 100644
+index 000000000..739113742
+--- /dev/null
++++ b/tests/data/krb5.conf
+@@ -0,0 +1,32 @@
++[libdefaults]
++  default_realm = @KRB5REALM@
++  dns_lookup_realm = false
++  dns_lookup_kdc = false
++  default_ccache_name = FILE://@TESTDIR@/ccache
++  #udp_preference_limit = 1
++[realms]
++ @KRB5REALM@ = {
++  kdc = @KDCHOST@:@KDCPORT@
++  acl_file = @TESTDIR@/kadm.acl
++  database_name = @TESTDIR@/kdc.db
++  key_stash_file = @TESTDIR@/kdc.stash
++ }
++[kdcdefaults]
++  kdc_ports = @KDCPORT@
++  kdc_tcp_ports = @KDCPORT@
++[logging]
++  kdc = FILE:@TESTDIR@/kdc.log
++  admin_server = FILE:@TESTDIR@/kadm.log
++  default = FILE:@TESTDIR@/krb5.log
++
++#Heimdal
++[kdc]
++ database = {
++  dbname = @TESTDIR@/kdc.db
++  realm = @KRB5REALM@
++  mkey_file = @TESTDIR@/kdc.stash
++  log_file = @TESTDIR@/kdc.log
++  acl_file = @TESTDIR@/kadm.acl
++ }
++[hdb]
++  db-dir = @TESTDIR@
+diff --git a/tests/data/slapd-sasl-gssapi.conf b/tests/data/slapd-sasl-gssapi.conf
+new file mode 100644
+index 000000000..611fc7097
+--- /dev/null
++++ b/tests/data/slapd-sasl-gssapi.conf
+@@ -0,0 +1,65 @@
++# stand-alone slapd config -- for testing (with indexing)
++# $OpenLDAP$
++## This work is part of OpenLDAP Software <http://www.openldap.org/>.
++##
++## Copyright 1998-2020 The OpenLDAP Foundation.
++## All rights reserved.
++##
++## Redistribution and use in source and binary forms, with or without
++## modification, are permitted only as authorized by the OpenLDAP
++## Public License.
++##
++## A copy of this license is available in the file LICENSE in the
++## top-level directory of the distribution or, alternatively, at
++## <http://www.OpenLDAP.org/license.html>.
++
++#
++include		@SCHEMADIR@/core.schema
++include		@SCHEMADIR@/cosine.schema
++#
++include		@SCHEMADIR@/corba.schema
++include		@SCHEMADIR@/java.schema
++include		@SCHEMADIR@/inetorgperson.schema
++include		@SCHEMADIR@/misc.schema
++include		@SCHEMADIR@/nis.schema
++include		@SCHEMADIR@/openldap.schema
++#
++include		@SCHEMADIR@/duaconf.schema
++include		@SCHEMADIR@/dyngroup.schema
++
++#
++pidfile		@TESTDIR@/slapd.1.pid
++argsfile	@TESTDIR@/slapd.1.args
++
++# SSL configuration
++TLSCACertificateFile @TESTDIR@/tls/ca/certs/testsuiteCA.crt
++TLSCertificateKeyFile @TESTDIR@/tls/private/localhost.key
++TLSCertificateFile @TESTDIR@/tls/certs/localhost.crt
++
++#
++rootdse 	@DATADIR@/rootdse.ldif
++
++#mod#modulepath	../servers/slapd/back-@BACKEND@/
++#mod#moduleload	back_@BACKEND@.la
++#monitormod#modulepath ../servers/slapd/back-monitor/
++#monitormod#moduleload back_monitor.la
++
++
++#######################################################################
++# database definitions
++#######################################################################
++
++database	@BACKEND@
++suffix          "dc=example,dc=com"
++rootdn          "cn=Manager,dc=example,dc=com"
++rootpw          secret
++#~null~#directory	@TESTDIR@/db.1.a
++#indexdb#index		objectClass eq
++#indexdb#index		mail eq
++#ndb#dbname db_1_a
++#ndb#include @DATADIR@/ndb.conf
++
++#monitor#database	monitor
++
++sasl-realm	@KRB5REALM@
++sasl-host	localhost
+diff --git a/tests/scripts/conf.sh b/tests/scripts/conf.sh
+index b0393865d..c9e1a4b0a 100755
+--- a/tests/scripts/conf.sh
++++ b/tests/scripts/conf.sh
+@@ -99,4 +99,7 @@ sed -e "s/@BACKEND@/${BACKEND}/"			\
+ 	-e "s;@TESTWD@;${TESTWD};"			\
+ 	-e "s;@DATADIR@;${DATADIR};"			\
+ 	-e "s;@SCHEMADIR@;${SCHEMADIR};"		\
++	-e "s;@KRB5REALM@;${KRB5REALM};"		\
++	-e "s;@KDCHOST@;${KDCHOST};"			\
++	-e "s;@KDCPORT@;${KDCPORT};"			\
+ 	-e "/^#/d"
+diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh
+index 1d6c2b3f1..ccb2e5b41 100755
+--- a/tests/scripts/defines.sh
++++ b/tests/scripts/defines.sh
+@@ -114,6 +114,7 @@ REFSLAVECONF=$DATADIR/slapd-ref-slave.conf
+ SCHEMACONF=$DATADIR/slapd-schema.conf
+ TLSCONF=$DATADIR/slapd-tls.conf
+ TLSSASLCONF=$DATADIR/slapd-tls-sasl.conf
++SASLGSSAPICONF=$DATADIR/slapd-sasl-gssapi.conf
+ GLUECONF=$DATADIR/slapd-glue.conf
+ REFINTCONF=$DATADIR/slapd-refint.conf
+ RETCODECONF=$DATADIR/slapd-retcode.conf
+@@ -223,6 +224,7 @@ PORT3=`expr $BASEPORT + 3`
+ PORT4=`expr $BASEPORT + 4`
+ PORT5=`expr $BASEPORT + 5`
+ PORT6=`expr $BASEPORT + 6`
++KDCPORT=`expr $BASEPORT + 7`
+ URI1="ldap://${LOCALHOST}:$PORT1/"
+ URIP1="ldap://${LOCALIP}:$PORT1/"
+ URI2="ldap://${LOCALHOST}:$PORT2/"
+@@ -248,6 +250,9 @@ SURIP5="ldaps://${LOCALIP}:$PORT5/"
+ SURI6="ldaps://${LOCALHOST}:$PORT6/"
+ SURIP6="ldaps://${LOCALIP}:$PORT6/"
+ 
++KRB5REALM="K5.REALM"
++KDCHOST=$LOCALHOST
++
+ # LDIF
+ LDIF=$DATADIR/test.ldif
+ LDIFADD1=$DATADIR/do_add.1
+diff --git a/tests/scripts/setup_kdc.sh b/tests/scripts/setup_kdc.sh
+new file mode 100755
+index 000000000..1cb784075
+--- /dev/null
++++ b/tests/scripts/setup_kdc.sh
+@@ -0,0 +1,144 @@
++#! /bin/sh
++# $OpenLDAP$
++## This work is part of OpenLDAP Software <http://www.openldap.org/>.
++##
++## Copyright 1998-2020 The OpenLDAP Foundation.
++## All rights reserved.
++##
++## Redistribution and use in source and binary forms, with or without
++## modification, are permitted only as authorized by the OpenLDAP
++## Public License.
++##
++## A copy of this license is available in the file LICENSE in the
++## top-level directory of the distribution or, alternatively, at
++## <http://www.OpenLDAP.org/license.html>.
++
++export KRB5_TRACE=$TESTDIR/k5_trace
++export KRB5_CONFIG=$TESTDIR/krb5.conf
++export KRB5_KDC_PROFILE=$KRB5_CONFIG
++export KRB5_KTNAME=$TESTDIR/server.kt
++export KRB5_CLIENT_KTNAME=$TESTDIR/client.kt
++export KRB5CCNAME=$TESTDIR/client.ccache
++
++KDCLOG=$TESTDIR/setup_kdc.log
++KSERVICE=ldap/$LOCALHOST
++KUSER=kuser
++
++. $CONFFILTER < $DATADIR/krb5.conf > $KRB5_CONFIG
++
++PATH=${PATH}:/usr/lib/heimdal-servers:/usr/sbin:/usr/local/sbin
++
++echo "Trying Heimdal KDC..."
++
++kdc --version 2>&1 | grep Heimdal > $KDCLOG 2>&1
++RC=$?
++if test $RC = 0 ; then
++
++	kstash --random-key > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "Heimdal: kstash failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	flags="--realm-max-ticket-life=1h --realm-max-renewable-life=1h"
++	kadmin -l init $flags $KRB5REALM > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "Heimdal: kadmin init failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	kadmin -l add --random-key --use-defaults $KSERVICE > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "Heimdal: kadmin add failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	kadmin -l ext -k $KRB5_KTNAME $KSERVICE > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "Heimdal: kadmin ext failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	kadmin -l add --random-key --use-defaults $KUSER > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "Heimdal: kadmin add failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	kadmin -l ext -k $KRB5_CLIENT_KTNAME $KUSER > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "Heimdal: kadmin ext failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	kdc --addresses=$LOCALIP --ports="$KDCPORT/udp" > $KDCLOG 2>&1 &
++else
++	echo "Trying MIT KDC..."
++
++	kdb5_util create -r $KRB5REALM -s -P password > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "MIT: kdb5_util create failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	kadmin.local -q "addprinc -randkey $KSERVICE" > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "MIT: admin addprinc failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	kadmin.local -q "ktadd -k $KRB5_KTNAME $KSERVICE" > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "MIT: kadmin ktadd failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	kadmin.local -q "addprinc -randkey $KUSER" > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "MIT: kadmin addprinc failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	kadmin.local -q "ktadd -k $KRB5_CLIENT_KTNAME $KUSER" > $KDCLOG 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "MIT: kadmin ktadd failed, skipping GSSAPI tests"
++		exit 0
++	fi
++
++	krb5kdc -n > $KDCLOG 2>&1 &
++fi
++
++KDCPROC=$!
++sleep 1
++
++kinit -kt $KRB5_CLIENT_KTNAME $KUSER > $KDCLOG 2>&1
++RC=$?
++if test $RC != 0 ; then
++	kill $KDCPROC
++	echo "SASL/GSSAPI: kinit failed, skipping GSSAPI tests"
++	exit 0
++fi
++
++pluginviewer -m GSSAPI > $TESTDIR/plugin_out 2>/dev/null
++RC=$?
++if test $RC != 0 ; then
++
++	saslpluginviewer -m GSSAPI > $TESTDIR/plugin_out 2>/dev/null
++	RC=$?
++	if test $RC != 0 ; then
++		kill $KDCPROC
++		echo "cyrus-sasl has no GSSAPI support, test skipped"
++		exit 0
++	fi
++fi
+diff --git a/tests/scripts/test077-sasl-gssapi b/tests/scripts/test077-sasl-gssapi
+new file mode 100755
+index 000000000..64abe16fe
+--- /dev/null
++++ b/tests/scripts/test077-sasl-gssapi
+@@ -0,0 +1,159 @@
++#! /bin/sh
++# $OpenLDAP$
++## This work is part of OpenLDAP Software <http://www.openldap.org/>.
++##
++## Copyright 1998-2020 The OpenLDAP Foundation.
++## All rights reserved.
++##
++## Redistribution and use in source and binary forms, with or without
++## modification, are permitted only as authorized by the OpenLDAP
++## Public License.
++##
++## A copy of this license is available in the file LICENSE in the
++## top-level directory of the distribution or, alternatively, at
++## <http://www.OpenLDAP.org/license.html>.
++
++echo "running defines.sh"
++. $SRCDIR/scripts/defines.sh
++
++if test $WITH_SASL = no ; then
++        echo "SASL support not available, test skipped"
++        exit 0
++fi
++
++mkdir -p $TESTDIR $DBDIR1
++cp -r $DATADIR/tls $TESTDIR
++
++cd $TESTWD
++
++
++echo "Starting KDC for SASL/GSSAPI tests..."
++. $SRCDIR/scripts/setup_kdc.sh
++
++echo "Running slapadd to build slapd database..."
++. $CONFFILTER $BACKEND $MONITORDB < $SASLGSSAPICONF > $CONF1
++$SLAPADD -f $CONF1 -l $LDIFORDERED
++RC=$?
++if test $RC != 0 ; then
++	echo "slapadd failed ($RC)!"
++	kill $KDCPROC
++	exit $RC
++fi
++
++echo "Starting ldap:/// slapd on TCP/IP port $PORT1 and ldaps:/// slapd on $PORT2..."
++$SLAPD -f $CONF1 -h "$URI1 $SURI2" -d $LVL $TIMING > $LOG1 2>&1 &
++PID=$!
++if test $WAIT != 0 ; then
++    echo PID $PID
++    read foo
++fi
++KILLPIDS="$PID"
++
++sleep 1
++
++for i in 0 1 2 3 4 5; do
++	$LDAPSEARCH -s base -b "" -H $URI1 \
++		'objectclass=*' > /dev/null 2>&1
++        RC=$?
++        if test $RC = 0 ; then
++                break
++        fi
++        echo "Waiting 5 seconds for slapd to start..."
++        sleep 5
++done
++
++if test $RC != 0 ; then
++	echo "ldapsearch failed ($RC)!"
++	kill $KDCPROC
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++$LDAPSEARCH -x -H $URI1 -s "base" -b "" supportedSASLMechanisms > $TESTOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapsearch failed ($RC)!"
++	kill $KDCPROC
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++grep GSSAPI $TESTOUT
++RC=$?
++if test $RC != 0 ; then
++	echo "failed: GSSAPI mechanism not in supportedSASLMechanisms."
++	kill $KDCPROC
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++fi
++
++echo -n "Using ldapwhoami with SASL/GSSAPI: "
++$LDAPSASLWHOAMI -N -Y GSSAPI -H $URI1 > $TESTOUT 2>&1
++RC=$?
++if test $RC != 0 ; then
++	echo "ldapwhoami failed ($RC)!"
++	kill $KDCPROC
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++else
++	echo "success"
++fi
++
++echo -n "Validating mapped SASL/GSSAPI ID: "
++echo "dn:uid=$KUSER,cn=$KRB5REALM,cn=gssapi,cn=auth" > $TESTDIR/dn.out
++$CMP $TESTDIR/dn.out $TESTOUT > $CMPOUT
++RC=$?
++if test $RC != 0 ; then
++	echo "Comparison failed"
++	kill $KDCPROC
++	test $KILLSERVERS != no && kill -HUP $KILLPIDS
++	exit $RC
++else
++	echo "success"
++fi
++
++if test $WITH_TLS = no ; then
++        echo "SASL/GSSAPI: TLS support not available, skipping TLS part."
++else
++	echo -n "Using ldapwhoami with SASL/GSSAPI with start-tls: "
++	$LDAPSASLWHOAMI -N -Y GSSAPI -H $URI1 -ZZ -o tls_reqcert=allow	\
++		-o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt	\
++		> $TESTOUT 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "ldapwhoami failed ($RC)!"
++		kill $KDCPROC
++		test $KILLSERVERS != no && kill -HUP $KILLPIDS
++		exit $RC
++	else
++		echo "success"
++	fi
++
++	echo -n "Using ldapwhoami with SASL/GSSAPI with ldaps: "
++	$LDAPSASLWHOAMI -N -Y GSSAPI -H $SURI2 -o tls_reqcert=allow	\
++		-o tls_cacert=$TESTDIR/tls/ca/certs/testsuiteCA.crt	\
++		> $TESTOUT 2>&1
++	RC=$?
++	if test $RC != 0 ; then
++		echo "ldapwhoami failed ($RC)!"
++		kill $KDCPROC
++		test $KILLSERVERS != no && kill -HUP $KILLPIDS
++		exit $RC
++	else
++		echo "success"
++	fi
++fi
++
++kill $KDCPROC
++test $KILLSERVERS != no && kill -HUP $KILLPIDS
++
++if test $RC != 0 ; then
++	echo ">>>>> Test failed"
++else
++	echo ">>>>> Test succeeded"
++	RC=0
++fi
++
++test $KILLSERVERS != no && wait
++
++exit $RC
+-- 
+2.26.2
+
diff --git a/SPECS/openldap.spec b/SPECS/openldap.spec
index 61140f2..937b7a3 100644
--- a/SPECS/openldap.spec
+++ b/SPECS/openldap.spec
@@ -5,7 +5,7 @@
 
 Name: openldap
 Version: 2.4.46
-Release: 11%{?dist}
+Release: 15%{?dist}
 Summary: LDAP support libraries
 License: OpenLDAP
 URL: http://www.openldap.org/
@@ -39,6 +39,24 @@ Patch23: openldap-openssl-ITS7595-Add-EC-support-2.patch
 Patch24: openldap-openssl-manpage-defaultCA.patch
 Patch25: openldap-tlso-use-openssl-api-to-verify-host.patch
 
+# The below patches come from upstream master and are necessary for Channel Binding
+# (both tls-unique and tls-server-end-point) to work properly.
+# Additionally, for Samba to be able to implement Channel Binding, the PEERCERT option
+# is being included as well.
+Patch50: openldap-cbinding-Add-channel-binding-support.patch
+Patch51: openldap-cbinding-ITS-8573-allow-all-libldap-options-in-tools-o-option.patch
+Patch52: openldap-cbinding-ITS-8573-TLS-option-test-suite.patch
+Patch53: openldap-cbinding-ITS-8573-Add-missing-URI-variables-for-tests.patch
+Patch54: openldap-cbinding-auth-add-SASL-GSSAPI-tests.patch
+Patch55: openldap-cbinding-ITS-7398-add-LDAP_OPT_X_TLS_PEERCERT.patch
+Patch56: openldap-cbinding-Make-prototypes-available-where-needed.patch
+Patch57: openldap-cbinding-ITS-9189_1-rework-sasl-cbinding-support.patch
+Patch58: openldap-cbinding-ITS-9189_2-add-channel-bindings-tests.patch
+Patch59: openldap-cbinding-ITS-9189_3-initialize-ldo_sasl_cbinding-in-LDAP_LDO_SA.patch
+Patch60: openldap-cbinding-Fix-slaptest-in-test077.patch
+Patch61: openldap-cbinding-Convert-test077-to-LDIF-config.patch
+Patch62: openldap-cbinding-Update-keys-to-RSA-4096.patch
+
 # check-password module specific patches
 Patch90: check-password-makefile.patch
 Patch91: check-password.patch
@@ -118,6 +136,19 @@ AUTOMAKE=%{_bindir}/true autoreconf -fi
 %patch23 -p1
 %patch24 -p1
 %patch25 -p1
+%patch50 -p1
+%patch51 -p1
+%patch52 -p1
+%patch53 -p1
+%patch54 -p1
+%patch55 -p1
+%patch56 -p1
+%patch57 -p1
+%patch58 -p1
+%patch59 -p1
+%patch60 -p1
+%patch61 -p1
+%patch62 -p1
 
 # build smbk5pwd with other overlays
 ln -s ../../../contrib/slapd-modules/smbk5pwd/smbk5pwd.c servers/slapd/overlays
@@ -487,6 +518,12 @@ exit 0
 %{_mandir}/man3/*
 
 %changelog
+* Thu Jun 18 2020 Matus Honek <mhonek@redhat.com> - 2.4.46-15
+- Fix covscan issues from previous release (#1822737)
+
+* Tue Jun 16 2020 Matus Honek <mhonek@redhat.com> - 2.4.46-14
+- Backport Channel Binding support (#1822904, #1822737)
+
 * Wed Jan 15 2020 Matus Honek <mhonek@redhat.com> - 2.4.46-11
 - Use OpenSSL-1.0.2+ API for host name verification (#1788572)