summaryrefslogtreecommitdiffstats
path: root/server/providers/ldap/ldap_id_cleanup.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers/ldap/ldap_id_cleanup.c')
-rw-r--r--server/providers/ldap/ldap_id_cleanup.c555
1 files changed, 0 insertions, 555 deletions
diff --git a/server/providers/ldap/ldap_id_cleanup.c b/server/providers/ldap/ldap_id_cleanup.c
deleted file mode 100644
index f3fb4443c..000000000
--- a/server/providers/ldap/ldap_id_cleanup.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- SSSD
-
- LDAP Identity Cleanup Functions
-
- Authors:
- Simo Sorce <ssorce@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-
-#include "util/util.h"
-#include "db/sysdb.h"
-#include "providers/ldap/ldap_common.h"
-#include "providers/ldap/sdap_async.h"
-
-/* ==Cleanup-Task========================================================= */
-
-struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-static void ldap_id_cleanup_reschedule(struct tevent_req *req);
-
-static void ldap_id_cleanup_timeout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt);
-
-static void ldap_id_cleanup_timer(struct tevent_context *ev,
- struct tevent_timer *tt,
- struct timeval tv, void *pvt)
-{
- struct sdap_id_ctx *ctx = talloc_get_type(pvt, struct sdap_id_ctx);
- struct tevent_timer *timeout;
- struct tevent_req *req;
- int delay;
-
- if (be_is_offline(ctx->be)) {
- DEBUG(4, ("Backend is marked offline, retry later!\n"));
- /* schedule starting from now, not the last run */
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- tv = tevent_timeval_current_ofs(delay, 0);
- ldap_id_cleanup_set_timer(ctx, tv);
- return;
- }
-
- req = ldap_id_cleanup_send(ctx, ev, ctx);
- if (!req) {
- DEBUG(1, ("Failed to schedule cleanup, retrying later!\n"));
- /* schedule starting from now, not the last run */
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- tv = tevent_timeval_current_ofs(delay, 0);
- ldap_id_cleanup_set_timer(ctx, tv);
- return;
- }
- tevent_req_set_callback(req, ldap_id_cleanup_reschedule, ctx);
-
- /* if cleanup takes so long, either we try to cleanup too
- * frequently, or something went seriously wrong */
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- tv = tevent_timeval_current_ofs(delay, 0);
- timeout = tevent_add_timer(ctx->be->ev, req, tv,
- ldap_id_cleanup_timeout, req);
- return;
-}
-
-static void ldap_id_cleanup_timeout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_id_ctx *ctx = tevent_req_callback_data(req,
- struct sdap_id_ctx);
- int delay;
-
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- DEBUG(1, ("Cleanup timed out! Timeout too small? (%ds)!\n", delay));
-
- tv = tevent_timeval_current_ofs(delay, 0);
- ldap_id_enumerate_set_timer(ctx, tv);
-
- talloc_zfree(req);
-}
-
-static void ldap_id_cleanup_reschedule(struct tevent_req *req)
-{
- struct sdap_id_ctx *ctx = tevent_req_callback_data(req,
- struct sdap_id_ctx);
- enum tevent_req_state tstate;
- uint64_t err;
- struct timeval tv;
- int delay;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- /* On error schedule starting from now, not the last run */
- tv = tevent_timeval_current();
- } else {
- tv = ctx->last_purge;
- }
- talloc_zfree(req);
-
- delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT);
- tv = tevent_timeval_add(&tv, delay, 0);
- ldap_id_enumerate_set_timer(ctx, tv);
-}
-
-
-
-int ldap_id_cleanup_set_timer(struct sdap_id_ctx *ctx, struct timeval tv)
-{
- struct tevent_timer *cleanup_task;
-
- DEBUG(6, ("Scheduling next cleanup at %ld.%ld\n",
- (long)tv.tv_sec, (long)tv.tv_usec));
-
- cleanup_task = tevent_add_timer(ctx->be->ev, ctx,
- tv, ldap_id_cleanup_timer, ctx);
- if (!cleanup_task) {
- DEBUG(0, ("FATAL: failed to setup cleanup task!\n"));
- return EFAULT;
- }
-
- return EOK;
-}
-
-
-
-struct global_cleanup_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
-};
-
-static struct tevent_req *cleanup_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-static void ldap_id_cleanup_users_done(struct tevent_req *subreq);
-static struct tevent_req *cleanup_groups_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx);
-static void ldap_id_cleanup_groups_done(struct tevent_req *subreq);
-
-struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx)
-{
- struct global_cleanup_state *state;
- struct tevent_req *req, *subreq;
-
- req = tevent_req_create(memctx, &state, struct global_cleanup_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
-
- subreq = cleanup_users_send(state, ev, ctx);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, ldap_id_cleanup_users_done, req);
-
- ctx->last_purge = tevent_timeval_current();
-
- return req;
-}
-
-static void ldap_id_cleanup_users_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct global_cleanup_state *state = tevent_req_data(req,
- struct global_cleanup_state);
- enum tevent_req_state tstate;
- uint64_t err = 0;
-
- if (tevent_req_is_error(subreq, &tstate, &err)) {
- if (tstate != TEVENT_REQ_USER_ERROR) {
- err = EIO;
- }
- if (err != ENOENT) {
- goto fail;
- }
- }
- talloc_zfree(subreq);
-
- subreq = cleanup_groups_send(state, state->ev, state->ctx);
- if (!subreq) {
- goto fail;
- }
- tevent_req_set_callback(subreq, ldap_id_cleanup_groups_done, req);
-
- return;
-
-fail:
- if (err) {
- DEBUG(9, ("User cleanup failed with: (%d)[%s]\n",
- (int)err, strerror(err)));
-
- if (sdap_check_gssapi_reconnect(state->ctx)) {
- talloc_zfree(state->ctx->gsh);
- subreq = cleanup_users_send(state, state->ev, state->ctx);
- if (subreq != NULL) {
- tevent_req_set_callback(subreq, ldap_id_cleanup_users_done, req);
- return;
- }
- }
- sdap_mark_offline(state->ctx);
- }
-
- DEBUG(1, ("Failed to cleanup users, retrying later!\n"));
- tevent_req_done(req);
-}
-
-static void ldap_id_cleanup_groups_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct global_cleanup_state *state = tevent_req_data(req,
- struct global_cleanup_state);
- enum tevent_req_state tstate;
- uint64_t err;
-
- if (tevent_req_is_error(subreq, &tstate, &err)) {
- if (tstate != TEVENT_REQ_USER_ERROR) {
- err = EIO;
- }
- if (err != ENOENT) {
- goto fail;
- }
- }
- talloc_zfree(subreq);
-
- tevent_req_done(req);
- return;
-
-fail:
- /* check if credentials are expired otherwise go offline on failures */
- if (sdap_check_gssapi_reconnect(state->ctx)) {
- talloc_zfree(state->ctx->gsh);
- subreq = cleanup_groups_send(state, state->ev, state->ctx);
- if (subreq != NULL) {
- tevent_req_set_callback(subreq, ldap_id_cleanup_groups_done, req);
- return;
- }
- }
- sdap_mark_offline(state->ctx);
- DEBUG(1, ("Failed to cleanup groups (%d [%s]), retrying later!\n",
- (int)err, strerror(err)));
- tevent_req_done(req);
-}
-
-
-/* ==User-Cleanup-Process================================================= */
-
-struct cleanup_users_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
- struct sysdb_ctx *sysdb;
- struct sss_domain_info *domain;
-
- struct sysdb_handle *handle;
-
- struct ldb_message **msgs;
- size_t count;
- int cur;
-};
-
-static void cleanup_users_process(struct tevent_req *subreq);
-static void cleanup_users_update(struct tevent_req *req);
-static void cleanup_users_up_done(struct tevent_req *subreq);
-
-static struct tevent_req *cleanup_users_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx)
-{
- struct tevent_req *req, *subreq;
- struct cleanup_users_state *state;
- static const char *attrs[] = { SYSDB_NAME, NULL };
- time_t now = time(NULL);
- char *subfilter;
-
- req = tevent_req_create(memctx, &state, struct cleanup_users_state);
- if (!req) {
- return NULL;
- }
-
- state->ev = ev;
- state->ctx = ctx;
- state->sysdb = ctx->be->sysdb;
- state->domain = ctx->be->domain;
- state->msgs = NULL;
- state->count = 0;
- state->cur = 0;
-
- subfilter = talloc_asprintf(state, "(&(!(%s=0))(%s<=%ld))",
- SYSDB_CACHE_EXPIRE,
- SYSDB_CACHE_EXPIRE, (long)now);
- if (!subfilter) {
- DEBUG(2, ("Failed to build filter\n"));
- talloc_zfree(req);
- return NULL;
- }
-
- subreq = sysdb_search_users_send(state, state->ev,
- state->sysdb, NULL,
- state->domain, subfilter, attrs);
- if (!subreq) {
- DEBUG(2, ("Failed to send entry search\n"));
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, cleanup_users_process, req);
-
- return req;
-}
-
-static void cleanup_users_process(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cleanup_users_state *state = tevent_req_data(req,
- struct cleanup_users_state);
- int ret;
-
- ret = sysdb_search_users_recv(subreq, state, &state->count, &state->msgs);
- talloc_zfree(subreq);
- if (ret) {
- if (ret == ENOENT) {
- tevent_req_done(req);
- return;
- }
- tevent_req_error(req, ret);
- return;
- }
-
- DEBUG(4, ("Found %d expired user entries!\n", state->count));
-
- if (state->count == 0) {
- tevent_req_done(req);
- }
-
- cleanup_users_update(req);
-}
-
-static void cleanup_users_update(struct tevent_req *req)
-{
- struct tevent_req *subreq;
- struct cleanup_users_state *state = tevent_req_data(req,
- struct cleanup_users_state);
- const char *str;
-
- str = ldb_msg_find_attr_as_string(state->msgs[state->cur],
- SYSDB_NAME, NULL);
- if (!str) {
- DEBUG(2, ("Entry %s has no Name Attribute ?!?\n",
- ldb_dn_get_linearized(state->msgs[state->cur]->dn)));
- tevent_req_error(req, EFAULT);
- return;
- }
-
- subreq = users_get_send(state, state->ev, state->ctx,
- str, BE_FILTER_NAME, BE_ATTR_CORE);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, cleanup_users_up_done, req);
-}
-
-static void cleanup_users_up_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cleanup_users_state *state = tevent_req_data(req,
- struct cleanup_users_state);
- int ret;
-
- ret = users_get_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("User check returned: %d(%s)\n",
- ret, strerror(ret)));
- }
-
- /* if the entry doesn't need to be purged, remove it from the list */
- if (ret != ENOENT) {
- talloc_zfree(state->msgs[state->cur]);
- }
-
- state->cur++;
- if (state->cur < state->count) {
- cleanup_users_update(req);
- return;
- }
-
- tevent_req_done(req);
-}
-
-/* ==Group-Cleanup-Process================================================ */
-
-struct cleanup_groups_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *ctx;
- struct sysdb_ctx *sysdb;
- struct sss_domain_info *domain;
-
- struct sysdb_handle *handle;
-
- struct ldb_message **msgs;
- size_t count;
- int cur;
-};
-
-static void cleanup_groups_process(struct tevent_req *subreq);
-static void cleanup_groups_update(struct tevent_req *req);
-static void cleanup_groups_up_done(struct tevent_req *subreq);
-
-static struct tevent_req *cleanup_groups_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx)
-{
- struct tevent_req *req, *subreq;
- struct cleanup_groups_state *state;
- static const char *attrs[] = { SYSDB_NAME, NULL };
- time_t now = time(NULL);
- char *subfilter;
-
- req = tevent_req_create(memctx, &state, struct cleanup_groups_state);
- if (!req) {
- return NULL;
- }
-
- state->ev = ev;
- state->ctx = ctx;
- state->sysdb = ctx->be->sysdb;
- state->domain = ctx->be->domain;
- state->msgs = NULL;
- state->count = 0;
- state->cur = 0;
-
- subfilter = talloc_asprintf(state, "(&(!(%s=0))(%s<=%ld))",
- SYSDB_CACHE_EXPIRE,
- SYSDB_CACHE_EXPIRE, (long)now);
- if (!subfilter) {
- DEBUG(2, ("Failed to build filter\n"));
- talloc_zfree(req);
- return NULL;
- }
-
- subreq = sysdb_search_groups_send(state, state->ev,
- state->sysdb, NULL,
- state->domain, subfilter, attrs);
- if (!subreq) {
- DEBUG(2, ("Failed to send entry search\n"));
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, cleanup_groups_process, req);
-
- return req;
-}
-
-static void cleanup_groups_process(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cleanup_groups_state *state = tevent_req_data(req,
- struct cleanup_groups_state);
- int ret;
-
- ret = sysdb_search_groups_recv(subreq, state, &state->count, &state->msgs);
- talloc_zfree(subreq);
- if (ret) {
- if (ret == ENOENT) {
- tevent_req_done(req);
- return;
- }
- tevent_req_error(req, ret);
- return;
- }
-
- DEBUG(4, ("Found %d expired group entries!\n", state->count));
-
- if (state->count == 0) {
- tevent_req_done(req);
- }
-
- cleanup_groups_update(req);
-}
-
-static void cleanup_groups_update(struct tevent_req *req)
-{
- struct tevent_req *subreq;
- struct cleanup_groups_state *state = tevent_req_data(req,
- struct cleanup_groups_state);
- const char *str;
-
- str = ldb_msg_find_attr_as_string(state->msgs[state->cur],
- SYSDB_NAME, NULL);
- if (!str) {
- DEBUG(2, ("Entry %s has no Name Attribute ?!?\n",
- ldb_dn_get_linearized(state->msgs[state->cur]->dn)));
- tevent_req_error(req, EFAULT);
- return;
- }
-
- subreq = groups_get_send(state, state->ev, state->ctx,
- str, BE_FILTER_NAME, BE_ATTR_CORE);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, cleanup_groups_up_done, req);
-}
-
-static void cleanup_groups_up_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cleanup_groups_state *state = tevent_req_data(req,
- struct cleanup_groups_state);
- int ret;
-
- ret = groups_get_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("User check returned: %d(%s)\n",
- ret, strerror(ret)));
- }
-
- state->cur++;
- if (state->cur < state->count) {
- cleanup_groups_update(req);
- return;
- }
-
- tevent_req_done(req);
-}
-