diff options
-rw-r--r-- | source4/lib/ldb/common/ldb_msg.c | 55 | ||||
-rw-r--r-- | source4/lib/ldb/include/ldb.h | 4 | ||||
-rw-r--r-- | source4/lib/ldb/tools/ldbedit.c | 47 |
3 files changed, 63 insertions, 43 deletions
diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 4c903cf936..7a6dea049a 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -456,3 +456,58 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, return msg2; } + + +/* + return a ldb_message representing the differences between msg1 and msg2. If you + then use this in a ldb_modify() call it can be used to save edits to a message +*/ +struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2) +{ + struct ldb_message *mod; + struct ldb_message_element *el; + unsigned int i; + + mod = ldb_msg_new(ldb); + + mod->dn = msg1->dn; + mod->num_elements = 0; + mod->elements = NULL; + + msg2 = ldb_msg_canonicalize(ldb, msg2); + if (msg2 == NULL) { + return NULL; + } + + /* look in msg2 to find elements that need to be added + or modified */ + for (i=0;i<msg2->num_elements;i++) { + el = ldb_msg_find_element(msg1, msg2->elements[i].name); + + if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { + continue; + } + + if (ldb_msg_add(ldb, mod, + &msg2->elements[i], + el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) { + return NULL; + } + } + + /* look in msg1 to find elements that need to be deleted */ + for (i=0;i<msg1->num_elements;i++) { + el = ldb_msg_find_element(msg2, msg1->elements[i].name); + if (!el) { + if (ldb_msg_add_empty(ldb, mod, + msg1->elements[i].name, + LDB_FLAG_MOD_DELETE) != 0) { + return NULL; + } + } + } + + return mod; +} diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index f748bb6b42..18d974cf42 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -295,6 +295,10 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, const struct ldb_message *msg); +struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2); + struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v); /* diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index 4c41b6b19a..851eaeebdf 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -65,51 +65,12 @@ static int modify_record(struct ldb_context *ldb, struct ldb_message *msg2) { struct ldb_message *mod; - struct ldb_message_element *el; - unsigned int i; - int count = 0; - mod = ldb_msg_new(ldb); - - mod->dn = msg1->dn; - mod->num_elements = 0; - mod->elements = NULL; - - msg2 = ldb_msg_canonicalize(ldb, msg2); - if (msg2 == NULL) { - fprintf(stderr, "Failed to canonicalise msg2\n"); + mod = ldb_msg_diff(ldb, msg1, msg2); + if (mod == NULL) { + fprintf(stderr, "Failed to calculate message differences\n"); return -1; } - - /* look in msg2 to find elements that need to be added - or modified */ - for (i=0;i<msg2->num_elements;i++) { - el = ldb_msg_find_element(msg1, msg2->elements[i].name); - - if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { - continue; - } - - if (ldb_msg_add(ldb, mod, - &msg2->elements[i], - el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) { - return -1; - } - count++; - } - - /* look in msg1 to find elements that need to be deleted */ - for (i=0;i<msg1->num_elements;i++) { - el = ldb_msg_find_element(msg2, msg1->elements[i].name); - if (!el) { - if (ldb_msg_add_empty(ldb, mod, - msg1->elements[i].name, - LDB_FLAG_MOD_DELETE) != 0) { - return -1; - } - count++; - } - } if (mod->num_elements == 0) { return 0; @@ -125,7 +86,7 @@ static int modify_record(struct ldb_context *ldb, ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod); } - return count; + return mod->num_elements; } /* |