diff options
author | Sumit Bose <sbose@redhat.com> | 2009-10-29 12:57:57 +0100 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2009-11-02 16:31:55 -0500 |
commit | c2a29bea5248554a9112d051a7b5be492aa729b6 (patch) | |
tree | 30b20d2f9c831c57049a391332ec0370044ca1ae /server/db | |
parent | 40291f16b36de0af70c62847ec04a9615811c92e (diff) | |
download | sssd-c2a29bea5248554a9112d051a7b5be492aa729b6.tar.gz sssd-c2a29bea5248554a9112d051a7b5be492aa729b6.tar.bz2 sssd-c2a29bea5248554a9112d051a7b5be492aa729b6.zip |
add sysdb_delete_recursive request to sysdb API
Diffstat (limited to 'server/db')
-rw-r--r-- | server/db/sysdb.c | 12 | ||||
-rw-r--r-- | server/db/sysdb.h | 10 | ||||
-rw-r--r-- | server/db/sysdb_ops.c | 153 |
3 files changed, 175 insertions, 0 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c index 5811ddc9..a2ac3b22 100644 --- a/server/db/sysdb.c +++ b/server/db/sysdb.c @@ -1417,3 +1417,15 @@ int sysdb_get_ctx_from_list(struct sysdb_ctx_list *ctx_list, /* definitely not found */ return ENOENT; } + + +int compare_ldb_dn_comp_num(const void *m1, const void *m2) +{ + struct ldb_message *msg1 = talloc_get_type(*(void **) discard_const(m1), + struct ldb_message); + struct ldb_message *msg2 = talloc_get_type(*(void **) discard_const(m2), + struct ldb_message); + + return ldb_dn_get_comp_num(msg2->dn) - ldb_dn_get_comp_num(msg1->dn); +} + diff --git a/server/db/sysdb.h b/server/db/sysdb.h index 00a3378c..72f56dba 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -190,6 +190,8 @@ struct ldb_dn *sysdb_custom_dn(struct sysdb_ctx *ctx, void *memctx, struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *ctx); struct ldb_context *sysdb_handle_get_ldb(struct sysdb_handle *handle); +int compare_ldb_dn_comp_num(const void *m1, const void *m2); + /* function to start and finish a transaction * sysdb_transaction_send() will queue a request for a transaction * when it is done it will call the tevent_req callback, which must @@ -311,6 +313,14 @@ struct tevent_req *sysdb_delete_entry_send(TALLOC_CTX *mem_ctx, bool ignore_not_found); int sysdb_delete_entry_recv(struct tevent_req *req); + +struct tevent_req *sysdb_delete_recursive_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_handle *handle, + struct ldb_dn *dn, + bool ignore_not_found); +int sysdb_delete_recursive_recv(struct tevent_req *req); + /* Search Entry */ struct tevent_req *sysdb_search_entry_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c index acff5e51..0dcf2e37 100644 --- a/server/db/sysdb_ops.c +++ b/server/db/sysdb_ops.c @@ -300,6 +300,159 @@ int sysdb_delete_entry_recv(struct tevent_req *req) } +/* =Remove-Subentries-From-Sysdb=============================================== */ + +struct sysdb_delete_recursive_state { + struct tevent_context *ev; + struct sysdb_handle *handle; + + bool ignore_not_found; + + struct ldb_reply *ldbreply; + size_t msgs_count; + struct ldb_message **msgs; + size_t current_item; +}; + +static void sysdb_delete_search_done(struct tevent_req *subreq); +static void sysdb_delete_recursive_prepare_op(struct tevent_req *req); +static void sysdb_delete_recursive_op_done(struct tevent_req *req); + +struct tevent_req *sysdb_delete_recursive_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_handle *handle, + struct ldb_dn *dn, + bool ignore_not_found) +{ + struct tevent_req *req, *subreq; + struct sysdb_delete_recursive_state *state; + int ret; + const char *no_attrs[] = { NULL }; + + req = tevent_req_create(mem_ctx, &state, + struct sysdb_delete_recursive_state); + if (!req) return NULL; + + state->ev = ev; + state->handle = handle; + state->ignore_not_found = ignore_not_found; + state->ldbreply = NULL; + state->msgs_count = 0; + state->msgs = NULL; + state->current_item = 0; + + subreq = sysdb_search_entry_send(state, ev, handle, dn, LDB_SCOPE_SUBTREE, + "(distinguishedName=*)", no_attrs); + + if (!subreq) { + ERROR_OUT(ret, ENOMEM, fail); + } + tevent_req_set_callback(subreq, sysdb_delete_search_done, req); + + return req; + +fail: + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; +} + +static void sysdb_delete_search_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sysdb_delete_recursive_state *state = tevent_req_data(req, + struct sysdb_delete_recursive_state); + int ret; + + ret = sysdb_search_entry_recv(subreq, state, &state->msgs_count, + &state->msgs); + talloc_zfree(subreq); + if (ret) { + if (state->ignore_not_found && ret == ENOENT) { + tevent_req_done(req); + return; + } + DEBUG(6, ("Search error: %d (%s)\n", ret, strerror(ret))); + tevent_req_error(req, ret); + return; + } + DEBUG(9, ("Found [%d] items to delete.\n", state->msgs_count)); + + qsort(state->msgs, state->msgs_count, sizeof(struct ldb_message *), + compare_ldb_dn_comp_num); + + state->current_item = 0; + sysdb_delete_recursive_prepare_op(req); +} + +static void sysdb_delete_recursive_prepare_op(struct tevent_req *req) +{ + struct sysdb_delete_recursive_state *state = tevent_req_data(req, + struct sysdb_delete_recursive_state); + struct tevent_req *subreq; + int ret; + struct ldb_request *ldbreq; + + if (state->current_item < state->msgs_count) { + DEBUG(9 ,("Trying to delete [%s].\n", + ldb_dn_canonical_string(state, + state->msgs[state->current_item]->dn))); + ret = ldb_build_del_req(&ldbreq, state->handle->ctx->ldb, state, + state->msgs[state->current_item]->dn, NULL, + NULL, NULL, NULL); + if (ret != LDB_SUCCESS) { + DEBUG(1, ("LDB Error: %s(%d)\nError Message: [%s]\n", + ldb_strerror(ret), ret, + ldb_errstring(state->handle->ctx->ldb))); + ret = sysdb_error_to_errno(ret); + goto fail; + } + + subreq = sldb_request_send(state, state->ev, state->handle->ctx->ldb, + ldbreq); + if (!subreq) { + ret = ENOMEM; + goto fail; + } + + state->current_item++; + tevent_req_set_callback(subreq, sysdb_delete_recursive_op_done, req); + return; + } + + tevent_req_done(req); + return; + +fail: + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + tevent_req_error(req, ret); +} + +static void sysdb_delete_recursive_op_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + int ret; + + ret = sysdb_op_default_recv(subreq); + talloc_zfree(subreq); + if (ret) { + DEBUG(6, ("Delete error: %d (%s)\n", ret, strerror(ret))); + tevent_req_error(req, ret); + return; + } + + sysdb_delete_recursive_prepare_op(req); +} + +int sysdb_delete_recursive_recv(struct tevent_req *req) +{ + return sysdb_op_default_recv(req); +} + + /* =Search-Entry========================================================== */ static void sysdb_search_entry_done(struct tevent_req *subreq); |