4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Pavel Březina <pbrezina@redhat.com>
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina Copyright (C) 2016 Red Hat
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 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 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řezinatypedef errno_t (*nss_setent_set_timeout_fn)(struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic void nss_setent_internal_done(struct tevent_req *subreq);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina/* Cache request data is stealed on internal state. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic struct tevent_req *
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina req = tevent_req_create(mem_ctx, &state, struct nss_setent_internal_state);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->nss_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct nss_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Object is already constructed, just return here. */
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 "Unable to register setent reference [%d]: %s!\n",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Create new object. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina subreq = cache_req_send(req, ev, cli_ctx->rctx, cli_ctx->rctx->ncache,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send cache request!\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina tevent_req_set_callback(subreq, nss_setent_internal_done, req);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinastatic void nss_setent_internal_done(struct tevent_req *subreq)
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 /* This is the ongoing request and it is finished. Remove it. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina state->enum_ctx->result = talloc_steal(state->nss_ctx, result);
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 /* Reset the result but build it again next time setent is called. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* In case of an error, we do not touch the enumeration context. */
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 /* The object is ready now. */
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 * Because callback invoked from tevent_req_done will free state,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina * we must remember notify_list explicitly to avoid segfault.
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setent_internal_recv(struct tevent_req *req)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Enumeration result object has expired.\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina /* Reset enumeration context. */
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setent_set_timeout(struct tevent_context *ev,
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 "Could not set up life timer for enumeration object.\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set cache request data!\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return nss_setent_internal_send(mem_ctx, ev, cli_ctx, data, type, enum_ctx,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinaerrno_t nss_setent_recv(struct tevent_req *req)
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setnetgrent_timeout(struct tevent_context *ev,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Enumeration result object has expired.\n");
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řezinanss_setnetgrent_set_timeout(struct tevent_context *ev,
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek timeout = enum_ctx->result[0]->domain->netgroup_timeout *
f22528922c065f37ca928f95fd86ed2ea79e0d51Jakub Hrozek timeout = enum_ctx->result[0]->domain->netgroup_timeout;
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
f6a1cef87abdd983d6b5349cd341c9a249826577Sumit Bose te = tevent_add_timer(ev, enum_ctx, tv, nss_setnetgrent_timeout, enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Could not set up life timer for enumeration object.\n");
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březinanss_setnetgrent_set_enum_ctx(hash_table_t *table,
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum_ctx = sss_ptr_hash_lookup(table, netgroup, struct nss_enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum_ctx = talloc_zero(table, struct nss_enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina ret = sss_ptr_hash_add(table, netgroup, enum_ctx, struct nss_enum_ctx);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina "Unable to add enumeration context into table [%d]: %s\n",
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina enum_ctx = nss_setnetgrent_set_enum_ctx(table, netgroup);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina data = cache_req_data_name(mem_ctx, type, netgroup);
4049b63f8c67ada17b453463b0451ca6be3d5de4Pavel Březina return nss_setent_internal_send(mem_ctx, ev, cli_ctx, data, type, enum_ctx,