The branch, master has been updated via 35b1e00... s4: Remove trailing whitespaces via 11a44ce... ldb: Mark _DEPRECATED_ ldb_msg_diff() and ldb_msg_canonicalize() functions via 31aeb84... s4-dsdb: use ldb_msg_normalize() in ldb_msg_difference() via 1e20dbd... s4-test: Use ldb_msg_normalize() in sqlite3 backend via 91d9f88... s4-test: Use ldb_msg_normalize() in torture/rpc/dssync.c test via d71b20e... s4-dsdb: use ldb_msg_normalize() in ldbadd-process_file() via 2ad7019... s4-dsdb: use ldb_msg_normalize() in source4/lib/ldb/common/ldb.c via 86cc914... s4-dsdb: use ldb_msg_normalize() in source4/dsdb/schema/schema_set.c via e5a9469... s4-ldb: Add ldb_msg_normalize() to accept a memory context from client via 48574cc... s4-ldb: Use _ldb_msg_add_el() in ldb_msg_add() via 3944c81... s4-ldb: Use _ldb_msg_add_el() in ldb_msg_add_empty() via 8d523d4... s4-ldb: Add separate function to add empty element into ldb_msg via a95fd4e... s4-ldb: Write more explanatory comment for ldb_msg_add() via 8deae13... s4-pyldb: Use ldb_msg_difference() in py_ldb_msg_diff() via 148b858... s4-test: Use ldb_msg_difference() in torture/rpc/dssync.c test via fa0db46... s4-tools: use ldb_msg_difference() in ldbedit - modify_record() via fb1c079... s4-dsdb/schema/schema_set.c: fix trailing spaces and comments spelling via a11d3b4... s4-dsdb: use ldb_msg_difference() in source4/dsdb/schema/schema_set.c via 65b967a... s4-ldb: Implement ldb_msg_difference() function to accept a memory context from client from c09dcb9... s3-auth: Use talloc hierarchies to properly free auth_ntlmssp_state contexts
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 35b1e00ba330d5f90f121f2af384ff416dd4a62b Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 14:19:07 2010 +0300 s4: Remove trailing whitespaces Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 11a44ce6f885de1c1f78c791cbe85a915934ae8a Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 14:18:49 2010 +0300 ldb: Mark _DEPRECATED_ ldb_msg_diff() and ldb_msg_canonicalize() functions They are not quite safe to use (requires caller to steal resulting message in own context) and may lead to holding memory for too long. Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 31aeb841c9823574cb6f13986f4da34d00bb40a1 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 14:18:14 2010 +0300 s4-dsdb: use ldb_msg_normalize() in ldb_msg_difference() Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 1e20dbd8127bcecda8e4a656d326b391cc5c8e8d Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 14:16:38 2010 +0300 s4-test: Use ldb_msg_normalize() in sqlite3 backend Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 91d9f88d28e58157ca63caeb76ff779321d7bb53 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 14:13:20 2010 +0300 s4-test: Use ldb_msg_normalize() in torture/rpc/dssync.c test Signed-off-by: Andrew Bartlett <abart...@samba.org> commit d71b20e8dc9d8e8366ffb5147c84586f5d71416e Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 14:03:53 2010 +0300 s4-dsdb: use ldb_msg_normalize() in ldbadd-process_file() Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 2ad701911e2bd5d4cdc5d5db64449f3cc01df3cd Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 14:01:49 2010 +0300 s4-dsdb: use ldb_msg_normalize() in source4/lib/ldb/common/ldb.c Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 86cc914717a915808479126a14baa915450b24f6 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:59:40 2010 +0300 s4-dsdb: use ldb_msg_normalize() in source4/dsdb/schema/schema_set.c Signed-off-by: Andrew Bartlett <abart...@samba.org> commit e5a9469a88e039b558e13273ae637f874bbb42b3 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:55:42 2010 +0300 s4-ldb: Add ldb_msg_normalize() to accept a memory context from client Previos implementation from ldb_msg_canonicalize() was moved into this function and now ldb_msg_canonicalize() is based on ldb_msg_normalize() Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 48574ccc3f46a58940a06b524ff3be3c6da6b104 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:47:41 2010 +0300 s4-ldb: Use _ldb_msg_add_el() in ldb_msg_add() Previous implementation was 'leaking' attribute name string, that is allocated by ldb_msg_add_empty() Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 3944c81d08177e7fa360b1925648686c729e2773 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:46:05 2010 +0300 s4-ldb: Use _ldb_msg_add_el() in ldb_msg_add_empty() Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 8d523d46f5dfcbf5a428fd75b908fe5bd738e62c Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:44:13 2010 +0300 s4-ldb: Add separate function to add empty element into ldb_msg It just adds another element, nothing more. Caller is responsible to fill-in the added element and determine how to handle data allocation contexts. Signed-off-by: Andrew Bartlett <abart...@samba.org> commit a95fd4ef647ed6d4c81ab862e08e7c42ee2fe0d6 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:41:57 2010 +0300 s4-ldb: Write more explanatory comment for ldb_msg_add() Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 8deae13313b87c0d7efa64e9334c06987ed90ac6 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:40:50 2010 +0300 s4-pyldb: Use ldb_msg_difference() in py_ldb_msg_diff() Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 148b8588bc7864f4771c8dcf21cfdc150b22e701 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:38:09 2010 +0300 s4-test: Use ldb_msg_difference() in torture/rpc/dssync.c test Signed-off-by: Andrew Bartlett <abart...@samba.org> commit fa0db46af16080dd3a540072f7ad664c0b9270ca Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:35:07 2010 +0300 s4-tools: use ldb_msg_difference() in ldbedit - modify_record() Signed-off-by: Andrew Bartlett <abart...@samba.org> commit fb1c0796c7c533f468b74d55507e9877b93ead72 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 14:27:30 2010 +0300 s4-dsdb/schema/schema_set.c: fix trailing spaces and comments spelling Few comments split on several lines also... (Sorry Metze, I know you hate reviewing "and this, and that" type of patches, but those are just cosmetics) Signed-off-by: Andrew Bartlett <abart...@samba.org> commit a11d3b4dfbdddb16d3f132ea8fe0175cb7d09444 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 13:26:45 2010 +0300 s4-dsdb: use ldb_msg_difference() in source4/dsdb/schema/schema_set.c Signed-off-by: Andrew Bartlett <abart...@samba.org> commit 65b967a706bb4ee2da1d4211c31c91d31a81e8f1 Author: Kamen Mazdrashki <kame...@samba.org> Date: Fri Jul 16 14:23:24 2010 +0300 s4-ldb: Implement ldb_msg_difference() function to accept a memory context from client Old implementation from ldb_msg_diff() was moved into this this function but with changed interface so that a memory context may be passed. ldb_msg_diff() function is now based on ldb_msg_difference(), which fixes a hidden leak - internal ldb_msg object (returned from ldb_msg_canonicalize) wasn't freed and stays attached to ldb_context for the connection lifetime. Signed-off-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: source4/dsdb/schema/schema_set.c | 89 ++++++----- source4/lib/ldb/common/ldb.c | 12 +- source4/lib/ldb/common/ldb_msg.c | 240 +++++++++++++++++++++-------- source4/lib/ldb/include/ldb.h | 55 +++++++- source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c | 17 ++- source4/lib/ldb/pyldb.c | 12 ++- source4/lib/ldb/tools/ldbadd.c | 18 ++- source4/lib/ldb/tools/ldbedit.c | 34 +++-- source4/torture/rpc/dssync.c | 15 ++- 9 files changed, 355 insertions(+), 137 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index 5d63670..b8ed7ca 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -1,7 +1,7 @@ -/* - Unix SMB/CIFS mplementation. +/* + Unix SMB/CIFS implementation. DSDB schema header - + Copyright (C) Stefan Metzmacher <me...@samba.org> 2006-2007 Copyright (C) Andrew Bartlett <abart...@samba.org> 2006-2008 @@ -9,15 +9,15 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. - + */ #include "includes.h" @@ -32,7 +32,7 @@ /* override the name to attribute handler function */ -const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, +const struct ldb_schema_attribute *dsdb_attribute_handler_override(struct ldb_context *ldb, void *private_data, const char *name) { @@ -96,17 +96,20 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem for (attr = schema->attributes; attr; attr = attr->next) { const char *syntax = attr->syntax->ldb_syntax; - + if (!syntax) { syntax = attr->syntax->ldap_oid; } - /* Write out a rough approximation of the schema as an @ATTRIBUTES value, for bootstrapping */ + /* + * Write out a rough approximation of the schema + * as an @ATTRIBUTES value, for bootstrapping + */ if (strcmp(syntax, LDB_SYNTAX_INTEGER) == 0) { ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "INTEGER"); } else if (strcmp(syntax, LDB_SYNTAX_DIRECTORY_STRING) == 0) { ret = ldb_msg_add_string(msg, attr->lDAPDisplayName, "CASE_INSENSITIVE"); - } + } if (ret != LDB_SUCCESS) { break; } @@ -124,7 +127,10 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem return ret; } - /* Try to avoid churning the attributes too much - we only want to do this if they have changed */ + /* + * Try to avoid churning the attributes too much, + * we only want to do this if they have changed + */ ret = ldb_search(ldb, mem_ctx, &res, msg->dn, LDB_SCOPE_BASE, NULL, NULL); if (ret == LDB_ERR_NO_SUCH_OBJECT) { @@ -136,8 +142,12 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem ret = LDB_SUCCESS; /* Annoyingly added to our search results */ ldb_msg_remove_attr(res->msgs[0], "distinguishedName"); - - mod_msg = ldb_msg_diff(ldb, res->msgs[0], msg); + + ret = ldb_msg_difference(ldb, mem_ctx, + res->msgs[0], msg, &mod_msg); + if (ret != LDB_SUCCESS) { + goto op_error; + } if (mod_msg->num_elements > 0) { ret = dsdb_replace(ldb, mod_msg, 0); } @@ -153,7 +163,7 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem return ret; } - /* Now write out the indexs, as found in the schema (if they have changed) */ + /* Now write out the indexes, as found in the schema (if they have changed) */ ret = ldb_search(ldb, mem_ctx, &res_idx, msg_idx->dn, LDB_SCOPE_BASE, NULL, NULL); @@ -167,7 +177,11 @@ static int dsdb_schema_set_attributes(struct ldb_context *ldb, struct dsdb_schem /* Annoyingly added to our search results */ ldb_msg_remove_attr(res_idx->msgs[0], "distinguishedName"); - mod_msg = ldb_msg_diff(ldb, res_idx->msgs[0], msg_idx); + ret = ldb_msg_difference(ldb, mem_ctx, + res_idx->msgs[0], msg_idx, &mod_msg); + if (ret != LDB_SUCCESS) { + goto op_error; + } if (mod_msg->num_elements > 0) { ret = dsdb_replace(ldb, mod_msg, 0); } @@ -354,17 +368,16 @@ int dsdb_setup_schema_inversion(struct ldb_context *ldb, struct dsdb_schema *sch * order as an integer in the dsdb_class (for sorting * objectClass lists efficiently) */ - /* Walk the list of scheam classes */ - + /* Walk the list of schema classes */ + /* Create a 'total possible superiors' on each class */ return LDB_SUCCESS; } /** - * Attach the schema to an opaque pointer on the ldb, so ldb modules - * can find it + * Attach the schema to an opaque pointer on the ldb, + * so ldb modules can find it */ - int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema) { struct dsdb_schema *old_schema; @@ -461,7 +474,7 @@ int dsdb_set_global_schema(struct ldb_context *ldb) /* Set the new attributes based on the new schema */ ret = dsdb_schema_set_attributes(ldb, global_schema, false /* Don't write attributes, it's expensive */); if (ret == LDB_SUCCESS) { - /* Keep a reference to this schema, just incase the original copy is replaced */ + /* Keep a reference to this schema, just in case the original copy is replaced */ if (talloc_reference(ldb, global_schema) == NULL) { return ldb_oom(ldb); } @@ -503,7 +516,10 @@ struct dsdb_schema *dsdb_get_schema(struct ldb_context *ldb, TALLOC_CTX *referen if (schema_in->refresh_fn && !schema_in->refresh_in_progress) { if (!talloc_reference(tmp_ctx, schema_in)) { - /* ensure that the schema_in->refresh_in_progress remains valid for the right amount of time */ + /* + * ensure that the schema_in->refresh_in_progress + * remains valid for the right amount of time + */ talloc_free(tmp_ctx); return NULL; } @@ -548,9 +564,11 @@ void dsdb_make_schema_global(struct ldb_context *ldb, struct dsdb_schema *schema dsdb_set_global_schema(ldb); } -/* When loading the schema from LDIF files, we don't get the extended DNs. - - We need to set these up, so that from the moment we start the provision, the defaultObjectCategory links are set up correctly. +/** + * When loading the schema from LDIF files, we don't get the extended DNs. + * + * We need to set these up, so that from the moment we start the provision, + * the defaultObjectCategory links are set up correctly. */ int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *schema) { @@ -575,7 +593,7 @@ int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *sc talloc_free(dn); return LDB_ERR_CONSTRAINT_VIOLATION; } - + status = GUID_to_ndr_blob(&target_class->objectGUID, dn, &guid); if (!NT_STATUS_IS_OK(status)) { talloc_free(dn); @@ -589,11 +607,11 @@ int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *sc return LDB_SUCCESS; } -/** +/** * Add an element to the schema (attribute or class) from an LDB message */ -WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, struct dsdb_schema *schema, - struct ldb_message *msg) +WERROR dsdb_schema_set_el_from_ldb_msg(struct ldb_context *ldb, struct dsdb_schema *schema, + struct ldb_message *msg) { if (samdb_find_attribute(ldb, msg, "objectclass", "attributeSchema") != NULL) { @@ -649,11 +667,10 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const } talloc_steal(mem_ctx, ldif); - msg = ldb_msg_canonicalize(ldb, ldif->msg); - if (!msg) { + ret = ldb_msg_normalize(ldb, mem_ctx, ldif->msg, &msg); + if (ret != LDB_SUCCESS) { goto nomem; } - talloc_steal(mem_ctx, msg); talloc_free(ldif); prefix_val = ldb_msg_find_ldb_val(msg, "prefixMap"); @@ -675,14 +692,12 @@ WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const goto failed; } - /* - * load the attribute and class definitions outof df - */ + /* load the attribute and class definitions out of df */ while ((ldif = ldb_ldif_read_string(ldb, &df))) { talloc_steal(mem_ctx, ldif); - msg = ldb_msg_canonicalize(ldb, ldif->msg); - if (!msg) { + ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &msg); + if (ret != LDB_SUCCESS) { goto nomem; } diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 877f283..3a0ca46 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -795,15 +795,17 @@ int ldb_request(struct ldb_context *ldb, struct ldb_request *req) ret = module->ops->search(module, req); break; case LDB_ADD: - /* we have to canonicalise here, as so many places + /* + * we have to normalize here, as so many places * in modules and backends assume we don't have two - * elements with the same name */ - req->op.add.message = ldb_msg_canonicalize(ldb, req->op.add.message); - if (!req->op.add.message) { + * elements with the same name + */ + ret = ldb_msg_normalize(ldb, req, req->op.add.message, + discard_const(&req->op.add.message)); + if (ret != LDB_SUCCESS) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; } - talloc_steal(req, req->op.add.message); FIRST_OP(ldb, add); ret = module->ops->add(module, req); break; diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c index 4d0149a..8cf2584 100644 --- a/source4/lib/ldb/common/ldb_msg.c +++ b/source4/lib/ldb/common/ldb_msg.c @@ -114,58 +114,94 @@ struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v) return v2; } -/* - add an empty element to a message -*/ -int ldb_msg_add_empty( struct ldb_message *msg, - const char *attr_name, - int flags, - struct ldb_message_element **return_el) +/** + * Adds new empty element to msg->elements + */ +static int _ldb_msg_add_el(struct ldb_message *msg, + struct ldb_message_element **return_el) { struct ldb_message_element *els; - els = talloc_realloc(msg, msg->elements, - struct ldb_message_element, msg->num_elements+1); + /* + * TODO: Find out a way to assert on input parameters. + * msg and return_el must be valid + */ + + els = talloc_realloc(msg, msg->elements, + struct ldb_message_element, msg->num_elements + 1); if (!els) { errno = ENOMEM; return LDB_ERR_OPERATIONS_ERROR; } - els[msg->num_elements].values = NULL; - els[msg->num_elements].num_values = 0; - els[msg->num_elements].flags = flags; - els[msg->num_elements].name = talloc_strdup(els, attr_name); - if (!els[msg->num_elements].name) { - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } + ZERO_STRUCT(els[msg->num_elements]); msg->elements = els; msg->num_elements++; + *return_el = &els[msg->num_elements-1]; + + return LDB_SUCCESS; +} + +/** + * Add an empty element with a given name to a message + */ +int ldb_msg_add_empty(struct ldb_message *msg, + const char *attr_name, + int flags, + struct ldb_message_element **return_el) +{ + int ret; + struct ldb_message_element *el; + + ret = _ldb_msg_add_el(msg, &el); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* initialize newly added element */ + el->flags = flags; + el->name = talloc_strdup(msg->elements, attr_name); + if (!el->name) { + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + if (return_el) { - *return_el = &els[msg->num_elements-1]; + *return_el = el; } return LDB_SUCCESS; } -/* - add an empty element to a message -*/ +/** + * Adds an element to a message. + * + * NOTE: Ownership of ldb_message_element fields + * is NOT transferred. Thus, if *el pointer + * is invalidated for some reason, this will + * corrupt *msg contents also + */ int ldb_msg_add(struct ldb_message *msg, const struct ldb_message_element *el, int flags) { + int ret; + struct ldb_message_element *el_new; /* We have to copy this, just in case *el is a pointer into * what ldb_msg_add_empty() is about to realloc() */ struct ldb_message_element el_copy = *el; - if (ldb_msg_add_empty(msg, el->name, flags, NULL) != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; + + ret = _ldb_msg_add_el(msg, &el_new); + if (ret != LDB_SUCCESS) { + return ret; } - msg->elements[msg->num_elements-1] = el_copy; - msg->elements[msg->num_elements-1].flags = flags; + el_new->flags = flags; + el_new->name = el_copy.name; + el_new->num_values = el_copy.num_values; + el_new->values = el_copy.values; return LDB_SUCCESS; } @@ -541,36 +577,64 @@ failed: } -/* - canonicalise a message, merging elements of the same name -*/ +/** + * Canonicalize a message, merging elements of the same name + */ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, const struct ldb_message *msg) { + int ret; + struct ldb_message *msg2; + + /* + * Preserve previous behavior and allocate + * *msg2 into *ldb context + */ + ret = ldb_msg_normalize(ldb, ldb, msg, &msg2); + if (ret != LDB_SUCCESS) { + return NULL; + } + + return msg2; +} + +/** + * Canonicalize a message, merging elements of the same name + */ +int ldb_msg_normalize(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + struct ldb_message **_msg_out) +{ unsigned int i; struct ldb_message *msg2; - msg2 = ldb_msg_copy(ldb, msg); - if (msg2 == NULL) return NULL; + msg2 = ldb_msg_copy(mem_ctx, msg); + if (msg2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } ldb_msg_sort_elements(msg2); - for (i=1;i<msg2->num_elements;i++) { + for (i=1; i < msg2->num_elements; i++) { struct ldb_message_element *el1 = &msg2->elements[i-1]; struct ldb_message_element *el2 = &msg2->elements[i]; + if (ldb_msg_element_compare_name(el1, el2) == 0) { - el1->values = talloc_realloc(msg2->elements, el1->values, struct ldb_val, - el1->num_values + el2->num_values); + el1->values = talloc_realloc(msg2->elements, + el1->values, struct ldb_val, + el1->num_values + el2->num_values); if (el1->num_values + el2->num_values > 0 && el1->values == NULL) { - return NULL; + talloc_free(msg2); + return LDB_ERR_OPERATIONS_ERROR; } memcpy(el1->values + el1->num_values, el2->values, sizeof(struct ldb_val) * el2->num_values); el1->num_values += el2->num_values; talloc_free(discard_const_p(char, el2->name)); - if (i+1<msg2->num_elements) { - memmove(el2, el2+1, sizeof(struct ldb_message_element) * + if ((i+1) < msg2->num_elements) { + memmove(el2, el2+1, sizeof(struct ldb_message_element) * (msg2->num_elements - (i+1))); } msg2->num_elements--; @@ -578,39 +642,81 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, } } - return msg2; + *_msg_out = msg2; + return LDB_SUCCESS; } -/* - 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 -*/ +/** + * 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) { + int ldb_ret; struct ldb_message *mod; - struct ldb_message_element *el; + + ldb_ret = ldb_msg_difference(ldb, ldb, msg1, msg2, &mod); + if (ldb_ret != LDB_SUCCESS) { + return NULL; + } + + 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 -- Samba Shared Repository