/* 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 "sbus/interface_dbus/sbus_dbus_arguments.h" #include "sbus/interface_dbus/sbus_dbus_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_dbus_invoke_in__out_as_state { struct _sbus_dbus_invoker_args_as out; 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 *); 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_dbus_invoke_in__out_as_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in__out_as_done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_invoke_in__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_dbus_invoke_in__out_as_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_dbus_invoke_in__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; ret = sbus_invoker_schedule(state, ev, _sbus_dbus_invoke_in__out_as_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_dbus_invoke_in__out_as_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_invoke_in__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_dbus_invoke_in__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->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_dbus_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); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_dbus_invoke_in__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_dbus_invoke_in__out_as_done(struct tevent_req *subreq) { struct _sbus_dbus_invoke_in__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_dbus_invoke_in__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_dbus_invoker_write_as(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_dbus_invoke_in__out_s_state { struct _sbus_dbus_invoker_args_s out; 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 *); 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_dbus_invoke_in__out_s_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in__out_s_done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_invoke_in__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_dbus_invoke_in__out_s_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_dbus_invoke_in__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; ret = sbus_invoker_schedule(state, ev, _sbus_dbus_invoke_in__out_s_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_dbus_invoke_in__out_s_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_invoke_in__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_dbus_invoke_in__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->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_dbus_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); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_dbus_invoke_in__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_dbus_invoke_in__out_s_done(struct tevent_req *subreq) { struct _sbus_dbus_invoke_in__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_dbus_invoke_in__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_dbus_invoker_write_s(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_dbus_invoke_in_raw_out__state { struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, DBusMessageIter *); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, DBusMessageIter *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_dbus_invoke_in_raw_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_raw_out__done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_invoke_in_raw_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_dbus_invoke_in_raw_out__state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_dbus_invoke_in_raw_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_dbus_invoke_in_raw_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_dbus_invoke_in_raw_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_invoke_in_raw_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_dbus_invoke_in_raw_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->read_iterator); 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->read_iterator); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_dbus_invoke_in_raw_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_dbus_invoke_in_raw_out__done(struct tevent_req *subreq) { struct _sbus_dbus_invoke_in_raw_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_dbus_invoke_in_raw_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_dbus_invoke_in_s_out__state { struct _sbus_dbus_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_dbus_invoke_in_s_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_s_out__done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_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_dbus_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_dbus_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_dbus_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_dbus_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_dbus_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_dbus_invoke_in_s_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_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_dbus_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_dbus_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_dbus_invoke_in_s_out__done(struct tevent_req *subreq) { struct _sbus_dbus_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_dbus_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_dbus_invoke_in_s_out_as_state { struct _sbus_dbus_invoker_args_s *in; struct _sbus_dbus_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_dbus_invoke_in_s_out_as_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_s_out_as_done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_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_dbus_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_dbus_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_dbus_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_dbus_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_dbus_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_dbus_invoke_in_s_out_as_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_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_dbus_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_dbus_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_dbus_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_dbus_invoke_in_s_out_as_done(struct tevent_req *subreq) { struct _sbus_dbus_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_dbus_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_dbus_invoker_write_as(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_dbus_invoke_in_s_out_b_state { struct _sbus_dbus_invoker_args_s *in; struct _sbus_dbus_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_dbus_invoke_in_s_out_b_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_s_out_b_done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_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_dbus_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_dbus_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_dbus_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_dbus_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_dbus_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_dbus_invoke_in_s_out_b_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_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_dbus_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_dbus_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_dbus_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_dbus_invoke_in_s_out_b_done(struct tevent_req *subreq) { struct _sbus_dbus_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_dbus_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_dbus_invoker_write_b(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_dbus_invoke_in_s_out_raw_state { struct _sbus_dbus_invoker_args_s *in; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, DBusMessageIter *); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, DBusMessageIter *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_dbus_invoke_in_s_out_raw_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_s_out_raw_done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_invoke_in_s_out_raw_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_dbus_invoke_in_s_out_raw_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_dbus_invoke_in_s_out_raw_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_dbus_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_dbus_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_dbus_invoke_in_s_out_raw_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_dbus_invoke_in_s_out_raw_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_invoke_in_s_out_raw_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_dbus_invoke_in_s_out_raw_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->write_iterator); 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->write_iterator); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_dbus_invoke_in_s_out_raw_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_dbus_invoke_in_s_out_raw_done(struct tevent_req *subreq) { struct _sbus_dbus_invoke_in_s_out_raw_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_dbus_invoke_in_s_out_raw_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_dbus_invoke_in_s_out_s_state { struct _sbus_dbus_invoker_args_s *in; struct _sbus_dbus_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_dbus_invoke_in_s_out_s_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_s_out_s_done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_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_dbus_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_dbus_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_dbus_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_dbus_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_dbus_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_dbus_invoke_in_s_out_s_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_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_dbus_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_dbus_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_dbus_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_dbus_invoke_in_s_out_s_done(struct tevent_req *subreq) { struct _sbus_dbus_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_dbus_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_dbus_invoker_write_s(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_dbus_invoke_in_s_out_u_state { struct _sbus_dbus_invoker_args_s *in; struct _sbus_dbus_invoker_args_u out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, uint32_t*); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *); 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_dbus_invoke_in_s_out_u_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_s_out_u_done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_invoke_in_s_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_dbus_invoke_in_s_out_u_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_dbus_invoke_in_s_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; state->in = talloc_zero(state, struct _sbus_dbus_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_dbus_invoker_read_s(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_dbus_invoke_in_s_out_u_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_dbus_invoke_in_s_out_u_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_invoke_in_s_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_dbus_invoke_in_s_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->in->arg0, &state->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_dbus_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, 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_dbus_invoke_in_s_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_dbus_invoke_in_s_out_u_done(struct tevent_req *subreq) { struct _sbus_dbus_invoke_in_s_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_dbus_invoke_in_s_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_dbus_invoker_write_u(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } struct _sbus_dbus_invoke_in_ss_out_raw_state { struct _sbus_dbus_invoker_args_ss *in; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, const char *, DBusMessageIter *); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, const char *, DBusMessageIter *); errno_t (*recv)(TALLOC_CTX *, struct tevent_req *); } handler; struct sbus_request *sbus_req; DBusMessageIter *read_iterator; DBusMessageIter *write_iterator; }; static void _sbus_dbus_invoke_in_ss_out_raw_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_ss_out_raw_done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_invoke_in_ss_out_raw_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_dbus_invoke_in_ss_out_raw_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_dbus_invoke_in_ss_out_raw_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_dbus_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_dbus_invoker_read_ss(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_dbus_invoke_in_ss_out_raw_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_dbus_invoke_in_ss_out_raw_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_invoke_in_ss_out_raw_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_dbus_invoke_in_ss_out_raw_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->write_iterator); 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->write_iterator); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, _sbus_dbus_invoke_in_ss_out_raw_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_dbus_invoke_in_ss_out_raw_done(struct tevent_req *subreq) { struct _sbus_dbus_invoke_in_ss_out_raw_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_dbus_invoke_in_ss_out_raw_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_dbus_invoke_in_sss_out__state { struct _sbus_dbus_invoker_args_sss *in; 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 *, 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_dbus_invoke_in_sss_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_sss_out__done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_invoke_in_sss_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_dbus_invoke_in_sss_out__state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_dbus_invoke_in_sss_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_dbus_invoker_args_sss); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_dbus_invoker_read_sss(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_dbus_invoke_in_sss_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_dbus_invoke_in_sss_out__step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_invoke_in_sss_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_dbus_invoke_in_sss_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_dbus_invoke_in_sss_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_dbus_invoke_in_sss_out__done(struct tevent_req *subreq) { struct _sbus_dbus_invoke_in_sss_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_dbus_invoke_in_sss_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_dbus_invoke_in_su_out_u_state { struct _sbus_dbus_invoker_args_su *in; struct _sbus_dbus_invoker_args_u out; struct { enum sbus_handler_type type; void *data; errno_t (*sync)(TALLOC_CTX *, struct sbus_request *, void *, const char *, uint32_t, uint32_t*); struct tevent_req * (*send)(TALLOC_CTX *, struct tevent_context *, struct sbus_request *, void *, const char *, uint32_t); 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_dbus_invoke_in_su_out_u_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data); static void _sbus_dbus_invoke_in_su_out_u_done (struct tevent_req *subreq); struct tevent_req * _sbus_dbus_invoke_in_su_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_dbus_invoke_in_su_out_u_state *state; struct tevent_req *req; const char *key; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct _sbus_dbus_invoke_in_su_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; state->in = talloc_zero(state, struct _sbus_dbus_invoker_args_su); if (state->in == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate space for input parameters!\n"); ret = ENOMEM; goto done; } ret = _sbus_dbus_invoker_read_su(state, read_iterator, state->in); if (ret != EOK) { goto done; } ret = sbus_invoker_schedule(state, ev, _sbus_dbus_invoke_in_su_out_u_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_dbus_invoke_in_su_out_u_step (struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *private_data) { struct _sbus_dbus_invoke_in_su_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_dbus_invoke_in_su_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->in->arg0, state->in->arg1, &state->out.arg0); if (ret != EOK) { goto done; } ret = _sbus_dbus_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, 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_dbus_invoke_in_su_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_dbus_invoke_in_su_out_u_done(struct tevent_req *subreq) { struct _sbus_dbus_invoke_in_su_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_dbus_invoke_in_su_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_dbus_invoker_write_u(state->write_iterator, &state->out); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; }