LCOV - code coverage report
Current view: top level - responder/ifp - ifp_cache.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 132 0.0 %
Date: 2015-10-19 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2015 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 "db/sysdb.h"
      25             : #include "util/util.h"
      26             : #include "responder/common/responder.h"
      27             : #include "responder/ifp/ifp_cache.h"
      28             : #include "responder/ifp/ifp_users.h"
      29             : #include "responder/ifp/ifp_groups.h"
      30             : #include "responder/ifp/ifp_iface_generated.h"
      31             : 
      32             : static struct ldb_dn *
      33           0 : ifp_cache_build_base_dn(TALLOC_CTX *mem_ctx,
      34             :                         enum ifp_cache_type type,
      35             :                         struct sss_domain_info *domain)
      36             : {
      37           0 :     struct ldb_dn *base_dn = NULL;
      38             : 
      39           0 :     switch (type) {
      40             :     case IFP_CACHE_USER:
      41           0 :         base_dn = sysdb_user_base_dn(mem_ctx, domain);
      42           0 :         break;
      43             :     case IFP_CACHE_GROUP:
      44           0 :         base_dn = sysdb_group_base_dn(mem_ctx, domain);
      45           0 :         break;
      46             :     }
      47             : 
      48           0 :     return base_dn;
      49             : }
      50             : 
      51             : static char *
      52           0 : ifp_cache_build_path(TALLOC_CTX *mem_ctx,
      53             :                      enum ifp_cache_type type,
      54             :                      struct sss_domain_info *domain,
      55             :                      struct ldb_message *msg)
      56             : {
      57           0 :     char *path = NULL;
      58             : 
      59           0 :     switch (type) {
      60             :     case IFP_CACHE_USER:
      61           0 :         path = ifp_users_build_path_from_msg(mem_ctx, domain, msg);
      62           0 :         break;
      63             :     case IFP_CACHE_GROUP:
      64           0 :         path = ifp_groups_build_path_from_msg(mem_ctx, domain, msg);
      65           0 :         break;
      66             :     }
      67             : 
      68           0 :     return path;
      69             : }
      70             : 
      71             : static const char *
      72           0 : ifp_cache_object_class(enum ifp_cache_type type)
      73             : {
      74           0 :     const char *class = NULL;
      75             : 
      76           0 :     switch (type) {
      77             :     case IFP_CACHE_USER:
      78           0 :         class = SYSDB_USER_CLASS;
      79           0 :         break;
      80             :     case IFP_CACHE_GROUP:
      81           0 :         class = SYSDB_GROUP_CLASS;
      82           0 :         break;
      83             :     }
      84             : 
      85           0 :     return class;
      86             : }
      87             : 
      88             : static errno_t
      89           0 : ifp_cache_get_cached_objects(TALLOC_CTX *mem_ctx,
      90             :                              enum ifp_cache_type type,
      91             :                              struct sss_domain_info *domain,
      92             :                              const char ***_paths,
      93             :                              int *_num_paths)
      94             : {
      95             :     TALLOC_CTX *tmp_ctx;
      96             :     struct ldb_dn *base_dn;
      97             :     struct ldb_result *result;
      98           0 :     const char *class = ifp_cache_object_class(type);
      99             :     const char **paths;
     100             :     errno_t ret;
     101             :     int ldb_ret;
     102             :     int i;
     103           0 :     const char *attrs[] = {SYSDB_OBJECTCLASS, SYSDB_UIDNUM,
     104             :                            SYSDB_GIDNUM, NULL};
     105             : 
     106           0 :     tmp_ctx = talloc_new(NULL);
     107           0 :     if (tmp_ctx == NULL) {
     108           0 :         return ENOMEM;
     109             :     }
     110             : 
     111           0 :     base_dn = ifp_cache_build_base_dn(tmp_ctx, type, domain);
     112           0 :     if (base_dn == NULL) {
     113           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create base dn\n");
     114           0 :         ret = ENOMEM;
     115           0 :         goto done;
     116             :     }
     117             : 
     118           0 :     ldb_ret = ldb_search(sysdb_ctx_get_ldb(domain->sysdb), tmp_ctx, &result,
     119             :                          base_dn, LDB_SCOPE_SUBTREE, attrs,
     120             :                          "(&(objectClass=%s)(%s=TRUE))", class,
     121             :                          SYSDB_IFP_CACHED);
     122           0 :     if (ldb_ret != LDB_SUCCESS) {
     123           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to search the cache\n");
     124           0 :         ret = sysdb_error_to_errno(ldb_ret);
     125           0 :         goto done;
     126             :     }
     127             : 
     128           0 :     paths = talloc_zero_array(tmp_ctx, const char *, result->count + 1);
     129           0 :     if (paths == NULL) {
     130           0 :         ret = ENOMEM;
     131           0 :         goto done;
     132             :     }
     133             : 
     134           0 :     for (i = 0; i < result->count; i++) {
     135           0 :         paths[i] = ifp_cache_build_path(paths, type, domain, result->msgs[i]);
     136           0 :         if (paths[i] == NULL) {
     137           0 :             ret = ENOMEM;
     138           0 :             goto done;
     139             :         }
     140             :     }
     141             : 
     142           0 :     *_paths = talloc_steal(mem_ctx, paths);
     143           0 :     *_num_paths = result->count;
     144             : 
     145           0 :     ret = EOK;
     146             : 
     147             : done:
     148           0 :     talloc_free(tmp_ctx);
     149           0 :     return ret;
     150             : }
     151             : 
     152           0 : errno_t ifp_cache_list_domains(TALLOC_CTX *mem_ctx,
     153             :                                struct sss_domain_info *domains,
     154             :                                enum ifp_cache_type type,
     155             :                                const char ***_paths,
     156             :                                int *_num_paths)
     157             : {
     158             :     TALLOC_CTX *tmp_ctx;
     159             :     struct sss_domain_info *domain;
     160             :     const char **tmp_paths;
     161             :     int num_tmp_paths;
     162             :     const char **paths;
     163             :     int num_paths;
     164             :     errno_t ret;
     165             : 
     166           0 :     tmp_ctx = talloc_new(NULL);
     167           0 :     if (tmp_ctx == NULL) {
     168           0 :         return ENOMEM;
     169             :     }
     170             : 
     171           0 :     domain = domains;
     172           0 :     num_paths = 0;
     173           0 :     paths = NULL;
     174           0 :     while (domain != NULL) {
     175           0 :         ret = ifp_cache_get_cached_objects(tmp_ctx, type, domain,
     176             :                                            &tmp_paths, &num_tmp_paths);
     177           0 :         if (ret != EOK) {
     178           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build object list "
     179             :                   "[%d]: %s\n", ret, sss_strerror(ret));
     180           0 :             goto done;
     181             :         }
     182             : 
     183           0 :         ret = add_strings_lists(tmp_ctx, paths, tmp_paths, true,
     184             :                                 discard_const(&paths));
     185           0 :         if (ret != EOK) {
     186           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build object list "
     187             :                   "[%d]: %s\n", ret, sss_strerror(ret));
     188           0 :             goto done;
     189             :         }
     190             : 
     191           0 :         num_paths += num_tmp_paths;
     192             : 
     193           0 :         domain = get_next_domain(domain, true);
     194             :     }
     195             : 
     196           0 :     if (_paths != NULL) {
     197           0 :         *_paths = talloc_steal(mem_ctx, paths);
     198             :     }
     199             : 
     200           0 :     if (_num_paths != NULL) {
     201           0 :         *_num_paths = num_paths;
     202             :     }
     203             : 
     204           0 :     ret = EOK;
     205             : 
     206             : done:
     207           0 :     talloc_free(tmp_ctx);
     208           0 :     return ret;
     209             : }
     210             : 
     211           0 : int ifp_cache_list(struct sbus_request *sbus_req,
     212             :                    void *data,
     213             :                    enum ifp_cache_type type)
     214             : {
     215             :     DBusError *error;
     216             :     struct ifp_ctx *ifp_ctx;
     217             :     const char **paths;
     218             :     int num_paths;
     219             :     errno_t ret;
     220             : 
     221           0 :     ifp_ctx = talloc_get_type(data, struct ifp_ctx);
     222           0 :     if (ifp_ctx == NULL) {
     223           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     224           0 :         return ERR_INTERNAL;
     225             :     }
     226             : 
     227           0 :     ret = ifp_cache_list_domains(sbus_req, ifp_ctx->rctx->domains, type,
     228             :                                  &paths, &num_paths);
     229           0 :     if (ret != EOK) {
     230           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED,
     231             :                                "Unable to build object list [%d]: %s\n",
     232             :                                ret, sss_strerror(ret));
     233           0 :         return sbus_request_fail_and_finish(sbus_req, error);
     234             :     }
     235             : 
     236           0 :     iface_ifp_cache_List_finish(sbus_req, paths, num_paths);
     237             : 
     238           0 :     return EOK;
     239             : }
     240             : 
     241           0 : int ifp_cache_list_by_domain(struct sbus_request *sbus_req,
     242             :                              void *data,
     243             :                              const char *domainname,
     244             :                              enum ifp_cache_type type)
     245             : {
     246             :     DBusError *error;
     247             :     struct sss_domain_info *domain;
     248             :     struct ifp_ctx *ifp_ctx;
     249             :     const char **paths;
     250             :     int num_paths;
     251             :     errno_t ret;
     252             : 
     253           0 :     ifp_ctx = talloc_get_type(data, struct ifp_ctx);
     254           0 :     if (ifp_ctx == NULL) {
     255           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     256           0 :         return ERR_INTERNAL;
     257             :     }
     258             : 
     259           0 :     domain = find_domain_by_name(ifp_ctx->rctx->domains, domainname, true);
     260           0 :     if (domain == NULL) {
     261           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Unknown domain");
     262           0 :         return sbus_request_fail_and_finish(sbus_req, error);
     263             :     }
     264             : 
     265           0 :     ret = ifp_cache_get_cached_objects(sbus_req, type, domain,
     266             :                                        &paths, &num_paths);
     267           0 :     if (ret != EOK) {
     268           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Unable to build "
     269             :                            "object list [%d]: %s\n", ret, sss_strerror(ret));
     270           0 :         return sbus_request_fail_and_finish(sbus_req, error);
     271             :     }
     272             : 
     273           0 :     iface_ifp_cache_ListByDomain_finish(sbus_req, paths, num_paths);
     274             : 
     275           0 :     return EOK;
     276             : }
     277             : 
     278           0 : static errno_t ifp_cache_object_set(struct sss_domain_info *domain,
     279             :                                     struct ldb_dn *dn,
     280             :                                     bool value)
     281             : {
     282             :     struct sysdb_attrs *attrs;
     283             :     errno_t ret;
     284             : 
     285           0 :     attrs = sysdb_new_attrs(NULL);
     286           0 :     if (attrs == NULL) {
     287           0 :         return ENOMEM;
     288             :     }
     289             : 
     290           0 :     ret = sysdb_attrs_add_bool(attrs, SYSDB_IFP_CACHED, value);
     291           0 :     if (ret != EOK) {
     292           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add attribute [%d]: %s\n",
     293             :               ret, sss_strerror(ret));
     294           0 :         goto done;
     295             :     }
     296             : 
     297           0 :     ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, SYSDB_MOD_REP);
     298           0 :     if (ret != EOK) {
     299           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to modify entry [%d]: %s\n",
     300             :               ret, sss_strerror(ret));
     301           0 :         goto done;
     302             :     }
     303             : 
     304           0 :     ret = EOK;
     305             : 
     306             : done:
     307           0 :     talloc_free(attrs);
     308             : 
     309           0 :     return ret;
     310             : }
     311             : 
     312           0 : int ifp_cache_object_store(struct sbus_request *sbus_req,
     313             :                            struct sss_domain_info *domain,
     314             :                            struct ldb_dn *dn)
     315             : {
     316             :     errno_t ret;
     317             : 
     318           0 :     ret = ifp_cache_object_set(domain, dn, true);
     319             : 
     320           0 :     if (ret == EOK) {
     321           0 :         iface_ifp_cache_object_Store_finish(sbus_req, true);
     322             :     } else {
     323           0 :         iface_ifp_cache_object_Store_finish(sbus_req, false);
     324             :     }
     325             : 
     326           0 :     return EOK;
     327             : }
     328             : 
     329           0 : int ifp_cache_object_remove(struct sbus_request *sbus_req,
     330             :                             struct sss_domain_info *domain,
     331             :                             struct ldb_dn *dn)
     332             : {
     333             :     errno_t ret;
     334             : 
     335           0 :     ret = ifp_cache_object_set(domain, dn, false);
     336             : 
     337           0 :     if (ret == EOK) {
     338           0 :         iface_ifp_cache_object_Remove_finish(sbus_req, true);
     339             :     } else {
     340           0 :         iface_ifp_cache_object_Remove_finish(sbus_req, false);
     341             :     }
     342             : 
     343           0 :     return EOK;
     344             : }

Generated by: LCOV version 1.10