svn commit: samba r4366 - in branches/SAMBA_4_0/source/lib/ldb/ldb_tdb: .

vlendec at samba.org vlendec at samba.org
Sun Dec 26 17:30:28 GMT 2004


Author: vlendec
Date: 2004-12-26 17:30:27 +0000 (Sun, 26 Dec 2004)
New Revision: 4366

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=4366

Log:
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

Modified:
   branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_tdb.c


Changeset:
Modified: branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_tdb.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_tdb.c	2004-12-26 08:41:11 UTC (rev 4365)
+++ branches/SAMBA_4_0/source/lib/ldb/ldb_tdb/ldb_tdb.c	2004-12-26 17:30:27 UTC (rev 4366)
@@ -513,24 +513,51 @@
 	}
 
 	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;
 			}
-			if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
+
+			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;
+				}
+			}
+
+		        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:



More information about the samba-cvs mailing list