LCOV - code coverage report
Current view: top level - providers/data_provider - dp_request_table.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 72 99 72.7 %
Date: 2016-06-29 Functions: 11 12 91.7 %

          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             : #include <dhash.h>
      24             : 
      25             : #include "sbus/sssd_dbus.h"
      26             : #include "providers/data_provider/dp_private.h"
      27             : #include "providers/backend.h"
      28             : #include "util/dlinklist.h"
      29             : #include "util/sss_utf8.h"
      30             : #include "util/util.h"
      31             : 
      32             : static int
      33           8 : dp_sbus_req_item_destructor(struct dp_sbus_req_item *item)
      34             : {
      35           8 :     DLIST_REMOVE(item->parent->list, item);
      36             : 
      37           8 :     return 0;
      38             : }
      39             : 
      40             : static int
      41           3 : dp_table_value_destructor(struct dp_table_value *value)
      42             : {
      43             :     struct dp_sbus_req_item *next_item;
      44             :     struct dp_sbus_req_item *item;
      45             : 
      46           3 :     DEBUG(SSSDBG_TRACE_FUNC, "Removing [%s] from reply table\n", value->key);
      47             : 
      48           3 :     dp_req_table_del(value->table, value->key);
      49             : 
      50           6 :     for (item = value->list; item != NULL; item = next_item) {
      51           3 :         next_item = item->next;
      52           3 :         talloc_free(item);
      53             :     }
      54             : 
      55           3 :     return 0;
      56             : }
      57             : 
      58             : static struct dp_sbus_req_item *
      59           8 : dp_sbus_req_item_new(struct dp_table_value *value,
      60             :                      struct sbus_request *sbus_req)
      61             : {
      62             :     struct dp_sbus_req_item *item;
      63             : 
      64             :     /* Attach to sbus_request so we ensure that this sbus_req is removed
      65             :      * from the list when it is unexpectedly freed, for example when
      66             :      * client connection is dropped. */
      67           8 :     item = talloc_zero(sbus_req, struct dp_sbus_req_item);
      68           8 :     if (item == NULL) {
      69           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed\n");
      70           0 :         return NULL;
      71             :     }
      72             : 
      73           8 :     item->parent = value;
      74           8 :     item->sbus_req = sbus_req;
      75             : 
      76           8 :     talloc_set_destructor(item, dp_sbus_req_item_destructor);
      77             : 
      78           8 :     return item;
      79             : }
      80             : 
      81           4 : char *dp_req_table_key(TALLOC_CTX *mem_ctx,
      82             :                        enum dp_targets target,
      83             :                        enum dp_methods method,
      84             :                        uint32_t dp_flags,
      85             :                        const char *custom_part)
      86             : {
      87           4 :     const char *str = custom_part == NULL ? "(null)" : custom_part;
      88             : 
      89           4 :     return talloc_asprintf(mem_ctx, "%u:%u:%#.4x:%s",
      90             :                            target, method, dp_flags, str);
      91             : }
      92             : 
      93           4 : errno_t dp_req_table_init(TALLOC_CTX *mem_ctx, hash_table_t **_table)
      94             : {
      95           4 :     return sss_hash_create(mem_ctx, 100, _table);
      96             : }
      97             : 
      98          16 : struct dp_table_value *dp_req_table_lookup(hash_table_t *table,
      99             :                                            const char *key)
     100             : {
     101             :     hash_key_t hkey;
     102             :     hash_value_t hvalue;
     103             :     int hret;
     104             : 
     105          16 :     hkey.type = HASH_KEY_STRING;
     106          16 :     hkey.str = discard_const_p(char, key);
     107             : 
     108          16 :     hret = hash_lookup(table, &hkey, &hvalue);
     109          16 :     if (hret == HASH_ERROR_KEY_NOT_FOUND) {
     110           6 :         return NULL;
     111          10 :     } else if (hret != HASH_SUCCESS) {
     112           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to search hash table [%d]\n", hret);
     113           0 :         return NULL;
     114             :     }
     115             : 
     116          10 :     return hvalue.ptr;
     117             : }
     118             : 
     119           3 : static errno_t dp_req_table_new_item(hash_table_t *table,
     120             :                                      const char *key,
     121             :                                      struct tevent_req *req,
     122             :                                      struct sbus_request *sbus_req)
     123             : {
     124             :     hash_key_t hkey;
     125             :     hash_value_t hvalue;
     126             :     struct dp_table_value *table_value;
     127             :     errno_t ret;
     128             :     int hret;
     129             : 
     130             :     /* Attach it to request. */
     131           3 :     table_value = talloc_zero(req, struct dp_table_value);
     132           3 :     if (table_value == NULL) {
     133           0 :         return ENOMEM;
     134             :     }
     135             : 
     136           3 :     table_value->table = table;
     137           3 :     table_value->key = talloc_strdup(table_value, key);
     138           3 :     if (table_value->key == NULL) {
     139           0 :         ret = ENOMEM;
     140           0 :         goto done;
     141             :     }
     142             : 
     143           3 :     table_value->req = req;
     144           3 :     table_value->list = dp_sbus_req_item_new(table_value, sbus_req);
     145           3 :     if (table_value->list == NULL) {
     146           0 :         ret = ENOMEM;
     147           0 :         goto done;
     148             :     }
     149             : 
     150           3 :     talloc_set_destructor(table_value, dp_table_value_destructor);
     151             : 
     152           3 :     hkey.type = HASH_KEY_STRING;
     153           3 :     hkey.str = discard_const_p(char, key);
     154             : 
     155           3 :     hvalue.type = HASH_VALUE_PTR;
     156           3 :     hvalue.ptr = table_value;
     157             : 
     158           3 :     hret = hash_enter(table, &hkey, &hvalue);
     159           3 :     if (hret != HASH_SUCCESS) {
     160           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to enter value into hash table "
     161             :               "[%d]\n", hret);
     162           0 :         ret = EIO;
     163           0 :         goto done;
     164             :     }
     165             : 
     166           3 :     ret = EOK;
     167             : 
     168             : done:
     169           3 :     if (ret != EOK) {
     170           0 :         talloc_free(table_value);
     171             :     }
     172             : 
     173           3 :     return ret;
     174             : }
     175             : 
     176           5 : static errno_t dp_req_table_mod_item(hash_table_t *table,
     177             :                                      struct dp_table_value *table_value,
     178             :                                      struct sbus_request *sbus_req)
     179             : {
     180             :     struct dp_sbus_req_item *item;
     181             : 
     182           5 :     item = dp_sbus_req_item_new(table_value, sbus_req);
     183           5 :     if (item == NULL) {
     184           0 :         return ENOMEM;
     185             :     }
     186             : 
     187           5 :     DLIST_ADD(table_value->list, item);
     188             : 
     189           5 :     return EOK;
     190             : }
     191             : 
     192           8 : errno_t dp_req_table_add(hash_table_t *table,
     193             :                          const char *key,
     194             :                          struct tevent_req *req,
     195             :                          struct sbus_request *sbus_req)
     196             : {
     197             :     struct dp_table_value *table_value;
     198             : 
     199           8 :     if (sbus_req == NULL) {
     200           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "SBUS request cannot be NULL\n");
     201           0 :         return EINVAL;
     202             :     }
     203             : 
     204           8 :     table_value = dp_req_table_lookup(table, key);
     205           8 :     if (table_value == NULL) {
     206           3 :         if (req == NULL) {
     207           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Tevent request cannot be NULL\n");
     208           0 :             return EINVAL;
     209             :         }
     210             : 
     211           3 :         return dp_req_table_new_item(table, key, req, sbus_req);
     212             :     }
     213             : 
     214           5 :     return dp_req_table_mod_item(table, table_value, sbus_req);
     215             : }
     216             : 
     217           7 : void dp_req_table_del(hash_table_t *table,
     218             :                       const char *key)
     219             : {
     220             :     hash_key_t hkey;
     221             :     int hret;
     222             : 
     223           7 :     if (table == NULL || key == NULL) {
     224           0 :         return;
     225             :     }
     226             : 
     227           7 :     hkey.type = HASH_KEY_STRING;
     228           7 :     hkey.str = discard_const_p(char, key);
     229             : 
     230           7 :     hret = hash_delete(table, &hkey);
     231           7 :     if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) {
     232           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to remove key from table [%d]\n",
     233             :               hret);
     234             :     }
     235             : 
     236           7 :     return;
     237             : }
     238             : 
     239           0 : void dp_req_table_del_and_free(hash_table_t *table,
     240             :                                const char *key)
     241             : {
     242             :     struct dp_table_value *value;
     243             : 
     244           0 :     value = dp_req_table_lookup(table, key);
     245           0 :     if (value == NULL) {
     246             :         /* We're done here. */
     247           0 :         return;
     248             :     }
     249             : 
     250           0 :     dp_req_table_del(table, key);
     251           0 :     talloc_free(value);
     252             : 
     253           0 :     return;
     254             : }
     255             : 
     256          14 : bool dp_req_table_has_key(hash_table_t *table,
     257             :                           const char *key)
     258             : {
     259             :     hash_key_t hkey;
     260             : 
     261          14 :     hkey.type = HASH_KEY_STRING;
     262          14 :     hkey.str = discard_const_p(char, key);
     263             : 
     264          14 :     return hash_has_key(table, &hkey);
     265             : }

Generated by: LCOV version 1.10