-#ifdef SLAPD_SCHEMA_NOT_COMPAT
- ad_free( a->a_desc, 1 );
-#else
- free( a->a_type );
-#endif
- ber_bvecfree( a->a_vals );
- free( a );
+ if ( a->a_nvals && a->a_nvals != a->a_vals &&
+ !( a->a_flags & SLAP_ATTR_DONT_FREE_VALS )) {
+ if ( a->a_flags & SLAP_ATTR_DONT_FREE_DATA ) {
+ free( a->a_nvals );
+ } else {
+ ber_bvarray_free( a->a_nvals );
+ }
+ }
+ /* a_vals may be equal to slap_dummy_bv, a static empty berval;
+ * this is used as a placeholder for attributes that do not carry
+ * values, e.g. when proxying search entries with the "attrsonly"
+ * bit set. */
+ if ( a->a_vals != &slap_dummy_bv &&
+ !( a->a_flags & SLAP_ATTR_DONT_FREE_VALS )) {
+ if ( a->a_flags & SLAP_ATTR_DONT_FREE_DATA ) {
+ free( a->a_vals );
+ } else {
+ ber_bvarray_free( a->a_vals );
+ }
+ }
+ memset( a, 0, sizeof( Attribute ));
+ ldap_pvt_thread_mutex_lock( &attr_mutex );
+ a->a_next = attr_list;
+ attr_list = a;
+ ldap_pvt_thread_mutex_unlock( &attr_mutex );
+}
+
+#ifdef LDAP_COMP_MATCH
+void
+comp_tree_free( Attribute *a )
+{
+ Attribute *next;
+
+ for( ; a != NULL ; a = next ) {
+ next = a->a_next;
+ if ( component_destructor && a->a_comp_data ) {
+ if ( a->a_comp_data->cd_mem_op )
+ component_destructor( a->a_comp_data->cd_mem_op );
+ free ( a->a_comp_data );
+ }
+ }