Provide a runtime configuration directive to allow selection of hostname
canonicalization for SASL connections.

Author: Joel Johnson
Version: 0.5.0

diff -ru ./clients/tools/common.c ../openldap-2.4.8.new/clients/tools/common.c
--- ./clients/tools/common.c	2008-02-11 23:26:38.000000000 +0000
+++ ../openldap-2.4.8.new/clients/tools/common.c	2008-03-07 03:46:44.000000000 +0000
@@ -88,6 +88,7 @@
 char		*sasl_authz_id = NULL;
 char		*sasl_mech = NULL;
 char		*sasl_secprops = NULL;
+int		sasl_canonicalize = 1;
 #endif
 
 /* controls */
@@ -275,6 +276,7 @@
 N_("  -h host    LDAP server\n"),
 N_("  -H URI     LDAP Uniform Resource Identifier(s)\n"),
 N_("  -I         use SASL Interactive mode\n"),
+N_("  -j         don't use reverse DNS for canonicalization\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_("  -O props   SASL security properties\n"),
@@ -678,6 +680,10 @@
 				prog );
 			exit( EXIT_FAILURE );
 #endif
+		case 'j':
+			/* Disable using reverse DNS for hostname canonicalizaion */
+			sasl_canonicalize = 0;
+			break;
 		case 'M':
 			/* enable Manage DSA IT */
 			manageDSAit++;
@@ -1326,6 +1332,14 @@
 			}
 		}
 
