From: Tim Beale Date: Tue, 20 Nov 2018 02:54:31 +0000 (+1300) Subject: replmd: Move logic into new replmd_should_apply_isDeleted() function X-Git-Tag: tdb-1.3.17~659 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d5af87e66c4e936ddd06607cc98f20c24e035b1;p=thirdparty%2Fsamba.git replmd: Move logic into new replmd_should_apply_isDeleted() function It's easier to follow the logic involved here when it's split out into a separate function. This patch should not alter the existing logic/functionality. Note the 'else' case is somewhat redundant, but it avoids excessive whitespace changes to the function. It'll be tidied up in the next patch. Signed-off-by: Tim Beale Reviewed-by: Andrew Bartlett --- diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 0a01bd4440f..97ab6ac7b9b 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -6798,6 +6798,45 @@ static int replmd_replicated_apply_next(struct replmd_replicated_request *ar) return ldb_next_request(ar->module, search_req); } +/* + * Returns true if we need to do extra processing to handle deleted object + * changes received via replication + */ +static bool replmd_should_apply_isDeleted(struct replmd_replicated_request *ar, + struct ldb_message *msg) +{ + struct ldb_dn *deleted_objects_dn; + int ret; + + if (!ar->isDeleted) { + + /* not a deleted object, so don't set isDeleted */ + return false; + } + + ret = dsdb_get_deleted_objects_dn(ldb_module_get_ctx(ar->module), + msg, msg->dn, + &deleted_objects_dn); + + /* + * if the Deleted Object container lookup failed, then just apply + * isDeleted (note that it doesn't exist for the Schema partition) + */ + if (ret != LDB_SUCCESS) { + return true; + } + + /* + * the Deleted Objects container has isDeleted set but is not entirely + * a deleted object, so DON'T re-apply isDeleted to it + */ + if (ldb_dn_compare(msg->dn, deleted_objects_dn) == 0) { + return false; + } + + return true; +} + /* * This is essentially a wrapper for replmd_replicated_apply_next() * @@ -6805,20 +6844,19 @@ static int replmd_replicated_apply_next(struct replmd_replicated_request *ar) */ static int replmd_replicated_apply_isDeleted(struct replmd_replicated_request *ar) { - struct ldb_dn *deleted_objects_dn; struct ldb_message *msg = ar->objs->objects[ar->index_current].msg; int ret; + bool apply_isDeleted; - if (!ar->isDeleted) { + apply_isDeleted = replmd_should_apply_isDeleted(ar, msg); - /* not a deleted object, so nothing to do */ + if (!apply_isDeleted) { + + /* nothing to do */ ar->index_current++; return replmd_replicated_apply_next(ar); - } - ret = dsdb_get_deleted_objects_dn(ldb_module_get_ctx(ar->module), msg, - msg->dn, &deleted_objects_dn); - if (ret != LDB_SUCCESS || ldb_dn_compare(msg->dn, deleted_objects_dn) != 0) { + } else { /* * Do a delete here again, so that if there is * anything local that conflicts with this