From: Kamen Mazdrashki Date: Fri, 9 Jul 2010 16:27:13 +0000 (+0300) Subject: s4-ldb: Implement ldb_msg_diff_ex() function to accept a memory context from client X-Git-Url: http://git.samba.org/?p=kamenim%2Fsamba.git;a=commitdiff_plain;h=35a3455f1a0062d77ba7e03d4da2bd6eab7bb040 s4-ldb: Implement ldb_msg_diff_ex() function to accept a memory context from client This function does what ldb_msg_diff() function should do, but the interface is little bit changed to accept memory context from caller. --- diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 4d0149af8f..e54caa8811 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -642,6 +642,98 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, return mod; } +/** + * 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 + * + * Result message is constructed as follows: + * - LDB_FLAG_MOD_ADD - elements found only in msg2 + * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1 + * Value for msg2 element is used + * - LDB_FLAG_MOD_DELETE - elements found only in msg2 + * + * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR + */ +int ldb_msg_diff_ex(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2, + TALLOC_CTX *mem_ctx, + struct ldb_message **_msg_out) +{ + int ldb_res; + unsigned int i; + struct ldb_message *mod; + struct ldb_message_element *el; + TALLOC_CTX *temp_ctx; + + temp_ctx = talloc_new(mem_ctx); + if (!temp_ctx) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = ldb_msg_new(temp_ctx); + if (mod == NULL) { + goto failed; + } + + mod->dn = msg1->dn; + mod->num_elements = 0; + mod->elements = NULL; + + /* canonicalize msg2 so we have no + * repeated elements */ + msg2 = ldb_msg_canonicalize(ldb, msg2); + if (msg2 == NULL) { + goto failed; + } + + /* steal msg2 into mod context as it is + * allocated in ldb's context */ + talloc_steal(mod, msg2); + + /* look in msg2 to find elements that need to be added + or modified */ + for (i=0;inum_elements;i++) { + el = ldb_msg_find_element(msg1, msg2->elements[i].name); + + if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { + continue; + } + + ldb_res = ldb_msg_add(mod, + &msg2->elements[i], + el ? LDB_FLAG_MOD_REPLACE : LDB_FLAG_MOD_ADD); + if (ldb_res != LDB_SUCCESS) { + goto failed; + } + } + + /* look in msg1 to find elements that need to be deleted */ + for (i=0;inum_elements;i++) { + el = ldb_msg_find_element(msg2, msg1->elements[i].name); + if (el == NULL) { + ldb_res = ldb_msg_add_empty(mod, + msg1->elements[i].name, + LDB_FLAG_MOD_DELETE, NULL); + if (ldb_res != LDB_SUCCESS) { + goto failed; + } + } + } + + /* steal resulting message into supplied context */ + talloc_steal(mem_ctx, mod); + *_msg_out = mod; + + talloc_free(temp_ctx); + return LDB_SUCCESS; + +failed: + talloc_free(temp_ctx); + return LDB_ERR_OPERATIONS_ERROR; +} + + int ldb_msg_sanity_check(struct ldb_context *ldb, const struct ldb_message *msg) { diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 039f70895a..f2362c5394 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -1859,6 +1859,24 @@ struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, struct ldb_message *msg1, struct ldb_message *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 + * + * Result message is constructed as follows: + * - LDB_FLAG_MOD_ADD - elements found only in msg2 + * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1 + * Value for msg2 element is used + * - LDB_FLAG_MOD_DELETE - elements found only in msg2 + * + * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR + */ +int ldb_msg_diff_ex(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2, + TALLOC_CTX *mem_ctx, + struct ldb_message **_msg_out); + /** Tries to find a certain string attribute in a message