Blame SOURCES/0064-overrides-fixes-for-sysdb_invalidate_overrides.patch

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