summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-01-06 00:10:33 -0500
committerJakub Hrozek <jhrozek@redhat.com>2013-01-10 10:50:11 +0100
commit4c2cf6607ddc82c5061d805c11e163de4bc1bd82 (patch)
tree8f71f9bea29f1753ababa18f86f18a927e8560db
parentfd555d130dc733509347fa096a2cb858b014a196 (diff)
downloadsssd-4c2cf6607ddc82c5061d805c11e163de4bc1bd82.tar.gz
sssd-4c2cf6607ddc82c5061d805c11e163de4bc1bd82.tar.bz2
sssd-4c2cf6607ddc82c5061d805c11e163de4bc1bd82.zip
Fix sdap reinit.
This set of functions had a few important issues: 1. the base_dn was always NULL, as the base array was never actually used to construct any DN. This means each function searched the whole database multiple times. It would try to remove SYSDB_USN from all database entries 3 times. Then it would try to find non updated entries another 3 times and delete them, arguably find empty results the last 2 times. 2. Remove use of sysdb_private.h, that header is *PRIVATE* which means it should not be used anywhere but within sysdb. Do this by using existing functions instead of using ldb calls directly. This is important to keep sysdb as conistent and self-contained as possible.
-rw-r--r--src/providers/ldap/sdap_reinit.c171
1 files changed, 89 insertions, 82 deletions
diff --git a/src/providers/ldap/sdap_reinit.c b/src/providers/ldap/sdap_reinit.c
index 0200de0a..4c75f6c3 100644
--- a/src/providers/ldap/sdap_reinit.c
+++ b/src/providers/ldap/sdap_reinit.c
@@ -27,7 +27,6 @@
#include "providers/ldap/ldap_common.h"
#include "db/sysdb.h"
#include "db/sysdb_services.h"
-#include "db/sysdb_private.h"
struct sdap_reinit_cleanup_state {
struct sysdb_ctx *sysdb;
@@ -61,21 +60,23 @@ struct tevent_req* sdap_reinit_cleanup_send(TALLOC_CTX *mem_ctx,
return NULL;
}
+ state->sysdb = be_ctx->domain->sysdb;
+
if (!be_ctx->domain->enumerate) {
/* enumeration is disabled, this whole process is meaningless */
ret = EOK;
goto immediately;
}
- ret = sdap_reinit_clear_usn(be_ctx->domain->sysdb);
+ ret = sdap_reinit_clear_usn(state->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to clear USN attributes [%d]: %s\n",
ret, strerror(ret)));
goto immediately;
}
- req = ldap_id_enumerate_send(be_ctx->ev, id_ctx);
- if (req == NULL) {
+ subreq = ldap_id_enumerate_send(be_ctx->ev, id_ctx);
+ if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to issue enumeration request\n"));
ret = ENOMEM;
goto immediately;
@@ -96,23 +97,32 @@ immediately:
return req;
}
+static void sdap_delete_msgs_usn(struct sysdb_ctx *sysdb,
+ struct ldb_message **msgs,
+ size_t msgs_num)
+{
+ struct ldb_message_element el = { 0, SYSDB_USN, 0, NULL };
+ struct sysdb_attrs usn_el = { 1, &el };
+ errno_t ret;
+ int i;
+
+ for (i = 0; i < msgs_num; i++) {
+ ret = sysdb_set_entry_attr(sysdb, msgs[i]->dn, &usn_el, SYSDB_MOD_DEL);
+ if (ret) {
+ DEBUG(SSSDBG_TRACE_FUNC, ("Failed to clean USN on entry: [%s]\n",
+ ldb_dn_get_linearized(msgs[i]->dn)));
+ }
+ }
+}
+
static errno_t sdap_reinit_clear_usn(struct sysdb_ctx *sysdb)
{
TALLOC_CTX *tmp_ctx = NULL;
bool in_transaction = false;
- struct ldb_result *result = NULL;
- struct ldb_message **messages = NULL;
- struct ldb_message *msg = NULL;
- int messages_num = 0;
- struct ldb_dn *base_dn = NULL;
- const char *base[] = { SYSDB_TMPL_USER_BASE,
- SYSDB_TMPL_GROUP_BASE,
- SYSDB_TMPL_SVC_BASE,
- NULL };
+ struct ldb_message **msgs = NULL;
+ size_t msgs_num = 0;
const char *attrs[] = { "dn", NULL };
- int i, j;
int sret;
- int lret;
errno_t ret;
tmp_ctx = talloc_new(NULL);
@@ -121,56 +131,35 @@ static errno_t sdap_reinit_clear_usn(struct sysdb_ctx *sysdb)
return ENOMEM;
}
- for (i = 0; base[i] != NULL; i++) {
- lret = ldb_search(sysdb->ldb, tmp_ctx, &result, base_dn,
- LDB_SCOPE_SUBTREE, attrs, NULL);
- if (lret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(lret);
- goto done;
- }
-
- if (result->count == 0) {
- talloc_zfree(result);
- continue;
- }
-
- messages = talloc_realloc(tmp_ctx, messages, struct ldb_message*,
- messages_num + result->count);
-
- for (j = 0; j < result->count; j++) {
- msg = ldb_msg_new(messages);
- if (msg == NULL) {
- ret = ENOMEM;
- goto done;
- }
- msg->dn = talloc_move(tmp_ctx, &result->msgs[j]->dn);
-
- lret = ldb_msg_add_empty(msg, SYSDB_USN, LDB_FLAG_MOD_DELETE, NULL);
- if (lret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(lret);
- goto done;
- }
-
- messages[messages_num + j] = msg;
- }
-
- messages_num += result->count;
- talloc_zfree(result);
- }
-
ret = sysdb_transaction_start(sysdb);
if (ret != EOK) {
goto done;
}
in_transaction = true;
- for (i = 0; i < messages_num; i++) {
- lret = ldb_modify(sysdb->ldb, messages[i]);
- if (lret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(lret);
- goto done;
- }
+ /* reset users' usn */
+ ret = sysdb_search_users(tmp_ctx, sysdb, "", attrs, &msgs_num, &msgs);
+ if (ret != EOK) {
+ goto done;
+ }
+ sdap_delete_msgs_usn(sysdb, msgs, msgs_num);
+ talloc_zfree(msgs);
+ msgs_num = 0;
+
+ /* reset groups' usn */
+ ret = sysdb_search_groups(tmp_ctx, sysdb, "", attrs, &msgs_num, &msgs);
+ if (ret != EOK) {
+ goto done;
}
+ sdap_delete_msgs_usn(sysdb, msgs, msgs_num);
+ talloc_zfree(msgs);
+ msgs_num = 0;
+
+ /* reset services' usn */
+ ret = sysdb_search_services(tmp_ctx, sysdb, "", attrs, &msgs_num, &msgs);
+ sdap_delete_msgs_usn(sysdb, msgs, msgs_num);
+ talloc_zfree(msgs);
+ msgs_num = 0;
ret = sysdb_transaction_commit(sysdb);
if (ret == EOK) {
@@ -234,20 +223,30 @@ fail:
tevent_req_error(req, ret);
}
+static void sdap_delete_msgs_dn(struct sysdb_ctx *sysdb,
+ struct ldb_message **msgs,
+ size_t msgs_num)
+{
+ errno_t ret;
+ int i;
+
+ for (i = 0; i < msgs_num; i++) {
+ ret = sysdb_delete_entry(sysdb, msgs[i]->dn, true);
+ if (ret) {
+ DEBUG(SSSDBG_TRACE_FUNC, ("Failed to delete entry: [%s]\n",
+ ldb_dn_get_linearized(msgs[i]->dn)));
+ }
+ }
+}
+
static errno_t sdap_reinit_delete_records(struct sysdb_ctx *sysdb)
{
TALLOC_CTX *tmp_ctx = NULL;
bool in_transaction = false;
- struct ldb_result *result = NULL;
- struct ldb_dn *base_dn = NULL;
- const char *base[] = { SYSDB_TMPL_USER_BASE,
- SYSDB_TMPL_GROUP_BASE,
- SYSDB_TMPL_SVC_BASE,
- NULL };
+ struct ldb_message **msgs = NULL;
+ size_t msgs_num = 0;
const char *attrs[] = { "dn", NULL };
- int i, j;
int sret;
- int lret;
errno_t ret;
tmp_ctx = talloc_new(NULL);
@@ -262,24 +261,32 @@ static errno_t sdap_reinit_delete_records(struct sysdb_ctx *sysdb)
}
in_transaction = true;
- for (i = 0; base[i] != NULL; i++) {
- lret = ldb_search(sysdb->ldb, tmp_ctx, &result, base_dn,
- LDB_SCOPE_SUBTREE, attrs, "(!("SYSDB_USN"=*))");
- if (lret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(lret);
- goto done;
- }
-
- for (j = 0; j < result->count; j++) {
- ret = ldb_delete(sysdb->ldb, result->msgs[i]->dn);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
- }
+ /* purge untouched users */
+ ret = sysdb_search_users(tmp_ctx, sysdb, "(!("SYSDB_USN"=*))",
+ attrs, &msgs_num, &msgs);
+ if (ret != EOK) {
+ goto done;
+ }
+ sdap_delete_msgs_dn(sysdb, msgs, msgs_num);
+ talloc_zfree(msgs);
+ msgs_num = 0;
- talloc_zfree(result);
+ /* purge untouched groups */
+ ret = sysdb_search_groups(tmp_ctx, sysdb, "(!("SYSDB_USN"=*))",
+ attrs, &msgs_num, &msgs);
+ if (ret != EOK) {
+ goto done;
}
+ sdap_delete_msgs_dn(sysdb, msgs, msgs_num);
+ talloc_zfree(msgs);
+ msgs_num = 0;
+
+ /* purge untouched services */
+ ret = sysdb_search_services(tmp_ctx, sysdb, "(!("SYSDB_USN"=*))",
+ attrs, &msgs_num, &msgs);
+ sdap_delete_msgs_dn(sysdb, msgs, msgs_num);
+ talloc_zfree(msgs);
+ msgs_num = 0;
ret = sysdb_transaction_commit(sysdb);
if (ret == EOK) {