LCOV - code coverage report
Current view: top level - responder/common/data_provider - rdp_message.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 96 0.0 %
Date: 2016-06-29 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2016 Red Hat
       6             : 
       7             :     This program is free software; you can redistribute it and/or modify
       8             :     it under the terms of the GNU General Public License as published by
       9             :     the Free Software Foundation; either version 3 of the License, or
      10             :     (at your option) any later version.
      11             : 
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :     GNU General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include <talloc.h>
      22             : #include <tevent.h>
      23             : 
      24             : #include "responder/common/data_provider/rdp.h"
      25             : #include "sbus/sssd_dbus.h"
      26             : #include "sbus/sssd_dbus_errors.h"
      27             : #include "util/util.h"
      28             : 
      29           0 : static errno_t rdp_error_to_errno(DBusError *error)
      30             : {
      31             :     static struct {
      32             :         const char *name;
      33             :         errno_t ret;
      34             :     } list[] = {{SBUS_ERROR_INTERNAL, ERR_INTERNAL},
      35             :                 {SBUS_ERROR_NOT_FOUND, ENOENT},
      36             :                 {SBUS_ERROR_DP_FATAL, ERR_TERMINATED},
      37             :                 {SBUS_ERROR_DP_OFFLINE, ERR_OFFLINE},
      38             :                 {SBUS_ERROR_DP_NOTSUP, ENOTSUP},
      39             :                 {NULL, ERR_INTERNAL}
      40             :     };
      41             :     int i;
      42             : 
      43           0 :     if (!dbus_error_is_set(error)) {
      44           0 :         return EOK;
      45             :     }
      46             : 
      47           0 :     for (i = 0; list[i].name != NULL; i ++) {
      48           0 :         if (dbus_error_has_name(error, list[i].name)) {
      49           0 :             return list[i].ret;
      50             :         }
      51             :     }
      52             : 
      53           0 :     return EIO;
      54             : }
      55             : 
      56             : struct rdp_message_state {
      57             :     struct DBusMessage *reply;
      58             : };
      59             : 
      60           0 : static int rdp_message_state_destructor(struct rdp_message_state *state)
      61             : {
      62           0 :     if (state->reply != NULL) {
      63           0 :         dbus_message_unref(state->reply);
      64             :     }
      65             : 
      66           0 :     return 0;
      67             : }
      68             : 
      69             : static void rdp_message_done(DBusPendingCall *pending, void *ptr);
      70             : 
      71           0 : struct tevent_req *_rdp_message_send(TALLOC_CTX *mem_ctx,
      72             :                                      struct resp_ctx *rctx,
      73             :                                      struct sss_domain_info *domain,
      74             :                                      const char *path,
      75             :                                      const char *iface,
      76             :                                      const char *method,
      77             :                                      int first_arg_type,
      78             :                                      ...)
      79             : {
      80             :     struct rdp_message_state *state;
      81             :     struct be_conn *be_conn;
      82             :     struct tevent_req *req;
      83             :     DBusMessage *msg;
      84             :     dbus_bool_t bret;
      85             :     errno_t ret;
      86             :     va_list va;
      87             : 
      88           0 :     req = tevent_req_create(mem_ctx, &state, struct rdp_message_state);
      89           0 :     if (req == NULL) {
      90           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
      91           0 :         return NULL;
      92             :     }
      93             : 
      94           0 :     talloc_set_destructor(state, rdp_message_state_destructor);
      95             : 
      96           0 :     ret = sss_dp_get_domain_conn(rctx, domain->conn_name, &be_conn);
      97           0 :     if (ret != EOK) {
      98           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "BUG: The Data Provider connection for "
      99             :               "%s is not available!\n", domain->name);
     100           0 :         ret = ERR_INTERNAL;
     101           0 :         goto immediately;
     102             :     }
     103             : 
     104           0 :     msg = dbus_message_new_method_call(NULL, path, iface, method);
     105           0 :     if (msg == NULL) {
     106           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create message\n");
     107           0 :         ret = ENOMEM;
     108           0 :         goto immediately;
     109             :     }
     110             : 
     111           0 :     va_start(va, first_arg_type);
     112           0 :     bret = dbus_message_append_args_valist(msg, first_arg_type, va);
     113           0 :     va_end(va);
     114           0 :     if (!bret) {
     115           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n");
     116           0 :         ret = EIO;
     117           0 :         goto immediately;
     118             :     }
     119             : 
     120           0 :     DEBUG(SSSDBG_TRACE_FUNC, "DP Request: %s %s.%s\n", path, iface, method);
     121             : 
     122           0 :     ret = sbus_conn_send(be_conn->conn, msg, 30000,
     123             :                          rdp_message_done, req, NULL);
     124           0 :     if (ret != EOK) {
     125           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to contact Data Provider "
     126             :               "[%d]: %s\n", ret, sss_strerror(ret));
     127           0 :         goto immediately;
     128             :     }
     129             : 
     130           0 :     return req;
     131             : 
     132             : immediately:
     133           0 :     if (ret == EOK) {
     134           0 :         tevent_req_done(req);
     135             :     } else {
     136           0 :         tevent_req_error(req, ret);
     137             :     }
     138           0 :     tevent_req_post(req, rctx->ev);
     139             : 
     140           0 :     return req;
     141             : }
     142             : 
     143           0 : static void rdp_message_done(DBusPendingCall *pending, void *ptr)
     144             : {
     145             :     struct rdp_message_state *state;
     146           0 :     DBusMessage *reply = NULL;
     147             :     struct tevent_req *req;
     148             :     DBusError error;
     149             :     dbus_bool_t bret;
     150             :     errno_t ret;
     151             : 
     152           0 :     req = talloc_get_type(ptr, struct tevent_req);
     153           0 :     state = tevent_req_data(req, struct rdp_message_state);
     154             : 
     155           0 :     dbus_error_init(&error);
     156             : 
     157           0 :     reply = dbus_pending_call_steal_reply(pending);
     158           0 :     if (reply == NULL) {
     159           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Severe error. A reply callback was "
     160             :               "called but no reply was received and no timeout occurred\n");
     161           0 :         ret = EFAULT;
     162           0 :         goto done;
     163             :     }
     164             : 
     165           0 :     switch (dbus_message_get_type(reply)) {
     166             :     case DBUS_MESSAGE_TYPE_METHOD_RETURN:
     167           0 :         DEBUG(SSSDBG_TRACE_FUNC, "DP Success\n");
     168           0 :         state->reply = reply;
     169           0 :         ret = EOK;
     170           0 :         goto done;
     171             : 
     172             :     case DBUS_MESSAGE_TYPE_ERROR:
     173           0 :         bret = dbus_set_error_from_message(&error, reply);
     174           0 :         if (bret == false) {
     175           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read error from message\n");
     176           0 :             ret = EIO;
     177           0 :             goto done;
     178             :         }
     179             : 
     180           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "DP Error [%s]: %s\n",
     181             :               error.name, (error.message == NULL ? "(null)" : error.message));
     182           0 :         ret = rdp_error_to_errno(&error);
     183           0 :         goto done;
     184             :     default:
     185           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected type?\n");
     186           0 :         ret = ERR_INTERNAL;
     187           0 :         goto done;
     188             :     }
     189             : 
     190             :     ret = ERR_INTERNAL;
     191             : 
     192             : done:
     193           0 :     dbus_pending_call_unref(pending);
     194           0 :     dbus_error_free(&error);
     195             : 
     196           0 :     if (ret == EOK) {
     197           0 :         tevent_req_done(req);
     198           0 :         return;
     199             :     }
     200             : 
     201           0 :     if (reply != NULL) {
     202           0 :         dbus_message_unref(reply);
     203             :     }
     204           0 :     tevent_req_error(req, ret);
     205             : }
     206             : 
     207           0 : errno_t _rdp_message_recv(struct tevent_req *req,
     208             :                           int first_arg_type,
     209             :                           ...)
     210             : {
     211             :     struct rdp_message_state *state;
     212             :     DBusError error;
     213             :     dbus_bool_t bret;
     214             :     errno_t ret;
     215             :     va_list va;
     216             : 
     217           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     218             : 
     219           0 :     state = tevent_req_data(req, struct rdp_message_state);
     220           0 :     dbus_error_init(&error);
     221             : 
     222           0 :     va_start(va, first_arg_type);
     223           0 :     bret = dbus_message_get_args_valist(state->reply, &error, first_arg_type, va);
     224           0 :     va_end(va);
     225             : 
     226           0 :     if (bret == false) {
     227           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse reply\n");
     228           0 :         ret = EIO;
     229           0 :         goto done;
     230             :     }
     231             : 
     232           0 :     ret = rdp_error_to_errno(&error);
     233           0 :     if (ret != EOK) {
     234           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse message [%s]: %s\n",
     235             :               error.name, error.message);
     236           0 :         goto done;
     237             :     }
     238             : 
     239             : done:
     240           0 :     dbus_error_free(&error);
     241           0 :     return ret;
     242             : }
     243             : 

Generated by: LCOV version 1.10