Blob Blame History Raw
From 26ae40bd74a00a9701f732a8957c06ff8fc857a4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 12 Nov 2014 16:26:55 +0100
Subject: [PATCH 114/115] sysdb: add sysdb_invalidate_overrides()

---
 src/db/sysdb.h                      |   2 +
 src/db/sysdb_views.c                | 123 ++++++++++++++++++++++++++++++++++++
 src/tests/cmocka/test_sysdb_views.c |  69 ++++++++++++++++++++
 3 files changed, 194 insertions(+)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index a3ffa7b759e8aa16fc8a60cb01c6f0cb49278cc0..5bd7f90acb685bbaff5c98f433c7dce8175c33ca 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -446,6 +446,8 @@ errno_t sysdb_get_view_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
 
 errno_t sysdb_delete_view_tree(struct sysdb_ctx *sysdb, const char *view_name);
 
+errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb);
+
 errno_t sysdb_apply_default_override(struct sss_domain_info *domain,
                                      struct sysdb_attrs *override_attrs,
                                      struct ldb_dn *obj_dn);
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
index e17321455ad2ac4e4f17094f83c482d95bb00d8b..970d83e657d4fdfb73ac0e1fcc124ec690e29d4b 100644
--- a/src/db/sysdb_views.c
+++ b/src/db/sysdb_views.c
@@ -214,6 +214,129 @@ done:
     return ret;
 }
 
+errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb)
+{
+    int ret;
+    int sret;
+    TALLOC_CTX *tmp_ctx;
+    bool in_transaction = false;
+    struct ldb_result *res;
+    size_t c;
+    struct ldb_message *msg;
+    struct ldb_dn *base_dn;
+
+    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");
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = ldb_msg_add_empty(msg, 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, 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");
+        goto done;
+    }
+    in_transaction = true;
+
+    ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE,
+                     NULL, "%s", SYSDB_UC);
+    if (ret != LDB_SUCCESS) {
+        DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n");
+        ret = sysdb_error_to_errno(ret);
+        goto done;
+    }
+
+    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) {
+            DEBUG(SSSDBG_OP_FAILURE, "ldb_modify failed.\n");
+            ret = sysdb_error_to_errno(ret);
+            goto done;
+        }
+    }
+
+    talloc_free(res);
+
+    ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE,
+                     NULL, "%s", SYSDB_GC);
+    if (ret != LDB_SUCCESS) {
+        DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n");
+        ret = sysdb_error_to_errno(ret);
+        goto done;
+    }
+
+    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) {
+            DEBUG(SSSDBG_OP_FAILURE, "ldb_modify failed.\n");
+            ret = sysdb_error_to_errno(ret);
+            goto done;
+        }
+    }
+
+    ret = EOK;
+done:
+    if (in_transaction) {
+        if (ret == EOK) {
+            sret = sysdb_transaction_commit(sysdb);
+            if (sret != EOK) {
+                DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_commit failed, " \
+                                         "nothing we can do about.\n");
+                ret = sret;
+            }
+        } else {
+            sret = sysdb_transaction_cancel(sysdb);
+            if (sret != EOK) {
+                DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_cancel failed, " \
+                                         "nothing we can do about.\n");
+            }
+        }
+    }
+
+    talloc_free(tmp_ctx);
+
+    return ret;
+}
+
 static errno_t
 add_name_and_aliases_for_name_override(struct sss_domain_info *domain,
                                        struct sysdb_attrs *attrs,
diff --git a/src/tests/cmocka/test_sysdb_views.c b/src/tests/cmocka/test_sysdb_views.c
index 6be28e624d102060121f9afa91b282f7e8620676..7238467c3c9bf91fd0d48204dd7217d4d273e965 100644
--- a/src/tests/cmocka/test_sysdb_views.c
+++ b/src/tests/cmocka/test_sysdb_views.c
@@ -291,6 +291,73 @@ void test_sysdb_delete_view_tree(void **state)
 
 }
 
+void test_sysdb_invalidate_overrides(void **state)
+{
+    int ret;
+    struct ldb_message *msg;
+    struct sysdb_attrs *attrs;
+    struct ldb_dn *views_dn;
+    const char *user_attrs[] = { SYSDB_NAME,
+                                 SYSDB_CACHE_EXPIRE,
+                                 SYSDB_OVERRIDE_DN,
+                                 NULL};
+
+    struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state,
+                                                         struct sysdb_test_ctx);
+
+    test_ctx->domain->mpg = false;
+
+    ret = sysdb_update_view_name(test_ctx->domain->sysdb, TEST_VIEW_NAME);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_store_user(test_ctx->domain, TEST_USER_NAME, NULL,
+                           TEST_USER_UID, TEST_USER_GID, TEST_USER_GECOS,
+                           TEST_USER_HOMEDIR, TEST_USER_SHELL, NULL, NULL, NULL,
+                           10,0);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, TEST_USER_NAME,
+                                    NULL, &msg);
+    assert_int_equal(ret, EOK);
+    assert_non_null(msg);
+
+    attrs = sysdb_new_attrs(test_ctx);
+    assert_non_null(attrs);
+
+    ret = sysdb_attrs_add_string(attrs, SYSDB_OVERRIDE_ANCHOR_UUID,
+                                 TEST_ANCHOR_PREFIX TEST_USER_SID);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_store_override(test_ctx->domain, TEST_VIEW_NAME,
+                               SYSDB_MEMBER_USER, attrs, msg->dn);
+    assert_int_equal(ret, EOK);
+
+    views_dn = ldb_dn_new(test_ctx, test_ctx->domain->sysdb->ldb,
+                          SYSDB_TMPL_VIEW_BASE);
+    assert_non_null(views_dn);
+
+    ret = sysdb_delete_view_tree(test_ctx->domain->sysdb, TEST_VIEW_NAME);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, TEST_USER_NAME,
+                                    user_attrs, &msg);
+    assert_int_equal(ret, EOK);
+    assert_non_null(msg);
+    assert_true(ldb_msg_find_attr_as_uint64(msg, SYSDB_CACHE_EXPIRE, 0) > 1);
+    assert_non_null(ldb_msg_find_attr_as_string(msg, SYSDB_OVERRIDE_DN, NULL));
+
+    ret = sysdb_invalidate_overrides(test_ctx->domain->sysdb);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, TEST_USER_NAME,
+                                    user_attrs, &msg);
+    assert_int_equal(ret, EOK);
+    assert_non_null(msg);
+    assert_int_equal(ldb_msg_find_attr_as_uint64(msg, SYSDB_CACHE_EXPIRE, 0),
+                     1);
+    assert_null(ldb_msg_find_attr_as_string(msg, SYSDB_OVERRIDE_DN, NULL));
+}
+
 int main(int argc, const char *argv[])
 {
     int rv;
@@ -312,6 +379,8 @@ int main(int argc, const char *argv[])
                                  test_sysdb_setup, test_sysdb_teardown),
         unit_test_setup_teardown(test_sysdb_delete_view_tree,
                                  test_sysdb_setup, test_sysdb_teardown),
+        unit_test_setup_teardown(test_sysdb_invalidate_overrides,
+                                 test_sysdb_setup, test_sysdb_teardown),
     };
 
     /* Set debug level to invalid value so we can deside if -d 0 was used. */
-- 
1.9.3