d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina Pavel Březina <pbrezina@redhat.com>
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina Copyright (C) 2016 Red Hat
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina This program is free software; you can redistribute it and/or modify
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina it under the terms of the GNU General Public License as published by
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina the Free Software Foundation; either version 3 of the License, or
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina (at your option) any later version.
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina This program is distributed in the hope that it will be useful,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina GNU General Public License for more details.
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina You should have received a copy of the GNU General Public License
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina#include "providers/data_provider/dp_private.h"
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinavoid dp_req_reply_default(const char *req_name,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina DP_REQ_DEBUG(SSSDBG_TRACE_FUNC, req_name, "Replying with empty message");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina sbus_request_return_and_finish(sbus_req, DBUS_TYPE_INVALID);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinastatic DBusError *dp_req_reply_gen_error(TALLOC_CTX *mem_ctx,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "Bug: Success case must be handled by custom handler.");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina error = sbus_error_new(mem_ctx, SBUS_ERROR_INTERNAL,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "Operation succeeded but result was not handled");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "Finished. Backend is currently offline.");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina error = sbus_error_new(mem_ctx, SBUS_ERROR_DP_OFFLINE,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "Backend is currently offline");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "Finished. Target is not supported "
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "with this configuration.");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina error = sbus_error_new(mem_ctx, SBUS_ERROR_DP_NOTSUP,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "Target is not supported.");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "Finished. Error [%d]: %s", ret, sss_strerror(ret));
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina error = sbus_error_new(mem_ctx, SBUS_ERROR_DP_FATAL,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "An error occurred [%d]: %s", ret, sss_strerror(ret));
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinavoid dp_req_reply_error(struct sbus_request *sbus_req,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina error = dp_req_reply_gen_error(sbus_req, req_name, ret);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "Out of memory, killing request...");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina sbus_request_fail_and_finish(sbus_req, error);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinastatic void dp_req_reply_list_error(struct dp_sbus_req_item *list,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina error = dp_req_reply_gen_error(NULL, req_name, ret);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "Out of memory, killing request...");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina for (item = list; item != NULL; item = next_item) {
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina for (item = list; item != NULL; item = next_item) {
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina sbus_request_fail_and_finish(item->sbus_req, error);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinastatic void dp_req_reply_list_success(struct dp_sbus_req_item *list,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina DP_REQ_DEBUG(SSSDBG_TRACE_FUNC, request_name, "Finished. Success.");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina for (item = list; item != NULL; item = next_item) {
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina reply_fn(request_name, item->sbus_req, output_data);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinastatic errno_t dp_req_with_reply_step(struct data_provider *provider,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinastatic void dp_req_with_reply_done(struct tevent_req *req);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinavoid _dp_req_with_reply(struct dp_client *dp_cli,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina /* It may not be always possible or desirable to have a meaningful key
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina * to chain sbus request. In such cases, we generate a unique key from
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina * sbus_req address that allows us to use the same code but the
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina * chaining is logically disabled. */
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina custom_key = talloc_asprintf(tmp_ctx, "%p", sbus_req);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina key = dp_req_table_key(tmp_ctx, target, method, dp_flags, custom_key);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina has_key = dp_req_table_has_key(provider->requests.reply_table, key);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina ret = dp_req_table_add(provider->requests.reply_table,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to attach sbus request to "
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "existing data provider request [%d]: %s\n",
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Attaching to DP request: %s\n", key);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina ret = dp_req_with_reply_step(provider, dp_cli, domain, request_name, key,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina request_data, postprocess_fn, postprocess_data,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate memory for "
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "new DP request, killing D-Bus request...\n");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize "
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina "DP request [%d: %s], killing D-Bus request...\n",
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinastatic errno_t dp_req_with_reply_step(struct data_provider *provider,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina state = talloc_zero(tmp_ctx, struct dp_req_with_reply_state);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina state->key = talloc_strdup(state, custom_key);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina state->output_dtype = talloc_strdup(state, output_dtype);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina req = dp_req_send(tmp_ctx, provider, dp_cli, domain, request_name, target,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina method, dp_flags, request_data, &state->name);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina ret = dp_req_table_add(provider->requests.reply_table,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add request to table "
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina tevent_req_set_callback(req, dp_req_with_reply_done, state);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březinastatic void dp_req_with_reply_done(struct tevent_req *req)
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina state = tevent_req_callback_data(req, struct dp_req_with_reply_state);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina value = dp_req_table_lookup(state->provider->requests.reply_table,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup table!\n");
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina ret = _dp_req_recv(state, req, state->output_dtype, &output_data);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina dp_req_reply_list_error(value->list, state->name, ret);
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina /* Run postprocess function if any. */
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina /* Reply with data. */
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina dp_req_reply_list_success(value->list, state->reply_fn,
d3dee2a07f1a8ee9ae6f94e149ced754ef76c248Pavel Březina /* Freeing value will remove it from the table as well. */