diff --git a/servers/slapd/add.c b/servers/slapd/add.c
index 376e931afc5fd5e42e40d8fe5bb808ed96f1a950..208f882e66c9a6b2b02663365ce979ac7ee12b51 100644
--- a/servers/slapd/add.c
+++ b/servers/slapd/add.c
@@ -78,7 +78,7 @@ do_add( Operation *op, SlapReply *rs )
 
 	e = (Entry *) ch_calloc( 1, sizeof(Entry) );
 
-	rs->sr_err = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname, op->o_tmpmemctx );
+	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx );
 
 	if( rs->sr_err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
@@ -91,6 +91,9 @@ do_add( Operation *op, SlapReply *rs )
 		goto done;
 	}
 
+	ber_dupbv( &e->e_name, &op->o_req_dn );
+	ber_dupbv( &e->e_nname, &op->o_req_ndn );
+
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, ARGS, 
 		"do_add: conn %d  dn (%s)\n", op->o_connid, e->e_dn, 0 );
@@ -98,9 +101,6 @@ do_add( Operation *op, SlapReply *rs )
 	Debug( LDAP_DEBUG_ARGS, "do_add: dn (%s)\n", e->e_dn, 0, 0 );
 #endif
 
-	op->o_req_dn = e->e_name;
-	op->o_req_ndn = e->e_nname;
-
 	/* get the attrs */
 	for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
 	    tag = ber_next_element( ber, &len, last ) )
@@ -242,7 +242,7 @@ do_add( Operation *op, SlapReply *rs )
 			size_t textlen = sizeof textbuf;
 
 			rs->sr_err = slap_mods_check( modlist, update, &rs->sr_text,
-				textbuf, textlen, op->o_tmpmemctx );
+				textbuf, textlen, NULL );
 
 			if( rs->sr_err != LDAP_SUCCESS ) {
 				send_ldap_result( op, rs );
@@ -353,6 +353,8 @@ done:
 	if( e != NULL ) {
 		entry_free( e );
 	}
+	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
 
 	return rs->sr_err;
 }
diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c
index eec734a565514569a3ca9db3513d7c561af502ee..badc54723a274b5650d8169765c706a2e66d9ac6 100644
--- a/servers/slapd/back-bdb/cache.c
+++ b/servers/slapd/back-bdb/cache.c
@@ -156,8 +156,13 @@ bdb_cache_entry_db_lock
 	else
 		db_rw = DB_LOCK_READ;
 
+#if 0
 	lockobj.data = e->e_nname.bv_val;
 	lockobj.size = e->e_nname.bv_len;
+#else
+	lockobj.data = &e->e_private;
+	lockobj.size = sizeof(e->e_private);
+#endif
 	rc = LOCK_GET(env, locker, flags | DB_LOCK_NOWAIT,
 					&lockobj, db_rw, lock);
 	if (rc) {
diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c
index 01734bb1837aed6ac22761d41662ada23460ff7c..6076f743a405e0c683b5c1977ada8180b66d39f3 100644
--- a/servers/slapd/back-bdb/modrdn.c
+++ b/servers/slapd/back-bdb/modrdn.c
@@ -647,7 +647,11 @@ retry:	/* transaction retry */
 	/* Build target dn and make sure target entry doesn't exist already. */
 	if (!new_dn.bv_val) build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn ); 
 
