diff --git a/CHANGES b/CHANGES
index 82c9bdce73e5af2f87534356df6c4d9fa2ab40e0..669bec75b650fb87760c470bb33bbf75bb48c976 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,7 @@
 OpenLDAP 2.4 Change Log
 
 OpenLDAP 2.4.14 Engineering
+	Added libldap option to disable SASL host canonicalization (ITS#5812)
 	Fixed libldap deref handling (ITS#5768)
 	Fixed libldap peer cert memory leak (ITS#5849)
 	Fixed libldap_r deref building (ITS#5768)
diff --git a/clients/tools/common.c b/clients/tools/common.c
index 82ad17403d33bdfedadc0b3c0112df6887323136..b2b06ef553b0bde62015271b482e846cb54ae531 100644
--- a/clients/tools/common.c
+++ b/clients/tools/common.c
@@ -62,6 +62,7 @@ int		contoper = 0;
 int		debug = 0;
 char		*infile = NULL;
 int		dont = 0;
+int		nocanon = 0;
 int		referrals = 0;
 int		verbose = 0;
 int		ldif = 0;
@@ -300,6 +301,7 @@ N_("  -H URI     LDAP Uniform Resource Identifier(s)\n"),
 N_("  -I         use SASL Interactive mode\n"),
 N_("  -M         enable Manage DSA IT control (-MM to make critical)\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_("             nettimeout=<timeout> (in seconds, or \"none\" or \"max\")\n"),
@@ -708,6 +710,9 @@ tool_args( int argc, char **argv )
 		case 'n':	/* print operations, don't actually do them */
 			dont++;
 			break;
+		case 'N':
+			nocanon++;
+			break;
 		case 'o':
 			control = ber_strdup( optarg );
 			if ( (cvalue = strchr( control, '=' )) != NULL ) {
@@ -1258,6 +1263,14 @@ dnssrv_free:;
 			exit( EXIT_FAILURE );
 		}
 
+		/* canon */
+		if( ldap_set_option( ld, LDAP_OPT_X_SASL_NOCANON,
+			nocanon ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
+		{
+			fprintf( stderr, "Could not set LDAP_OPT_X_SASL_NOCANON %s\n",
+				nocanon ? "on" : "off" );
+			exit( EXIT_FAILURE );
+		}
 		if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &protocol )
 			!= LDAP_OPT_SUCCESS )
 		{
diff --git a/clients/tools/ldapcompare.c b/clients/tools/ldapcompare.c
index e0ffbc83d783f6222706e874310c61e985f615e9..a9e6897166295831f2ee5e4445275e7fcb1e9d9f 100644
--- a/clients/tools/ldapcompare.c
+++ b/clients/tools/ldapcompare.c
@@ -102,7 +102,7 @@ static int docompare LDAP_P((
 
 
 const char options[] = "z"
-	"Cd:D:e:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
+	"Cd:D:e:h:H:IMnNO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
 #ifdef LDAP_CONTROL_DONTUSECOPY
 int dontUseCopy = 0;
diff --git a/clients/tools/ldapdelete.c b/clients/tools/ldapdelete.c
index 754d96aae421b732c63a9d9ea62753fadf369992..f271fc3efad852c4c742aeca3f127f7502b4e2a6 100644
--- a/clients/tools/ldapdelete.c
+++ b/clients/tools/ldapdelete.c
@@ -78,7 +78,7 @@ usage( void )
 
 
 const char options[] = "r"
-	"cd:D:e:f:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:z:Z";
+	"cd:D:e:f:h:H:IMnNO:o:p:P:QR:U:vVw:WxX:y:Y:z:Z";
 
 int
 handle_private_option( int i )
diff --git a/clients/tools/ldapexop.c b/clients/tools/ldapexop.c
index 9d77fbab5a0950832efa640740c491cbfd0fb914..ac8f9be5aaf8a2b1247b32631fdd8bf2b84647c6 100644
--- a/clients/tools/ldapexop.c
+++ b/clients/tools/ldapexop.c
@@ -49,7 +49,7 @@ usage( void )
 
 
 const char options[] = ""
-	"d:D:e:h:H:InO:o:p:QR:U:vVw:WxX:y:Y:Z";
+	"d:D:e:h:H:InNO:o:p:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
diff --git a/clients/tools/ldapmodify.c b/clients/tools/ldapmodify.c
index 9fef596368a5adbe7db9c1405651462735dfbb91..1d6f4cbd457886d697b7b3181cb61c99644c1419 100644
--- a/clients/tools/ldapmodify.c
+++ b/clients/tools/ldapmodify.c
@@ -151,7 +151,7 @@ usage( void )
 
 
 const char options[] = "aE:rS:"
-	"cd:D:e:f:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
+	"cd:D:e:f:h:H:IMnNO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
diff --git a/clients/tools/ldapmodrdn.c b/clients/tools/ldapmodrdn.c
index 97f8a918f512be7a9945f4c3dbf74b4f168f5bba..69b902ddf80ccf63c4c2ddf5df18b0494555e8dc 100644
--- a/clients/tools/ldapmodrdn.c
+++ b/clients/tools/ldapmodrdn.c
@@ -91,7 +91,7 @@ usage( void )
 
 
 const char options[] = "rs:"
-	"cd:D:e:f:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
+	"cd:D:e:f:h:H:IMnNO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c
index 728b29201e3302f62d48ed3cf40764146bcf1a84..a989a10dddbba4602ed8c3798dc561420ece4d50 100644
--- a/clients/tools/ldappasswd.c
+++ b/clients/tools/ldappasswd.c
@@ -81,7 +81,7 @@ usage( void )
 
 
 const char options[] = "a:As:St:T:"
-	"d:D:e:h:H:InO:o:p:QR:U:vVw:WxX:y:Y:Z";
+	"d:D:e:h:H:InNO:o:p:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c
index 735fc809387d4cdcd9656d476b3d6ad0d1561336..dc674caf9ff425b585437c6916c2f935e2d02074 100644
--- a/clients/tools/ldapsearch.c
+++ b/clients/tools/ldapsearch.c
@@ -265,7 +265,7 @@ urlize(char *url)
 
 
 const char options[] = "a:Ab:cE:F:l:Ls:S:tT:uz:"
-	"Cd:D:e:f:h:H:IMnO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
+	"Cd:D:e:f:h:H:IMnNO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
diff --git a/clients/tools/ldapwhoami.c b/clients/tools/ldapwhoami.c
index 611626a641f6c085c47a7b7666e0aa7b4a92b03e..a020d4248af72eebd1ef7d101e074b1b4e38d9ba 100644
--- a/clients/tools/ldapwhoami.c
+++ b/clients/tools/ldapwhoami.c
@@ -62,7 +62,7 @@ usage( void )
 
 
 const char options[] = ""
-	"d:D:e:h:H:InO:o:p:QR:U:vVw:WxX:y:Y:Z";
+	"d:D:e:h:H:InNO:o:p:QR:U:vVw:WxX:y:Y:Z";
 
 int
 handle_private_option( int i )
diff --git a/doc/devel/args b/doc/devel/args
index 60de07df78163d6a2da0b093220dc3ad64d4bb9e..271eed951c6f8d0ee4c5f7688ebf7b69b436e0f5 100644
--- a/doc/devel/args
+++ b/doc/devel/args
@@ -1,12 +1,13 @@
 Tools           ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
-ldapcompare      * DE**HI*K M*OPQR  UVWXYZ   de *h**k *nop*    vwxyz
-ldapdelete       *CDE**HI*K M*OPQR  UVWXYZ  cdef*h**k *nop*    vwxyz
-ldapmodify       *CDE**HI*K M*OPQRS UVWXYZabcde *h**k *nop*r t vwxy
-ldapmodrdn       *CDE**HI*K M*OPQR  UVWXYZ  cdef*h**k *nop*rs  vwxy
-ldappasswd      A*CDE**HI*   *O QRS UVWXYZa  def*h**  * o * s  vwxy  
-ldapsearch      A*CDE**HI*KLM*OPQRSTUVWXYZab def*h**kl*nop* stuvwxyz
-ldapurl          *  E**H *   *    S       ab   f*h**  *  p* s
-ldapwhoami       * DE**HI*   *O QR  UVWXYZ   def*h**  *nop*    vwxy 
+ldapcompare      * DE**HI** MNOPQR  UVWXYZ   de *h*** *nop*    vwxyz
+ldapdelete       *CDE**HI** MNOPQR  UVWXYZ  cdef*h*** *nop*    vwxyz
+ldapexop         * D **HI**  NO QR  UVWXYZ   de *h*** *nop     vwxy
+ldapmodify       *CDE**HI** MNOPQRS UVWXYZabcde *h*** *nop*r t vwxy
+ldapmodrdn       *CDE**HI** MNOPQR  UVWXYZ  cdef*h*** *nop*rs  vwxy
+ldappasswd      A*CDE**HI**  NO QRS UVWXYZa  def*h*** * o * s  vwxy  
+ldapsearch      A*CDE**HI**LMNOPQRSTUVWXYZab def*h***l*nop* stuvwxyz
+ldapurl          *  E**H **       S       ab   f*h*** *  p* s
+ldapwhoami       * DE**HI**  NO QR  UVWXYZ   def*h*** *nop*    vwxy 
 
 
 * reserved
@@ -33,6 +34,8 @@ ldapwhoami       * DE**HI*   *O QR  UVWXYZ   def*h**  *nop*    vwxy
 	-x simple bind
 	-y Bind password-file
 	-w Bind password
+
+Not used
 	-4 IPv4 only
 	-6 IPv6 only
 
@@ -51,7 +54,7 @@ ldapwhoami       * DE**HI*   *O QR  UVWXYZ   def*h**  *nop*    vwxy
 	-Q SASL quiet mode (default: automatic)
 
 
-* LDAPv2+ Only (DEPRECATED)
+* LDAPv2+ Only (REMOVED)
 	-K LDAPv2 Kerberos Bind (Step 1 only)
 	-k LDAPv2 Kerberos Bind
 
diff --git a/include/ldap.h b/include/ldap.h
index 460cdcdf1ec60cebdafad82677b8cf53e4be8d83..71df8e67cc670be9260d09d2f084e89ddd4acfa3 100644
--- a/include/ldap.h
+++ b/include/ldap.h
@@ -177,6 +177,7 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_X_SASL_SSF_MAX			0x6108
 #define LDAP_OPT_X_SASL_MAXBUFSIZE		0x6109
 #define LDAP_OPT_X_SASL_MECHLIST		0x610a /* read-only */
+#define LDAP_OPT_X_SASL_NOCANON			0x610b
 
 /* OpenLDAP GSSAPI options */
 #define LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT      0x6200
diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c
index aad8f8ed8843a34ff4e9cadbdc7430c0d8f660d9..a886d7d1c963a9cbc9e379cdbb054f704692d86f 100644
--- a/libraries/libldap/cyrus.c
+++ b/libraries/libldap/cyrus.c
@@ -446,10 +446,21 @@ ldap_int_sasl_bind(
 	}
 
 	{
-		char *saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb,
+		char *saslhost;
+		int nocanon = (int)LDAP_BOOL_GET( &ld->ld_options,
+			LDAP_BOOL_SASL_NOCANON );
+
+		/* If we don't need to canonicalize just use the host
+		 * from the LDAP URI.
+		 */
+		if ( nocanon )
+			saslhost = ld->ld_defconn->lconn_server->lud_host;
+		else 
+			saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb,
 			"localhost" );
 		rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost );
-		LDAP_FREE( saslhost );
+		if ( !nocanon )
+			LDAP_FREE( saslhost );
 	}
 
 	if ( rc != LDAP_SUCCESS ) return rc;
@@ -996,6 +1007,9 @@ ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
 		case LDAP_OPT_X_SASL_MAXBUFSIZE:
 			*(ber_len_t *)arg = ld->ld_options.ldo_sasl_secprops.maxbufsize;
 			break;
+		case LDAP_OPT_X_SASL_NOCANON:
+			*(int *)arg = (int) LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_SASL_NOCANON );
+			break;
 
 		case LDAP_OPT_X_SASL_SECPROPS:
 			/* this option is write only */
@@ -1010,7 +1024,10 @@ ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
 int
 ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
 {
-	if ( ld == NULL || arg == NULL )
+	if ( ld == NULL )
+		return -1;
+
+	if ( arg == NULL && option != LDAP_OPT_X_SASL_NOCANON )
 		return -1;
 
 	switch ( option ) {
@@ -1063,6 +1080,13 @@ ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
 	case LDAP_OPT_X_SASL_MAXBUFSIZE:
 		ld->ld_options.ldo_sasl_secprops.maxbufsize = *(ber_len_t *)arg;
 		break;
+	case LDAP_OPT_X_SASL_NOCANON:
+		if ( arg == LDAP_OPT_OFF ) {
+			LDAP_BOOL_CLR(&ld->ld_options, LDAP_BOOL_SASL_NOCANON );
+		} else {
+			LDAP_BOOL_SET(&ld->ld_options, LDAP_BOOL_SASL_NOCANON );
+		}
+		break;
 
 	case LDAP_OPT_X_SASL_SECPROPS: {
 		int sc;
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index d61ec89fbf9b29fa2dea5d75e9f2734aa90c0b6c..1130cb885e4d4029c6e62cc4bb7a316600e488b7 100644
--- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c
@@ -106,6 +106,7 @@ static const struct ol_attribute {
 	{1, ATTR_STRING,	"SASL_AUTHZID",		NULL,
 		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},
 #endif
 
 #ifdef HAVE_GSSAPI
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index 2900649724c1872d42bab85fcb3d59fa0f88cffa..65320ef6f5905f3cab3e20ed57faab3bbec5fac5 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -121,6 +121,7 @@ LDAP_BEGIN_DECL
 #define LDAP_BOOL_RESTART		1
 #define LDAP_BOOL_TLS			3
 #define	LDAP_BOOL_CONNECT_ASYNC		4
+#define	LDAP_BOOL_SASL_NOCANON		5
 
 #define LDAP_BOOLEANS	unsigned long
 #define LDAP_BOOL(n)	((LDAP_BOOLEANS)1 << (n))