From 38b2bd97e41388995594126ea4e6b7c55ea0eb5c Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Wed, 20 Jan 2016 13:06:10 +0100 Subject: Rename dp_refresh.c to be_refresh.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Sumit Bose Reviewed-by: Jakub Hrozek Reviewed-by: Lukáš Slebodník --- src/providers/be_refresh.c | 346 +++++++++++++++++++++++++++++++++++++++++++++ src/providers/dp_refresh.c | 346 --------------------------------------------- 2 files changed, 346 insertions(+), 346 deletions(-) create mode 100644 src/providers/be_refresh.c delete mode 100644 src/providers/dp_refresh.c (limited to 'src') diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c new file mode 100644 index 000000000..47b626055 --- /dev/null +++ b/src/providers/be_refresh.c @@ -0,0 +1,346 @@ +/* + Authors: + Pavel Březina + + Copyright (C) 2013 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 . +*/ + +#include +#include +#include +#include + +#include "providers/dp_backend.h" +#include "providers/be_ptask.h" +#include "providers/be_refresh.h" +#include "util/util_errors.h" +#include "db/sysdb.h" + +static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + time_t period, + const char *objectclass, + struct ldb_dn *base_dn, + const char *attr, + char ***_values) +{ + TALLOC_CTX *tmp_ctx = NULL; + const char *attrs[] = {attr, NULL}; + const char *filter = NULL; + char **values = NULL; + struct ldb_message **msgs = NULL; + struct sysdb_attrs **records = NULL; + size_t count; + time_t now = time(NULL); + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + filter = talloc_asprintf(tmp_ctx, "(&(%s<=%lld))", + SYSDB_CACHE_EXPIRE, (long long) now + period); + if (filter == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_search_entry(tmp_ctx, domain->sysdb, base_dn, + LDB_SCOPE_SUBTREE, filter, attrs, + &count, &msgs); + if (ret == ENOENT) { + count = 0; + } else if (ret != EOK) { + goto done; + } + + ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &records); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not convert ldb message to sysdb_attrs\n"); + goto done; + } + + ret = sysdb_attrs_to_list(tmp_ctx, records, count, attr, &values); + if (ret != EOK) { + goto done; + } + + *_values = talloc_steal(mem_ctx, values); + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, + enum be_refresh_type type, + struct sss_domain_info *domain, + time_t period, + char ***_values) +{ + struct ldb_dn *base_dn = NULL; + const char *class = NULL; + errno_t ret; + + switch (type) { + case BE_REFRESH_TYPE_USERS: + base_dn = sysdb_user_base_dn(mem_ctx, domain); + class = SYSDB_USER_CLASS; + break; + case BE_REFRESH_TYPE_GROUPS: + base_dn = sysdb_group_base_dn(mem_ctx, domain); + class = SYSDB_GROUP_CLASS; + break; + case BE_REFRESH_TYPE_NETGROUPS: + base_dn = sysdb_netgroup_base_dn(mem_ctx, domain); + class = SYSDB_NETGROUP_CLASS; + break; + case BE_REFRESH_TYPE_SENTINEL: + return ERR_INTERNAL; + break; + } + + if (base_dn == NULL) { + return ENOMEM; + } + + ret = be_refresh_get_values_ex(mem_ctx, domain, period, class, + base_dn, SYSDB_NAME, _values); + + talloc_free(base_dn); + return ret; +} + +struct be_refresh_cb { + const char *name; + bool enabled; + be_refresh_send_t send_fn; + be_refresh_recv_t recv_fn; + void *pvt; +}; + +struct be_refresh_ctx { + struct be_refresh_cb callbacks[BE_REFRESH_TYPE_SENTINEL]; +}; + +struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx) +{ + struct be_refresh_ctx *ctx = NULL; + + ctx = talloc_zero(mem_ctx, struct be_refresh_ctx); + if (ctx == NULL) { + return NULL; + } + + ctx->callbacks[BE_REFRESH_TYPE_USERS].name = "users"; + ctx->callbacks[BE_REFRESH_TYPE_GROUPS].name = "groups"; + ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups"; + + return ctx; +} + +errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, + enum be_refresh_type type, + be_refresh_send_t send_fn, + be_refresh_recv_t recv_fn, + void *pvt) +{ + if (ctx == NULL || send_fn == NULL || recv_fn == NULL + || type >= BE_REFRESH_TYPE_SENTINEL) { + return EINVAL; + } + + if (ctx->callbacks[type].enabled) { + return EEXIST; + } + + ctx->callbacks[type].enabled = true; + ctx->callbacks[type].send_fn = send_fn; + ctx->callbacks[type].recv_fn = recv_fn; + ctx->callbacks[type].pvt = pvt; + + return EOK; +} + +struct be_refresh_state { + struct tevent_context *ev; + struct be_ctx *be_ctx; + struct be_refresh_ctx *ctx; + struct be_refresh_cb *cb; + + struct sss_domain_info *domain; + enum be_refresh_type index; + time_t period; +}; + +static errno_t be_refresh_step(struct tevent_req *req); +static void be_refresh_done(struct tevent_req *subreq); + +struct tevent_req *be_refresh_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct be_ctx *be_ctx, + struct be_ptask *be_ptask, + void *pvt) +{ + struct be_refresh_state *state = NULL; + struct tevent_req *req = NULL; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct be_refresh_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); + return NULL; + } + + state->ev = ev; + state->be_ctx = be_ctx; + state->domain = be_ctx->domain; + state->period = be_ptask_get_period(be_ptask); + state->ctx = talloc_get_type(pvt, struct be_refresh_ctx); + if (state->ctx == NULL) { + ret = EINVAL; + goto immediately; + } + + ret = be_refresh_step(req); + if (ret == EOK) { + goto immediately; + } else if (ret != EAGAIN) { + DEBUG(SSSDBG_CRIT_FAILURE, "be_refresh_step() failed [%d]: %s\n", + ret, sss_strerror(ret)); + goto immediately; + } + + return req; + +immediately: + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } + tevent_req_post(req, ev); + + return req; +} + +static errno_t be_refresh_step(struct tevent_req *req) +{ + struct be_refresh_state *state = NULL; + struct tevent_req *subreq = NULL; + char **values = NULL; + errno_t ret; + + state = tevent_req_data(req, struct be_refresh_state); + + while (state->domain != NULL) { + /* find first enabled callback */ + state->cb = &state->ctx->callbacks[state->index]; + while (state->index != BE_REFRESH_TYPE_SENTINEL && !state->cb->enabled) { + state->index++; + state->cb = &state->ctx->callbacks[state->index]; + } + + /* if not found than continue with next domain */ + if (state->index == BE_REFRESH_TYPE_SENTINEL) { + state->domain = get_next_domain(state->domain, 0); + continue; + } + + if (state->cb->send_fn == NULL || state->cb->recv_fn == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid parameters!\n"); + ret = ERR_INTERNAL; + goto done; + } + + ret = be_refresh_get_values(state, state->index, state->domain, + state->period, &values); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain DN list [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + DEBUG(SSSDBG_TRACE_FUNC, "Refreshing %s in domain %s\n", + state->cb->name, state->domain->name); + + subreq = state->cb->send_fn(state, state->ev, state->be_ctx, + state->domain, values, state->cb->pvt); + if (subreq == NULL) { + ret = ENOMEM; + goto done; + } + + /* make the list disappear with subreq */ + talloc_steal(subreq, values); + + tevent_req_set_callback(subreq, be_refresh_done, req); + + state->index++; + ret = EAGAIN; + goto done; + } + + ret = EOK; + +done: + if (ret != EOK && ret != EAGAIN) { + talloc_free(values); + } + + return ret; +} + +static void be_refresh_done(struct tevent_req *subreq) +{ + struct be_refresh_state *state = NULL; + struct tevent_req *req = NULL; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct be_refresh_state); + + ret = state->cb->recv_fn(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + goto done; + } + + ret = be_refresh_step(req); + if (ret == EAGAIN) { + return; + } + +done: + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +errno_t be_refresh_recv(struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} diff --git a/src/providers/dp_refresh.c b/src/providers/dp_refresh.c deleted file mode 100644 index 47b626055..000000000 --- a/src/providers/dp_refresh.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - Authors: - Pavel Březina - - Copyright (C) 2013 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 . -*/ - -#include -#include -#include -#include - -#include "providers/dp_backend.h" -#include "providers/be_ptask.h" -#include "providers/be_refresh.h" -#include "util/util_errors.h" -#include "db/sysdb.h" - -static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - time_t period, - const char *objectclass, - struct ldb_dn *base_dn, - const char *attr, - char ***_values) -{ - TALLOC_CTX *tmp_ctx = NULL; - const char *attrs[] = {attr, NULL}; - const char *filter = NULL; - char **values = NULL; - struct ldb_message **msgs = NULL; - struct sysdb_attrs **records = NULL; - size_t count; - time_t now = time(NULL); - errno_t ret; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - filter = talloc_asprintf(tmp_ctx, "(&(%s<=%lld))", - SYSDB_CACHE_EXPIRE, (long long) now + period); - if (filter == NULL) { - ret = ENOMEM; - goto done; - } - - ret = sysdb_search_entry(tmp_ctx, domain->sysdb, base_dn, - LDB_SCOPE_SUBTREE, filter, attrs, - &count, &msgs); - if (ret == ENOENT) { - count = 0; - } else if (ret != EOK) { - goto done; - } - - ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &records); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not convert ldb message to sysdb_attrs\n"); - goto done; - } - - ret = sysdb_attrs_to_list(tmp_ctx, records, count, attr, &values); - if (ret != EOK) { - goto done; - } - - *_values = talloc_steal(mem_ctx, values); - ret = EOK; - -done: - talloc_free(tmp_ctx); - - return ret; -} - -static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, - enum be_refresh_type type, - struct sss_domain_info *domain, - time_t period, - char ***_values) -{ - struct ldb_dn *base_dn = NULL; - const char *class = NULL; - errno_t ret; - - switch (type) { - case BE_REFRESH_TYPE_USERS: - base_dn = sysdb_user_base_dn(mem_ctx, domain); - class = SYSDB_USER_CLASS; - break; - case BE_REFRESH_TYPE_GROUPS: - base_dn = sysdb_group_base_dn(mem_ctx, domain); - class = SYSDB_GROUP_CLASS; - break; - case BE_REFRESH_TYPE_NETGROUPS: - base_dn = sysdb_netgroup_base_dn(mem_ctx, domain); - class = SYSDB_NETGROUP_CLASS; - break; - case BE_REFRESH_TYPE_SENTINEL: - return ERR_INTERNAL; - break; - } - - if (base_dn == NULL) { - return ENOMEM; - } - - ret = be_refresh_get_values_ex(mem_ctx, domain, period, class, - base_dn, SYSDB_NAME, _values); - - talloc_free(base_dn); - return ret; -} - -struct be_refresh_cb { - const char *name; - bool enabled; - be_refresh_send_t send_fn; - be_refresh_recv_t recv_fn; - void *pvt; -}; - -struct be_refresh_ctx { - struct be_refresh_cb callbacks[BE_REFRESH_TYPE_SENTINEL]; -}; - -struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx) -{ - struct be_refresh_ctx *ctx = NULL; - - ctx = talloc_zero(mem_ctx, struct be_refresh_ctx); - if (ctx == NULL) { - return NULL; - } - - ctx->callbacks[BE_REFRESH_TYPE_USERS].name = "users"; - ctx->callbacks[BE_REFRESH_TYPE_GROUPS].name = "groups"; - ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups"; - - return ctx; -} - -errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, - enum be_refresh_type type, - be_refresh_send_t send_fn, - be_refresh_recv_t recv_fn, - void *pvt) -{ - if (ctx == NULL || send_fn == NULL || recv_fn == NULL - || type >= BE_REFRESH_TYPE_SENTINEL) { - return EINVAL; - } - - if (ctx->callbacks[type].enabled) { - return EEXIST; - } - - ctx->callbacks[type].enabled = true; - ctx->callbacks[type].send_fn = send_fn; - ctx->callbacks[type].recv_fn = recv_fn; - ctx->callbacks[type].pvt = pvt; - - return EOK; -} - -struct be_refresh_state { - struct tevent_context *ev; - struct be_ctx *be_ctx; - struct be_refresh_ctx *ctx; - struct be_refresh_cb *cb; - - struct sss_domain_info *domain; - enum be_refresh_type index; - time_t period; -}; - -static errno_t be_refresh_step(struct tevent_req *req); -static void be_refresh_done(struct tevent_req *subreq); - -struct tevent_req *be_refresh_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct be_ctx *be_ctx, - struct be_ptask *be_ptask, - void *pvt) -{ - struct be_refresh_state *state = NULL; - struct tevent_req *req = NULL; - errno_t ret; - - req = tevent_req_create(mem_ctx, &state, - struct be_refresh_state); - if (req == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); - return NULL; - } - - state->ev = ev; - state->be_ctx = be_ctx; - state->domain = be_ctx->domain; - state->period = be_ptask_get_period(be_ptask); - state->ctx = talloc_get_type(pvt, struct be_refresh_ctx); - if (state->ctx == NULL) { - ret = EINVAL; - goto immediately; - } - - ret = be_refresh_step(req); - if (ret == EOK) { - goto immediately; - } else if (ret != EAGAIN) { - DEBUG(SSSDBG_CRIT_FAILURE, "be_refresh_step() failed [%d]: %s\n", - ret, sss_strerror(ret)); - goto immediately; - } - - return req; - -immediately: - if (ret == EOK) { - tevent_req_done(req); - } else { - tevent_req_error(req, ret); - } - tevent_req_post(req, ev); - - return req; -} - -static errno_t be_refresh_step(struct tevent_req *req) -{ - struct be_refresh_state *state = NULL; - struct tevent_req *subreq = NULL; - char **values = NULL; - errno_t ret; - - state = tevent_req_data(req, struct be_refresh_state); - - while (state->domain != NULL) { - /* find first enabled callback */ - state->cb = &state->ctx->callbacks[state->index]; - while (state->index != BE_REFRESH_TYPE_SENTINEL && !state->cb->enabled) { - state->index++; - state->cb = &state->ctx->callbacks[state->index]; - } - - /* if not found than continue with next domain */ - if (state->index == BE_REFRESH_TYPE_SENTINEL) { - state->domain = get_next_domain(state->domain, 0); - continue; - } - - if (state->cb->send_fn == NULL || state->cb->recv_fn == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Invalid parameters!\n"); - ret = ERR_INTERNAL; - goto done; - } - - ret = be_refresh_get_values(state, state->index, state->domain, - state->period, &values); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain DN list [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } - - DEBUG(SSSDBG_TRACE_FUNC, "Refreshing %s in domain %s\n", - state->cb->name, state->domain->name); - - subreq = state->cb->send_fn(state, state->ev, state->be_ctx, - state->domain, values, state->cb->pvt); - if (subreq == NULL) { - ret = ENOMEM; - goto done; - } - - /* make the list disappear with subreq */ - talloc_steal(subreq, values); - - tevent_req_set_callback(subreq, be_refresh_done, req); - - state->index++; - ret = EAGAIN; - goto done; - } - - ret = EOK; - -done: - if (ret != EOK && ret != EAGAIN) { - talloc_free(values); - } - - return ret; -} - -static void be_refresh_done(struct tevent_req *subreq) -{ - struct be_refresh_state *state = NULL; - struct tevent_req *req = NULL; - errno_t ret; - - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct be_refresh_state); - - ret = state->cb->recv_fn(subreq); - talloc_zfree(subreq); - if (ret != EOK) { - goto done; - } - - ret = be_refresh_step(req); - if (ret == EAGAIN) { - return; - } - -done: - if (ret != EOK) { - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); -} - -errno_t be_refresh_recv(struct tevent_req *req) -{ - TEVENT_REQ_RETURN_ON_ERROR(req); - - return EOK; -} -- cgit