LCOV - code coverage report
Current view: top level - sss_client/idmap - sss_nss_idmap.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 83 154 53.9 %
Date: 2015-10-19 Functions: 5 9 55.6 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     NSS Responder Interface for ID-SID mappings
       5             : 
       6             :     Authors:
       7             :         Sumit Bose <sbose@redhat.com>
       8             : 
       9             :     Copyright (C) 2013 Red Hat
      10             : 
      11             :     This program is free software; you can redistribute it and/or modify
      12             :     it under the terms of the GNU General Public License as published by
      13             :     the Free Software Foundation; either version 3 of the License, or
      14             :     (at your option) any later version.
      15             : 
      16             :     This program is distributed in the hope that it will be useful,
      17             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :     GNU General Public License for more details.
      20             : 
      21             :     You should have received a copy of the GNU General Public License
      22             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include <stdlib.h>
      26             : #include <errno.h>
      27             : #include <nss.h>
      28             : 
      29             : #include "sss_client/sss_cli.h"
      30             : #include "sss_client/idmap/sss_nss_idmap.h"
      31             : #include "util/strtonum.h"
      32             : 
      33             : #define DATA_START (3 * sizeof(uint32_t))
      34             : union input {
      35             :     const char *str;
      36             :     uint32_t id;
      37             : };
      38             : 
      39             : struct output {
      40             :     enum sss_id_type type;
      41             :     union {
      42             :         char *str;
      43             :         uint32_t id;
      44             :         struct sss_nss_kv *kv_list;
      45             :     } d;
      46             : };
      47             : 
      48           0 : int nss_status_to_errno(enum nss_status nret) {
      49           0 :     switch (nret) {
      50             :     case NSS_STATUS_TRYAGAIN:
      51           0 :         return EAGAIN;
      52             :     case NSS_STATUS_SUCCESS:
      53           0 :         return EOK;
      54             :     case NSS_STATUS_UNAVAIL:
      55             :     default:
      56           0 :         return ENOENT;
      57             :     }
      58             : 
      59             :     return EINVAL;
      60             : }
      61             : 
      62           1 : void sss_nss_free_kv(struct sss_nss_kv *kv_list)
      63             : {
      64             :     size_t c;
      65             : 
      66           1 :     if (kv_list != NULL) {
      67           2 :         for (c = 0; kv_list[c].key != NULL; c++) {
      68           1 :             free(kv_list[c].key);
      69           1 :             free(kv_list[c].value);
      70             :         }
      71           1 :         free(kv_list);
      72             :     }
      73           1 : }
      74             : 
      75           1 : static int  buf_to_kv_list(uint8_t *buf, size_t buf_len,
      76             :                            struct sss_nss_kv **kv_list)
      77             : {
      78             :     size_t c;
      79           1 :     size_t count = 0;
      80             :     struct sss_nss_kv *list;
      81             :     uint8_t *p;
      82             :     int ret;
      83             : 
      84          11 :     for (c = 0; c < buf_len; c++) {
      85          10 :         if (buf[c] == '\0') {
      86           2 :             count++;
      87             :         }
      88             :     }
      89             : 
      90           1 :     if ((count % 2) != 0) {
      91           0 :         return EINVAL;
      92             :     }
      93           1 :     count /= 2;
      94             : 
      95           1 :     list = calloc((count + 1), sizeof(struct sss_nss_kv));
      96           1 :     if (list == NULL) {
      97           0 :         return ENOMEM;
      98             :     }
      99             : 
     100           1 :     p = buf;
     101           2 :     for (c = 0; c < count; c++) {
     102           1 :         list[c].key = strdup((char *) p);
     103           1 :         if (list[c].key == NULL) {
     104           0 :             ret = ENOMEM;
     105           0 :             goto done;
     106             :         }
     107             : 
     108           1 :         p = memchr(p, '\0', buf_len - (p - buf));
     109           1 :         if (p == NULL) {
     110           0 :             ret = EINVAL;
     111           0 :             goto done;
     112             :         }
     113           1 :         p++;
     114             : 
     115           1 :         list[c].value = strdup((char *) p);
     116           1 :         if (list[c].value == NULL) {
     117           0 :             ret = ENOMEM;
     118           0 :             goto done;
     119             :         }
     120             : 
     121           1 :         p = memchr(p, '\0', buf_len - (p - buf));
     122           1 :         if (p == NULL) {
     123           0 :             ret = EINVAL;
     124           0 :             goto done;
     125             :         }
     126           1 :         p++;
     127             :     }
     128             : 
     129           1 :     *kv_list = list;
     130             : 
     131           1 :     ret = EOK;
     132             : 
     133             : done:
     134           1 :     if (ret != EOK) {
     135           0 :         sss_nss_free_kv(list);
     136             :     }
     137             : 
     138           1 :     return ret;
     139             : }
     140             : 
     141           5 : static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
     142             :                                struct output *out)
     143             : {
     144             :     int ret;
     145             :     size_t inp_len;
     146             :     struct sss_cli_req_data rd;
     147           5 :     uint8_t *repbuf = NULL;
     148             :     size_t replen;
     149             :     int errnop;
     150             :     enum nss_status nret;
     151             :     uint32_t num_results;
     152           5 :     char *str = NULL;
     153             :     size_t data_len;
     154             :     uint32_t c;
     155             :     struct sss_nss_kv *kv_list;
     156             : 
     157           5 :     switch (cmd) {
     158             :     case SSS_NSS_GETSIDBYNAME:
     159             :     case SSS_NSS_GETNAMEBYSID:
     160             :     case SSS_NSS_GETIDBYSID:
     161             :     case SSS_NSS_GETORIGBYNAME:
     162           5 :         ret = sss_strnlen(inp.str, SSS_NAME_MAX, &inp_len);
     163           5 :         if (ret != EOK) {
     164           0 :             return EINVAL;
     165             :         }
     166             : 
     167           5 :         rd.len = inp_len + 1;
     168           5 :         rd.data = inp.str;
     169             : 
     170           5 :         break;
     171             :     case SSS_NSS_GETSIDBYID:
     172           0 :         rd.len = sizeof(uint32_t);
     173           0 :         rd.data = &inp.id;
     174             : 
     175           0 :         break;
     176             :     default:
     177           0 :         return EINVAL;
     178             :     }
     179             : 
     180           5 :     sss_nss_lock();
     181             : 
     182           5 :     nret = sss_nss_make_request(cmd, &rd, &repbuf, &replen, &errnop);
     183           5 :     if (nret != NSS_STATUS_SUCCESS) {
     184           0 :         ret = nss_status_to_errno(nret);
     185           0 :         goto done;
     186             :     }
     187             : 
     188           5 :     if (replen < 8) {
     189           0 :         ret = EBADMSG;
     190           0 :         goto done;
     191             :     }
     192             : 
     193           5 :     SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL);
     194           5 :     if (num_results == 0) {
     195           0 :         ret = ENOENT;
     196           0 :         goto done;
     197           5 :     } else if (num_results > 1) {
     198           0 :         ret = EBADMSG;
     199           0 :         goto done;
     200             :     }
     201             : 
     202             :     /* Skip first two 32 bit values (number of results and
     203             :      * reserved padding) */
     204           5 :     SAFEALIGN_COPY_UINT32(&out->type, repbuf + 2 * sizeof(uint32_t), NULL);
     205             : 
     206           5 :     data_len = replen - DATA_START;
     207             : 
     208           5 :     switch(cmd) {
     209             :     case SSS_NSS_GETSIDBYID:
     210             :     case SSS_NSS_GETSIDBYNAME:
     211             :     case SSS_NSS_GETNAMEBYSID:
     212           4 :         if (data_len <= 1 || repbuf[replen - 1] != '\0') {
     213           0 :             ret = EBADMSG;
     214           0 :             goto done;
     215             :         }
     216             : 
     217           4 :         str = malloc(sizeof(char) * data_len);
     218           4 :         if (str == NULL) {
     219           0 :             ret = ENOMEM;
     220           0 :             goto done;
     221             :         }
     222             : 
     223           4 :         strncpy(str, (char *) repbuf + DATA_START, data_len);
     224             : 
     225           4 :         out->d.str = str;
     226             : 
     227           4 :         break;
     228             :     case SSS_NSS_GETIDBYSID:
     229           0 :         if (data_len != sizeof(uint32_t)) {
     230           0 :             ret = EBADMSG;
     231           0 :             goto done;
     232             :         }
     233             : 
     234           0 :         SAFEALIGN_COPY_UINT32(&c, repbuf + DATA_START, NULL);
     235           0 :         out->d.id = c;
     236             : 
     237           0 :         break;
     238             :     case SSS_NSS_GETORIGBYNAME:
     239           1 :         ret = buf_to_kv_list(repbuf + DATA_START, data_len, &kv_list);
     240           1 :         if (ret != EOK) {
     241           0 :             goto done;
     242             :         }
     243             : 
     244           1 :         out->d.kv_list = kv_list;
     245             : 
     246           1 :         break;
     247             :     default:
     248           0 :         ret = EINVAL;
     249           0 :         goto done;
     250             :     }
     251             : 
     252           5 :     ret = EOK;
     253             : 
     254             : done:
     255           5 :     sss_nss_unlock();
     256           5 :     free(repbuf);
     257           5 :     if (ret != EOK) {
     258           0 :         free(str);
     259             :     }
     260             : 
     261           5 :     return ret;
     262             : }
     263             : 
     264           7 : int sss_nss_getsidbyname(const char *fq_name, char **sid,
     265             :                          enum sss_id_type *type)
     266             : {
     267             :     int ret;
     268             :     union input inp;
     269             :     struct output out;
     270             : 
     271           7 :     if (sid == NULL || fq_name == NULL || *fq_name == '\0') {
     272           3 :         return EINVAL;
     273             :     }
     274             : 
     275           4 :     inp.str = fq_name;
     276             : 
     277           4 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, &out);
     278           4 :     if (ret == EOK) {
     279           4 :         *sid = out.d.str;
     280           4 :         *type = out.type;
     281             :     }
     282             : 
     283           4 :     return ret;
     284             : }
     285             : 
     286           0 : int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type)
     287             : {
     288             :     int ret;
     289             :     union input inp;
     290             :     struct output out;
     291             : 
     292           0 :     if (sid == NULL) {
     293           0 :         return EINVAL;
     294             :     }
     295             : 
     296           0 :     inp.id = id;
     297             : 
     298           0 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, &out);
     299           0 :     if (ret == EOK) {
     300           0 :         *sid = out.d.str;
     301           0 :         *type = out.type;
     302             :     }
     303             : 
     304           0 :     return ret;
     305             : }
     306             : 
     307           0 : int sss_nss_getnamebysid(const char *sid, char **fq_name,
     308             :                          enum sss_id_type *type)
     309             : {
     310             :     int ret;
     311             :     union input inp;
     312             :     struct output out;
     313             : 
     314           0 :     if (fq_name == NULL || sid == NULL || *sid == '\0') {
     315           0 :         return EINVAL;
     316             :     }
     317             : 
     318           0 :     inp.str = sid;
     319             : 
     320           0 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, &out);
     321           0 :     if (ret == EOK) {
     322           0 :         *fq_name = out.d.str;
     323           0 :         *type = out.type;
     324             :     }
     325             : 
     326           0 :     return ret;
     327             : }
     328             : 
     329           0 : int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type)
     330             : {
     331             :     int ret;
     332             :     union input inp;
     333             :     struct output out;
     334             : 
     335           0 :     if (id == NULL || id_type == NULL || sid == NULL || *sid == '\0') {
     336           0 :         return EINVAL;
     337             :     }
     338             : 
     339           0 :     inp.str = sid;
     340             : 
     341           0 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, &out);
     342           0 :     if (ret == EOK) {
     343           0 :         *id = out.d.id;
     344           0 :         *id_type = out.type;
     345             :     }
     346             : 
     347           0 :     return ret;
     348             : }
     349             : 
     350           1 : int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list,
     351             :                          enum sss_id_type *type)
     352             : {
     353             :     int ret;
     354             :     union input inp;
     355             :     struct output out;
     356             : 
     357           1 :     if (kv_list == NULL || fq_name == NULL || *fq_name == '\0') {
     358           0 :         return EINVAL;
     359             :     }
     360             : 
     361           1 :     inp.str = fq_name;
     362             : 
     363           1 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, &out);
     364           1 :     if (ret == EOK) {
     365           1 :         *kv_list = out.d.kv_list;
     366           1 :         *type = out.type;
     367             :     }
     368             : 
     369           1 :     return ret;
     370             : }

Generated by: LCOV version 1.10