diff --git a/include/ldap_pvt_thread.h b/include/ldap_pvt_thread.h
index 6c1b86845b279647395c99f7db0e62f1ef95ea1f..1ca300bd9861fd79a1d9d0d80c35ca2148cd7dcd 100644
--- a/include/ldap_pvt_thread.h
+++ b/include/ldap_pvt_thread.h
@@ -202,6 +202,9 @@ ldap_pvt_thread_pool_setkey LDAP_P((
 	void *data,
 	ldap_pvt_thread_pool_keyfree_t *kfree ));
 
+LDAP_F( void )
+ldap_pvt_thread_pool_purgekey LDAP_P(( void *key ));
+
 LDAP_F( void *)
 ldap_pvt_thread_pool_context LDAP_P(( void ));
 
diff --git a/libraries/libldap_r/tpool.c b/libraries/libldap_r/tpool.c
index 31fa541cb8d96aa44dbba1f3303c41e59215bd4a..50bac8d2c1c06c75011ccf80d79404f0c50b5225 100644
--- a/libraries/libldap_r/tpool.c
+++ b/libraries/libldap_r/tpool.c
@@ -616,6 +616,30 @@ int ldap_pvt_thread_pool_setkey(
 	return ENOMEM;
 }
 
+/* Free all elements with this key, no matter which thread they're in.
+ * May only be called while the pool is paused.
+ */
+void ldap_pvt_thread_pool_purgekey( void *key )
+{
+	int i, j;
+	ldap_int_thread_key_t *ctx;
+
+	for ( i=0; i<LDAP_MAXTHR; i++ ) {
+		if ( thread_keys[i].ctx ) {
+			ctx = thread_keys[i].ctx;
+			for ( j=0; j<MAXKEYS; j++ ) {
+				if ( ctx[j].ltk_key == key ) {
+					if (ctx[j].ltk_free)
+						ctx[j].ltk_free( ctx[j].ltk_key, ctx[j].ltk_data );
+					ctx[j].ltk_key = NULL;
+					ctx[j].ltk_free = NULL;
+					break;
+				}
+			}
+		}
+	}
+}
+
 /*
  * This is necessary if the caller does not have access to the
  * thread context handle (for example, a slapd plugin calling