From 7554a558f06b4e0e1509baf5dab6223691faa1e0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 11 Sep 2017 13:53:19 +1200 Subject: [PATCH] dsdb: Only trigger a re-index once per @INDEXLIST modification A modify of both @INDEXLIST and @ATTRIBUTES will still trigger two re-index passes but that is a task for later. BUG: https://bugzilla.samba.org/show_bug.cgi?id=9527 Signed-off-by: Andrew Bartlett --- source4/dsdb/samdb/ldb_modules/partition.c | 62 +++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index c304efa645d..f1fa860273b 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -432,30 +432,56 @@ static int partition_copy_all(struct ldb_module *module, return search_ret; } - /* now delete the object in the other partitions. Once that is - done we will re-add the object, if search_ret was not - LDB_ERR_NO_SUCH_OBJECT + /* now delete the object in the other partitions, if requried */ - for (i=0; data->partitions && data->partitions[i]; i++) { - int pret; - pret = dsdb_module_del(data->partitions[i]->module, dn, DSDB_FLAG_NEXT_MODULE, req); - if (pret != LDB_SUCCESS && pret != LDB_ERR_NO_SUCH_OBJECT) { - /* we should only get success or no - such object from the other partitions */ - return pret; - } - } - - - if (search_ret != LDB_ERR_NO_SUCH_OBJECT) { - /* now re-add in the other partitions */ + if (search_ret == LDB_ERR_NO_SUCH_OBJECT) { for (i=0; data->partitions && data->partitions[i]; i++) { int pret; - pret = dsdb_module_add(data->partitions[i]->module, res->msgs[0], DSDB_FLAG_NEXT_MODULE, req); - if (pret != LDB_SUCCESS) { + pret = dsdb_module_del(data->partitions[i]->module, + dn, + DSDB_FLAG_NEXT_MODULE, + req); + if (pret != LDB_SUCCESS && pret != LDB_ERR_NO_SUCH_OBJECT) { + /* we should only get success or no + such object from the other partitions */ return pret; } } + + return ldb_module_done(req, NULL, NULL, LDB_SUCCESS); + } + + /* now add/modify in the other partitions */ + for (i=0; data->partitions && data->partitions[i]; i++) { + int pret; + pret = dsdb_module_add(data->partitions[i]->module, + res->msgs[0], + DSDB_FLAG_NEXT_MODULE, + req); + if (pret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + struct ldb_message *replace_msg + = res->msgs[0]; + unsigned int el_idx; + /* + * mark all the message elements as + * LDB_FLAG_MOD_REPLACE + */ + for (el_idx=0; + el_idx < replace_msg->num_elements; + el_idx++) { + replace_msg->elements[el_idx].flags + = LDB_FLAG_MOD_REPLACE; + } + + pret = dsdb_module_modify(data->partitions[i]->module, + replace_msg, + DSDB_FLAG_NEXT_MODULE, + req); + + } + if (pret != LDB_SUCCESS) { + return pret; + } } return ldb_module_done(req, NULL, NULL, LDB_SUCCESS); -- 2.11.0