LCOV - code coverage report
Current view: top level - responder/ifp - ifp_groups.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 412 0.0 %
Date: 2015-10-19 Functions: 0 30 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 "util/util.h"
      25             : #include "db/sysdb.h"
      26             : #include "util/strtonum.h"
      27             : #include "sbus/sssd_dbus_errors.h"
      28             : #include "responder/common/responder.h"
      29             : #include "responder/common/responder_cache_req.h"
      30             : #include "responder/ifp/ifp_groups.h"
      31             : #include "responder/ifp/ifp_users.h"
      32             : #include "responder/ifp/ifp_cache.h"
      33             : 
      34           0 : char * ifp_groups_build_path_from_msg(TALLOC_CTX *mem_ctx,
      35             :                                       struct sss_domain_info *domain,
      36             :                                       struct ldb_message *msg)
      37             : {
      38             :     const char *gid;
      39             : 
      40           0 :     gid = ldb_msg_find_attr_as_string(msg, SYSDB_GIDNUM, NULL);
      41             : 
      42           0 :     if (gid == NULL) {
      43           0 :         return NULL;
      44             :     }
      45             : 
      46           0 :     return sbus_opath_compose(mem_ctx, IFP_PATH_GROUPS, domain->name, gid);
      47             : }
      48             : 
      49           0 : static errno_t ifp_groups_decompose_path(struct sss_domain_info *domains,
      50             :                                          const char *path,
      51             :                                          struct sss_domain_info **_domain,
      52             :                                          gid_t *_gid)
      53             : {
      54           0 :     char **parts = NULL;
      55             :     struct sss_domain_info *domain;
      56             :     gid_t gid;
      57             :     errno_t ret;
      58             : 
      59           0 :     ret = sbus_opath_decompose_exact(NULL, path, IFP_PATH_GROUPS, 2, &parts);
      60           0 :     if (ret != EOK) {
      61           0 :         return ret;
      62             :     }
      63             : 
      64           0 :     domain = find_domain_by_name(domains, parts[0], false);
      65           0 :     if (domain == NULL) {
      66           0 :         ret = ERR_DOMAIN_NOT_FOUND;
      67           0 :         goto done;
      68             :     }
      69             : 
      70           0 :     gid = strtouint32(parts[1], NULL, 10);
      71           0 :     ret = errno;
      72           0 :     if (ret != EOK) {
      73           0 :         goto done;
      74             :     }
      75             : 
      76           0 :     *_domain = domain;
      77           0 :     *_gid = gid;
      78             : 
      79             : done:
      80           0 :     talloc_free(parts);
      81           0 :     return ret;
      82             : }
      83             : 
      84           0 : static int ifp_groups_list_copy(struct ifp_list_ctx *list_ctx,
      85             :                                 struct ldb_result *result)
      86             : {
      87             :     size_t copy_count, i;
      88             : 
      89           0 :     copy_count = ifp_list_ctx_remaining_capacity(list_ctx, result->count);
      90             : 
      91           0 :     for (i = 0; i < copy_count; i++) {
      92           0 :         list_ctx->paths[list_ctx->path_count + i] = \
      93           0 :             ifp_groups_build_path_from_msg(list_ctx->paths,
      94             :                                            list_ctx->dom,
      95           0 :                                            result->msgs[i]);
      96           0 :         if (list_ctx->paths[list_ctx->path_count + i] == NULL) {
      97           0 :             return ENOMEM;
      98             :         }
      99             :     }
     100             : 
     101           0 :     list_ctx->path_count += copy_count;
     102           0 :     return EOK;
     103             : }
     104             : 
     105             : static void ifp_groups_find_by_name_done(struct tevent_req *req);
     106             : 
     107           0 : int ifp_groups_find_by_name(struct sbus_request *sbus_req,
     108             :                            void *data,
     109             :                            const char *name)
     110             : {
     111             :     struct ifp_ctx *ctx;
     112             :     struct tevent_req *req;
     113             : 
     114           0 :     ctx = talloc_get_type(data, struct ifp_ctx);
     115           0 :     if (ctx == NULL) {
     116           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     117           0 :         return ERR_INTERNAL;
     118             :     }
     119             : 
     120           0 :     req = cache_req_group_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
     121             :                                        ctx->ncache, ctx->neg_timeout, 0,
     122             :                                        NULL, name);
     123           0 :     if (req == NULL) {
     124           0 :         return ENOMEM;
     125             :     }
     126             : 
     127           0 :     tevent_req_set_callback(req, ifp_groups_find_by_name_done, sbus_req);
     128             : 
     129           0 :     return EOK;
     130             : }
     131             : 
     132             : static void
     133           0 : ifp_groups_find_by_name_done(struct tevent_req *req)
     134             : {
     135             :     DBusError *error;
     136             :     struct sbus_request *sbus_req;
     137             :     struct sss_domain_info *domain;
     138             :     struct ldb_result *result;
     139             :     char *object_path;
     140             :     errno_t ret;
     141             : 
     142           0 :     sbus_req = tevent_req_callback_data(req, struct sbus_request);
     143             : 
     144           0 :     ret = cache_req_group_by_name_recv(sbus_req, req, &result, &domain, NULL);
     145           0 :     talloc_zfree(req);
     146           0 :     if (ret == ENOENT) {
     147           0 :         error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND,
     148             :                                "Group not found");
     149           0 :         goto done;
     150           0 :     } else if (ret != EOK) {
     151           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
     152             :                                "group [%d]: %s\n", ret, sss_strerror(ret));
     153           0 :         goto done;
     154             :     }
     155             : 
     156           0 :     object_path = ifp_groups_build_path_from_msg(sbus_req, domain,
     157           0 :                                                  result->msgs[0]);
     158           0 :     if (object_path == NULL) {
     159           0 :         error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
     160             :                                "Failed to compose object path");
     161           0 :         goto done;
     162             :     }
     163             : 
     164           0 :     ret = EOK;
     165             : 
     166             : done:
     167           0 :     if (ret != EOK) {
     168           0 :         sbus_request_fail_and_finish(sbus_req, error);
     169           0 :         return;
     170             :     }
     171             : 
     172           0 :     iface_ifp_groups_FindByName_finish(sbus_req, object_path);
     173           0 :     return;
     174             : }
     175             : 
     176             : static void ifp_groups_find_by_id_done(struct tevent_req *req);
     177             : 
     178           0 : int ifp_groups_find_by_id(struct sbus_request *sbus_req,
     179             :                           void *data,
     180             :                           uint32_t id)
     181             : {
     182             :     struct ifp_ctx *ctx;
     183             :     struct tevent_req *req;
     184             : 
     185           0 :     ctx = talloc_get_type(data, struct ifp_ctx);
     186           0 :     if (ctx == NULL) {
     187           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     188           0 :         return ERR_INTERNAL;
     189             :     }
     190             : 
     191           0 :     req = cache_req_group_by_id_send(sbus_req, ctx->rctx->ev, ctx->rctx,
     192             :                                      ctx->ncache, ctx->neg_timeout, 0,
     193             :                                      NULL, id);
     194           0 :     if (req == NULL) {
     195           0 :         return ENOMEM;
     196             :     }
     197             : 
     198           0 :     tevent_req_set_callback(req, ifp_groups_find_by_id_done, sbus_req);
     199             : 
     200           0 :     return EOK;
     201             : }
     202             : 
     203             : static void
     204           0 : ifp_groups_find_by_id_done(struct tevent_req *req)
     205             : {
     206             :     DBusError *error;
     207             :     struct sbus_request *sbus_req;
     208             :     struct sss_domain_info *domain;
     209             :     struct ldb_result *result;
     210             :     char *object_path;
     211             :     errno_t ret;
     212             : 
     213           0 :     sbus_req = tevent_req_callback_data(req, struct sbus_request);
     214             : 
     215           0 :     ret = cache_req_group_by_id_recv(sbus_req, req, &result, &domain);
     216           0 :     talloc_zfree(req);
     217           0 :     if (ret == ENOENT) {
     218           0 :         error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND,
     219             :                                "Group not found");
     220           0 :         goto done;
     221           0 :     } else if (ret != EOK) {
     222           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
     223             :                                "group [%d]: %s\n", ret, sss_strerror(ret));
     224           0 :         goto done;
     225             :     }
     226             : 
     227           0 :     object_path = ifp_groups_build_path_from_msg(sbus_req, domain,
     228           0 :                                                  result->msgs[0]);
     229           0 :     if (object_path == NULL) {
     230           0 :         error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
     231             :                                "Failed to compose object path");
     232           0 :         goto done;
     233             :     }
     234             : 
     235             : done:
     236           0 :     if (ret != EOK) {
     237           0 :         sbus_request_fail_and_finish(sbus_req, error);
     238           0 :         return;
     239             :     }
     240             : 
     241           0 :     iface_ifp_groups_FindByID_finish(sbus_req, object_path);
     242           0 :     return;
     243             : }
     244             : 
     245             : static int ifp_groups_list_by_name_step(struct ifp_list_ctx *list_ctx);
     246             : static void ifp_groups_list_by_name_done(struct tevent_req *req);
     247             : static void ifp_groups_list_by_name_reply(struct ifp_list_ctx *list_ctx);
     248             : 
     249           0 : int ifp_groups_list_by_name(struct sbus_request *sbus_req,
     250             :                             void *data,
     251             :                             const char *filter,
     252             :                             uint32_t limit)
     253             : {
     254             :     struct ifp_ctx *ctx;
     255             :     struct ifp_list_ctx *list_ctx;
     256             : 
     257           0 :     ctx = talloc_get_type(data, struct ifp_ctx);
     258           0 :     if (ctx == NULL) {
     259           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     260           0 :         return ERR_INTERNAL;
     261             :     }
     262             : 
     263           0 :     list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit);
     264           0 :     if (list_ctx == NULL) {
     265           0 :         return ENOMEM;
     266             :     }
     267             : 
     268           0 :     return ifp_groups_list_by_name_step(list_ctx);
     269             : }
     270             : 
     271           0 : static int ifp_groups_list_by_name_step(struct ifp_list_ctx *list_ctx)
     272             : {
     273             :     struct tevent_req *req;
     274             : 
     275           0 :     req = cache_req_group_by_filter_send(list_ctx,
     276           0 :                                         list_ctx->ctx->rctx->ev,
     277           0 :                                         list_ctx->ctx->rctx,
     278           0 :                                         list_ctx->dom->name,
     279             :                                         list_ctx->filter);
     280           0 :     if (req == NULL) {
     281           0 :         return ENOMEM;
     282             :     }
     283           0 :     tevent_req_set_callback(req,
     284             :                             ifp_groups_list_by_name_done, list_ctx);
     285             : 
     286           0 :     return EOK;
     287             : }
     288             : 
     289           0 : static void ifp_groups_list_by_name_done(struct tevent_req *req)
     290             : {
     291             :     DBusError *error;
     292             :     struct ifp_list_ctx *list_ctx;
     293             :     struct sbus_request *sbus_req;
     294             :     struct ldb_result *result;
     295             :     struct sss_domain_info *domain;
     296             :     errno_t ret;
     297             : 
     298           0 :     list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx);
     299           0 :     sbus_req = list_ctx->sbus_req;
     300             : 
     301           0 :     ret = cache_req_group_by_name_recv(sbus_req, req, &result, &domain, NULL);
     302           0 :     talloc_zfree(req);
     303           0 :     if (ret != EOK && ret != ENOENT) {
     304           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
     305             :                                "groups by filter [%d]: %s\n", ret, sss_strerror(ret));
     306           0 :         sbus_request_fail_and_finish(sbus_req, error);
     307           0 :         return;
     308             :     }
     309             : 
     310           0 :     ret = ifp_groups_list_copy(list_ctx, result);
     311           0 :     if (ret != EOK) {
     312           0 :         error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
     313             :                                "Failed to copy domain result");
     314           0 :         sbus_request_fail_and_finish(sbus_req, error);
     315           0 :         return;
     316             :     }
     317             : 
     318           0 :     list_ctx->dom = get_next_domain(list_ctx->dom, true);
     319           0 :     if (list_ctx->dom == NULL) {
     320           0 :         return ifp_groups_list_by_name_reply(list_ctx);
     321             :     }
     322             : 
     323           0 :     ret = ifp_groups_list_by_name_step(list_ctx);
     324           0 :     if (ret != EOK) {
     325           0 :         error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
     326             :                                "Failed to start next-domain search");
     327           0 :         sbus_request_fail_and_finish(sbus_req, error);
     328           0 :         return;
     329             :     }
     330             : }
     331             : 
     332           0 : static void ifp_groups_list_by_name_reply(struct ifp_list_ctx *list_ctx)
     333             : {
     334           0 :     iface_ifp_groups_ListByDomainAndName_finish(list_ctx->sbus_req,
     335             :                                                list_ctx->paths,
     336           0 :                                                list_ctx->path_count);
     337           0 : }
     338             : 
     339             : static void ifp_groups_list_by_domain_and_name_done(struct tevent_req *req);
     340             : 
     341           0 : int ifp_groups_list_by_domain_and_name(struct sbus_request *sbus_req,
     342             :                                        void *data,
     343             :                                        const char *domain,
     344             :                                        const char *filter,
     345             :                                        uint32_t limit)
     346             : {
     347             :     struct tevent_req *req;
     348             :     struct ifp_ctx *ctx;
     349             :     struct ifp_list_ctx *list_ctx;
     350             : 
     351           0 :     ctx = talloc_get_type(data, struct ifp_ctx);
     352           0 :     if (ctx == NULL) {
     353           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     354           0 :         return ERR_INTERNAL;
     355             :     }
     356             : 
     357           0 :     list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit);
     358           0 :     if (list_ctx == NULL) {
     359           0 :         return ENOMEM;
     360             :     }
     361             : 
     362           0 :     req = cache_req_group_by_filter_send(list_ctx, ctx->rctx->ev, ctx->rctx,
     363             :                                         domain, filter);
     364           0 :     if (req == NULL) {
     365           0 :         return ENOMEM;
     366             :     }
     367           0 :     tevent_req_set_callback(req,
     368             :                             ifp_groups_list_by_domain_and_name_done, list_ctx);
     369             : 
     370           0 :     return EOK;
     371             : }
     372             : 
     373           0 : static void ifp_groups_list_by_domain_and_name_done(struct tevent_req *req)
     374             : {
     375             :     DBusError *error;
     376             :     struct ifp_list_ctx *list_ctx;
     377             :     struct sbus_request *sbus_req;
     378             :     struct ldb_result *result;
     379             :     struct sss_domain_info *domain;
     380             :     errno_t ret;
     381             : 
     382           0 :     list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx);
     383           0 :     sbus_req = list_ctx->sbus_req;
     384             : 
     385           0 :     ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL);
     386           0 :     talloc_zfree(req);
     387           0 :     if (ret == ENOENT) {
     388           0 :         error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND,
     389             :                                "User not found by filter");
     390           0 :         goto done;
     391           0 :     } else if (ret != EOK) {
     392           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
     393             :                                "groups by filter [%d]: %s\n", ret, sss_strerror(ret));
     394           0 :         goto done;
     395             :     }
     396             : 
     397           0 :     ret = ifp_groups_list_copy(list_ctx, result);
     398           0 :     if (ret != EOK) {
     399           0 :         error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
     400             :                                "Failed to copy domain result");
     401           0 :         goto done;
     402             :     }
     403             : 
     404             : done:
     405           0 :     if (ret != EOK) {
     406           0 :         sbus_request_fail_and_finish(sbus_req, error);
     407           0 :         return;
     408             :     }
     409             : 
     410           0 :     iface_ifp_groups_ListByDomainAndName_finish(sbus_req,
     411             :                                                 list_ctx->paths,
     412           0 :                                                 list_ctx->path_count);
     413           0 :     return;
     414             : }
     415             : 
     416             : static errno_t
     417           0 : ifp_groups_group_get(struct sbus_request *sbus_req,
     418             :                      void *data,
     419             :                      gid_t *_gid,
     420             :                      struct sss_domain_info **_domain,
     421             :                      struct ldb_message **_group)
     422             : {
     423             :     struct ifp_ctx *ctx;
     424             :     struct sss_domain_info *domain;
     425             :     struct ldb_result *res;
     426             :     uid_t gid;
     427             :     errno_t ret;
     428             : 
     429           0 :     ctx = talloc_get_type(data, struct ifp_ctx);
     430           0 :     if (ctx == NULL) {
     431           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     432           0 :         return ERR_INTERNAL;
     433             :     }
     434             : 
     435           0 :     ret = ifp_groups_decompose_path(ctx->rctx->domains, sbus_req->path,
     436             :                                     &domain, &gid);
     437           0 :     if (ret != EOK) {
     438           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to decompose object path"
     439             :               "[%s] [%d]: %s\n", sbus_req->path, ret, sss_strerror(ret));
     440           0 :         return ret;
     441             :     }
     442             : 
     443           0 :     if (_group != NULL) {
     444           0 :         ret = sysdb_getgrgid_with_views(sbus_req, domain, gid, &res);
     445           0 :         if (ret == EOK && res->count == 0) {
     446           0 :             *_group = NULL;
     447           0 :             ret = ENOENT;
     448             :         }
     449             : 
     450           0 :         if (ret != EOK) {
     451           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup group %u@%s [%d]: %s\n",
     452             :                   gid, domain->name, ret, sss_strerror(ret));
     453             :         } else {
     454           0 :             *_group = res->msgs[0];
     455             :         }
     456             :     }
     457             : 
     458           0 :     if (ret == EOK || ret == ENOENT) {
     459           0 :         if (_gid != NULL) {
     460           0 :             *_gid = gid;
     461             :         }
     462             : 
     463           0 :         if (_domain != NULL) {
     464           0 :             *_domain = domain;
     465             :         }
     466             :     }
     467             : 
     468           0 :     return ret;
     469             : }
     470             : 
     471             : struct resolv_ghosts_state {
     472             :     struct tevent_context *ev;
     473             :     struct sbus_request *sbus_req;
     474             :     struct ifp_ctx *ctx;
     475             :     void *data;
     476             : 
     477             :     struct sss_domain_info *domain;
     478             :     const char **ghosts;
     479             :     int index;
     480             : };
     481             : 
     482             : static void resolv_ghosts_group_done(struct tevent_req *subreq);
     483             : static errno_t resolv_ghosts_step(struct tevent_req *req);
     484             : static void resolv_ghosts_done(struct tevent_req *subreq);
     485             : 
     486           0 : static struct tevent_req *resolv_ghosts_send(TALLOC_CTX *mem_ctx,
     487             :                                              struct tevent_context *ev,
     488             :                                              struct sbus_request *sbus_req,
     489             :                                              void *data)
     490             : {
     491             :     struct resolv_ghosts_state *state;
     492             :     struct sss_domain_info *domain;
     493             :     struct tevent_req *req;
     494             :     struct tevent_req *subreq;
     495             :     struct ldb_message *group;
     496             :     struct ifp_ctx *ctx;
     497             :     const char *name;
     498             :     errno_t ret;
     499             : 
     500           0 :     req = tevent_req_create(mem_ctx, &state, struct resolv_ghosts_state);
     501           0 :     if (req == NULL) {
     502           0 :         DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
     503           0 :         return NULL;
     504             :     }
     505             : 
     506           0 :     ctx = talloc_get_type(data, struct ifp_ctx);
     507           0 :     if (ctx == NULL) {
     508           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     509           0 :         ret = ERR_INTERNAL;
     510           0 :         goto immediately;
     511             :     }
     512             : 
     513           0 :     state->ev = ev;
     514           0 :     state->sbus_req = sbus_req;
     515           0 :     state->ctx = ctx;
     516           0 :     state->data = data;
     517             : 
     518           0 :     ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
     519           0 :     if (ret != EOK) {
     520           0 :         goto immediately;
     521             :     }
     522             : 
     523           0 :     name = ldb_msg_find_attr_as_string(group, SYSDB_NAME, NULL);
     524           0 :     if (name == NULL) {
     525           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Group name is empty!\n");
     526           0 :         ret = ERR_INTERNAL;
     527           0 :         goto immediately;
     528             :     }
     529             : 
     530           0 :     subreq = cache_req_group_by_name_send(state, ev, ctx->rctx,
     531             :                                           ctx->ncache, ctx->neg_timeout, 0,
     532           0 :                                           domain->name, name);
     533           0 :     if (subreq == NULL) {
     534           0 :         ret = ENOMEM;
     535           0 :         goto immediately;
     536             :     }
     537             : 
     538           0 :     tevent_req_set_callback(subreq, resolv_ghosts_group_done, req);
     539             : 
     540           0 :     return req;
     541             : 
     542             : immediately:
     543           0 :     if (ret == EOK) {
     544           0 :         tevent_req_done(req);
     545             :     } else {
     546           0 :         tevent_req_error(req, ret);
     547             :     }
     548           0 :     tevent_req_post(req, ev);
     549             : 
     550           0 :     return req;
     551             : }
     552             : 
     553           0 : static void resolv_ghosts_group_done(struct tevent_req *subreq)
     554             : {
     555             :     struct resolv_ghosts_state *state;
     556             :     struct ldb_message_element *el;
     557             :     struct ldb_message *group;
     558             :     struct tevent_req *req;
     559             :     errno_t ret;
     560             : 
     561           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     562           0 :     state = tevent_req_data(req, struct resolv_ghosts_state);
     563             : 
     564           0 :     ret = ifp_groups_group_get(state->sbus_req, state->data, NULL,
     565             :                                &state->domain, &group);
     566           0 :     if (ret != EOK) {
     567           0 :         goto done;
     568             :     }
     569             : 
     570           0 :     el = ldb_msg_find_element(group, SYSDB_GHOST);
     571           0 :     if (el == NULL) {
     572           0 :         ret = ENOMEM;
     573           0 :         goto done;
     574             :     }
     575             : 
     576           0 :     if (el->num_values == 0) {
     577           0 :         ret = EOK;
     578           0 :         goto done;
     579             :     }
     580             : 
     581           0 :     state->ghosts = sss_ldb_el_to_string_list(state, el);
     582           0 :     if (state->ghosts == NULL) {
     583           0 :         ret = ENOMEM;
     584           0 :         goto done;
     585             :     }
     586             : 
     587           0 :     state->index = 0;
     588           0 :     ret = resolv_ghosts_step(req);
     589             : 
     590             : done:
     591           0 :     if (ret == EOK) {
     592           0 :         tevent_req_done(req);
     593           0 :     } else if (ret != EAGAIN) {
     594           0 :         tevent_req_error(req, ret);
     595             :     }
     596           0 : }
     597             : 
     598           0 : errno_t resolv_ghosts_step(struct tevent_req *req)
     599             : {
     600             :     struct resolv_ghosts_state *state;
     601             :     struct tevent_req *subreq;
     602             : 
     603           0 :     state = tevent_req_data(req, struct resolv_ghosts_state);
     604             : 
     605           0 :     if (state->ghosts[state->index] == NULL) {
     606           0 :         return EOK;
     607             :     }
     608             : 
     609           0 :     subreq = cache_req_user_by_name_send(state, state->ev, state->ctx->rctx,
     610           0 :                                    state->ctx->ncache, state->ctx->neg_timeout,
     611           0 :                                    0, state->domain->name,
     612           0 :                                    state->ghosts[state->index]);
     613           0 :     if (subreq == NULL) {
     614           0 :         return ENOMEM;
     615             :     }
     616             : 
     617           0 :     tevent_req_set_callback(subreq, resolv_ghosts_done, req);
     618             : 
     619           0 :     state->index++;
     620             : 
     621           0 :     return EAGAIN;
     622             : }
     623             : 
     624           0 : static void resolv_ghosts_done(struct tevent_req *subreq)
     625             : {
     626           0 :     struct resolv_ghosts_state *state = NULL;
     627           0 :     struct tevent_req *req = NULL;
     628             :     errno_t ret;
     629             : 
     630           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     631           0 :     state = tevent_req_data(req, struct resolv_ghosts_state);
     632             : 
     633           0 :     ret = cache_req_user_by_name_recv(state, subreq, NULL, NULL, NULL);
     634           0 :     talloc_zfree(subreq);
     635           0 :     if (ret != EOK) {
     636           0 :         goto done;
     637             :     }
     638             : 
     639           0 :     ret = resolv_ghosts_step(req);
     640             : 
     641             : done:
     642           0 :     if (ret == EOK) {
     643           0 :         tevent_req_done(req);
     644           0 :     } else if (ret != EAGAIN) {
     645           0 :         tevent_req_error(req, ret);
     646             :     }
     647           0 : }
     648             : 
     649           0 : static errno_t resolv_ghosts_recv(struct tevent_req *req)
     650             : {
     651           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     652             : 
     653           0 :     return EOK;
     654             : }
     655             : 
     656             : static void ifp_groups_group_update_member_list_done(struct tevent_req *req);
     657             : 
     658           0 : int ifp_groups_group_update_member_list(struct sbus_request *sbus_req,
     659             :                                         void *data)
     660             : {
     661             :     struct tevent_req *subreq;
     662             :     struct ifp_ctx *ctx;
     663             : 
     664           0 :     ctx = talloc_get_type(data, struct ifp_ctx);
     665           0 :     if (ctx == NULL) {
     666           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
     667           0 :         return ERR_INTERNAL;
     668             :     }
     669             : 
     670           0 :     subreq = resolv_ghosts_send(sbus_req, ctx->rctx->ev, sbus_req, data);
     671           0 :     if (subreq == NULL) {
     672           0 :         return ENOMEM;
     673             :     }
     674             : 
     675           0 :     tevent_req_set_callback(subreq, ifp_groups_group_update_member_list_done,
     676             :                             sbus_req);
     677             : 
     678           0 :     return EOK;
     679             : }
     680             : 
     681           0 : static void ifp_groups_group_update_member_list_done(struct tevent_req *subreq)
     682             : {
     683             :     DBusError *error;
     684             :     struct sbus_request *sbus_req;
     685             :     errno_t ret;
     686             : 
     687           0 :     sbus_req = tevent_req_callback_data(subreq, struct sbus_request);
     688             : 
     689           0 :     ret = resolv_ghosts_recv(subreq);
     690           0 :     talloc_zfree(subreq);
     691           0 :     if (ret != EOK) {
     692           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED,
     693             :                                "Unable to resolve ghost members [%d]: %s\n",
     694             :                                ret, sss_strerror(ret));
     695           0 :         sbus_request_fail_and_finish(sbus_req, error);
     696           0 :         return;
     697             :     }
     698             : 
     699           0 :     iface_ifp_groups_group_UpdateMemberList_finish(sbus_req);
     700           0 :     return;
     701             : }
     702             : 
     703           0 : void ifp_groups_group_get_name(struct sbus_request *sbus_req,
     704             :                                void *data,
     705             :                                const char **_out)
     706             : {
     707             :     struct ldb_message *msg;
     708             :     struct sss_domain_info *domain;
     709             :     errno_t ret;
     710             : 
     711           0 :     ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &msg);
     712           0 :     if (ret != EOK) {
     713           0 :         *_out = NULL;
     714           0 :         return;
     715             :     }
     716             : 
     717           0 :     *_out = sss_view_ldb_msg_find_attr_as_string(domain, msg, SYSDB_NAME, NULL);
     718             : 
     719           0 :     return;
     720             : }
     721             : 
     722           0 : void ifp_groups_group_get_gid_number(struct sbus_request *sbus_req,
     723             :                                      void *data,
     724             :                                      uint32_t *_out)
     725             : {
     726             :     struct ldb_message *msg;
     727             :     struct sss_domain_info *domain;
     728             :     errno_t ret;
     729             : 
     730           0 :     ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &msg);
     731           0 :     if (ret != EOK) {
     732           0 :         *_out = 0;
     733           0 :         return;
     734             :     }
     735             : 
     736           0 :     *_out = sss_view_ldb_msg_find_attr_as_uint64(domain, msg, SYSDB_GIDNUM, 0);
     737             : 
     738           0 :     return;
     739             : }
     740             : 
     741             : static errno_t
     742           0 : ifp_groups_group_get_members(TALLOC_CTX *mem_ctx,
     743             :                              struct sbus_request *sbus_req,
     744             :                              void *data,
     745             :                              const char ***_users,
     746             :                              int *_num_users,
     747             :                              const char ***_groups,
     748             :                              int *_num_groups)
     749             : {
     750             :     TALLOC_CTX *tmp_ctx;
     751             :     struct sss_domain_info *domain;
     752             :     struct ldb_message *group;
     753             :     struct ldb_message **members;
     754             :     size_t num_members;
     755             :     const char *class;
     756             :     const char **users;
     757             :     const char **groups;
     758             :     int num_users;
     759             :     int num_groups;
     760             :     int i;
     761             :     errno_t ret;
     762           0 :     const char *attrs[] = {SYSDB_OBJECTCLASS, SYSDB_UIDNUM,
     763             :                            SYSDB_GIDNUM, NULL};
     764             : 
     765           0 :     tmp_ctx = talloc_new(NULL);
     766           0 :     if (tmp_ctx == NULL) {
     767           0 :         return ENOMEM;
     768             :     }
     769             : 
     770           0 :     ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
     771           0 :     if (ret != EOK) {
     772           0 :         goto done;
     773             :     }
     774             : 
     775           0 :     ret = sysdb_asq_search(tmp_ctx, domain, group->dn, NULL, SYSDB_MEMBER,
     776             :                            attrs, &num_members, &members);
     777           0 :     if (ret != EOK) {
     778           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform ASQ search [%d]: %s\n",
     779             :               ret, sss_strerror(ret));
     780           0 :         goto done;
     781             :     }
     782             : 
     783           0 :     if (num_members == 0) {
     784           0 :         users = NULL;
     785           0 :         groups = NULL;
     786           0 :         num_users = 0;
     787           0 :         num_groups = 0;
     788           0 :         ret = EOK;
     789           0 :         goto done;
     790             :     }
     791             : 
     792           0 :     users = talloc_zero_array(tmp_ctx, const char *, num_members + 1);
     793           0 :     if (users == NULL) {
     794           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
     795           0 :         ret = ENOMEM;
     796           0 :         goto done;
     797             :     }
     798             : 
     799           0 :     groups = talloc_zero_array(tmp_ctx, const char *, num_members + 1);
     800           0 :     if (groups == NULL) {
     801           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
     802           0 :         ret = ENOMEM;
     803           0 :         goto done;
     804             :     }
     805             : 
     806           0 :     num_users = 0;
     807           0 :     num_groups = 0;
     808           0 :     for (i = 0; i < num_members; i++) {
     809           0 :         class = ldb_msg_find_attr_as_string(members[i], SYSDB_OBJECTCLASS,
     810             :                                             NULL);
     811           0 :         if (class == NULL) {
     812           0 :             ret = ERR_INTERNAL;
     813           0 :             goto done;
     814             :         }
     815             : 
     816           0 :         if (strcmp(class, SYSDB_USER_CLASS) == 0) {
     817           0 :             users[num_users] = ifp_users_build_path_from_msg(users, domain,
     818           0 :                                                              members[i]);
     819           0 :             if (users[num_users] == NULL) {
     820           0 :                 ret = ENOMEM;
     821           0 :                 goto done;
     822             :             }
     823             : 
     824           0 :             num_users++;
     825           0 :         } else if (strcmp(class, SYSDB_GROUP_CLASS) == 0) {
     826           0 :             groups[num_groups] = ifp_groups_build_path_from_msg(groups,
     827           0 :                                                          domain, members[i]);
     828           0 :             if (groups[num_groups] == NULL) {
     829           0 :                 ret = ENOMEM;
     830           0 :                 goto done;
     831             :             }
     832             : 
     833           0 :             num_groups++;
     834             :         } else {
     835           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected object class %s\n", class);
     836           0 :             ret = ERR_INTERNAL;
     837           0 :             goto done;
     838             :         }
     839             :     }
     840             : 
     841           0 :     ret = EOK;
     842             : 
     843             : done:
     844           0 :     if (ret == EOK) {
     845           0 :         if (_users != NULL) {
     846           0 :             *_users = talloc_steal(mem_ctx, users);
     847             :         }
     848             : 
     849           0 :         if (_num_users != NULL) {
     850           0 :             *_num_users = num_users;
     851             :         }
     852             : 
     853           0 :         if (_groups != NULL) {
     854           0 :             *_groups = talloc_steal(mem_ctx, groups);
     855             :         }
     856             : 
     857           0 :         if (_num_groups != NULL) {
     858           0 :             *_num_groups = num_groups;
     859             :         }
     860             :     }
     861             : 
     862           0 :     talloc_free(tmp_ctx);
     863           0 :     return ret;
     864             : }
     865             : 
     866           0 : void ifp_groups_group_get_users(struct sbus_request *sbus_req,
     867             :                                 void *data,
     868             :                                 const char ***_out,
     869             :                                 int *_size)
     870             : {
     871             :     errno_t ret;
     872             : 
     873           0 :     *_out = NULL;
     874           0 :     *_size = 0;
     875             : 
     876           0 :     ret = ifp_groups_group_get_members(sbus_req, sbus_req, data, _out, _size,
     877             :                                        NULL, NULL);
     878           0 :     if (ret != EOK) {
     879           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire groups members\n");
     880             :     }
     881           0 : }
     882             : 
     883           0 : void ifp_groups_group_get_groups(struct sbus_request *sbus_req,
     884             :                                 void *data,
     885             :                                 const char ***_out,
     886             :                                 int *_size)
     887             : {
     888             :     errno_t ret;
     889             : 
     890           0 :     *_out = NULL;
     891           0 :     *_size = 0;
     892             : 
     893           0 :     ret = ifp_groups_group_get_members(sbus_req, sbus_req, data, NULL, NULL,
     894             :                                        _out, _size);
     895           0 :     if (ret != EOK) {
     896           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire groups members\n");
     897             :     }
     898           0 : }
     899             : 
     900           0 : int ifp_cache_list_group(struct sbus_request *sbus_req,
     901             :                          void *data)
     902             : {
     903           0 :     return ifp_cache_list(sbus_req, data, IFP_CACHE_GROUP);
     904             : }
     905             : 
     906           0 : int ifp_cache_list_by_domain_group(struct sbus_request *sbus_req,
     907             :                                    void *data,
     908             :                                    const char *domain)
     909             : {
     910           0 :     return ifp_cache_list_by_domain(sbus_req, data, domain, IFP_CACHE_GROUP);
     911             : }
     912             : 
     913           0 : int ifp_cache_object_store_group(struct sbus_request *sbus_req,
     914             :                                  void *data)
     915             : {
     916             :     DBusError *error;
     917             :     struct sss_domain_info *domain;
     918             :     struct ldb_message *group;
     919             :     errno_t ret;
     920             : 
     921           0 :     ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
     922           0 :     if (ret != EOK) {
     923           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
     924             :                                "group [%d]: %s\n", ret, sss_strerror(ret));
     925           0 :         return sbus_request_fail_and_finish(sbus_req, error);
     926             :     }
     927             : 
     928             :     /* The request is finished inside. */
     929           0 :     return ifp_cache_object_store(sbus_req, domain, group->dn);
     930             : }
     931             : 
     932           0 : int ifp_cache_object_remove_group(struct sbus_request *sbus_req,
     933             :                                   void *data)
     934             : {
     935             :     DBusError *error;
     936             :     struct sss_domain_info *domain;
     937             :     struct ldb_message *group;
     938             :     errno_t ret;
     939             : 
     940           0 :     ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
     941           0 :     if (ret != EOK) {
     942           0 :         error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
     943             :                                "group [%d]: %s\n", ret, sss_strerror(ret));
     944           0 :         return sbus_request_fail_and_finish(sbus_req, error);
     945             :     }
     946             : 
     947             :     /* The request is finished inside. */
     948           0 :     return ifp_cache_object_remove(sbus_req, domain, group->dn);
     949             : }

Generated by: LCOV version 1.10