diff --git a/CHANGES b/CHANGES
index f532c4e887a11953bd0c41096c4f47cbe93a4020..e29cc9251eff6c4976bc033e0275f52791f054de 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,7 @@ OpenLDAP 2.4 Change Log
 OpenLDAP 2.4.13 Engineering
 	Fixed liblutil hex conversion (ITS#5699)
 	Fixed slapd database open with real structure (ITS#5724)
+	Fixed slapd rewriting undefined filter (ITS#5731)
 	Added slapd GSSAPI refactoring (ITS#5369)
 	Added slapd support for certificateListExactMatch from RFC4523 (ITS#5700)
 	Fixed slapd-bdb/hdb invalid db crash (ITS#5698)
@@ -10,6 +11,7 @@ OpenLDAP 2.4.13 Engineering
 	Added slapo-constraint support for constraining rename (ITS#5703)
 	Added slapo-constraint support for relax control (ITS#5705)
 	Added slapo-constraint "set" type (ITS#5702)
+	Fixed slapo-rwm reusing freed filter (ITS#5732)
 	Added slapo-translucent try local bind when remote fails (ITS#5656)
 	Added slapo-translucent support for RFC3062 password mod extended op (ITS#5656)
 
diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c
index 5913ea9907e0456ce8ea4f5453011284d6ba4537..dcb0844aa35319593d498bae9373f66324fc3d81 100644
--- a/servers/slapd/acl.c
+++ b/servers/slapd/acl.c
@@ -2211,7 +2211,7 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de
 
 url_done:;
 	if ( op2.ors_filter && op2.ors_filter != slap_filter_objectClass_pres ) {
-		filter_free_x( cp->asc_op, op2.ors_filter );
+		filter_free_x( cp->asc_op, op2.ors_filter, 1 );
 	}
 	if ( !BER_BVISNULL( &op2.o_req_ndn ) ) {
 		slap_sl_free( op2.o_req_ndn.bv_val, cp->asc_op->o_tmpmemctx );
diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c
index 3fd6cf978d31959ca6ed616cf4310736ef472bd2..fe2280f666ec86d3d11f51d5eac05c13411fd34b 100644
--- a/servers/slapd/back-monitor/init.c
+++ b/servers/slapd/back-monitor/init.c
@@ -868,7 +868,7 @@ monitor_search2ndn(
 
 cleanup:;
 	if ( op->ors_filter != NULL ) {
-		filter_free_x( op, op->ors_filter );
+		filter_free_x( op, op->ors_filter, 1 );
 	}
 	if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
 		op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index 78c655cc64cb8e3fdcdb7c06a48a0b112ac3dd3a..db3f299b61f475af52fd8e7e200ee9cd83097690 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -1496,7 +1496,7 @@ fe_acl_group(
 						{
 							rc = 0;
 						}
-						filter_free_x( op, filter );
+						filter_free_x( op, filter, 1 );
 					}
 loopit:
 					ldap_free_urldesc( ludp );
diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c
index 042fccca8f080fabb569356d14c6a37ff3e59bc8..bb4ca528afd8f68f371926fb8909efbf20be9d43 100644
--- a/servers/slapd/controls.c
+++ b/servers/slapd/controls.c
@@ -1205,7 +1205,7 @@ static int parseAssert (
 			send_ldap_result( op, rs );
 		}
 		if( op->o_assertion != NULL ) {
-			filter_free_x( op, op->o_assertion );
+			filter_free_x( op, op->o_assertion, 1 );
 		}
 		return rs->sr_err;
 	}
diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c
index 0a76e2bdd617ad181957297858a88747d6e15c50..bf855f573470b0994357c52840bb880e11ab1093 100644
--- a/servers/slapd/filter.c
+++ b/servers/slapd/filter.c
@@ -492,7 +492,7 @@ return_error:
 }
 
 void
-filter_free_x( Operation *op, Filter *f )
+filter_free_x( Operation *op, Filter *f, int freeme )
 {
 	Filter	*p, *next;
 
@@ -531,7 +531,7 @@ filter_free_x( Operation *op, Filter *f )
 	case LDAP_FILTER_NOT:
 		for ( p = f->f_list; p != NULL; p = next ) {
 			next = p->f_next;
-			filter_free_x( op, p );
+			filter_free_x( op, p, 1 );
 		}
 		break;
 
@@ -548,7 +548,9 @@ filter_free_x( Operation *op, Filter *f )
 		break;
 	}
 
-	op->o_tmpfree( f, op->o_tmpmemctx );
+	if ( freeme ) {
+		op->o_tmpfree( f, op->o_tmpmemctx );
+	}
 }
 
 void
@@ -560,7 +562,7 @@ filter_free( Filter *f )
 	op.o_hdr = &ohdr;
 	op.o_tmpmemctx = slap_sl_context( f );
 	op.o_tmpmfuncs = &slap_sl_mfuncs;
-	filter_free_x( &op, f );
+	filter_free_x( &op, f, 1 );
 }
 
 void
diff --git a/servers/slapd/overlays/dds.c b/servers/slapd/overlays/dds.c
index d235327a2a283d3f84c6b88bd1cc117abca8350e..8230c1bbe5ec65ea7d48b655d95db6e7c9db6512 100644
--- a/servers/slapd/overlays/dds.c
+++ b/servers/slapd/overlays/dds.c
@@ -185,7 +185,7 @@ dds_expire( void *ctx, dds_info_t *di )
 
 done_search:;
 	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
-	filter_free_x( op, op->ors_filter );
+	filter_free_x( op, op->ors_filter, 1 );
 
 	rc = rs.sr_err;
 	switch ( rs.sr_err ) {
@@ -1671,7 +1671,7 @@ dds_count( void *ctx, BackendDB *be )
 
 done_search:;
 	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
-	filter_free_x( op, op->ors_filter );
+	filter_free_x( op, op->ors_filter, 1 );
 
 	rc = rs.sr_err;
 	switch ( rs.sr_err ) {
diff --git a/servers/slapd/overlays/dynlist.c b/servers/slapd/overlays/dynlist.c
index 71c0eb0b3a3666393b142c0ddf6ad4723e8de532..5a5eb09f391ff549f2bf6978ef46c34d48ff7a3d 100644
--- a/servers/slapd/overlays/dynlist.c
+++ b/servers/slapd/overlays/dynlist.c
@@ -579,7 +579,7 @@ cleanup:;
 			slap_op_groups_free( &o );
 		}
 		if ( o.ors_filter ) {
-			filter_free_x( &o, o.ors_filter );
+			filter_free_x( &o, o.ors_filter, 1 );
 		}
 		if ( o.ors_attrs && o.ors_attrs != rs->sr_attrs
 				&& o.ors_attrs != slap_anlist_no_attrs )
diff --git a/servers/slapd/overlays/retcode.c b/servers/slapd/overlays/retcode.c
index f100ca5022e5cb6bfc72545bb7ee9be9f2191c3e..6325b47b826a64deaab8fcd8167dc9c7164f05b2 100644
--- a/servers/slapd/overlays/retcode.c
+++ b/servers/slapd/overlays/retcode.c
@@ -273,7 +273,7 @@ retcode_op_internal( Operation *op, SlapReply *rs )
 	rc = op2.o_bd->be_search( &op2, rs );
 	op->o_abandon = op2.o_abandon;
 
-	filter_free_x( &op2, op2.ors_filter );
+	filter_free_x( &op2, op2.ors_filter, 1 );
 	ber_memfree_x( op2.ors_filterstr.bv_val, op2.o_tmpmemctx );
 
 	if ( rdc.rdc_flags == SLAP_CB_CONTINUE ) {
diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c
index 8236a6516e19912abade4938fc5917c075309d47..f9301ccf9fc846ccacb3a303745e230098d9ca98 100644
--- a/servers/slapd/overlays/rwm.c
+++ b/servers/slapd/overlays/rwm.c
@@ -96,7 +96,7 @@ rwm_op_rollback( Operation *op, SlapReply *rs, rwm_op_state *ros )
 		break;
 	case LDAP_REQ_SEARCH:
 		ch_free( ros->mapped_attrs );
-		filter_free_x( op, op->ors_filter );
+		filter_free_x( op, op->ors_filter, 1 );
 		ch_free( op->ors_filterstr.bv_val );
 		op->ors_attrs = ros->ors_attrs;
 		op->ors_filter = ros->ors_filter;
@@ -833,7 +833,7 @@ error_return:;
 	}
 
 	if ( f != NULL ) {
-		filter_free_x( op, f );
+		filter_free_x( op, f, 1 );
 	}
 
 	if ( !BER_BVISNULL( &fstr ) ) {
diff --git a/servers/slapd/overlays/rwmmap.c b/servers/slapd/overlays/rwmmap.c
index bc79ae17b64fdb1379577f8039d6948610ec4ba5..ad03d87effddc4ccf1c98be167fff91dedb434f3 100644
--- a/servers/slapd/overlays/rwmmap.c
+++ b/servers/slapd/overlays/rwmmap.c
@@ -495,6 +495,10 @@ rwm_int_filter_map_rewrite(
 		return LDAP_OTHER;
 	}
 
+	if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) {
+		goto computed;
+	}
+
 	switch ( f->f_choice & SLAPD_FILTER_MASK ) {
 	case LDAP_FILTER_EQUALITY:
 		ad = f->f_av_desc;
@@ -706,7 +710,7 @@ rwm_int_filter_map_rewrite(
 
 	case -1:
 computed:;
-		filter_free_x( op, f );
+		filter_free_x( op, f, 0 );
 		f->f_choice = SLAPD_FILTER_COMPUTED;
 		f->f_result = SLAPD_COMPARE_UNDEFINED;
 		/* fallthru */
diff --git a/servers/slapd/overlays/unique.c b/servers/slapd/overlays/unique.c
index a3c5ac90ae0f36259841d9b14edef5a15fab4e0e..4a17e5a25652660381b6e4df06ed123b1febce22 100644
--- a/servers/slapd/overlays/unique.c
+++ b/servers/slapd/overlays/unique.c
@@ -1013,7 +1013,7 @@ unique_search(
 
 	nop->o_bd = on->on_info->oi_origdb;
 	rc = nop->o_bd->be_search(nop, &nrs);
-	filter_free_x(nop, nop->ors_filter);
+	filter_free_x(nop, nop->ors_filter, 1);
 	op->o_tmpfree( key->bv_val, op->o_tmpmemctx );
 
 	if(rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT) {
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 27aaee29517580dca543d31d448eab028164c33a..4c2db2960d8ae604a03b1f67213a1dded232a8f8 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -1029,7 +1029,7 @@ LDAP_SLAPD_F (int) get_filter LDAP_P((
 	const char **text ));
 
 LDAP_SLAPD_F (void) filter_free LDAP_P(( Filter *f ));
-LDAP_SLAPD_F (void) filter_free_x LDAP_P(( Operation *op, Filter *f ));
+LDAP_SLAPD_F (void) filter_free_x LDAP_P(( Operation *op, Filter *f, int freeme ));
 LDAP_SLAPD_F (void) filter2bv LDAP_P(( Filter *f, struct berval *bv ));
 LDAP_SLAPD_F (void) filter2bv_x LDAP_P(( Operation *op, Filter *f, struct berval *bv ));
 LDAP_SLAPD_F (Filter *) filter_dup LDAP_P(( Filter *f, void *memctx ));
diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c
index 3d728339a3ef1f712402402a06c6ad73c79762a9..b73258e66dc9dc2c59d25fbd0fcc76efec83957d 100644
--- a/servers/slapd/sasl.c
+++ b/servers/slapd/sasl.c
@@ -1044,7 +1044,7 @@ slapd_rw_apply( void *private, const char *filter, struct berval *val )
 		}
 		rc = REWRITE_ERR;
 	}
-	filter_free_x( op, op->ors_filter );
+	filter_free_x( op, op->ors_filter, 1 );
 	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
 	return rc;
 }
diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c
index fafc2a4d91a51e2eca71c0b2a90538298ecbc4d4..08c7c690f58c426386ef7b5c4386d3db0b189ecf 100644
--- a/servers/slapd/saslauthz.c
+++ b/servers/slapd/saslauthz.c
@@ -1226,7 +1226,7 @@ is_dn:		bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
 
 done:
 	if( rc != LDAP_SUCCESS ) {
-		if( *filter ) filter_free_x( op, *filter );
+		if( *filter ) filter_free_x( op, *filter, 1 );
 		BER_BVZERO( base );
 		BER_BVZERO( fstr );
 	} else {
@@ -1843,7 +1843,7 @@ exact_match:
 CONCLUDED:
 	if( !BER_BVISNULL( &op.o_req_dn ) ) slap_sl_free( op.o_req_dn.bv_val, opx->o_tmpmemctx );
 	if( !BER_BVISNULL( &op.o_req_ndn ) ) slap_sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx );
-	if( op.ors_filter ) filter_free_x( opx, op.ors_filter );
+	if( op.ors_filter ) filter_free_x( opx, op.ors_filter, 1 );
 	if( !BER_BVISNULL( &op.ors_filterstr ) ) ch_free( op.ors_filterstr.bv_val );
 
 	Debug( LDAP_DEBUG_TRACE,
@@ -2015,7 +2015,7 @@ FINISHED:
 		slap_sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx );
 	}
 	if( op.ors_filter ) {
-		filter_free_x( opx, op.ors_filter );
+		filter_free_x( opx, op.ors_filter, 1 );
 	}
 	if( !BER_BVISNULL( &op.ors_filterstr ) ) {
 		ch_free( op.ors_filterstr.bv_val );
diff --git a/servers/slapd/search.c b/servers/slapd/search.c
index 2d998d97202a3b39f7343be55abec4cec4f2f815..25b88053811a5f2e95bd4f3a6b23fc30ef68ce8e 100644
--- a/servers/slapd/search.c
+++ b/servers/slapd/search.c
@@ -227,7 +227,7 @@ return_results:;
 		op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
 	}
 	if ( op->ors_filter != NULL) {
-		filter_free_x( op, op->ors_filter );
+		filter_free_x( op, op->ors_filter, 1 );
 	}
 	if ( op->ors_attrs != NULL ) {
 		op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
index 128f30295609fd26765a37120de6ebb24a86cb8d..516eb4a710ec9cebf8ddcacbbc3c7a0689ccb49d 100644
--- a/servers/slapd/syncrepl.c
+++ b/servers/slapd/syncrepl.c
@@ -2475,7 +2475,7 @@ syncrepl_del_nonpresent(
 			op->o_tmpfree( cf, op->o_tmpmemctx );
 			op->ors_filter = of;
 		}
-		if ( op->ors_filter ) filter_free_x( op, op->ors_filter );
+		if ( op->ors_filter ) filter_free_x( op, op->ors_filter, 1 );
 
 	}