summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2004-12-26 17:30:27 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:07:38 -0500
commitb29b10e48ee351c19cb7a0e9766718fa1715f747 (patch)
tree306d9bab82bc2772f2dbd2c9fb15ec0decb8d09f
parent6c4d5917e148819384271d2960c3f6ccca2e5b54 (diff)
downloadsamba-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.c45
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: