diff options
author | Volker Lendecke <vlendec@samba.org> | 2004-12-26 17:30:27 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:07:38 -0500 |
commit | b29b10e48ee351c19cb7a0e9766718fa1715f747 (patch) | |
tree | 306d9bab82bc2772f2dbd2c9fb15ec0decb8d09f | |
parent | 6c4d5917e148819384271d2960c3f6ccca2e5b54 (diff) | |
download | samba-b29b10e48ee351c19cb7a0e9766718fa1715f747.tar.gz samba-b29b10e48ee351c19cb7a0e9766718fa1715f747.tar.bz2 samba-b29b10e48ee351c19cb7a0e9766718fa1715f747.zip |
r4366: Fix ldb_modify_internal: Adding values to an existing attribute you could end
up with a corrupt data structure on disk, namely with two attribute structures
for the same attribute name.
Volker
(This used to be commit 284044b5b20102894a8128f84ab41d59cfcc9285)
-rw-r--r-- | source4/lib/ldb/ldb_tdb/ldb_tdb.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 5bceab0f13..179b205097 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -513,24 +513,51 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms } for (i=0;i<msg->num_elements;i++) { + struct ldb_message_element *el = &msg->elements[i]; + struct ldb_message_element *el2; + struct ldb_val *vals; + switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { case LDB_FLAG_MOD_ADD: /* add this element to the message. fail if it already exists */ - ret = find_element(&msg2, msg->elements[i].name); - if (ret != -1) { - for (j=0;j<msg->elements[i].num_values;j++) { - if (ldb_msg_find_val(&msg2.elements[ret], - &msg->elements[i].values[j])) { - ltdb->last_err_string = "Type or value exists"; - goto failed; - } + ret = find_element(&msg2, el->name); + + if (ret == -1) { + if (msg_add_element(ldb, &msg2, el) != 0) { + goto failed; + } + continue; + } + + el2 = &msg2.elements[ret]; + + /* An attribute with this name already exists, add all + * values if they don't already exist. */ + + for (j=0;j<el->num_values;j++) { + if (ldb_msg_find_val(el2, &el->values[j])) { + ltdb->last_err_string = + "Type or value exists"; + goto failed; } } - if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) { + + vals = ldb_realloc_p(ldb, el2->values, struct ldb_val, + el2->num_values + el->num_values); + + if (vals == NULL) goto failed; + + for (j=0;j<el->num_values;j++) { + vals[el2->num_values + j] = + ldb_val_dup(ldb, &el->values[j]); } + + el2->values = vals; + el2->num_values += el->num_values; + break; case LDB_FLAG_MOD_REPLACE: |