LCOV - code coverage report
Current view: top level - responder/ifp - ifpsrv_util.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 52 136 38.2 %
Date: 2016-06-29 Functions: 4 10 40.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Jakub Hrozek <jhrozek@redhat.com>
       4             :         Stephen Gallagher <sgallagh@redhat.com>
       5             : 
       6             :     Copyright (C) 2013 Red Hat
       7             : 
       8             :     InfoPipe responder: Utility functions
       9             : 
      10             :     This program is free software; you can redistribute it and/or modify
      11             :     it under the terms of the GNU General Public License as published by
      12             :     the Free Software Foundation; either version 3 of the License, or
      13             :     (at your option) any later version.
      14             : 
      15             :     This program is distributed in the hope that it will be useful,
      16             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :     GNU General Public License for more details.
      19             : 
      20             :     You should have received a copy of the GNU General Public License
      21             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include <sys/param.h>
      25             : 
      26             : #include "db/sysdb.h"
      27             : #include "responder/ifp/ifp_private.h"
      28             : 
      29             : #define IFP_USER_DEFAULT_ATTRS {SYSDB_NAME, SYSDB_UIDNUM,   \
      30             :                                 SYSDB_GIDNUM, SYSDB_GECOS,  \
      31             :                                 SYSDB_HOMEDIR, SYSDB_SHELL, \
      32             :                                 "groups", \
      33             :                                 NULL}
      34             : 
      35           3 : errno_t ifp_req_create(struct sbus_request *dbus_req,
      36             :                        struct ifp_ctx *ifp_ctx,
      37             :                        struct ifp_req **_ifp_req)
      38             : {
      39           3 :     struct ifp_req *ireq = NULL;
      40             :     errno_t ret;
      41             : 
      42           3 :     if (ifp_ctx->sysbus == NULL) {
      43           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Responder not connected to sysbus!\n");
      44           0 :         return EINVAL;
      45             :     }
      46             : 
      47           3 :     ireq = talloc_zero(dbus_req, struct ifp_req);
      48           3 :     if (ireq == NULL) {
      49           0 :         return ENOMEM;
      50             :     }
      51             : 
      52           3 :     ireq->ifp_ctx = ifp_ctx;
      53           3 :     ireq->dbus_req = dbus_req;
      54             : 
      55           3 :     if (dbus_req->client == -1) {
      56             :         /* We got a sysbus message but couldn't identify the
      57             :          * caller? Bail out! */
      58           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
      59             :               "BUG: Received a message without a known caller!\n");
      60           0 :         ret = EACCES;
      61           0 :         goto done;
      62             :     }
      63             : 
      64           6 :     ret = check_allowed_uids(dbus_req->client,
      65           3 :                              ifp_ctx->rctx->allowed_uids_count,
      66           3 :                              ifp_ctx->rctx->allowed_uids);
      67           3 :     if (ret == EACCES) {
      68           1 :         DEBUG(SSSDBG_MINOR_FAILURE,
      69             :               "User %"PRIi64" not in ACL\n", dbus_req->client);
      70           1 :         goto done;
      71           2 :     } else if (ret != EOK) {
      72           0 :         DEBUG(SSSDBG_OP_FAILURE,
      73             :               "Cannot check if user %"PRIi64" is present in ACL\n",
      74             :               dbus_req->client);
      75           0 :         goto done;
      76             :     }
      77             : 
      78           2 :     *_ifp_req = ireq;
      79           2 :     ret = EOK;
      80             : done:
      81           3 :     if (ret != EOK) {
      82           1 :         talloc_free(ireq);
      83             :     }
      84           3 :     return ret;
      85             : }
      86             : 
      87           0 : int ifp_req_create_handle_failure(struct sbus_request *dbus_req, errno_t err)
      88             : {
      89           0 :     if (err == EACCES) {
      90           0 :         return sbus_request_fail_and_finish(dbus_req,
      91           0 :                                sbus_error_new(dbus_req,
      92             :                                               DBUS_ERROR_ACCESS_DENIED,
      93             :                                               "User %"PRIi64" not in ACL\n",
      94             :                                               dbus_req->client));
      95             :     }
      96             : 
      97           0 :     return sbus_request_fail_and_finish(dbus_req,
      98           0 :                                         sbus_error_new(dbus_req,
      99             :                                             DBUS_ERROR_FAILED,
     100             :                                             "Cannot create IFP request\n"));
     101             : }
     102             : 
     103           1 : errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict,
     104             :                                struct ldb_message_element *el)
     105             : {
     106             :     DBusMessageIter iter_dict_entry;
     107             :     DBusMessageIter iter_dict_val;
     108             :     DBusMessageIter iter_array;
     109             :     dbus_bool_t dbret;
     110             :     unsigned int i;
     111             : 
     112           1 :     if (el == NULL) {
     113           0 :         return EINVAL;
     114             :     }
     115             : 
     116           1 :     dbret = dbus_message_iter_open_container(iter_dict,
     117             :                                              DBUS_TYPE_DICT_ENTRY, NULL,
     118             :                                              &iter_dict_entry);
     119           1 :     if (!dbret) {
     120           0 :         return ENOMEM;
     121             :     }
     122             : 
     123             :     /* Start by appending the key */
     124           1 :     dbret = dbus_message_iter_append_basic(&iter_dict_entry,
     125           1 :                                            DBUS_TYPE_STRING, &(el->name));
     126           1 :     if (!dbret) {
     127           0 :         return ENOMEM;
     128             :     }
     129             : 
     130           1 :     dbret = dbus_message_iter_open_container(&iter_dict_entry,
     131             :                                              DBUS_TYPE_VARIANT,
     132             :                                              DBUS_TYPE_ARRAY_AS_STRING
     133             :                                              DBUS_TYPE_STRING_AS_STRING,
     134             :                                              &iter_dict_val);
     135           1 :     if (!dbret) {
     136           0 :         return ENOMEM;
     137             :     }
     138             : 
     139             :     /* Open container for values */
     140           1 :     dbret = dbus_message_iter_open_container(&iter_dict_val,
     141             :                                  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING,
     142             :                                  &iter_array);
     143           1 :     if (!dbret) {
     144           0 :         return ENOMEM;
     145             :     }
     146             : 
     147             :     /* Now add all the values */
     148           3 :     for (i = 0; i < el->num_values; i++) {
     149           2 :         DEBUG(SSSDBG_TRACE_FUNC, "element [%s] has value [%s]\n",
     150             :               el->name, (const char *) el->values[i].data);
     151             : 
     152           2 :         dbret = dbus_message_iter_append_basic(&iter_array,
     153             :                                                DBUS_TYPE_STRING,
     154           2 :                                                &(el->values[i].data));
     155           2 :         if (!dbret) {
     156           0 :             return ENOMEM;
     157             :         }
     158             :     }
     159             : 
     160           1 :     dbret = dbus_message_iter_close_container(&iter_dict_val,
     161             :                                               &iter_array);
     162           1 :     if (!dbret) {
     163           0 :         return ENOMEM;
     164             :     }
     165             : 
     166           1 :     dbret = dbus_message_iter_close_container(&iter_dict_entry,
     167             :                                               &iter_dict_val);
     168           1 :     if (!dbret) {
     169           0 :         return ENOMEM;
     170             :     }
     171             : 
     172           1 :     dbret = dbus_message_iter_close_container(iter_dict,
     173             :                                               &iter_dict_entry);
     174           1 :     if (!dbret) {
     175           0 :         return ENOMEM;
     176             :     }
     177             : 
     178           1 :     return EOK;
     179             : }
     180             : 
     181             : 
     182             : bool
     183           5 : ifp_attr_allowed(const char *whitelist[], const char *attr)
     184             : {
     185             :     size_t i;
     186             : 
     187           5 :     if (whitelist == NULL) {
     188           1 :         return false;
     189             :     }
     190             : 
     191           7 :     for (i = 0; whitelist[i]; i++) {
     192           5 :         if (strcasecmp(whitelist[i], attr) == 0) {
     193           2 :             break;
     194             :         }
     195             :     }
     196             : 
     197           4 :     return (whitelist[i]) ? true : false;
     198             : }
     199             : 
     200             : const char **
     201           7 : ifp_parse_user_attr_list(TALLOC_CTX *mem_ctx, const char *csv)
     202             : {
     203             :     static const char *defaults[] = IFP_USER_DEFAULT_ATTRS;
     204             : 
     205           7 :     return parse_attr_list_ex(mem_ctx, csv, defaults);
     206             : }
     207             : 
     208             : const char **
     209           0 : ifp_get_user_extra_attributes(TALLOC_CTX *mem_ctx, struct ifp_ctx *ifp_ctx)
     210             : {
     211           0 :     TALLOC_CTX *tmp_ctx = NULL;
     212           0 :     const char *std[] = IFP_USER_DEFAULT_ATTRS;
     213           0 :     const char **whitelist = ifp_ctx->user_whitelist;
     214             :     const char **extra;
     215             :     bool found;
     216             :     int extra_num;
     217             :     int i, j;
     218             : 
     219           0 :     tmp_ctx = talloc_new(NULL);
     220           0 :     if (tmp_ctx == NULL) {
     221           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
     222           0 :         return NULL;
     223             :     }
     224             : 
     225           0 :     for (i = 0; whitelist[i] != NULL; i++) {
     226             :         /* Just count number of attributes in whitelist. */
     227             :     }
     228             : 
     229           0 :     extra = talloc_zero_array(tmp_ctx, const char *, i + 1);
     230           0 :     if (extra == NULL) {
     231           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
     232           0 :         goto fail;
     233             :     }
     234             : 
     235           0 :     extra_num = 0;
     236           0 :     for (i = 0; whitelist[i] != NULL; i++) {
     237           0 :         found = false;
     238           0 :         for (j = 0; std[j] != NULL; j++) {
     239           0 :             if (strcmp(whitelist[i], std[j]) == 0) {
     240           0 :                 found = true;
     241           0 :                 break;
     242             :             }
     243             :         }
     244             : 
     245           0 :         if (!found) {
     246           0 :             extra[extra_num] = talloc_strdup(extra, whitelist[i]);
     247           0 :             if (extra[extra_num] == NULL) {
     248           0 :                 goto fail;
     249             :             }
     250             : 
     251           0 :             extra_num++;
     252             :         }
     253             :     }
     254             : 
     255           0 :     extra = talloc_realloc(tmp_ctx, extra, const char *, extra_num + 1);
     256           0 :     if (extra == NULL) {
     257           0 :         goto fail;
     258             :     }
     259             : 
     260           0 :     talloc_steal(mem_ctx, extra);
     261           0 :     talloc_free(tmp_ctx);
     262           0 :     return extra;
     263             : 
     264             : fail:
     265           0 :     talloc_free(tmp_ctx);
     266           0 :     return NULL;
     267             : }
     268             : 
     269             : bool
     270           0 : ifp_is_user_attr_allowed(struct ifp_ctx *ifp_ctx, const char *attr)
     271             : {
     272           0 :     return ifp_attr_allowed(ifp_ctx->user_whitelist, attr);
     273             : }
     274             : 
     275           0 : static uint32_t ifp_list_limit(struct ifp_ctx *ctx, uint32_t limit)
     276             : {
     277           0 :     if (limit == 0) {
     278           0 :         return ctx->wildcard_limit;
     279           0 :     } else if (ctx->wildcard_limit) {
     280           0 :         return MIN(ctx->wildcard_limit, limit);
     281             :     } else {
     282           0 :         return limit;
     283             :     }
     284             : }
     285             : 
     286           0 : struct ifp_list_ctx *ifp_list_ctx_new(struct sbus_request *sbus_req,
     287             :                                       struct ifp_ctx *ctx,
     288             :                                       const char *filter,
     289             :                                       uint32_t limit)
     290             : {
     291             :     struct ifp_list_ctx *list_ctx;
     292             : 
     293           0 :     list_ctx = talloc_zero(sbus_req, struct ifp_list_ctx);
     294           0 :     if (list_ctx == NULL) {
     295           0 :         return NULL;
     296             :     }
     297             : 
     298           0 :     list_ctx->sbus_req = sbus_req;
     299           0 :     list_ctx->limit = ifp_list_limit(ctx, limit);
     300           0 :     list_ctx->ctx = ctx;
     301           0 :     list_ctx->dom = ctx->rctx->domains;
     302           0 :     list_ctx->filter = filter;
     303           0 :     list_ctx->paths = talloc_zero_array(list_ctx, const char *, limit);
     304           0 :     if (list_ctx->paths == NULL) {
     305           0 :         talloc_free(list_ctx);
     306           0 :         return NULL;
     307             :     }
     308             : 
     309           0 :     return list_ctx;
     310             : }
     311             : 
     312           0 : size_t ifp_list_ctx_remaining_capacity(struct ifp_list_ctx *list_ctx,
     313             :                                        size_t entries)
     314             : {
     315           0 :     size_t capacity = list_ctx->limit - list_ctx->path_count;
     316             : 
     317           0 :     if (capacity < entries) {
     318           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     319             :               "IFP list request has limit of %"PRIu32" entries but back end "
     320             :               "returned %zu entries\n", list_ctx->limit, entries);
     321           0 :         return capacity;
     322             :     } else {
     323           0 :         return entries;
     324             :     }
     325             : }

Generated by: LCOV version 1.10