From 2c9d53301286e04a50c50a9f17e6113ca65c7d04 Mon Sep 17 00:00:00 2001
From: Quanah Gibson-Mount <quanah@openldap.org>
Date: Thu, 4 Jun 2009 20:18:10 +0000
Subject: [PATCH] ITS#6056 refint fix

---
 CHANGES                         |  1 +
 servers/slapd/overlays/refint.c | 50 +++++++++++++++------------------
 2 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/CHANGES b/CHANGES
index 55c7144f60..748bf419ca 100644
--- a/CHANGES
+++ b/CHANGES
@@ -29,6 +29,7 @@ OpenLDAP 2.4.17 Engineering
 	Fixed slapd-hdb dncache lockups (ITS#6095)
 	Fixed slapd-relay to return failure on failure (ITS#5328)
 	Fixed slapd-sql with BACKSQL_ARBITRARY_KEY defined (ITS#6100)
+	Fixed slapo-refint refint_repair handling (ITS#6056)
 	Added slapo-rwm rwm-drop-unrequested-attrs config option (ITS#6057)
 	Fixed slapo-rwm dn passing (ITS#6070)
 	Fixed slapo-rwm entry free (ITS#6058)
diff --git a/servers/slapd/overlays/refint.c b/servers/slapd/overlays/refint.c
index 88ada0c496..a9c0e50c5b 100644
--- a/servers/slapd/overlays/refint.c
+++ b/servers/slapd/overlays/refint.c
@@ -547,7 +547,7 @@ refint_repair(
 	refint_data	*id,
 	refint_q	*rq )
 {
-	dependent_data	*dp, *dp_next;
+	dependent_data	*dp;
 	int		rc;
 
 	op->o_callback->sc_response = refint_search_cb;
@@ -586,13 +586,11 @@ refint_repair(
 	 *
 	 */
 
-	for ( dp = rq->attrs; dp; dp = dp_next ) {
+	for ( dp = rq->attrs; dp; dp = dp->next ) {
 		Operation	op2 = *op;
 		SlapReply	rs2 = { 0 };
 		refint_attrs	*ra;
-		Modifications	*m, *first = NULL;
-
-		dp_next = dp->next;
+		Modifications	*m;
 
 		op2.o_tag = LDAP_REQ_MODIFY;
 		op2.orm_modlist = NULL;
@@ -603,21 +601,18 @@ refint_repair(
 			Debug( LDAP_DEBUG_TRACE,
 				"refint_repair: no backend for DN %s!\n",
 				dp->dn.bv_val, 0, 0 );
-			return 0;
+			continue;
 		}
 
 		rs2.sr_type = REP_RESULT;
-		for ( ra = dp->attrs; ra; ra = dp->attrs ) {
+		for ( ra = dp->attrs; ra; ra = ra->next ) {
 			size_t	len;
 
-			dp->attrs = ra->next;
 			/* Set our ModifiersName */
 			if ( SLAP_LASTMOD( op->o_bd ) ) {
 				m = op2.o_tmpalloc( sizeof(Modifications) +
 					4*sizeof(BerValue), op2.o_tmpmemctx );
 				m->sml_next = op2.orm_modlist;
-				if ( !first )
-					first = m;
 				op2.orm_modlist = m;
 				m->sml_op = LDAP_MOD_REPLACE;
 				m->sml_flags = SLAP_MOD_INTERNAL;
@@ -642,8 +637,6 @@ refint_repair(
 
 				m = op2.o_tmpalloc( len, op2.o_tmpmemctx );
 				m->sml_next = op2.orm_modlist;
-				if ( !first )
-					first = m;
 				op2.orm_modlist = m;
 				m->sml_op = LDAP_MOD_ADD;
 				m->sml_flags = 0;
@@ -656,9 +649,6 @@ refint_repair(
 					BER_BVZERO( &m->sml_nvalues[1] );
 					m->sml_numvals = 1;
 					if ( BER_BVISEMPTY( &rq->newdn ) ) {
-						op2.o_tmpfree( ra, op2.o_tmpmemctx );
-						ra = dp->attrs;
-						dp->attrs = ra->next;
 						m->sml_values[0] = id->nothing;
 						m->sml_nvalues[0] = id->nnothing;
 					} else {
@@ -680,8 +670,6 @@ refint_repair(
 			m = op2.o_tmpalloc( len, op2.o_tmpmemctx );
 			m->sml_next = op2.orm_modlist;
 			op2.orm_modlist = m;
-			if ( !first )
-				first = m;
 			m->sml_op = LDAP_MOD_DELETE;
 			m->sml_flags = 0;
 			m->sml_desc = ra->attr;
@@ -699,7 +687,6 @@ refint_repair(
 				m->sml_nvalues = ra->old_nvals;
 				m->sml_numvals = ra->ra_numvals;
 			}
-			op2.o_tmpfree( ra, op2.o_tmpmemctx );
 		}
 
 		op2.o_dn = op2.o_bd->be_rootdn;
@@ -713,17 +700,8 @@ refint_repair(
 
 		while ( ( m = op2.orm_modlist ) ) {
 			op2.orm_modlist = m->sml_next;
-			if ( m->sml_values && m->sml_values != (BerVarray)(m+1) ) {
-				ber_bvarray_free_x( m->sml_values, op2.o_tmpmemctx );
-				ber_bvarray_free_x( m->sml_nvalues, op2.o_tmpmemctx );
-			}
 			op2.o_tmpfree( m, op2.o_tmpmemctx );
-			if ( m == first ) break;
 		}
-		slap_mods_free( op2.orm_modlist, 1 );
-		op2.o_tmpfree( dp->ndn.bv_val, op2.o_tmpmemctx );
-		op2.o_tmpfree( dp->dn.bv_val, op2.o_tmpmemctx );
-		op2.o_tmpfree( dp, op2.o_tmpmemctx );
 	}
 
 	return 0;
@@ -776,6 +754,9 @@ refint_qtask( void *ctx, void *arg )
 	}
 
 	for (;;) {
+		dependent_data	*dp, *dp_next;
+		refint_attrs *ra, *ra_next;
+
 		/* Dequeue an op */
 		ldap_pvt_thread_mutex_lock( &id->qmutex );
 		rq = id->qhead;
@@ -829,6 +810,21 @@ refint_qtask( void *ctx, void *arg )
 			}
 		}
 
+		for ( dp = rq->attrs; dp; dp = dp_next ) {
+			dp_next = dp->next;
+			for ( ra = dp->attrs; ra; ra = ra_next ) {
+				ra_next = ra->next;
+				ber_bvarray_free_x( ra->new_nvals, op->o_tmpmemctx );
+				ber_bvarray_free_x( ra->new_vals, op->o_tmpmemctx );
+				ber_bvarray_free_x( ra->old_nvals, op->o_tmpmemctx );
+				ber_bvarray_free_x( ra->old_vals, op->o_tmpmemctx );
+				op->o_tmpfree( ra, op->o_tmpmemctx );
+			}
+			op->o_tmpfree( dp->ndn.bv_val, op->o_tmpmemctx );
+			op->o_tmpfree( dp->dn.bv_val, op->o_tmpmemctx );
+			op->o_tmpfree( dp, op->o_tmpmemctx );
+		}
+
 		if ( !BER_BVISNULL( &rq->newndn )) {
 			ch_free( rq->newndn.bv_val );
 			ch_free( rq->newdn.bv_val );
-- 
GitLab