-	if (!new_ndn.bv_val) dnNormalize2( NULL, &new_dn, &new_ndn, op->o_tmpmemctx );
+	if (!new_ndn.bv_val) {
+		struct berval bv = {0, NULL};
+		dnNormalize2( NULL, &new_dn, &bv, op->o_tmpmemctx );
+		ber_dupbv( &new_ndn, &bv );
+	}
 
 #ifdef NEW_LOGGING
 	LDAP_LOG ( OPERATION, RESULTS, 
@@ -922,10 +926,10 @@ done:
 
 	/* LDAP v2 supporting correct attribute handling. */
 	if ( new_rdn != NULL ) {
-		ldap_rdnfree( new_rdn );
+		ldap_rdnfree_x( new_rdn, op->o_tmpmemctx );
 	}
 	if ( old_rdn != NULL ) {
-		ldap_rdnfree( old_rdn );
+		ldap_rdnfree_x( old_rdn, op->o_tmpmemctx );
 	}
 	if( mod != NULL ) {
 		Modifications *tmp;
diff --git a/servers/slapd/back-bdb/passwd.c b/servers/slapd/back-bdb/passwd.c
index 2e21acf9d647376ad84eefad767ee658ae12f54b..9631178d4b458c8bdff8d1c8cfbed244f8de3cdf 100644
--- a/servers/slapd/back-bdb/passwd.c
+++ b/servers/slapd/back-bdb/passwd.c
@@ -272,7 +272,7 @@ done:
 	}
 
 	if( ndn.bv_val != NULL ) {
-		free( ndn.bv_val );
+		op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
 	}
 
 	if( ltid != NULL ) {
diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c
index 41db98229b2807fa65a427a021f69057dd3aeeaa..b1410bb07610f6b8ff4f011419a76aa70f7513ea 100644
--- a/servers/slapd/back-ldbm/modrdn.c
+++ b/servers/slapd/back-ldbm/modrdn.c
@@ -466,7 +466,7 @@ ldbm_back_modrdn(
 	
 	/* Build target dn and make sure target entry doesn't exist already. */
 	build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn ); 
-	dnNormalize2( NULL, &new_dn, &new_ndn, op->o_tmpmemctx );
+	dnNormalize2( NULL, &new_dn, &new_ndn, NULL );
 
 #ifdef NEW_LOGGING
 	LDAP_LOG( BACK_LDBM, DETAIL1, "ldbm_back_modrdn: new ndn=%s\n", 
diff --git a/servers/slapd/back-ldbm/passwd.c b/servers/slapd/back-ldbm/passwd.c
index 74191f19a94258be6a4351b083f2cb27ad9fffac..ace00ba53c80a218cfe90ae309a276240c68a248 100644
--- a/servers/slapd/back-ldbm/passwd.c
+++ b/servers/slapd/back-ldbm/passwd.c
@@ -176,7 +176,7 @@ done:
 	}
 
 	if( ndn.bv_val != NULL ) {
-		free( ndn.bv_val );
+		op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
 	}
 
 	return rc;
diff --git a/servers/slapd/compare.c b/servers/slapd/compare.c
index 92d0a45350efa7414485d5bf83771387a9cd65cb..d999b7c20ff5342e7e3e3c22d420104d212eaf37 100644
--- a/servers/slapd/compare.c
+++ b/servers/slapd/compare.c
@@ -299,9 +299,9 @@ do_compare(
 #endif /* defined( LDAP_SLAPI ) */
 
 cleanup:
-	free( op->o_req_dn.bv_val );
-	free( op->o_req_ndn.bv_val );
-	if ( ava.aa_value.bv_val ) free( ava.aa_value.bv_val );
+	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+	if ( ava.aa_value.bv_val ) op->o_tmpfree( ava.aa_value.bv_val, op->o_tmpmemctx );
 
 	return rs->sr_err;
 }
diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
index 343a4f3bb2ed964f5ac4f54d9a5b18e71a9cc7e9..436a76c5d2cb33948a84b3fceb1107b70aa20d9a 100644
--- a/servers/slapd/connection.c
+++ b/servers/slapd/connection.c
@@ -912,21 +912,21 @@ connection_operation( void *ctx, void *arg_v )
 		goto operations_error;
 	}
 
-	/* For all operations besides Add, we can use thread-local
-	 * storage for most mallocs.
+	/* We can use Thread-Local storage for most mallocs. We can
+	 * also use TL for ber parsing, but not on Add or Modify.
 	 */
 #define	SLAB_SIZE	1048576
-	memsiz = ber_len( op->o_ber ) * 32;
+#if 0
+	memsiz = ber_len( op->o_ber ) * 64;
 	if ( SLAB_SIZE > memsiz ) memsiz = SLAB_SIZE;
+#endif
+	memsiz = SLAB_SIZE;
 
-	if ( tag == LDAP_REQ_SEARCH || tag == LDAP_REQ_BIND ) {
-		memctx = sl_mem_create( memsiz, ctx );
+	memctx = sl_mem_create( memsiz, ctx );
+	op->o_tmpmemctx = memctx;
+	op->o_tmpmfuncs = &sl_mfuncs;
+	if ( tag != LDAP_REQ_ADD && tag != LDAP_REQ_MODIFY ) {
 		ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, memctx );
-		op->o_tmpmemctx = memctx;
-		op->o_tmpmfuncs = &sl_mfuncs;
-	} else {
-		op->o_tmpmemctx = NULL;
-		op->o_tmpmfuncs = &ch_mfuncs;
 	}
 
 	switch ( tag ) {
diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c
index 64b32f8dbe9c6e2ee84b4fac2cfb477fc07a7bb3..2858abdc17aa508e7e64e83a085e229441be3c7f 100644
--- a/servers/slapd/delete.c
+++ b/servers/slapd/delete.c
@@ -228,7 +228,7 @@ do_delete(
 #endif /* defined( LDAP_SLAPI ) */
 
 cleanup:
-	free( op->o_req_dn.bv_val );
-	free( op->o_req_ndn.bv_val );
+	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
 	return rs->sr_err;
 }
diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c
index c00bb762d5e7c3ed996378b3e409befd90f97609..40529e4a81164a17457a120cc135aaf08dea9ae1 100644
--- a/servers/slapd/modify.c
+++ b/servers/slapd/modify.c
@@ -394,7 +394,7 @@ do_modify(
 			size_t textlen = sizeof textbuf;
 
 			rs->sr_err = slap_mods_check( modlist, update, &rs->sr_text,
-				textbuf, textlen, op->o_tmpmemctx );
+				textbuf, textlen, NULL );
 
 			if( rs->sr_err != LDAP_SUCCESS ) {
 				send_ldap_result( op, rs );
@@ -459,8 +459,8 @@ do_modify(
 #endif /* defined( LDAP_SLAPI ) */
 
 cleanup:
-	free( op->o_req_dn.bv_val );
-	free( op->o_req_ndn.bv_val );
+	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
 	if ( modlist != NULL ) slap_mods_free( modlist );
 #if defined( LDAP_SLAPI )
 	if ( modv != NULL ) slapi_x_free_ldapmods( modv );
diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c
index 49d6a3842a8c817ff9ab414119e39a8b99275caf..8c5566375e88924581c1f8189e4aa0c8ad5ca486 100644
--- a/servers/slapd/modrdn.c
+++ b/servers/slapd/modrdn.c
@@ -390,14 +390,14 @@ do_modrdn(
 #endif /* defined( LDAP_SLAPI ) */
 
 cleanup:
-	free( op->o_req_dn.bv_val );
-	free( op->o_req_ndn.bv_val );
+	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
 
-	free( op->orr_newrdn.bv_val );	
-	free( op->orr_nnewrdn.bv_val );	
+	op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );	
+	op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );	
 
-	if ( pnewSuperior.bv_val ) free( pnewSuperior.bv_val );
-	if ( nnewSuperior.bv_val ) free( nnewSuperior.bv_val );
+	if ( pnewSuperior.bv_val ) op->o_tmpfree( pnewSuperior.bv_val, op->o_tmpmemctx );
+	if ( nnewSuperior.bv_val ) op->o_tmpfree( nnewSuperior.bv_val, op->o_tmpmemctx );
 
 	return rs->sr_err;
 }
diff --git a/servers/slapd/result.c b/servers/slapd/result.c
index 5e9503ad613e31e4e2071d0bf21ea06c671fde3f..14791ce7c3359f3b6d799754725f0f54664b550e 100644
--- a/servers/slapd/result.c
+++ b/servers/slapd/result.c
@@ -238,7 +238,10 @@ send_ldap_response(
 		ber = op->o_res_ber;
 	else
 #endif
-	ber_init_w_nullc( ber, LBER_USE_DER );
+	{
+		ber_init_w_nullc( ber, LBER_USE_DER );
+		ber_set_option( ber, LBER_OPT_BER_MEMCTX, op->o_tmpmemctx );
+	}
 
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, ENTRY, 
@@ -1189,8 +1192,9 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 {
 	char berbuf[LBER_ELEMENT_SIZEOF];
 	BerElement	*ber = (BerElement *)berbuf;
-	int rc;
+	int rc = 0;
 	int bytes;
+	void *mark;
 
 	AttributeDescription *ad_ref = slap_schema.si_ad_ref;
 	AttributeDescription *ad_entry = slap_schema.si_ad_entry;
@@ -1200,6 +1204,8 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 		return op->o_callback->sc_response( op, rs );
 	}
 
+	mark = sl_mark( op->o_tmpmemctx );
+
 #ifdef NEW_LOGGING
 	LDAP_LOG( OPERATION, ENTRY, 
 		"send_search_reference: conn %lu  dn=\"%s\"\n", 
@@ -1223,8 +1229,8 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 			"send_search_reference: access to entry not allowed\n",
 		    0, 0, 0 );
 #endif
-
-		return( 1 );
+		rc = 1;
+		goto rel;
 	}
 
 	if ( rs->sr_entry && ! access_allowed( op, rs->sr_entry,
@@ -1240,8 +1246,8 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 			"to reference not allowed\n",
 		    0, 0, 0 );
 #endif
-
-		return( 1 );
+		rc = 1;
+		goto rel;
 	}
 
 #ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
@@ -1255,8 +1261,8 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 			"send_search_reference: domainScope control in (%s)\n", 
 			rs->sr_entry->e_dn, 0, 0 );
 #endif
-
-		return( 0 );
+		rc = 0;
+		goto rel;
 	}
 #endif
 