+		if( ldap_set_option( ld, LDAP_OPT_X_SASL_CANONICALIZE,
+			sasl_canonicalize ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
+		{
+			fprintf( stderr, "Could not set LDAP_OPT_X_SASL_CANONICALIZE %s\n",
+				sasl_canonicalize ? "on" : "off" );
+			exit( EXIT_FAILURE );
+		}
+
 		defaults = lutil_sasl_defaults( ld,
 			sasl_mech,
 			sasl_realm,
diff -ru ./clients/tools/common.h ../openldap-2.4.8.new/clients/tools/common.h
--- ./clients/tools/common.h	2008-02-11 23:26:38.000000000 +0000
+++ ../openldap-2.4.8.new/clients/tools/common.h	2008-03-07 02:50:17.000000000 +0000
@@ -78,6 +78,7 @@
 extern char		*sasl_authz_id;
 extern char		*sasl_mech;
 extern char		*sasl_secprops;
+extern int		sasl_canonicalize;
 #endif
 
 /* controls */
diff -ru ./doc/man/man1/ldapcompare.1 ../openldap-2.4.8.new/doc/man/man1/ldapcompare.1
--- ./doc/man/man1/ldapcompare.1	2008-02-11 23:26:39.000000000 +0000
+++ ../openldap-2.4.8.new/doc/man/man1/ldapcompare.1	2008-03-07 03:29:59.000000000 +0000
@@ -39,6 +39,8 @@
 [\c
 .BR \-Q ]
 [\c
+.BR \-j ]
+[\c
 .BI \-U \ authcid\fR]
 [\c
 .BI \-R \ realm\fR]
@@ -147,6 +149,9 @@
 .B \-Q
 Enable SASL Quiet mode.  Never prompt.
 .TP
+.B \-j
+Disable SASL using reverse DNS for hostname canonicalization.
+.TP
 .BI \-U \ authcid
 Specify the authentication ID for SASL bind. The form of the ID
 depends on the actual SASL mechanism used.
diff -ru ./doc/man/man1/ldapdelete.1 ../openldap-2.4.8.new/doc/man/man1/ldapdelete.1
--- ./doc/man/man1/ldapdelete.1	2008-02-11 23:26:39.000000000 +0000
+++ ../openldap-2.4.8.new/doc/man/man1/ldapdelete.1	2008-03-07 03:30:22.000000000 +0000
@@ -49,6 +49,8 @@
 [\c
 .BR \-Q ]
 [\c
+.BR \-j ]
+[\c
 .BI \-X \ authzid\fR]
 [\c
 .BI \-Y \ mech\fR]
@@ -155,6 +157,9 @@
 .B \-Q
 Enable SASL Quiet mode.  Never prompt.
 .TP
+.B \-j
+Disable SASL using reverse DNS for hostname canonicalization.
+.TP
 .BI \-U \ authcid
 Specify the authentication ID for SASL bind. The form of the identity depends on the
 actual SASL mechanism used.
diff -ru ./doc/man/man1/ldapmodify.1 ../openldap-2.4.8.new/doc/man/man1/ldapmodify.1
--- ./doc/man/man1/ldapmodify.1	2008-02-11 23:26:39.000000000 +0000
+++ ../openldap-2.4.8.new/doc/man/man1/ldapmodify.1	2008-03-07 03:31:25.000000000 +0000
@@ -43,6 +43,8 @@
 [\c
 .BR \-Q ]
 [\c
+.BR \-j ]
+[\c
 .BI \-U \ authcid\fR]
 [\c
 .BI \-R \ realm\fR]
@@ -93,6 +95,8 @@
 [\c
 .BR \-Q ]
 [\c
+.BR \-j ]
+[\c
 .BI \-U \ authcid\fR]
 [\c
 .BI \-R \ realm\fR]
@@ -208,6 +212,9 @@
 .B \-Q
 Enable SASL Quiet mode.  Never prompt.
 .TP
+.B \-j
+Disable SASL using reverse DNS for hostname canonicalization.
+.TP
 .BI \-U \ authcid
 Specify the authentication ID for SASL bind. The form of the ID
 depends on the actual SASL mechanism used.
diff -ru ./doc/man/man1/ldapmodrdn.1 ../openldap-2.4.8.new/doc/man/man1/ldapmodrdn.1
--- ./doc/man/man1/ldapmodrdn.1	2008-02-11 23:26:39.000000000 +0000
+++ ../openldap-2.4.8.new/doc/man/man1/ldapmodrdn.1	2008-03-07 03:31:45.000000000 +0000
@@ -43,6 +43,8 @@
 [\c
 .BR \-Q ]
 [\c
+.BR \-j ]
+[\c
 .BI \-U \ authcid\fR]
 [\c
 .BI \-R \ realm\fR]
@@ -150,6 +152,9 @@
 .B \-Q
 Enable SASL Quiet mode.  Never prompt.
 .TP
+.B \-j
+Disable SASL using reverse DNS for hostname canonicalization.
+.TP
 .BI \-U \ authcid
 Specify the authentication ID for SASL bind. The form of the ID
 depends on the actual SASL mechanism used.
diff -ru ./doc/man/man1/ldappasswd.1 ../openldap-2.4.8.new/doc/man/man1/ldappasswd.1
--- ./doc/man/man1/ldappasswd.1	2008-02-11 23:26:39.000000000 +0000
+++ ../openldap-2.4.8.new/doc/man/man1/ldappasswd.1	2008-03-07 03:32:07.000000000 +0000
@@ -45,6 +45,8 @@
 [\c
 .BR \-Q ]
 [\c
+.BR \-j ]
+[\c
 .BI \-U \ authcid\fR]
 [\c
 .BI \-R \ realm\fR]
@@ -152,6 +154,9 @@
 .B \-Q
 Enable SASL Quiet mode.  Never prompt.
 .TP
+.B \-j
+Disable SASL using reverse DNS for hostname canonicalization.
+.TP
 .BI \-U \ authcid
 Specify the authentication ID for SASL bind. The form of the ID
 depends on the actual SASL mechanism used.
diff -ru ./doc/man/man1/ldapsearch.1 ../openldap-2.4.8.new/doc/man/man1/ldapsearch.1
--- ./doc/man/man1/ldapsearch.1	2008-02-11 23:26:39.000000000 +0000
+++ ../openldap-2.4.8.new/doc/man/man1/ldapsearch.1	2008-03-07 03:29:27.000000000 +0000
@@ -71,6 +71,8 @@
 [\c
 .BR \-Q ]
 [\c
+.BR \-j ]
+[\c
 .BI \-U \ authcid\fR]
 [\c
 .BI \-R \ realm\fR]
@@ -315,6 +317,9 @@
 .B \-Q
 Enable SASL Quiet mode.  Never prompt.
 .TP
+.B \-j
+Disable SASL using reverse DNS for hostname canonicalization.
+.TP
 .BI \-U \ authcid
 Specify the authentication ID for SASL bind. The form of the ID
 depends on the actual SASL mechanism used.
diff -ru ./doc/man/man1/ldapwhoami.1 ../openldap-2.4.8.new/doc/man/man1/ldapwhoami.1
--- ./doc/man/man1/ldapwhoami.1	2008-02-11 23:26:39.000000000 +0000
+++ ../openldap-2.4.8.new/doc/man/man1/ldapwhoami.1	2008-03-07 03:32:33.000000000 +0000
@@ -35,6 +35,8 @@
 [\c
 .BR \-Q ]
 [\c
+.BR \-j ]
+[\c
 .BI \-U \ authcid\fR]
 [\c
 .BI \-R \ realm\fR]
@@ -111,6 +113,9 @@
 .B \-Q
 Enable SASL Quiet mode.  Never prompt.
 .TP
+.B \-j
+Disable SASL using reverse DNS for hostname canonicalization.
+.TP
 .BI \-U \ authcid
 Specify the authentication ID for SASL bind. The form of the ID
 depends on the actual SASL mechanism used.
diff -ru ./doc/man/man5/ldap.conf.5 ../openldap-2.4.8.new/doc/man/man5/ldap.conf.5
--- ./doc/man/man5/ldap.conf.5	2008-02-11 23:26:39.000000000 +0000
+++ ../openldap-2.4.8.new/doc/man/man5/ldap.conf.5	2008-03-07 02:41:11.000000000 +0000
@@ -211,6 +211,10 @@
 Specifies the proxy authorization identity.
 .B This is a user\-only option.
 .TP
+.B SASL_CANONICALIZE <on/true/yes/off/false/no>
+Specifies whether to use a reverse DNS lookup to determine the canonical
+name for the host.  The default is enabled.
+.TP
 .B SASL_SECPROPS <properties>
 Specifies Cyrus SASL security properties. The 
 .B <properties>
diff -ru ./include/ldap.h ../openldap-2.4.8.new/include/ldap.h
--- ./include/ldap.h	2008-02-11 23:26:40.000000000 +0000
+++ ../openldap-2.4.8.new/include/ldap.h	2008-03-04 01:43:07.000000000 +0000
@@ -164,6 +164,7 @@
 #define LDAP_OPT_X_SASL_SSF_MIN			0x6107
 #define LDAP_OPT_X_SASL_SSF_MAX			0x6108
 #define	LDAP_OPT_X_SASL_MAXBUFSIZE		0x6109
+#define	LDAP_OPT_X_SASL_CANONICALIZE		0x610a
 
 /* Private API Extensions -- reserved for application use */
 #define LDAP_OPT_PRIVATE_EXTENSION_BASE 0x7000  /* Private API inclusive */
diff -ru ./libraries/libldap/cyrus.c ../openldap-2.4.8.new/libraries/libldap/cyrus.c
--- ./libraries/libldap/cyrus.c	2008-02-11 23:26:41.000000000 +0000
+++ ../openldap-2.4.8.new/libraries/libldap/cyrus.c	2008-03-07 04:29:58.000000000 +0000
@@ -638,11 +638,19 @@
 		ld->ld_defconn->lconn_sasl_authctx = NULL;
 	}
 
+	if ( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_SASL_CANONICALIZE) )
 	{
 		char *saslhost = ldap_host_connected_to( ld->ld_defconn->lconn_sb,
 			"localhost" );
 		rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost );
 		LDAP_FREE( saslhost );
+	} else {
+		/* TODO: track the actual host connected to, not just the default... */
+/*		char *saslhost = ld->ld_options.ldo_defludp->lud_host;
+		char *saslhost = ld->ld_defconn->lconn_server->lud_host;
+*/
+		rc = ldap_int_sasl_open( ld, ld->ld_defconn,
+			ld->ld_defconn->lconn_server->lud_host );
 	}
 
 	if ( rc != LDAP_SUCCESS ) return rc;
