diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/db/sysdb.h | 2 | ||||
-rw-r--r-- | src/db/sysdb_views.c | 124 | ||||
-rw-r--r-- | src/tests/cmocka/test_sysdb_views.c | 69 |
3 files changed, 195 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h index a3ffa7b75..5bd7f90ac 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 e17321455..079e2bbbf 100644 --- a/src/db/sysdb_views.c +++ b/src/db/sysdb_views.c @@ -214,6 +214,130 @@ 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 6be28e624..7238467c3 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. */ |