@@ -1270,8 +1276,8 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 			"send_search_reference: null ref in (%s)\n", 
 			rs->sr_entry ? rs->sr_entry->e_dn : "(null)", 0, 0 );
 #endif
-
-		return( 1 );
+		rc = 1;
+		goto rel;
 	}
 
 	if( op->o_protocol < LDAP_VERSION3 ) {
@@ -1280,7 +1286,8 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 			if( value_add( &rs->sr_v2ref, rs->sr_ref ) )
 				return LDAP_OTHER;
 		}
-		return 0;
+		rc = 0;
+		goto rel;
 	}
 
 #ifdef LDAP_CONNECTIONLESS
@@ -1288,7 +1295,10 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 		ber = op->o_res_ber;
 	else
 #endif
-	ber_init_w_nullc( ber, LBER_USE_DER );
+	{
+		ber_init_w_nullc( ber, LBER_USE_DER );
+		ber_set_option( ber, LBER_OPT_BER_MEMCTX, op->o_tmpmemctx );
+	}
 
 	rc = ber_printf( ber, "{it{W}" /*"}"*/ , op->o_msgid,
 		LDAP_RES_SEARCH_REFERENCE, rs->sr_ref );
@@ -1316,7 +1326,7 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 #endif
 		ber_free_buf( ber );
 		send_ldap_error( op, rs, LDAP_OTHER, "encode DN error" );
