LCOV - code coverage report
Current view: top level - providers/data_provider - dp_target_id.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 112 0.0 %
Date: 2016-06-29 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2016 Red Hat
       6             : 
       7             :     This program is free software; you can redistribute it and/or modify
       8             :     it under the terms of the GNU General Public License as published by
       9             :     the Free Software Foundation; either version 3 of the License, or
      10             :     (at your option) any later version.
      11             : 
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :     GNU General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include <talloc.h>
      22             : #include <tevent.h>
      23             : 
      24             : #include "sbus/sssd_dbus.h"
      25             : #include "providers/data_provider/dp_private.h"
      26             : #include "providers/data_provider/dp_iface.h"
      27             : #include "providers/backend.h"
      28             : #include "util/util.h"
      29             : 
      30             : #define FILTER_TYPE(str, type) {str "=", sizeof(str "=") - 1, type}
      31             : 
      32           0 : static bool check_attr_type(uint32_t attr_type)
      33             : {
      34           0 :     switch (attr_type) {
      35             :     case BE_ATTR_CORE:
      36             :     case BE_ATTR_MEM:
      37             :     case BE_ATTR_ALL:
      38           0 :         return true;
      39             :     default:
      40           0 :         return false;
      41             :     }
      42             : 
      43             :     return false;
      44             : }
      45             : 
      46           0 : static bool check_and_parse_filter(struct be_acct_req *data,
      47             :                                    const char *filter,
      48             :                                    const char *extra)
      49             : {
      50             :     /* We will use sizeof() to determine the length of a string so we don't
      51             :      * call strlen over and over again with each request. Not a bottleneck,
      52             :      * but unnecessary and simple to avoid. */
      53             :     static struct {
      54             :         const char *name;
      55             :         size_t lenght;
      56             :         uint32_t type;
      57             :     } types[] = {FILTER_TYPE("name", BE_FILTER_NAME),
      58             :                  FILTER_TYPE("idnumber", BE_FILTER_IDNUM),
      59             :                  FILTER_TYPE(DP_SEC_ID, BE_FILTER_SECID),
      60             :                  FILTER_TYPE(DP_CERT, BE_FILTER_CERT),
      61             :                  FILTER_TYPE(DP_WILDCARD, BE_FILTER_WILDCARD),
      62             :                  {0, 0, 0}};
      63             :     int i;
      64             : 
      65           0 :     if (filter == NULL) {
      66           0 :         return false;
      67             :     }
      68             : 
      69           0 :     for (i = 0; types[i].name != NULL; i++) {
      70           0 :         if (strncmp(filter, types[i].name, types[i].lenght) == 0) {
      71           0 :             data->filter_type = types[i].type;
      72           0 :             data->filter_value = &filter[types[i].lenght];
      73           0 :             data->extra_value = extra;
      74           0 :             return true;
      75             :         }
      76             :     }
      77             : 
      78           0 :     if (strcmp(filter, ENUM_INDICATOR) == 0) {
      79           0 :         data->filter_type = BE_FILTER_ENUM;
      80           0 :         data->filter_value = NULL;
      81           0 :         data->extra_value = NULL;
      82           0 :         return true;
      83             :     }
      84             : 
      85           0 :     return false;
      86             : }
      87             : 
      88             : struct dp_initgr_ctx {
      89             :     const char *username;
      90             :     const char *domain;
      91             :     uint32_t gnum;
      92             :     uint32_t *groups;
      93             : };
      94             : 
      95           0 : static struct dp_initgr_ctx *create_initgr_ctx(TALLOC_CTX *mem_ctx,
      96             :                                                const char *domain,
      97             :                                                struct ldb_result *res)
      98             : {
      99             :     struct dp_initgr_ctx *ctx;
     100             :     const char *username;
     101             :     unsigned int i;
     102             :     errno_t ret;
     103             : 
     104           0 :     ctx = talloc_zero(mem_ctx, struct dp_initgr_ctx);
     105           0 :     if (ctx == NULL) {
     106           0 :         return NULL;
     107             :     }
     108             : 
     109           0 :     username = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL);
     110           0 :     if (username == NULL) {
     111           0 :         ret = EINVAL;
     112           0 :         goto done;
     113             :     }
     114             : 
     115           0 :     ctx->username = talloc_strdup(ctx, username);
     116           0 :     if (ctx->username == NULL) {
     117           0 :         ret = ENOMEM;
     118           0 :         goto done;
     119             :     }
     120             : 
     121           0 :     ctx->domain = talloc_strdup(ctx, domain);
     122           0 :     if (ctx->domain == NULL) {
     123           0 :         ret = ENOMEM;
     124           0 :         goto done;
     125             :     }
     126             : 
     127           0 :     ctx->groups = talloc_array(mem_ctx, uint32_t, res->count);
     128           0 :     if (ctx->groups == NULL) {
     129           0 :         ret = ENOMEM;
     130           0 :         goto done;
     131             :     }
     132             : 
     133             :     /* The first GID is the primary so it might be duplicated
     134             :      * later in the list. */
     135           0 :     for (ctx->gnum = 0, i = 0; i < res->count; i++) {
     136           0 :         ctx->groups[ctx->gnum] = ldb_msg_find_attr_as_uint(res->msgs[i],
     137             :                                                            SYSDB_GIDNUM, 0);
     138             :         /* If 0 it may be a non-posix group, so we skip it. */
     139           0 :         if (ctx->groups[ctx->gnum] != 0) {
     140           0 :             ctx->gnum++;
     141             :         }
     142             :     }
     143             : 
     144           0 :     ret = EOK;
     145             : 
     146             : done:
     147           0 :     if (ret != EOK) {
     148           0 :         talloc_free(ctx);
     149           0 :         return NULL;
     150             :     }
     151             : 
     152           0 :     return ctx;
     153             : }
     154             : 
     155           0 : static void dp_req_initgr_pp(const char *req_name,
     156             :                              struct data_provider *provider,
     157             :                              struct dp_initgr_ctx *ctx,
     158             :                              struct dp_reply_std *reply)
     159             : {
     160             :     struct dp_client *dp_cli;
     161             :     DBusMessage *msg;
     162             :     dbus_bool_t dbret;
     163             :     int num;
     164             : 
     165           0 :     dp_cli = provider->clients[DPC_NSS];
     166           0 :     if (dp_cli == NULL) {
     167           0 :         return;
     168             :     }
     169             : 
     170           0 :     msg = dbus_message_new_method_call(NULL,
     171             :                                        DP_PATH,
     172             :                                        DATA_PROVIDER_REV_IFACE,
     173             :                                        DATA_PROVIDER_REV_IFACE_INITGRCHECK);
     174           0 :     if (msg == NULL) {
     175           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
     176           0 :         return;
     177             :     }
     178             : 
     179           0 :     num = ctx->gnum;
     180           0 :     dbret = dbus_message_append_args(msg,
     181             :                                      DBUS_TYPE_STRING, &ctx->username,
     182             :                                      DBUS_TYPE_STRING, &ctx->domain,
     183             :                                      DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
     184             :                                      &ctx->groups, num,
     185             :                                      DBUS_TYPE_INVALID);
     186           0 :     if (!dbret) {
     187           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
     188           0 :         dbus_message_unref(msg);
     189           0 :         return;
     190             :     }
     191             : 
     192           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     193             :           "Ordering NSS responder to update memory cache\n");
     194             : 
     195           0 :     sbus_conn_send_reply(dp_client_conn(dp_cli), msg);
     196           0 :     dbus_message_unref(msg);
     197             : 
     198           0 :     return;
     199             : }
     200             : 
     201           0 : static errno_t dp_initgroups(struct sbus_request *sbus_req,
     202             :                              struct dp_client *dp_cli,
     203             :                              const char *key,
     204             :                              uint32_t dp_flags,
     205             :                              struct be_acct_req *data)
     206             : {
     207             :     struct be_ctx *be_ctx;
     208             :     struct sss_domain_info *domain;
     209             :     struct dp_initgr_ctx *ctx;
     210             :     struct ldb_result *res;
     211             :     errno_t ret;
     212             : 
     213           0 :     be_ctx = dp_client_be(dp_cli);
     214             : 
     215           0 :     if (data->domain == NULL) {
     216           0 :         domain = be_ctx->domain;
     217             :     } else {
     218           0 :         domain = find_domain_by_name(be_ctx->domain, data->domain, true);
     219           0 :         if (domain == NULL) {
     220           0 :             return ERR_DOMAIN_NOT_FOUND;
     221             :         }
     222             :     }
     223             : 
     224           0 :     ret = sysdb_initgroups(sbus_req, domain, data->filter_value, &res);
     225           0 :     if (ret == ENOENT || (ret == EOK && res->count == 0)) {
     226             :         /* There is no point in concacting NSS responder. Proceed as usual. */
     227           0 :         return EAGAIN;
     228           0 :     } else if (ret != EOK) {
     229           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get initgroups [%d]: %s\n",
     230             :               ret, sss_strerror(ret));
     231           0 :         goto done;
     232             :     }
     233             : 
     234           0 :     ctx = create_initgr_ctx(sbus_req, data->domain, res);
     235           0 :     if (ctx == NULL) {
     236           0 :         ret = ENOMEM;
     237           0 :         goto done;
     238             :     }
     239             : 
     240           0 :     dp_req_with_reply_pp(dp_cli, data->domain, "Initgroups", key,
     241             :                       sbus_req, DPT_ID, DPM_ACCOUNT_HANDLER, dp_flags, data,
     242             :                       dp_req_initgr_pp, ctx, struct dp_initgr_ctx,
     243             :                       dp_req_reply_std, struct dp_reply_std);
     244             : 
     245           0 :     ret = EOK;
     246             : 
     247             : done:
     248           0 :     talloc_free(res);
     249           0 :     return ret;
     250             : }
     251             : 
     252           0 : errno_t dp_get_account_info_handler(struct sbus_request *sbus_req,
     253             :                                     void *dp_cli,
     254             :                                     uint32_t dp_flags,
     255             :                                     uint32_t entry_type,
     256             :                                     uint32_t attr_type,
     257             :                                     const char *filter,
     258             :                                     const char *domain,
     259             :                                     const char *extra)
     260             : {
     261             :     struct be_acct_req *data;
     262             :     const char *key;
     263             :     errno_t ret;
     264             : 
     265           0 :     if (!check_attr_type(attr_type)) {
     266           0 :         return EINVAL;
     267             :     }
     268             : 
     269           0 :     data = talloc_zero(sbus_req, struct be_acct_req);
     270           0 :     if (data == NULL) {
     271           0 :         return ENOMEM;
     272             :     }
     273             : 
     274           0 :     data->entry_type = entry_type;
     275           0 :     data->attr_type = attr_type;
     276           0 :     data->domain = domain;
     277             : 
     278           0 :     if (!check_and_parse_filter(data, filter, extra)) {
     279           0 :         ret = EINVAL;
     280           0 :         goto done;
     281             :     }
     282             : 
     283           0 :     key = talloc_asprintf(data, "%u:%u:%s:%s:%s", data->entry_type,
     284             :                           data->attr_type, extra, domain, filter);
     285           0 :     if (key == NULL) {
     286           0 :         ret = ENOMEM;
     287           0 :         goto done;
     288             :     }
     289             : 
     290           0 :     if ((data->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_INITGROUPS) {
     291           0 :         ret =  dp_initgroups(sbus_req, dp_cli, key, dp_flags, data);
     292           0 :         if (ret != EAGAIN) {
     293           0 :             goto done;
     294             :         }
     295             :     }
     296             : 
     297           0 :     dp_req_with_reply(dp_cli, domain, "Account", key,
     298             :                       sbus_req, DPT_ID, DPM_ACCOUNT_HANDLER, dp_flags, data,
     299             :                       dp_req_reply_std, struct dp_reply_std);
     300             : 
     301           0 :     ret = EOK;
     302             : 
     303             : done:
     304           0 :     if (ret != EOK) {
     305           0 :         talloc_free(data);
     306             :     }
     307             : 
     308           0 :     return ret;
     309             : }

Generated by: LCOV version 1.10