/* Generated by sbus code generator Copyright (C) 2017 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "sbus/sbus_private.h" #include "sbus/sbus_interface_declarations.h" #include "sss_iface/sbus_sss_arguments.h" #include "sss_iface/sbus_sss_invokers.h" static errno_t sbus_invoker_schedule(TALLOC_CTX *mem_ctx, struct tevent_context *ev, void *handler, void *private_data) { /* Schedule invoker as a timed event so it is processed after other * event types. This will give dispatcher a chance to catch more * messages before this invoker is triggered and therefore it will * allow to potentially chain more request into one, especially for * synchronous handlers. */ struct tevent_timer *te; struct timeval tv; tv = tevent_timeval_current_ofs(0, 5); te = tevent_add_timer(ev, mem_ctx, tv, handler, private_data); if (te == NULL) { /* There is not enough memory to create a timer. We can't do * anything about it. */ DEBUG(SSSDBG_OP_FAILURE, "Could not add invoker event!\n"); return ENOMEM; } return EOK; } struct _sbus_sss_invoke_in__out__state { struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in__out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in__out__done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in__out__send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in__out__state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in__out__state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in__out__step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in__out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in__out__state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in__out__state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data); if (ret != EOK) { goto done; } goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in__out__done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in__out__done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in__out__state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in__out__state); ret = state->handler.recv(state, subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in__out_u_state { struct _sbus_sss_invoker_args_u out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t*); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, uint32_t*); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in__out_u_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in__out_u_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in__out_u_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in__out_u_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in__out_u_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in__out_u_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in__out_u_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in__out_u_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in__out_u_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, &state->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_u(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in__out_u_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in__out_u_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in__out_u_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in__out_u_state); ret = state->handler.recv(state, subreq, &state->out.arg0); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_u(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_pam_data_out_pam_response_state { struct _sbus_sss_invoker_args_pam_data *in; struct _sbus_sss_invoker_args_pam_response out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, struct pam_data *, struct pam_data **); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, struct pam_data *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, struct pam_data **); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_pam_data_out_pam_response_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_pam_data_out_pam_response_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_pam_data_out_pam_response_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_pam_data_out_pam_response_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_pam_data_out_pam_response_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_pam_data); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_pam_data(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_pam_data_out_pam_response_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_pam_data_out_pam_response_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_pam_data_out_pam_response_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_pam_data_out_pam_response_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_pam_response(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_pam_data_out_pam_response_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_pam_data_out_pam_response_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_pam_data_out_pam_response_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_pam_data_out_pam_response_state); ret = state->handler.recv(state, subreq, &state->out.arg0); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_pam_response(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_raw_out_qus_state { struct _sbus_sss_invoker_args_qus out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, DBusMessageIter *, uint16_t*, uint32_t*, const char **); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, DBusMessageIter *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, uint16_t*, uint32_t*, const char **); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_raw_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_raw_out_qus_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_raw_out_qus_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_raw_out_qus_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_raw_out_qus_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_raw_out_qus_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, NULL, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_raw_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_raw_out_qus_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_raw_out_qus_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->read_iterator, &state->out.arg0, &state->out.arg1, &state->out.arg2); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->read_iterator); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_raw_out_qus_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_raw_out_qus_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_raw_out_qus_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_raw_out_qus_state); ret = state->handler.recv(state, subreq, &state->out.arg0, &state->out.arg1, &state->out.arg2); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_s_out__state { struct _sbus_sss_invoker_args_s *in; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_s_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_s_out__done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_s_out__send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_s_out__state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_s_out__state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_s); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_s_out__step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_s_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_s_out__state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out__state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0); if (ret != EOK) { goto done; } goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_s_out__done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_s_out__done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_s_out__state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out__state); ret = state->handler.recv(state, subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_s_out_as_state { struct _sbus_sss_invoker_args_s *in; struct _sbus_sss_invoker_args_as out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char ***); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char ***); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_s_out_as_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_s_out_as_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_s_out_as_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_s_out_as_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_s_out_as_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_s); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_s_out_as_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_s_out_as_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_s_out_as_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out_as_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_as(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_s_out_as_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_s_out_as_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_s_out_as_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out_as_state); ret = state->handler.recv(state, subreq, &state->out.arg0); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_as(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_s_out_b_state { struct _sbus_sss_invoker_args_s *in; struct _sbus_sss_invoker_args_b out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, bool*); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, bool*); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_s_out_b_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_s_out_b_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_s_out_b_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_s_out_b_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_s_out_b_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_s); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_s_out_b_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_s_out_b_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_s_out_b_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out_b_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_b(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_s_out_b_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_s_out_b_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_s_out_b_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out_b_state); ret = state->handler.recv(state, subreq, &state->out.arg0); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_b(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_s_out_qus_state { struct _sbus_sss_invoker_args_s *in; struct _sbus_sss_invoker_args_qus out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, uint16_t*, uint32_t*, const char **); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, uint16_t*, uint32_t*, const char **); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_s_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_s_out_qus_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_s_out_qus_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_s_out_qus_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_s_out_qus_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_s); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_s_out_qus_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_s_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_s_out_qus_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out_qus_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0, &state->out.arg1, &state->out.arg2); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_s_out_qus_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_s_out_qus_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_s_out_qus_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out_qus_state); ret = state->handler.recv(state, subreq, &state->out.arg0, &state->out.arg1, &state->out.arg2); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_s_out_s_state { struct _sbus_sss_invoker_args_s *in; struct _sbus_sss_invoker_args_s out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char **); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char **); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_s_out_s_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_s_out_s_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_s_out_s_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_s_out_s_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_s_out_s_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_s); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_s_out_s_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_s_out_s_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_s_out_s_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out_s_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, &state->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_s(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_s_out_s_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_s_out_s_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_s_out_s_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_s_out_s_state); ret = state->handler.recv(state, subreq, &state->out.arg0); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_s(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_sqq_out_q_state { struct _sbus_sss_invoker_args_sqq *in; struct _sbus_sss_invoker_args_q out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, uint16_t, uint16_t, uint16_t*); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, uint16_t, uint16_t); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, uint16_t*); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_sqq_out_q_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_sqq_out_q_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_sqq_out_q_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_sqq_out_q_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_sqq_out_q_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_sqq); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_sqq(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_sqq_out_q_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_sqq_out_q_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_sqq_out_q_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_sqq_out_q_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, &state->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_q(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_sqq_out_q_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_sqq_out_q_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_sqq_out_q_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_sqq_out_q_state); ret = state->handler.recv(state, subreq, &state->out.arg0); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_q(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_ss_out_o_state { struct _sbus_sss_invoker_args_ss *in; struct _sbus_sss_invoker_args_o out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char *, const char **); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, const char *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, const char **); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_ss_out_o_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_ss_out_o_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_ss_out_o_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_ss_out_o_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_ss_out_o_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_ss); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_ss(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_ss_out_o_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_ss_out_o_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_ss_out_o_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_ss_out_o_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, &state->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_o(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_ss_out_o_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_ss_out_o_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_ss_out_o_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_ss_out_o_state); ret = state->handler.recv(state, subreq, &state->out.arg0); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_o(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_ssau_out__state { struct _sbus_sss_invoker_args_ssau *in; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char *, uint32_t *); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, const char *, uint32_t *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_ssau_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_ssau_out__done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_ssau_out__send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_ssau_out__state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_ssau_out__state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_ssau); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_ssau(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_ssau_out__step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_ssau_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_ssau_out__state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_ssau_out__state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2); if (ret != EOK) { goto done; } goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_ssau_out__done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_ssau_out__done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_ssau_out__state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_ssau_out__state); ret = state->handler.recv(state, subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_u_out__state { struct _sbus_sss_invoker_args_u *in; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, uint32_t); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_u_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_u_out__done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_u_out__send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_u_out__state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_u_out__state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_u); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_u(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_u_out__step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_u_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_u_out__state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_u_out__state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0); if (ret != EOK) { goto done; } goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_u_out__done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_u_out__done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_u_out__state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_u_out__state); ret = state->handler.recv(state, subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_usq_out__state { struct _sbus_sss_invoker_args_usq *in; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t, const char *, uint16_t); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, uint32_t, const char *, uint16_t); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_usq_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_usq_out__done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_usq_out__send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_usq_out__state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_usq_out__state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_usq); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_usq(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_usq_out__step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_usq_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_usq_out__state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_usq_out__state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2); if (ret != EOK) { goto done; } goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_usq_out__done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_usq_out__done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_usq_out__state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_usq_out__state); ret = state->handler.recv(state, subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_ussu_out__state { struct _sbus_sss_invoker_args_ussu *in; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t, const char *, const char *, uint32_t); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, uint32_t, const char *, const char *, uint32_t); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_ussu_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_ussu_out__done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_ussu_out__send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_ussu_out__state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_ussu_out__state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_ussu); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_ussu(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_ussu_out__step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_ussu_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_ussu_out__state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_ussu_out__state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3); if (ret != EOK) { goto done; } goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_ussu_out__done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_ussu_out__done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_ussu_out__state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_ussu_out__state); ret = state->handler.recv(state, subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_ussu_out_qus_state { struct _sbus_sss_invoker_args_ussu *in; struct _sbus_sss_invoker_args_qus out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t, const char *, const char *, uint32_t, uint16_t*, uint32_t*, const char **); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, uint32_t, const char *, const char *, uint32_t); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, uint16_t*, uint32_t*, const char **); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_ussu_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_ussu_out_qus_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_ussu_out_qus_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_ussu_out_qus_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_ussu_out_qus_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_ussu); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_ussu(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_ussu_out_qus_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_ussu_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_ussu_out_qus_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_ussu_out_qus_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3, &state->out.arg0, &state->out.arg1, &state->out.arg2); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_ussu_out_qus_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_ussu_out_qus_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_ussu_out_qus_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_ussu_out_qus_state); ret = state->handler.recv(state, subreq, &state->out.arg0, &state->out.arg1, &state->out.arg2); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_usu_out__state { struct _sbus_sss_invoker_args_usu *in; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t, const char *, uint32_t); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, uint32_t, const char *, uint32_t); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_usu_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_usu_out__done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_usu_out__send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_usu_out__state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_usu_out__state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_usu); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_usu(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_usu_out__step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_usu_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_usu_out__state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_usu_out__state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2); if (ret != EOK) { goto done; } goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_usu_out__done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_usu_out__done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_usu_out__state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_usu_out__state); ret = state->handler.recv(state, subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_uusssu_out_qus_state { struct _sbus_sss_invoker_args_uusssu *in; struct _sbus_sss_invoker_args_qus out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t, uint32_t, const char *, const char *, const char *, uint32_t, uint16_t*, uint32_t*, const char **); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, uint32_t, uint32_t, const char *, const char *, const char *, uint32_t); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, uint16_t*, uint32_t*, const char **); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_uusssu_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_uusssu_out_qus_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_uusssu_out_qus_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_uusssu_out_qus_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_uusssu_out_qus_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_uusssu); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_uusssu(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_uusssu_out_qus_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_uusssu_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_uusssu_out_qus_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_uusssu_out_qus_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3, state->in->arg4, state->in->arg5, &state->out.arg0, &state->out.arg1, &state->out.arg2); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3, state->in->arg4, state->in->arg5); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_uusssu_out_qus_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_uusssu_out_qus_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_uusssu_out_qus_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_uusssu_out_qus_state); ret = state->handler.recv(state, subreq, &state->out.arg0, &state->out.arg1, &state->out.arg2); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_uusu_out_qus_state { struct _sbus_sss_invoker_args_uusu *in; struct _sbus_sss_invoker_args_qus out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t, uint32_t, const char *, uint32_t, uint16_t*, uint32_t*, const char **); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, uint32_t, uint32_t, const char *, uint32_t); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, uint16_t*, uint32_t*, const char **); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_uusu_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_uusu_out_qus_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_uusu_out_qus_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_uusu_out_qus_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_uusu_out_qus_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_uusu); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_uusu(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_uusu_out_qus_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_uusu_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_uusu_out_qus_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_uusu_out_qus_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3, &state->out.arg0, &state->out.arg1, &state->out.arg2); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_uusu_out_qus_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_uusu_out_qus_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_uusu_out_qus_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_uusu_out_qus_state); ret = state->handler.recv(state, subreq, &state->out.arg0, &state->out.arg1, &state->out.arg2); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_sss_invoke_in_uuusu_out_qus_state { struct _sbus_sss_invoker_args_uuusu *in; struct _sbus_sss_invoker_args_qus out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, uint32_t, uint32_t, uint32_t, const char *, uint32_t, uint16_t*, uint32_t*, const char **); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, uint32_t, uint32_t, uint32_t, const char *, uint32_t); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *, uint16_t*, uint32_t*, const char **); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_sss_invoke_in_uuusu_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_sss_invoke_in_uuusu_out_qus_done (struct tevent_req *subreq); struct tevent_req * _sbus_sss_invoke_in_uuusu_out_qus_send (TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, sbus_invoker_keygen keygen, const struct sbus_handler *handler, DBusMessageIter *read_iterator, DBusMessageIter *write_iterator, const char **_key) { struct _sbus_sss_invoke_in_uuusu_out_qus_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_sss_invoke_in_uuusu_out_qus_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); return NULL; } state->handler.type = handler->type; state->handler.data = handler->data; state->handler.sync = handler->sync; state->handler.send = handler->async_send; state->handler.recv = handler->async_recv; state->sbus_req = sbus_req; state->read_iterator = read_iterator; state->write_iterator = write_iterator; state->in = talloc_zero(state, struct _sbus_sss_invoker_args_uuusu); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_sss_invoker_read_uuusu(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_sss_invoke_in_uuusu_out_qus_step, req); if (ret != EOK) { goto done; } ret = sbus_request_key(state, keygen, sbus_req, state->in, &key); if (ret != EOK) { goto done; } if (_key != NULL) { *_key = talloc_steal(mem_ctx, key); } ret = EAGAIN; done: if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void _sbus_sss_invoke_in_uuusu_out_qus_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_sss_invoke_in_uuusu_out_qus_state *state; struct tevent_req *subreq; struct tevent_req *req; errno_t ret; req = talloc_get_type(private_data, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_uuusu_out_qus_state); switch (state->handler.type) { case SBUS_HANDLER_SYNC: if (state->handler.sync == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: sync handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } ret = state->handler.sync(state, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3, state->in->arg4, &state->out.arg0, &state->out.arg1, &state->out.arg2); if (ret != EOK) { goto done; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); goto done; case SBUS_HANDLER_ASYNC: if (state->handler.send == NULL || state->handler.recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: async handler is not specified!\n"); ret = ERR_INTERNAL; goto done; } subreq = state->handler.send(state, ev, state->sbus_req, state->handler.data, state->in->arg0, state->in->arg1, state->in->arg2, state->in->arg3, state->in->arg4); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_sss_invoke_in_uuusu_out_qus_done, req); ret = EAGAIN; goto done; } ret = ERR_INTERNAL; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static void _sbus_sss_invoke_in_uuusu_out_qus_done(struct tevent_req *subreq) { struct _sbus_sss_invoke_in_uuusu_out_qus_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct _sbus_sss_invoke_in_uuusu_out_qus_state); ret = state->handler.recv(state, subreq, &state->out.arg0, &state->out.arg1, &state->out.arg2); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = _sbus_sss_invoker_write_qus(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; }