Blob Blame History Raw
From c0263b48a3512d8b6984693c4b8e772844215f9e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 20 Nov 2017 15:51:27 +0100
Subject: [PATCH 64/67] 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 <fidencio@redhat.com>
(cherry picked from commit 4671acb949c65c5c080532e03b1b6f1c9377a6a5)
---
 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 afc7852ecf402ef144beca9c1b94fbe3cc4bbb6a..70082d8db9b25c11e8c0823d4e5da2ba0c0d10d1 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.14.3