From 3edca52d650154bcd784674d631a76512c6c4004 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Mon, 20 Nov 2017 15:51:27 +0100 Subject: [PATCH 71/79] overrides: fixes for sysdb_invalidate_overrides() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There were two issues in sysdb_invalidate_overrides(). First, SYSDB_CACHE_EXPIRE was only reset for the entry in the data cache but not in the timestamp cache. Second, if one of the steps in the combined replace and delete operation failed no change was committed to the cache. If, for whatever reasons, a user or group object didn't had SYSDB_OVERRIDE_DN set the delete failed and hence SYSDB_CACHE_EXPIRE wasn't reset as well. To make sure the cache is in a consistent state after a view change the replace and the delete operations are don in two steps. Related to https://pagure.io/SSSD/sssd/issue/3579 Reviewed-by: Fabiano FidĂȘncio --- src/db/sysdb_views.c | 111 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 80 insertions(+), 31 deletions(-) diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c index f640c813acf4deafe98eb15708d3a94790502dcb..bcd7dd46168aecdf808ad315175a12cef9ee03dd 100644 --- a/src/db/sysdb_views.c +++ b/src/db/sysdb_views.c @@ -279,6 +279,45 @@ done: return ret; } +static errno_t invalidate_entry_override(struct sysdb_ctx *sysdb, + struct ldb_dn *dn, + struct ldb_message *msg_del, + struct ldb_message *msg_repl) +{ + int ret; + + msg_del->dn = dn; + msg_repl->dn = dn; + + ret = ldb_modify(sysdb->ldb, msg_del); + if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { + DEBUG(SSSDBG_OP_FAILURE, + "ldb_modify failed: [%s](%d)[%s]\n", + ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); + return sysdb_error_to_errno(ret); + } + + ret = ldb_modify(sysdb->ldb, msg_repl); + if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { + DEBUG(SSSDBG_OP_FAILURE, + "ldb_modify failed: [%s](%d)[%s]\n", + ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); + return sysdb_error_to_errno(ret); + } + + if (sysdb->ldb_ts != NULL) { + ret = ldb_modify(sysdb->ldb_ts, msg_repl); + if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { + DEBUG(SSSDBG_OP_FAILURE, + "ldb_modify failed: [%s](%d)[%s]\n", + ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb_ts)); + return sysdb_error_to_errno(ret); + } + } + + return EOK; +} + errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) { int ret; @@ -287,22 +326,23 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) bool in_transaction = false; struct ldb_result *res; size_t c; - struct ldb_message *msg; + struct ldb_message *msg_del; + struct ldb_message *msg_repl; struct ldb_dn *base_dn; + if (sysdb->ldb_ts == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Timestamp cache context not available, cache might not be " + "invalidated completely. Please call 'sss_cache -E' or remove " + "the cache file if there are issues after a view name change.\n"); + } + tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); - ret = ENOMEM; - goto done; - } - base_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE); if (base_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed\n"); @@ -310,27 +350,40 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) goto done; } - ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE, LDB_FLAG_MOD_REPLACE, + msg_del = ldb_msg_new(tmp_ctx); + if (msg_del == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_empty(msg_del, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_DELETE, NULL); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } - ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1"); + + msg_repl = ldb_msg_new(tmp_ctx); + if (msg_repl == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_empty(msg_repl, SYSDB_CACHE_EXPIRE, + LDB_FLAG_MOD_REPLACE, NULL); + if (ret != LDB_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); + ret = sysdb_error_to_errno(ret); + goto done; + } + ret = ldb_msg_add_string(msg_repl, SYSDB_CACHE_EXPIRE, "1"); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } - ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_DELETE, NULL); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); - ret = sysdb_error_to_errno(ret); - goto done; - } - ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n"); @@ -347,14 +400,12 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) } for (c = 0; c < res->count; c++) { - msg->dn = res->msgs[c]->dn; - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { + ret = invalidate_entry_override(sysdb, res->msgs[c]->dn, msg_del, + msg_repl); + if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, - "ldb_modify failed: [%s](%d)[%s]\n", - ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); - ret = sysdb_error_to_errno(ret); + "invalidate_entry_override failed [%d][%s].\n", + ret, sss_strerror(ret)); goto done; } } @@ -370,14 +421,12 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) } for (c = 0; c < res->count; c++) { - msg->dn = res->msgs[c]->dn; - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { + ret = invalidate_entry_override(sysdb, res->msgs[c]->dn, msg_del, + msg_repl); + if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, - "ldb_modify failed: [%s](%d)[%s]\n", - ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); - ret = sysdb_error_to_errno(ret); + "invalidate_entry_override failed [%d][%s].\n", + ret, sss_strerror(ret)); goto done; } } -- 2.15.1