2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher/*
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher SSSD
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher proxy_auth.c
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher Authors:
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher Stephen Gallagher <sgallagh@redhat.com>
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher Copyright (C) 2010 Red Hat
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher This program is free software; you can redistribute it and/or modify
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher it under the terms of the GNU General Public License as published by
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher the Free Software Foundation; either version 3 of the License, or
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher (at your option) any later version.
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher This program is distributed in the hope that it will be useful,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher GNU General Public License for more details.
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher You should have received a copy of the GNU General Public License
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher*/
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher#include "providers/proxy/proxy.h"
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina#include "providers/proxy/proxy_iface_generated.h"
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstruct pc_init_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic int proxy_child_destructor(TALLOC_CTX *ctx)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_child_ctx *child_ctx =
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_get_type(ctx, struct proxy_child_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher hash_key_t key;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int hret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Removing proxy child id [%d]\n", child_ctx->id);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher key.type = HASH_KEY_ULONG;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher key.ul = child_ctx->id;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher hret = hash_delete(child_ctx->auth_ctx->request_table, &key);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (!(hret == HASH_SUCCESS ||
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher hret == HASH_ERROR_KEY_NOT_FOUND)) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Hash error [%d][%s]\n", hret, hash_error_string(hret));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Nothing we can do about this, so just continue */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return 0;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic struct tevent_req *proxy_child_init_send(TALLOC_CTX *mem_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_child_ctx *child_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_auth_ctx *auth_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void proxy_child_init_done(struct tevent_req *subreq);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic struct tevent_req *proxy_child_send(TALLOC_CTX *mem_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_auth_ctx *auth_ctx,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct pam_data *pd)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *subreq;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_child_ctx *state;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int hret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher hash_key_t key;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher hash_value_t value;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher uint32_t first;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher req = tevent_req_create(mem_ctx, &state, struct proxy_child_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (req == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Could not send PAM request to child\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->auth_ctx = auth_ctx;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->pd = pd;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Find an available key */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher key.type = HASH_KEY_ULONG;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher key.ul = auth_ctx->next_id;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher first = auth_ctx->next_id;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher while (auth_ctx->next_id == 0 ||
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher hash_has_key(auth_ctx->request_table, &key)) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Handle overflow, zero is a reserved value
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * Also handle the unlikely case where the next ID
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * is still awaiting being run
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher auth_ctx->next_id++;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher key.ul = auth_ctx->next_id;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (auth_ctx->next_id == first) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* We've looped through all possible integers! */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Serious error: queue is too long!\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->id = auth_ctx->next_id;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher auth_ctx->next_id++;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher value.type = HASH_VALUE_PTR;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher value.ptr = req;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Queueing request [%lu]\n", key.ul);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher hret = hash_enter(auth_ctx->request_table,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher &key, &value);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (hret != HASH_SUCCESS) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Could not add request to the queue\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_set_destructor((TALLOC_CTX *) state,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher proxy_child_destructor);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (auth_ctx->running < auth_ctx->max_children) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* There's an available slot; start a child
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * to handle the request
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher auth_ctx->running++;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher subreq = proxy_child_init_send(auth_ctx, state, auth_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (!subreq) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Could not fork child process\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher auth_ctx->running--;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_set_callback(subreq, proxy_child_init_done, req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->running = true;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher else {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* If there was no available slot, it will be queued
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * until a slot is available
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "All available child slots are full, queuing request\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic int pc_init_destructor (TALLOC_CTX *ctx)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct pc_init_ctx *init_ctx =
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_get_type(ctx, struct pc_init_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* If the init request has died, forcibly kill the child */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher kill(init_ctx->pid, SIGKILL);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return 0;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void pc_init_sig_handler(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_signal *sige, int signum,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int count, void *__siginfo, void *pvt);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void pc_init_timeout(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_timer *te,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct timeval t, void *ptr);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic struct tevent_req *proxy_child_init_send(TALLOC_CTX *mem_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_child_ctx *child_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_auth_ctx *auth_ctx)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct pc_init_ctx *state;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher char **proxy_child_args;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct timeval tv;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher errno_t ret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher pid_t pid;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher req = tevent_req_create(mem_ctx, &state, struct pc_init_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (req == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Could not create tevent_req\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->child_ctx = child_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->command = talloc_asprintf(req,
1a7529bf5f867b43e0475f7f9ac0cd8671fb16f1Pavel Březina "%s/proxy_child -d %#.4x --debug-timestamps=%d "
1a7529bf5f867b43e0475f7f9ac0cd8671fb16f1Pavel Březina "--debug-microseconds=%d%s --domain %s --id %d",
47db32cd9cb2147bb40909352569d7c8274365dbPavel Březina SSSD_LIBEXEC_PATH, debug_level, debug_timestamps,
1a7529bf5f867b43e0475f7f9ac0cd8671fb16f1Pavel Březina debug_microseconds, (debug_to_file ? " --debug-to-files" : ""),
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher auth_ctx->be->domain->name,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher child_ctx->id);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (state->command == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Starting proxy child with args [%s]\n", state->command);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher pid = fork();
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (pid < 0) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "fork failed [%d][%s].\n", ret, strerror(ret));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (pid == 0) { /* child */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher proxy_child_args = parse_args(state->command);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher execvp(proxy_child_args[0], proxy_child_args);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Could not start proxy child [%s]: [%d][%s].\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov state->command, ret, strerror(ret));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher _exit(1);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher else { /* parent */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->pid = pid;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Make sure to kill the child process if we abort */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_set_destructor((TALLOC_CTX *)state, pc_init_destructor);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->sige = tevent_add_signal(auth_ctx->be->ev, req,
df233bce93c6e6752cf22cd4244c85c94d68b17bLukas Slebodnik SIGCHLD, 0,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher pc_init_sig_handler, req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (state->sige == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Save the init request to the child context.
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * This is technically a layering violation,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * but it's the only sane way to be able to
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * identify which client is which when it
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * connects to the backend in
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * client_registration()
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher child_ctx->init_req = req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Wait six seconds for the child to connect
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * This is because the connection handler will add
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * its own five-second timeout, and we don't want to
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * be faster here.
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tv = tevent_timeval_current_ofs(6, 0);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->timeout = tevent_add_timer(auth_ctx->be->ev, req,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tv, pc_init_timeout, req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* processing will continue once the connection is received
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * in proxy_client_init()
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void pc_init_sig_handler(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_signal *sige, int signum,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int count, void *__siginfo, void *pvt)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int ret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int child_status;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct pc_init_ctx *init_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (count <= 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "SIGCHLD handler called with invalid child count\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher req = talloc_get_type(pvt, struct tevent_req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher init_ctx = tevent_req_data(req, struct pc_init_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "Waiting for child [%d].\n", init_ctx->pid);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher errno = 0;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = waitpid(init_ctx->pid, &child_status, WNOHANG);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (ret == -1) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "waitpid failed [%d][%s].\n", ret, strerror(ret));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher } else if (ret == 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "waitpid did not find a child with changed status.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher } else {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (WIFEXITED(child_status)) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "child [%d] exited with status [%d].\n", ret,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov WEXITSTATUS(child_status));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, EIO);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher } else if (WIFSIGNALED(child_status)) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "child [%d] was terminate by signal [%d].\n", ret,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov WTERMSIG(child_status));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, EIO);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher } else {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (WIFSTOPPED(child_status)) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "child [%d] was stopped by signal [%d].\n", ret,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov WSTOPSIG(child_status));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
5085d263f2f084778b1314fc5e808668c3758d82Lukas Slebodnik if (WIFCONTINUED(child_status) == true) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "child [%d] was resumed by delivery of SIGCONT.\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Child is still running, no new child is started.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void pc_init_timeout(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_timer *te,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct timeval t, void *ptr)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "Client timed out before Identification!\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher req = talloc_get_type(ptr, struct tevent_req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, ETIMEDOUT);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic errno_t proxy_child_init_recv(struct tevent_req *req,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher pid_t *pid,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct sbus_connection **conn)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct pc_init_ctx *state;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher TEVENT_REQ_RETURN_ON_ERROR(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state = tevent_req_data(req, struct pc_init_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Unset the destructor since we initialized successfully.
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * We don't want to kill the child now that it's properly
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * set up.
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_set_destructor((TALLOC_CTX *)state, NULL);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher *pid = state->pid;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher *conn = state->conn;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return EOK;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstruct proxy_child_sig_ctx {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_auth_ctx *auth_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher pid_t pid;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher};
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void proxy_child_sig_handler(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_signal *sige, int signum,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int count, void *__siginfo, void *pvt);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic struct tevent_req *proxy_pam_conv_send(TALLOC_CTX *mem_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_auth_ctx *auth_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct sbus_connection *conn,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct pam_data *pd,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher pid_t pid);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void proxy_pam_conv_done(struct tevent_req *subreq);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void proxy_child_init_done(struct tevent_req *subreq) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int ret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_signal *sige;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *req =
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_callback_data(subreq, struct tevent_req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_child_ctx *child_ctx =
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_data(req, struct proxy_child_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_child_sig_ctx *sig_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = proxy_child_init_recv(subreq, &child_ctx->pid, &child_ctx->conn);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(subreq);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Proxy child init failed [%d]\n", ret);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, ret);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* An initialized child is available, awaiting the PAM command */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher subreq = proxy_pam_conv_send(req, child_ctx->auth_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher child_ctx->conn, child_ctx->pd,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher child_ctx->pid);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (!subreq) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,"Could not start PAM conversation\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, EIO);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_set_callback(subreq, proxy_pam_conv_done, req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Add a signal handler for the child under the auth_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * that way if the child exits after completion of the
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * request, it will still be handled.
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher sig_ctx = talloc_zero(child_ctx->auth_ctx, struct proxy_child_sig_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if(sig_ctx == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, ENOMEM);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher sig_ctx->auth_ctx = child_ctx->auth_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher sig_ctx->pid = child_ctx->pid;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher sige = tevent_add_signal(child_ctx->auth_ctx->be->ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher child_ctx->auth_ctx,
df233bce93c6e6752cf22cd4244c85c94d68b17bLukas Slebodnik SIGCHLD, 0,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher proxy_child_sig_handler,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher sig_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (sige == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, ENOMEM);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Steal the signal context onto the signal event
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * so that when the signal is freed, the context
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * will go with it.
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_steal(sige, sig_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void remove_sige(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_immediate *imm,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher void *pvt);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void run_proxy_child_queue(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_immediate *imm,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher void *pvt);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void proxy_child_sig_handler(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_signal *sige, int signum,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int count, void *__siginfo, void *pvt)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int ret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int child_status;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_child_sig_ctx *sig_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_immediate *imm;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_immediate *imm2;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (count <= 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "SIGCHLD handler called with invalid child count\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher sig_ctx = talloc_get_type(pvt, struct proxy_child_sig_ctx);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "Waiting for child [%d].\n", sig_ctx->pid);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher errno = 0;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = waitpid(sig_ctx->pid, &child_status, WNOHANG);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (ret == -1) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "waitpid failed [%d][%s].\n", ret, strerror(ret));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher } else if (ret == 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "waitpid did not found a child with changed status.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher } else {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (WIFEXITED(child_status)) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "child [%d] exited with status [%d].\n", ret,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov WEXITSTATUS(child_status));
5085d263f2f084778b1314fc5e808668c3758d82Lukas Slebodnik } else if (WIFSIGNALED(child_status) == true) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "child [%d] was terminated by signal [%d].\n", ret,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov WTERMSIG(child_status));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher } else {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (WIFSTOPPED(child_status)) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "child [%d] was stopped by signal [%d].\n", ret,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov WSTOPSIG(child_status));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
5085d263f2f084778b1314fc5e808668c3758d82Lukas Slebodnik if (WIFCONTINUED(child_status) == true) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "child [%d] was resumed by delivery of SIGCONT.\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Child is still running, no new child is started.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher imm = tevent_create_immediate(ev);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (imm == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_create_immediate failed.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_schedule_immediate(imm, ev, run_proxy_child_queue,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher sig_ctx->auth_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* schedule another immediate timer to delete the sigchld handler */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher imm2 = tevent_create_immediate(ev);
274fe6a4f8bcb23e31929430110c0b52e9ce233aJakub Hrozek if (imm2 == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_create_immediate failed.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_schedule_immediate(imm2, ev, remove_sige, sige);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void remove_sige(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_immediate *imm,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher void *pvt)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_free(pvt);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstruct proxy_conv_ctx {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_auth_ctx *auth_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct sbus_connection *conn;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct pam_data *pd;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher pid_t pid;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher};
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void proxy_pam_conv_reply(DBusPendingCall *pending, void *ptr);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic struct tevent_req *proxy_pam_conv_send(TALLOC_CTX *mem_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_auth_ctx *auth_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct sbus_connection *conn,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct pam_data *pd,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher pid_t pid)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher errno_t ret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher bool dp_ret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher DBusMessage *msg;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_conv_ctx *state;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher req = tevent_req_create(mem_ctx, &state, struct proxy_conv_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (req == NULL) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->auth_ctx = auth_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->conn = conn;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->pd = pd;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->pid = pid;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher msg = dbus_message_new_method_call(NULL,
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina PROXY_CHILD_PATH,
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina IFACE_PROXY_AUTH,
e07d700ed9daf0cf96607fa2d72978cb2431b794Pavel Březina IFACE_PROXY_AUTH_PAM);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (msg == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "dbus_message_new_method_call failed.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Sending request with the following data:\n");
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG_PAM_DATA(SSSDBG_CONF_SETTINGS, pd);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher dp_ret = dp_pack_pam_request(msg, pd);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (!dp_ret) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher dbus_message_unref(msg);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = sbus_conn_send(state->conn, msg, state->auth_ctx->timeout_ms,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher proxy_pam_conv_reply, req, NULL);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (ret != EOK) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher dbus_message_unref(msg);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return NULL;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher dbus_message_unref(msg);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void proxy_pam_conv_reply(DBusPendingCall *pending, void *ptr)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_conv_ctx *state;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher DBusError dbus_error;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher DBusMessage *reply;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int type;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int ret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_INTERNAL, "Handling pam conversation reply\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher req = talloc_get_type(ptr, struct tevent_req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state = tevent_req_data(req, struct proxy_conv_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher dbus_error_init(&dbus_error);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher reply = dbus_pending_call_steal_reply(pending);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher dbus_pending_call_unref(pending);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (reply == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Severe error. A reply callback was called but no reply was"
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "received and no timeout occurred\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->pd->pam_status = PAM_SYSTEM_ERR;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, EIO);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher type = dbus_message_get_type(reply);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher switch (type) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher case DBUS_MESSAGE_TYPE_METHOD_RETURN:
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = dp_unpack_pam_response(reply, state->pd, &dbus_error);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (!ret) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse reply.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->pd->pam_status = PAM_SYSTEM_ERR;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher dbus_message_unref(reply);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, EIO);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "received: [%d][%s]\n",
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->pd->pam_status,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov state->pd->domain);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher break;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher case DBUS_MESSAGE_TYPE_ERROR:
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Reply error [%s].\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov dbus_message_get_error_name(reply));
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->pd->pam_status = PAM_SYSTEM_ERR;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher break;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher default:
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Default... what now?.\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->pd->pam_status = PAM_SYSTEM_ERR;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher dbus_message_unref(reply);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Kill the child */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher kill(state->pid, SIGKILL);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Conversation is finished */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_done(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic errno_t proxy_pam_conv_recv(struct tevent_req *req)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher TEVENT_REQ_RETURN_ON_ERROR(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return EOK;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void proxy_pam_conv_done(struct tevent_req *subreq)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher int ret;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher req = tevent_req_callback_data(subreq, struct tevent_req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ret = proxy_pam_conv_recv(subreq);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(subreq);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Proxy PAM conversation failed [%d]\n", ret);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_error(req, ret);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_done(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic int proxy_child_recv(struct tevent_req *req,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher TALLOC_CTX *mem_ctx,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct pam_data **pd)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_child_ctx *ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher TEVENT_REQ_RETURN_ON_ERROR(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher ctx = tevent_req_data(req, struct proxy_child_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher *pd = talloc_steal(mem_ctx, ctx->pd);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return EOK;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagherstatic void run_proxy_child_queue(struct tevent_context *ev,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_immediate *imm,
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher void *pvt)
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher{
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_auth_ctx *auth_ctx;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct hash_iter_context_t *iter;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct hash_entry_t *entry;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *req;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct tevent_req *subreq;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher struct proxy_child_ctx *state;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher auth_ctx = talloc_get_type(pvt, struct proxy_auth_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Launch next queued request */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher iter = new_hash_iter_context(auth_ctx->request_table);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher while ((entry = iter->next(iter)) != NULL) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher req = talloc_get_type(entry->value.ptr, struct tevent_req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state = tevent_req_data(req, struct proxy_child_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (!state->running) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher break;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
71829db25d6a0beb63066d912702ac1b7787dbe2Jakub Hrozek free(iter);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (!entry) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* Nothing pending on the queue */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (auth_ctx->running < auth_ctx->max_children) {
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher /* There's an available slot; start a child
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher * to handle the request
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher */
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher auth_ctx->running++;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher subreq = proxy_child_init_send(auth_ctx, state, auth_ctx);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher if (!subreq) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Could not fork child process\n");
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher auth_ctx->running--;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher talloc_zfree(req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher return;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher tevent_req_set_callback(subreq, proxy_child_init_done, req);
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher state->running = true;
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher }
2dd3faebcd3cfd00efda38ffd2585d675e696b12Stephen Gallagher}
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinastruct proxy_pam_handler_state {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct pam_data *pd;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct proxy_auth_ctx *auth_ctx;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct be_ctx *be_ctx;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina};
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinastatic void proxy_pam_handler_done(struct tevent_req *subreq);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinastruct tevent_req *
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinaproxy_pam_handler_send(TALLOC_CTX *mem_ctx,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct proxy_auth_ctx *proxy_auth_ctx,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct pam_data *pd,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct dp_req_params *params)
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina{
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct proxy_pam_handler_state *state;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct tevent_req *subreq;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct tevent_req *req;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina req = tevent_req_create(mem_ctx, &state, struct proxy_pam_handler_state);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina if (req == NULL) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina return NULL;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->pd = pd;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->auth_ctx = proxy_auth_ctx;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->be_ctx = params->be_ctx;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina switch (pd->cmd) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina case SSS_PAM_AUTHENTICATE:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina case SSS_PAM_CHAUTHTOK:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina case SSS_PAM_CHAUTHTOK_PRELIM:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina case SSS_PAM_ACCT_MGMT:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* Queue the request and spawn a child if there is an available slot. */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina subreq = proxy_child_send(state, proxy_auth_ctx, state->pd);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina if (subreq == NULL) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina pd->pam_status = PAM_SYSTEM_ERR;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina goto immediately;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina tevent_req_set_callback(subreq, proxy_pam_handler_done, req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina break;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina case SSS_PAM_SETCRED:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina case SSS_PAM_OPEN_SESSION:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina case SSS_PAM_CLOSE_SESSION:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina pd->pam_status = PAM_SUCCESS;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina goto immediately;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina default:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported PAM task.\n");
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina pd->pam_status = PAM_MODULE_UNKNOWN;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina goto immediately;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina return req;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinaimmediately:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* TODO For backward compatibility we always return EOK to DP now. */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina tevent_req_done(req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina tevent_req_post(req, params->ev);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina return req;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina}
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinastatic void proxy_pam_handler_done(struct tevent_req *subreq)
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina{
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct proxy_pam_handler_state *state;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct tevent_immediate *imm;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct tevent_req *req;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina const char *password;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina errno_t ret;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state = tevent_req_data(req, struct proxy_pam_handler_state);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina ret = proxy_child_recv(subreq, state, &state->pd);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina talloc_zfree(subreq);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina if (ret != EOK) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->pd->pam_status = PAM_SYSTEM_ERR;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina goto done;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* Start the next auth in the queue, if any */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->auth_ctx->running--;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina imm = tevent_create_immediate(state->be_ctx->ev);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina if (imm == NULL) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "tevent_create_immediate failed.\n");
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* We'll still finish the current request, but we're
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina * likely to have problems if there are queued events
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina * if we've gotten into this state.
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina * Hopefully this is impossible, since freeing req
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina * above should guarantee that we have enough memory
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina * to create this immediate event.
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina } else {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina tevent_schedule_immediate(imm, state->be_ctx->ev,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina run_proxy_child_queue,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state->auth_ctx);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* Check if we need to save the cached credentials */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina if ((state->pd->cmd == SSS_PAM_AUTHENTICATE || state->pd->cmd == SSS_PAM_CHAUTHTOK)
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina && (state->pd->pam_status == PAM_SUCCESS) && state->be_ctx->domain->cache_credentials) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina ret = sss_authtok_get_password(state->pd->authtok, &password, NULL);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina if (ret) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* password caching failures are not fatal errors */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina DEBUG(SSSDBG_OP_FAILURE, "Failed to cache password\n");
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina goto done;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina ret = sysdb_cache_password(state->be_ctx->domain, state->pd->user, password);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* password caching failures are not fatal errors */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* so we just log it any return */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina if (ret != EOK) {
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina DEBUG(SSSDBG_OP_FAILURE, "Failed to cache password (%d)[%s]!?\n",
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina ret, sss_strerror(ret));
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina }
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinadone:
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina /* TODO For backward compatibility we always return EOK to DP now. */
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina tevent_req_done(req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina}
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinaerrno_t
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březinaproxy_pam_handler_recv(TALLOC_CTX *mem_ctx,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct tevent_req *req,
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct pam_data **_data)
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina{
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina struct proxy_pam_handler_state *state = NULL;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina state = tevent_req_data(req, struct proxy_pam_handler_state);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina *_data = talloc_steal(mem_ctx, state->pd);
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina return EOK;
dea636af4d1902a081ee891f1b19ee2f8729d759Pavel Březina}