-		return -1;
+		goto rel;
 	}
 
 #ifdef LDAP_CONNECTIONLESS
@@ -1344,7 +1354,9 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 	Debug( LDAP_DEBUG_TRACE, "<= send_search_reference\n", 0, 0, 0 );
 #endif
 
-	return 0;
+rel:
+	sl_release( mark, op->o_tmpmemctx );
+	return rc;
 }
 
 int
diff --git a/servers/slapd/value.c b/servers/slapd/value.c
index f7cd45c014ecfa9806899498f2d22b19d4380222..3da4bc511f40110db4272b94cc2e17742293404c 100644
--- a/servers/slapd/value.c
+++ b/servers/slapd/value.c
@@ -235,6 +235,7 @@ int value_find_ex(
 		}
 	}
 
+	rc = LDAP_NO_SUCH_ATTRIBUTE;
 	for ( i = 0; vals[i].bv_val != NULL; i++ ) {
 		int match;
 		const char *text;
@@ -243,11 +244,10 @@ int value_find_ex(
 			&vals[i], nval.bv_val == NULL ? val : &nval, &text );
 
 		if( rc == LDAP_SUCCESS && match == 0 ) {
-			free( nval.bv_val );
-			return LDAP_SUCCESS;
+			break;
 		}
 	}
 
-	ber_memfree_x( nval.bv_val, ctx );
-	return LDAP_NO_SUCH_ATTRIBUTE;
+	sl_free( nval.bv_val, ctx );
+	return rc;
 }