4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/*
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Authors:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Pavel Březina <pbrezina@redhat.com>
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Copyright (C) 2016 Red Hat
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina This program is free software; you can redistribute it and/or modify
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina it under the terms of the GNU General Public License as published by
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina the Free Software Foundation; either version 3 of the License, or
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina (at your option) any later version.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina This program is distributed in the hope that it will be useful,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina GNU General Public License for more details.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina You should have received a copy of the GNU General Public License
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina*/
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#include <tevent.h>
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#include <talloc.h>
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#include "util/util.h"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#include "util/sss_ptr_hash.h"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina#include "responder/nss/nss_private.h"
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinatypedef errno_t (*nss_setent_set_timeout_fn)(struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_ctx *nss_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct nss_setent_internal_state {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_context *ev;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_ctx *nss_ctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina nss_setent_set_timeout_fn timeout_handler;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum cache_req_type type;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina};
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic void nss_setent_internal_done(struct tevent_req *subreq);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Cache request data is stealed on internal state. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic struct tevent_req *
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setent_internal_send(TALLOC_CTX *mem_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_ctx *cli_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cache_req_data *data,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum cache_req_type type,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina nss_setent_set_timeout_fn timeout_handler)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_setent_internal_state *state;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_req *subreq;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_req *req;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina errno_t ret;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina req = tevent_req_create(mem_ctx, &state, struct nss_setent_internal_state);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (req == NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return NULL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_steal(state, data);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->ev = ev;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->nss_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct nss_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->enum_ctx = enum_ctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->type = type;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->timeout_handler = timeout_handler;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (state->enum_ctx->is_ready) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Object is already constructed, just return here. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_free(data);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (state->enum_ctx->ongoing != NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Object is being constructed. Register ourselves for
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina * notification when it is finished. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = setent_add_ref(state, &state->enum_ctx->notify_list, req);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret != EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Unable to register setent reference [%d]: %s!\n",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret, sss_strerror(ret));
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = EAGAIN;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Create new object. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->enum_ctx->is_ready = false;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina subreq = cache_req_send(req, ev, cli_ctx->rctx, cli_ctx->rctx->ncache,
cee85e8fb9534ec997e5388fce59f392cf029573Jakub Hrozek 0, CACHE_REQ_POSIX_DOM, NULL, data);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (subreq == NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send cache request!\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = ENOMEM;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tevent_req_set_callback(subreq, nss_setent_internal_done, req);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->enum_ctx->ongoing = subreq;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = EAGAIN;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinadone:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret == EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tevent_req_done(req);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tevent_req_post(req, ev);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina } else if (ret != EAGAIN) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tevent_req_error(req, ret);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tevent_req_post(req, ev);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return req;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic void nss_setent_internal_done(struct tevent_req *subreq)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cache_req_result **result;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_setent_internal_state *state;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct setent_req_list **notify_list;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_req *req;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina errno_t ret;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina errno_t tret;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state = tevent_req_data(req, struct nss_setent_internal_state);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* This is the ongoing request and it is finished. Remove it. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->enum_ctx->ongoing = NULL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = cache_req_recv(state, subreq, &result);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_zfree(subreq);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina switch (ret) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina case EOK:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_zfree(state->enum_ctx->result);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->enum_ctx->result = talloc_steal(state->nss_ctx, result);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (state->type == CACHE_REQ_NETGROUP_BY_NAME) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* We need to expand the netgroup into triples and members. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = sysdb_netgr_to_entries(state->enum_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina result[0]->ldb_result,
08db22b1b1a2e742edbca92e35087294d963addaSumit Bose &state->enum_ctx->netgroup,
08db22b1b1a2e742edbca92e35087294d963addaSumit Bose &state->enum_ctx->netgroup_count);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret != EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina break;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina case ENOENT:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Reset the result but build it again next time setent is called. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_zfree(state->enum_ctx->result);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_zfree(state->enum_ctx->netgroup);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina default:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* In case of an error, we do not touch the enumeration context. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Expire the result object after its timeout is reached. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tret = state->timeout_handler(state->ev, state->nss_ctx, state->enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (tret != EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = ENOMEM;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina goto done;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* The object is ready now. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->enum_ctx->is_ready = true;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinadone:
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* We want to finish the requests in correct order, this was the
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina * first request, notify_list contain the subsequent request.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina *
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina * Because callback invoked from tevent_req_done will free state,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina * we must remember notify_list explicitly to avoid segfault.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina notify_list = &state->enum_ctx->notify_list;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret == EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tevent_req_done(req);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina setent_notify_done(notify_list);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina } else {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tevent_req_error(req, ret);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina setent_notify(notify_list, ret);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic errno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setent_internal_recv(struct tevent_req *req)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic void
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setent_timeout(struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_timer *te,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct timeval current_time,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina void *pvt)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx = pvt;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Enumeration result object has expired.\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Reset enumeration context. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_zfree(enum_ctx->result);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum_ctx->is_ready = false;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic errno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setent_set_timeout(struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_ctx *nss_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_timer *te;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct timeval tv;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tv = tevent_timeval_current_ofs(nss_ctx->enum_cache_timeout, 0);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina te = tevent_add_timer(ev, nss_ctx, tv, nss_setent_timeout, enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (te == NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Could not set up life timer for enumeration object.\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return ENOMEM;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct tevent_req *
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setent_send(TALLOC_CTX *mem_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_ctx *cli_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum cache_req_type type,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cache_req_data *data;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina data = cache_req_data_enum(mem_ctx, type);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (data == NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set cache request data!\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return NULL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return nss_setent_internal_send(mem_ctx, ev, cli_ctx, data, type, enum_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina nss_setent_set_timeout);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t nss_setent_recv(struct tevent_req *req)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return nss_setent_internal_recv(req);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic void
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setnetgrent_timeout(struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_timer *te,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct timeval current_time,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina void *pvt)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Enumeration result object has expired.\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Free enumeration context. This will also remove it from the table. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum_ctx = talloc_get_type(pvt, struct nss_enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_free(enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic errno_t
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setnetgrent_set_timeout(struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_ctx *nss_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_timer *te;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct timeval tv;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina uint32_t timeout;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek if (nss_ctx->cache_refresh_percent) {
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek timeout = enum_ctx->result[0]->domain->netgroup_timeout *
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek (nss_ctx->cache_refresh_percent / 100.0);
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek } else {
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek timeout = enum_ctx->result[0]->domain->netgroup_timeout;
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek }
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek /* In order to not trash the cache between setnetgrent()/getnetgrent()
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek * calls with too low timeout values, we only allow 10 seconds as
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek * the minimal timeout
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek */
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek if (timeout < 10) timeout = 10;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tv = tevent_timeval_current_ofs(timeout, 0);
f6a1cef87abdd983d6b5349cd341c9a249826577Sumit Bose te = tevent_add_timer(ev, enum_ctx, tv, nss_setnetgrent_timeout, enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (te == NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Could not set up life timer for enumeration object.\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return ENOMEM;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return EOK;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic struct nss_enum_ctx *
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setnetgrent_set_enum_ctx(hash_table_t *table,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *netgroup)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina errno_t ret;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum_ctx = sss_ptr_hash_lookup(table, netgroup, struct nss_enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (enum_ctx != NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return enum_ctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum_ctx = talloc_zero(table, struct nss_enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (enum_ctx == NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return NULL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = sss_ptr_hash_add(table, netgroup, enum_ctx, struct nss_enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (ret != EOK) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Unable to add enumeration context into table [%d]: %s\n",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret, sss_strerror(ret));
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina talloc_free(enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return NULL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return enum_ctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastruct tevent_req *
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setnetgrent_send(TALLOC_CTX *mem_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cli_ctx *cli_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum cache_req_type type,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina hash_table_t *table,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina const char *netgroup)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct nss_enum_ctx *enum_ctx;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina struct cache_req_data *data;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum_ctx = nss_setnetgrent_set_enum_ctx(table, netgroup);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (enum_ctx == NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return NULL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina data = cache_req_data_name(mem_ctx, type, netgroup);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina if (data == NULL) {
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return NULL;
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina }
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return nss_setent_internal_send(mem_ctx, ev, cli_ctx, data, type, enum_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina nss_setnetgrent_set_timeout);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t nss_setnetgrent_recv(struct tevent_req *req)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina{
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return nss_setent_internal_recv(req);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina}