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

Generated by: LCOV version 1.10