summaryrefslogtreecommitdiff
path: root/source4/dsdb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-09-14 03:44:10 -0700
committerAndrew Tridgell <tridge@samba.org>2009-09-14 09:41:52 -0700
commit33160b1a5b2bc498f0dfb5c59d0ec0592cc37e8d (patch)
treebb19988febdc66a274a181776fab0481b16fa87f /source4/dsdb
parent3cf73dfdbdd33189e0f9f22e0e494962376f9b86 (diff)
downloadsamba-33160b1a5b2bc498f0dfb5c59d0ec0592cc37e8d.tar.gz
samba-33160b1a5b2bc498f0dfb5c59d0ec0592cc37e8d.tar.bz2
samba-33160b1a5b2bc498f0dfb5c59d0ec0592cc37e8d.zip
s4-repl: fixed a memory error handling linked attributes
We could get a double free with multiple linked attributes in a message
Diffstat (limited to 'source4/dsdb')
-rw-r--r--source4/dsdb/samdb/ldb_modules/repl_meta_data.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 3afe11ae51..b9323b912b 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -47,6 +47,7 @@
#include "lib/util/dlinklist.h"
struct replmd_private {
+ TALLOC_CTX *la_ctx;
struct la_entry *la_list;
uint32_t num_ncs;
struct nc_entry {
@@ -1896,13 +1897,10 @@ static int replmd_extended_replicated_objects(struct ldb_module *module, struct
for (i=0; i<ar->objs->linked_attributes_count; i++) {
struct la_entry *la_entry;
- if (replmd_private->la_list) {
- la_entry = talloc(replmd_private->la_list,
- struct la_entry);
- } else {
- la_entry = talloc(replmd_private,
- struct la_entry);
+ if (replmd_private->la_ctx == NULL) {
+ replmd_private->la_ctx = talloc_new(replmd_private);
}
+ la_entry = talloc(replmd_private->la_ctx, struct la_entry);
if (la_entry == NULL) {
ldb_oom(ldb);
return LDB_ERR_OPERATIONS_ERROR;
@@ -2108,8 +2106,9 @@ static int replmd_start_transaction(struct ldb_module *module)
int i;
struct replmd_private *replmd_private = talloc_get_type(ldb_module_get_private(module),
struct replmd_private);
- talloc_free(replmd_private->la_list);
+ talloc_free(replmd_private->la_ctx);
replmd_private->la_list = NULL;
+ replmd_private->la_ctx = NULL;
for (i=0; i<replmd_private->num_ncs; i++) {
replmd_private->ncs[i].mod_usn = 0;
@@ -2138,14 +2137,14 @@ static int replmd_prepare_commit(struct ldb_module *module)
prev = la->prev;
DLIST_REMOVE(replmd_private->la_list, la);
ret = replmd_process_linked_attribute(module, la);
- talloc_free(la);
if (ret != LDB_SUCCESS) {
return ret;
}
}
- talloc_free(replmd_private->la_list);
+ talloc_free(replmd_private->la_ctx);
replmd_private->la_list = NULL;
+ replmd_private->la_ctx = NULL;
/* possibly change @REPLCHANGED */
ret = replmd_notify_store(module);
@@ -2160,8 +2159,9 @@ static int replmd_del_transaction(struct ldb_module *module)
{
struct replmd_private *replmd_private =
talloc_get_type(ldb_module_get_private(module), struct replmd_private);
- talloc_free(replmd_private->la_list);
+ talloc_free(replmd_private->la_ctx);
replmd_private->la_list = NULL;
+ replmd_private->la_ctx = NULL;
return ldb_next_del_trans(module);
}