LCOV - code coverage report
Current view: top level - sbus - sssd_dbus_invokers.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 209 0.0 %
Date: 2016-06-29 Functions: 0 27 0.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2014 Red Hat
       6             : 
       7             :     SBUS: Interface introspection
       8             : 
       9             :     This program is free software; you can redistribute it and/or modify
      10             :     it under the terms of the GNU General Public License as published by
      11             :     the Free Software Foundation; either version 3 of the License, or
      12             :     (at your option) any later version.
      13             : 
      14             :     This program is distributed in the hope that it will be useful,
      15             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :     GNU General Public License for more details.
      18             : 
      19             :     You should have received a copy of the GNU General Public License
      20             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "config.h"
      24             : 
      25             : #include <dbus/dbus.h>
      26             : #include <errno.h>
      27             : 
      28             : #include "util/util.h"
      29             : #include "sbus/sssd_dbus.h"
      30             : #include "sbus/sssd_dbus_meta.h"
      31             : #include "sbus/sssd_dbus_private.h"
      32             : #include "sbus/sssd_dbus_invokers.h"
      33             : 
      34             : static int
      35           0 : sbus_invoke_get_basic(struct sbus_request *sbus_req,
      36             :                       void *function_ptr,
      37             :                       void *value_ptr,
      38             :                       int dbus_type,
      39             :                       DBusMessageIter *iter)
      40             : {
      41             :     void (*handler_fn)(struct sbus_request *, void *, void *);
      42             :     dbus_bool_t value_bool;
      43             :     dbus_bool_t dbret;
      44             : 
      45           0 :     handler_fn = function_ptr;
      46           0 :     handler_fn(sbus_req, sbus_req->intf->handler_data, value_ptr);
      47             : 
      48           0 :     if (dbus_type == DBUS_TYPE_BOOLEAN) {
      49             :         /* Special case to convert bool into dbus_bool_t. */
      50           0 :         value_bool = *((bool *) value_ptr);
      51           0 :         value_ptr = &value_bool;
      52             :     }
      53             : 
      54           0 :     dbret = dbus_message_iter_append_basic(iter, dbus_type, value_ptr);
      55           0 :     return dbret ? EOK : EIO;
      56             : }
      57             : 
      58             : static int
      59           0 : sbus_invoke_get_string(struct sbus_request *sbus_req,
      60             :                        void *function_ptr,
      61             :                        const char *default_value,
      62             :                        int dbus_type,
      63             :                        DBusMessageIter *iter)
      64             : {
      65             :     void (*handler_fn)(struct sbus_request *, void *, const char **);
      66           0 :     const char *value = NULL;
      67             :     dbus_bool_t dbret;
      68             : 
      69           0 :     handler_fn = function_ptr;
      70           0 :     handler_fn(sbus_req, sbus_req->intf->handler_data, &value);
      71             : 
      72           0 :     value = value == NULL ? default_value : value;
      73             : 
      74           0 :     dbret = dbus_message_iter_append_basic(iter, dbus_type, &value);
      75           0 :     return dbret ? EOK : EIO;
      76             : }
      77             : 
      78             : static int
      79           0 : sbus_invoke_get_array(struct sbus_request *sbus_req,
      80             :                       void *function_ptr,
      81             :                       unsigned int item_size,
      82             :                       int dbus_type,
      83             :                       DBusMessageIter *iter)
      84             : {
      85             :     void (*handler_fn)(struct sbus_request *, void *, void *, int *);
      86           0 :     const char array_type[2] = {dbus_type, '\0'};
      87             :     DBusMessageIter array;
      88             :     dbus_bool_t dbret;
      89             :     uint8_t *values;
      90             :     void *addr;
      91             :     int num_values;
      92             :     int i;
      93             : 
      94           0 :     handler_fn = function_ptr;
      95           0 :     handler_fn(sbus_req, sbus_req->intf->handler_data, &values, &num_values);
      96             : 
      97           0 :     dbret = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
      98             :                                              array_type, &array);
      99           0 :     if (!dbret) {
     100           0 :         return EIO;
     101             :     }
     102             : 
     103           0 :     for (i = 0; i < num_values; i++) {
     104           0 :         addr = values + i * item_size;
     105             : 
     106           0 :         dbret = dbus_message_iter_append_basic(&array, dbus_type, addr);
     107           0 :         if (!dbret) {
     108           0 :             return ENOMEM;
     109             :         }
     110             :     }
     111             : 
     112           0 :     dbret = dbus_message_iter_close_container(iter, &array);
     113           0 :     if (!dbret) {
     114           0 :         return EIO;
     115             :     }
     116             : 
     117           0 :     return EOK;
     118             : }
     119             : 
     120           0 : int sbus_invoke_get_y(DBusMessageIter *iter,
     121             :                       struct sbus_request *sbus_req,
     122             :                       void *function_ptr)
     123             : {
     124             :     uint8_t value;
     125             : 
     126           0 :     return sbus_invoke_get_basic(sbus_req, function_ptr, &value,
     127             :                                  DBUS_TYPE_BYTE, iter);
     128             : }
     129             : 
     130           0 : int sbus_invoke_get_b(DBusMessageIter *iter,
     131             :                       struct sbus_request *sbus_req,
     132             :                       void *function_ptr)
     133             : {
     134             :     bool value;
     135             : 
     136           0 :     return sbus_invoke_get_basic(sbus_req, function_ptr, &value,
     137             :                                  DBUS_TYPE_BOOLEAN, iter);
     138             : }
     139             : 
     140           0 : int sbus_invoke_get_n(DBusMessageIter *iter,
     141             :                       struct sbus_request *sbus_req,
     142             :                       void *function_ptr)
     143             : {
     144             :     int16_t value;
     145             : 
     146           0 :     return sbus_invoke_get_basic(sbus_req, function_ptr, &value,
     147             :                                  DBUS_TYPE_INT16, iter);
     148             : }
     149             : 
     150           0 : int sbus_invoke_get_q(DBusMessageIter *iter,
     151             :                       struct sbus_request *sbus_req,
     152             :                       void *function_ptr)
     153             : {
     154             :     uint16_t value;
     155             : 
     156           0 :     return sbus_invoke_get_basic(sbus_req, function_ptr, &value,
     157             :                                  DBUS_TYPE_UINT16, iter);
     158             : }
     159             : 
     160           0 : int sbus_invoke_get_i(DBusMessageIter *iter,
     161             :                       struct sbus_request *sbus_req,
     162             :                       void *function_ptr)
     163             : {
     164             :     int32_t value;
     165             : 
     166           0 :     return sbus_invoke_get_basic(sbus_req, function_ptr, &value,
     167             :                                  DBUS_TYPE_INT32, iter);
     168             : }
     169             : 
     170           0 : int sbus_invoke_get_u(DBusMessageIter *iter,
     171             :                       struct sbus_request *sbus_req,
     172             :                       void *function_ptr)
     173             : {
     174             :     uint32_t value;
     175             : 
     176           0 :     return sbus_invoke_get_basic(sbus_req, function_ptr, &value,
     177             :                                  DBUS_TYPE_UINT32, iter);
     178             : }
     179             : 
     180           0 : int sbus_invoke_get_x(DBusMessageIter *iter,
     181             :                       struct sbus_request *sbus_req,
     182             :                       void *function_ptr)
     183             : {
     184             :     int64_t value;
     185             : 
     186           0 :     return sbus_invoke_get_basic(sbus_req, function_ptr, &value,
     187             :                                  DBUS_TYPE_INT64, iter);
     188             : }
     189             : 
     190           0 : int sbus_invoke_get_t(DBusMessageIter *iter,
     191             :                       struct sbus_request *sbus_req,
     192             :                       void *function_ptr)
     193             : {
     194             :     uint64_t value;
     195             : 
     196           0 :     return sbus_invoke_get_basic(sbus_req, function_ptr, &value,
     197             :                                  DBUS_TYPE_UINT64, iter);
     198             : }
     199             : 
     200           0 : int sbus_invoke_get_d(DBusMessageIter *iter,
     201             :                       struct sbus_request *sbus_req,
     202             :                       void *function_ptr)
     203             : {
     204             :     double value;
     205             : 
     206           0 :     return sbus_invoke_get_basic(sbus_req, function_ptr, &value,
     207             :                                  DBUS_TYPE_DOUBLE, iter);
     208             : }
     209             : 
     210           0 : int sbus_invoke_get_s(DBusMessageIter *iter,
     211             :                       struct sbus_request *sbus_req,
     212             :                       void *function_ptr)
     213             : {
     214           0 :     return sbus_invoke_get_string(sbus_req, function_ptr, "",
     215             :                                   DBUS_TYPE_STRING, iter);
     216             : }
     217             : 
     218           0 : int sbus_invoke_get_o(DBusMessageIter *iter,
     219             :                       struct sbus_request *sbus_req,
     220             :                       void *function_ptr)
     221             : {
     222           0 :     return sbus_invoke_get_string(sbus_req, function_ptr, "/",
     223             :                                   DBUS_TYPE_OBJECT_PATH, iter);
     224             : }
     225             : 
     226           0 : int sbus_invoke_get_ay(DBusMessageIter *iter,
     227             :                        struct sbus_request *sbus_req,
     228             :                        void *function_ptr)
     229             : {
     230           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(uint8_t),
     231             :                                  DBUS_TYPE_BYTE, iter);
     232             : }
     233             : 
     234           0 : int sbus_invoke_get_an(DBusMessageIter *iter,
     235             :                        struct sbus_request *sbus_req,
     236             :                        void *function_ptr)
     237             : {
     238           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(int16_t),
     239             :                                  DBUS_TYPE_INT16, iter);
     240             : }
     241             : 
     242           0 : int sbus_invoke_get_aq(DBusMessageIter *iter,
     243             :                        struct sbus_request *sbus_req,
     244             :                        void *function_ptr)
     245             : {
     246           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(uint16_t),
     247             :                                  DBUS_TYPE_UINT16, iter);
     248             : }
     249             : 
     250           0 : int sbus_invoke_get_ai(DBusMessageIter *iter,
     251             :                        struct sbus_request *sbus_req,
     252             :                        void *function_ptr)
     253             : {
     254           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(int32_t),
     255             :                                  DBUS_TYPE_INT32, iter);
     256             : }
     257             : 
     258           0 : int sbus_invoke_get_au(DBusMessageIter *iter,
     259             :                        struct sbus_request *sbus_req,
     260             :                        void *function_ptr)
     261             : {
     262           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(uint32_t),
     263             :                                  DBUS_TYPE_UINT32, iter);
     264             : }
     265             : 
     266           0 : int sbus_invoke_get_ax(DBusMessageIter *iter,
     267             :                        struct sbus_request *sbus_req,
     268             :                        void *function_ptr)
     269             : {
     270           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(int64_t),
     271             :                                  DBUS_TYPE_INT64, iter);
     272             : }
     273             : 
     274           0 : int sbus_invoke_get_at(DBusMessageIter *iter,
     275             :                        struct sbus_request *sbus_req,
     276             :                        void *function_ptr)
     277             : {
     278           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(uint64_t),
     279             :                                  DBUS_TYPE_UINT64, iter);
     280             : }
     281             : 
     282           0 : int sbus_invoke_get_ad(DBusMessageIter *iter,
     283             :                        struct sbus_request *sbus_req,
     284             :                        void *function_ptr)
     285             : {
     286           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(double),
     287             :                                  DBUS_TYPE_DOUBLE, iter);
     288             : }
     289             : 
     290           0 : int sbus_invoke_get_as(DBusMessageIter *iter,
     291             :                        struct sbus_request *sbus_req,
     292             :                        void *function_ptr)
     293             : {
     294           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(const char *),
     295             :                                  DBUS_TYPE_STRING, iter);
     296             : }
     297             : 
     298           0 : int sbus_invoke_get_ao(DBusMessageIter *iter,
     299             :                        struct sbus_request *sbus_req,
     300             :                        void *function_ptr)
     301             : {
     302           0 :     return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(const char *),
     303             :                                  DBUS_TYPE_OBJECT_PATH, iter);
     304             : }
     305             : 
     306           0 : int sbus_invoke_get_aDOsasDE(DBusMessageIter *iter,
     307             :                              struct sbus_request *sbus_req,
     308             :                              void *function_ptr)
     309             : {
     310             :     void (*handler_fn)(struct sbus_request *, void *, hash_table_t **);
     311             :     DBusMessageIter it_array;
     312             :     DBusMessageIter it_dict;
     313             :     DBusMessageIter it_values;
     314             :     hash_table_t *table;
     315           0 :     struct hash_iter_context_t *table_iter = NULL;
     316             :     hash_entry_t *entry;
     317             :     const char **values;
     318             :     dbus_bool_t dbret;
     319             :     errno_t ret;
     320             :     int i;
     321             : 
     322           0 :     handler_fn = function_ptr;
     323           0 :     handler_fn(sbus_req, sbus_req->intf->handler_data, &table);
     324             : 
     325           0 :     dbret = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
     326             :                     DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
     327             :                     DBUS_TYPE_STRING_AS_STRING
     328             :                     DBUS_TYPE_ARRAY_AS_STRING
     329             :                     DBUS_TYPE_STRING_AS_STRING
     330             :                     DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &it_array);
     331           0 :     if (!dbret) {
     332           0 :         ret = EIO;
     333           0 :         goto done;
     334             :     }
     335             : 
     336             :     /* iterate over keys */
     337             : 
     338           0 :     if (table == NULL) {
     339           0 :         dbret = dbus_message_iter_close_container(iter, &it_array);
     340           0 :         if (!dbret) {
     341           0 :             ret = EIO;
     342           0 :             goto done;
     343             :         }
     344             : 
     345           0 :         ret = EOK;
     346           0 :         goto done;
     347             :     }
     348             : 
     349           0 :     table_iter = new_hash_iter_context(table);
     350           0 :     while ((entry = table_iter->next(table_iter)) != NULL) {
     351           0 :         if (entry->key.type != HASH_KEY_STRING || entry->key.str == NULL
     352           0 :                 || entry->value.type != HASH_VALUE_PTR
     353           0 :                 || entry->value.ptr == NULL) {
     354           0 :             continue;
     355             :         }
     356             : 
     357           0 :         dbret = dbus_message_iter_open_container(&it_array,
     358             :                                                  DBUS_TYPE_DICT_ENTRY, NULL,
     359             :                                                  &it_dict);
     360           0 :         if (!dbret) {
     361           0 :             ret = EIO;
     362           0 :             goto done;
     363             :         }
     364             : 
     365             :         /* append key as dict entry key */
     366             : 
     367           0 :         dbret = dbus_message_iter_append_basic(&it_dict,
     368             :                                                DBUS_TYPE_STRING,
     369           0 :                                                &entry->key.str);
     370           0 :         if (!dbret) {
     371           0 :             ret = EIO;
     372           0 :             goto done;
     373             :         }
     374             : 
     375             :         /* iterate over values */
     376             : 
     377           0 :         dbret = dbus_message_iter_open_container(&it_dict,
     378             :                                                  DBUS_TYPE_ARRAY,
     379             :                                                  DBUS_TYPE_STRING_AS_STRING,
     380             :                                                  &it_values);
     381           0 :         if (!dbret) {
     382           0 :             ret = EIO;
     383           0 :             goto done;
     384             :         }
     385             : 
     386           0 :         values = entry->value.ptr;
     387           0 :         for (i = 0; values[i] != NULL; i++) {
     388             :             /* append value into array */
     389           0 :             dbret = dbus_message_iter_append_basic(&it_values,
     390             :                                                    DBUS_TYPE_STRING,
     391           0 :                                                    &values[i]);
     392           0 :             if (!dbret) {
     393           0 :                 ret = EIO;
     394           0 :                 goto done;
     395             :             }
     396             :         }
     397             : 
     398           0 :         dbret = dbus_message_iter_close_container(&it_dict, &it_values);
     399           0 :         if (!dbret) {
     400           0 :             ret = EIO;
     401           0 :             goto done;
     402             :         }
     403             : 
     404           0 :         dbret = dbus_message_iter_close_container(&it_array, &it_dict);
     405           0 :         if (!dbret) {
     406           0 :             ret = EIO;
     407           0 :             goto done;
     408             :         }
     409             :     }
     410             : 
     411           0 :     dbret = dbus_message_iter_close_container(iter, &it_array);
     412           0 :     if (!dbret) {
     413           0 :         ret = EIO;
     414           0 :         goto done;
     415             :     }
     416             : 
     417           0 :     ret = EOK;
     418             : 
     419             : done:
     420           0 :     talloc_free(table_iter);
     421           0 :     return ret;
     422             : }
     423             : 
     424           0 : void sbus_invoke_get(struct sbus_request *sbus_req,
     425             :                      const char *type,
     426             :                      sbus_get_invoker_fn invoker_fn,
     427             :                      sbus_msg_handler_fn handler_fn)
     428             : {
     429           0 :     DBusMessage *reply = NULL;
     430             :     DBusMessageIter iter;
     431             :     DBusMessageIter variant;
     432             :     dbus_bool_t dbret;
     433             :     errno_t ret;
     434             : 
     435           0 :     reply = dbus_message_new_method_return(sbus_req->message);
     436           0 :     if (reply == NULL) {
     437           0 :         ret = ENOMEM;
     438           0 :         goto fail;
     439             :     }
     440             : 
     441           0 :     dbus_message_iter_init_append(reply, &iter);
     442             : 
     443           0 :     dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
     444             :                                              type, &variant);
     445           0 :     if (!dbret) {
     446           0 :         ret = ENOMEM;
     447           0 :         goto fail;
     448             :     }
     449             : 
     450           0 :     ret = invoker_fn(&variant, sbus_req, handler_fn);
     451           0 :     if (ret != EOK) {
     452           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     453             :               "Invoker error [%d]: %s\n", ret, sss_strerror(ret));
     454           0 :         goto fail;
     455             :     }
     456             : 
     457           0 :     dbret = dbus_message_iter_close_container(&iter, &variant);
     458           0 :     if (!dbret) {
     459           0 :         ret = EIO;
     460           0 :         goto fail;
     461             :     }
     462             : 
     463           0 :     sbus_request_finish(sbus_req, reply);
     464           0 :     return;
     465             : 
     466             : fail:
     467           0 :     DEBUG(SSSDBG_CRIT_FAILURE,
     468             :           "Unable to reply [%d]: %s\n", ret, sss_strerror(ret));
     469             : 
     470           0 :     if (reply != NULL) {
     471           0 :         dbus_message_unref(reply);
     472             :     }
     473           0 :     sbus_request_finish(sbus_req, NULL);
     474             : 
     475           0 :     return;
     476             : }
     477             : 
     478           0 : void sbus_invoke_get_all(struct sbus_request *sbus_req)
     479             : {
     480             :     const struct sbus_property_meta *props;
     481             :     sbus_msg_handler_fn *handler_fn;
     482           0 :     DBusMessage *reply = NULL;
     483             :     DBusMessageIter iter;
     484             :     DBusMessageIter array;
     485             :     DBusMessageIter dict;
     486             :     DBusMessageIter variant;
     487             :     dbus_bool_t dbret;
     488             :     errno_t ret;
     489             :     int i;
     490             : 
     491           0 :     reply = dbus_message_new_method_return(sbus_req->message);
     492           0 :     if (reply == NULL) {
     493           0 :         ret = ENOMEM;
     494           0 :         goto fail;
     495             :     }
     496             : 
     497           0 :     dbus_message_iter_init_append(reply, &iter);
     498             : 
     499           0 :     dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
     500             :                                      DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
     501             :                                      DBUS_TYPE_STRING_AS_STRING
     502             :                                      DBUS_TYPE_VARIANT_AS_STRING
     503             :                                      DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
     504             :                                      &array);
     505           0 :     if (!dbret) {
     506           0 :         ret = ENOMEM;
     507           0 :         goto fail;
     508             :     }
     509             : 
     510           0 :     props = sbus_req->intf->vtable->meta->properties;
     511             : 
     512           0 :     if (props != NULL) {
     513           0 :         for (i = 0; props[i].name != NULL; i++) {
     514           0 :             dbret = dbus_message_iter_open_container(&array,
     515             :                                                      DBUS_TYPE_DICT_ENTRY, NULL,
     516             :                                                      &dict);
     517           0 :             if (!dbret) {
     518           0 :                 ret = ENOMEM;
     519           0 :                 goto fail;
     520             :             }
     521             : 
     522             :             /* key */
     523           0 :             dbret = dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING,
     524           0 :                                                    &props[i].name);
     525           0 :             if (!dbret) {
     526           0 :                 ret = ENOMEM;
     527           0 :                 goto fail;
     528             :             }
     529             : 
     530             :             /* value */
     531           0 :             dbret = dbus_message_iter_open_container(&dict, DBUS_TYPE_VARIANT,
     532           0 :                                                      props[i].type, &variant);
     533           0 :             if (!dbret) {
     534           0 :                 ret = ENOMEM;
     535           0 :                 goto fail;
     536             :             }
     537             : 
     538           0 :             handler_fn = VTABLE_FUNC(sbus_req->intf->vtable,
     539             :                                      props[i].vtable_offset_get);
     540           0 :             if (handler_fn == NULL) {
     541           0 :                 ret = ERR_INTERNAL;
     542           0 :                 goto fail;
     543             :             }
     544             : 
     545           0 :             ret = props[i].invoker_get(&variant, sbus_req, handler_fn);
     546           0 :             if (ret != EOK) {
     547           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     548             :                       "Invoker error [%d]: %s\n", ret, sss_strerror(ret));
     549           0 :                 goto fail;
     550             :             }
     551             : 
     552           0 :             dbret = dbus_message_iter_close_container(&dict, &variant);
     553           0 :             if (!dbret) {
     554           0 :                 ret = EIO;
     555           0 :                 goto fail;
     556             :             }
     557             : 
     558           0 :             dbret = dbus_message_iter_close_container(&array, &dict);
     559           0 :             if (!dbret) {
     560           0 :                 ret = EIO;
     561           0 :                 goto fail;
     562             :             }
     563             :         }
     564             :     }
     565             : 
     566           0 :     dbret = dbus_message_iter_close_container(&iter, &array);
     567           0 :     if (!dbret) {
     568           0 :         ret = EIO;
     569           0 :         goto fail;
     570             :     }
     571             : 
     572           0 :     sbus_request_finish(sbus_req, reply);
     573           0 :     return;
     574             : 
     575             : fail:
     576           0 :     DEBUG(SSSDBG_CRIT_FAILURE,
     577             :           "Unable to reply [%d]: %s\n", ret, sss_strerror(ret));
     578             : 
     579           0 :     dbus_message_unref(reply);
     580           0 :     sbus_request_finish(sbus_req, NULL);
     581             : 
     582           0 :     return;
     583             : }

Generated by: LCOV version 1.10