From dc23771b05fa34c0354ec2a011eddd8e21b03304 Mon Sep 17 00:00:00 2001
From: Quanah Gibson-Mount <quanah@openldap.org>
Date: Mon, 10 Nov 2008 20:31:59 +0000
Subject: [PATCH] ITS#5772

---
 CHANGES                         |  1 +
 servers/slapd/overlays/rwm.c    |  2 +-
 servers/slapd/overlays/rwm.h    |  2 +-
 servers/slapd/overlays/rwmmap.c | 21 +++++++++++++++------
 4 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/CHANGES b/CHANGES
index 588c0fe049..673776c4c7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -31,6 +31,7 @@ OpenLDAP 2.4.13 Engineering
 	Fixed slapo-ppolicy unaligned BerElement (ITS#5770)
 	Fixed slapo-rwm objectClass preservation (ITS#5760)
 	Fixed slapo-rwm rewriting undefined filter (ITS#5731)
+	Fixed slapo-rwm rewritten DN-valued attrs (ITS#5772)
 	Fixed slapo-rwm reusing freed filter (ITS#5732)
 	Added slapo-translucent try local bind when remote fails (ITS#5656)
 	Added slapo-translucent support for PasswordModify exop (ITS#5656)
diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c
index 1c8e704751..48fbce147c 100644
--- a/servers/slapd/overlays/rwm.c
+++ b/servers/slapd/overlays/rwm.c
@@ -1225,7 +1225,7 @@ remove_oc:;
 				|| ( mapping != NULL && mapping->m_src_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
 		{
 			dc.ctx = "searchAttrDN";
-			rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals );
+			rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals, (*ap)->a_nvals );
 			if ( rc != LDAP_SUCCESS ) {
 				goto cleanup_attr;
 			}
diff --git a/servers/slapd/overlays/rwm.h b/servers/slapd/overlays/rwm.h
index 5a83dd0183..c7b4441035 100644
--- a/servers/slapd/overlays/rwm.h
+++ b/servers/slapd/overlays/rwm.h
@@ -175,7 +175,7 @@ rwm_referral_rewrite(
 	void			*cookie,
 	BerVarray		a_vals,
 	BerVarray		*pa_nvals );
-extern int rwm_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals );
+extern int rwm_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals, BerVarray a_nvals );
 extern int rwm_referral_result_rewrite( dncookie *dc, BerVarray a_vals );
 
 LDAP_END_DECL
diff --git a/servers/slapd/overlays/rwmmap.c b/servers/slapd/overlays/rwmmap.c
index ad03d87eff..8c77dbdad8 100644
--- a/servers/slapd/overlays/rwmmap.c
+++ b/servers/slapd/overlays/rwmmap.c
@@ -1178,7 +1178,8 @@ rwm_referral_result_rewrite(
 int
 rwm_dnattr_result_rewrite(
 	dncookie		*dc,
-	BerVarray		a_vals )
+	BerVarray		a_vals,
+	BerVarray		a_nvals )
 {
 	int		i, last;
 
@@ -1186,11 +1187,11 @@ rwm_dnattr_result_rewrite(
 	last--;
 
 	for ( i = 0; !BER_BVISNULL( &a_vals[i] ); i++ ) {
-		struct berval	dn;
+		struct berval	pdn, ndn;
 		int		rc;
 		
-		dn = a_vals[i];
-		rc = rwm_dn_massage_pretty( dc, &a_vals[i], &dn );
+		pdn = a_vals[i];
+		rc = rwm_dn_massage_pretty_normalize( dc, &a_vals[i], &pdn, &ndn );
 		switch ( rc ) {
 		case LDAP_UNWILLING_TO_PERFORM:
 			/*
@@ -1198,19 +1199,27 @@ rwm_dnattr_result_rewrite(
 			 * legal to trim values when adding/modifying;
 			 * it should be when searching (e.g. ACLs).
 			 */
+			assert( a_vals[i].bv_val != a_nvals[i].bv_val );
 			ch_free( a_vals[i].bv_val );
+			ch_free( a_nvals[i].bv_val );
 			if ( last > i ) {
 				a_vals[i] = a_vals[last];
+				a_nvals[i] = a_nvals[last];
 			}
 			BER_BVZERO( &a_vals[last] );
+			BER_BVZERO( &a_nvals[last] );
 			last--;
 			break;
 
 		default:
 			/* leave attr untouched if massage failed */
-			if ( !BER_BVISNULL( &dn ) && a_vals[i].bv_val != dn.bv_val ) {
+			if ( !BER_BVISNULL( &pdn ) && a_vals[i].bv_val != pdn.bv_val ) {
 				ch_free( a_vals[i].bv_val );
-				a_vals[i] = dn;
+				a_vals[i] = pdn;
+			}
+			if ( !BER_BVISNULL( &ndn ) && a_nvals[i].bv_val != ndn.bv_val ) {
+				ch_free( a_nvals[i].bv_val );
+				a_nvals[i] = ndn;
 			}
 			break;
 		}
-- 
GitLab