/* Retrieve an Entry that was stored using bdb_encode above.
* All we have to do is add the buffer address to all of the
* stored offsets. We also use the stored attribute names to
- * pull AttributeDescriptions from our ad_cache.
+ * pull AttributeDescriptions from our ad_cache. To detect if
+ * the attributes of an Entry are later modified, we also store
+ * the address of the end of this block in e_private. Since
+ * modify_internal always allocs a new list of attrs to work
+ * with, we need to free that separately.
*/
int bdb_decode(struct berval *bv, Entry **e)
{
#define entry_encode(a, b) bdb_encode(a,b)
#define entry_decode(a, b) bdb_decode(a,b)
-#define entry_free(e) ch_free(e)
#endif /* BDB_USE_BINARY_RW */
BackendDB *be,
Entry *e )
{
+#ifdef BDB_USE_BINARY_RW
+ /* bdb_modify_internal always operates on a dup'd set of attrs. */
+ if ((void *)e->e_attrs < (void *)e ||
+ (void *)e->e_attrs > e->e_private)
+ attrs_free(e->e_attrs);
+ ch_free(e);
+#else
entry_free( e );
+#endif
return 0;
}
goto return_results;
}
+#ifdef BDB_USE_BINARY_RW
+ /* Binary format uses a single contiguous block, cannot
+ * free individual fields. Leave new_dn/new_ndn set so
+ * they can be individually freed later.
+ */
+ e->e_dn = new_dn;
+ e->e_ndn = new_ndn;
+#else
free( e->e_dn );
free( e->e_ndn );
e->e_dn = new_dn;
e->e_ndn = new_ndn;
new_dn = NULL;
new_ndn = NULL;
+#endif
/* add new one */
rc = bdb_dn2id_add( be, ltid, e->e_ndn, e->e_id );