@@ -1144,6 +1152,10 @@
 				? LDAP_STRDUP( ld->ld_options.ldo_def_sasl_authzid ) : NULL;
 		} break;
 
+		case LDAP_OPT_X_SASL_CANONICALIZE: {
+			* (int *)arg = (int) LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_SASL_CANONICALIZE);
+		} break;
+
 		case LDAP_OPT_X_SASL_SSF: {
 			int sc;
 			sasl_ssf_t	*ssf;
@@ -1250,6 +1262,15 @@
 		ld->ld_options.ldo_sasl_secprops.maxbufsize = *(ber_len_t *)arg;
 		break;
 
+	case LDAP_OPT_X_SASL_CANONICALIZE:
+		if(arg == LDAP_OPT_OFF) {
+			LDAP_BOOL_CLR(&ld->ld_options, LDAP_BOOL_SASL_CANONICALIZE);
+		} else {
+			LDAP_BOOL_SET(&ld->ld_options, LDAP_BOOL_SASL_CANONICALIZE);
+		}
+	                return LDAP_OPT_SUCCESS;
+		break;
+
 	case LDAP_OPT_X_SASL_SECPROPS: {
 		int sc;
 		sc = ldap_pvt_sasl_secprops( (char *) arg,
diff -ru ./libraries/libldap/init.c ../openldap-2.4.8.new/libraries/libldap/init.c
--- ./libraries/libldap/init.c	2008-02-11 23:26:41.000000000 +0000
+++ ../openldap-2.4.8.new/libraries/libldap/init.c	2008-03-04 03:39:12.000000000 +0000
@@ -100,6 +100,7 @@
 	{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_CANONICALIZE",	NULL,	LDAP_BOOL_SASL_CANONICALIZE},
 #endif
 
 #ifdef HAVE_TLS
@@ -511,6 +512,7 @@
 	gopts->ldo_def_sasl_realm = NULL;
 	gopts->ldo_def_sasl_authcid = NULL;
 	gopts->ldo_def_sasl_authzid = NULL;
+	LDAP_BOOL_SET(gopts, LDAP_BOOL_SASL_CANONICALIZE);
 
 	memset( &gopts->ldo_sasl_secprops,
 		'\0', sizeof(gopts->ldo_sasl_secprops) );
diff -ru ./libraries/libldap/ldap-int.h ../openldap-2.4.8.new/libraries/libldap/ldap-int.h
--- ./libraries/libldap/ldap-int.h	2008-02-11 23:26:41.000000000 +0000
+++ ../openldap-2.4.8.new/libraries/libldap/ldap-int.h	2008-03-04 03:09:13.000000000 +0000
@@ -121,6 +121,7 @@
 #define LDAP_BOOL_RESTART		1
 #define LDAP_BOOL_TLS			3
 #define	LDAP_BOOL_CONNECT_ASYNC		4
+#define LDAP_BOOL_SASL_CANONICALIZE	5
 
 #define LDAP_BOOLEANS	unsigned long
 #define LDAP_BOOL(n)	((LDAP_BOOLEANS)1 << (n))
