LCOV - code coverage report
Current view: top level - sss_client/idmap - sss_nss_idmap.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 83 163 50.9 %
Date: 2016-06-29 Functions: 5 10 50.0 %

          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             :     case SSS_NSS_GETNAMEBYCERT:
     163           5 :         ret = sss_strnlen(inp.str, 2048, &inp_len);
     164           5 :         if (ret != EOK) {
     165           0 :             return EINVAL;
     166             :         }
     167             : 
     168           5 :         rd.len = inp_len + 1;
     169           5 :         rd.data = inp.str;
     170             : 
     171           5 :         break;
     172             :     case SSS_NSS_GETSIDBYID:
     173           0 :         rd.len = sizeof(uint32_t);
     174           0 :         rd.data = &inp.id;
     175             : 
     176           0 :         break;
     177             :     default:
     178           0 :         return EINVAL;
     179             :     }
     180             : 
     181           5 :     sss_nss_lock();
     182             : 
     183           5 :     nret = sss_nss_make_request(cmd, &rd, &repbuf, &replen, &errnop);
     184           5 :     if (nret != NSS_STATUS_SUCCESS) {
     185           0 :         ret = nss_status_to_errno(nret);
     186           0 :         goto done;
     187             :     }
     188             : 
     189           5 :     if (replen < 8) {
     190           0 :         ret = EBADMSG;
     191           0 :         goto done;
     192             :     }
     193             : 
     194           5 :     SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL);
     195           5 :     if (num_results == 0) {
     196           0 :         ret = ENOENT;
     197           0 :         goto done;
     198           5 :     } else if (num_results > 1) {
     199           0 :         ret = EBADMSG;
     200           0 :         goto done;
     201             :     }
     202             : 
     203             :     /* Skip first two 32 bit values (number of results and
     204             :      * reserved padding) */
     205           5 :     SAFEALIGN_COPY_UINT32(&out->type, repbuf + 2 * sizeof(uint32_t), NULL);
     206             : 
     207           5 :     data_len = replen - DATA_START;
     208             : 
     209           5 :     switch(cmd) {
     210             :     case SSS_NSS_GETSIDBYID:
     211             :     case SSS_NSS_GETSIDBYNAME:
     212             :     case SSS_NSS_GETNAMEBYSID:
     213             :     case SSS_NSS_GETNAMEBYCERT:
     214           4 :         if (data_len <= 1 || repbuf[replen - 1] != '\0') {
     215           0 :             ret = EBADMSG;
     216           0 :             goto done;
     217             :         }
     218             : 
     219           4 :         str = malloc(sizeof(char) * data_len);
     220           4 :         if (str == NULL) {
     221           0 :             ret = ENOMEM;
     222           0 :             goto done;
     223             :         }
     224             : 
     225           4 :         strncpy(str, (char *) repbuf + DATA_START, data_len);
     226             : 
     227           4 :         out->d.str = str;
     228             : 
     229           4 :         break;
     230             :     case SSS_NSS_GETIDBYSID:
     231           0 :         if (data_len != sizeof(uint32_t)) {
     232           0 :             ret = EBADMSG;
     233           0 :             goto done;
     234             :         }
     235             : 
     236           0 :         SAFEALIGN_COPY_UINT32(&c, repbuf + DATA_START, NULL);
     237           0 :         out->d.id = c;
     238             : 
     239           0 :         break;
     240             :     case SSS_NSS_GETORIGBYNAME:
     241           1 :         ret = buf_to_kv_list(repbuf + DATA_START, data_len, &kv_list);
     242           1 :         if (ret != EOK) {
     243           0 :             goto done;
     244             :         }
     245             : 
     246           1 :         out->d.kv_list = kv_list;
     247             : 
     248           1 :         break;
     249             :     default:
     250           0 :         ret = EINVAL;
     251           0 :         goto done;
     252             :     }
     253             : 
     254           5 :     ret = EOK;
     255             : 
     256             : done:
     257           5 :     sss_nss_unlock();
     258           5 :     free(repbuf);
     259           5 :     if (ret != EOK) {
     260           0 :         free(str);
     261             :     }
     262             : 
     263           5 :     return ret;
     264             : }
     265             : 
     266           7 : int sss_nss_getsidbyname(const char *fq_name, char **sid,
     267             :                          enum sss_id_type *type)
     268             : {
     269             :     int ret;
     270             :     union input inp;
     271             :     struct output out;
     272             : 
     273           7 :     if (sid == NULL || fq_name == NULL || *fq_name == '\0') {
     274           3 :         return EINVAL;
     275             :     }
     276             : 
     277           4 :     inp.str = fq_name;
     278             : 
     279           4 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, &out);
     280           4 :     if (ret == EOK) {
     281           4 :         *sid = out.d.str;
     282           4 :         *type = out.type;
     283             :     }
     284             : 
     285           4 :     return ret;
     286             : }
     287             : 
     288           0 : int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type)
     289             : {
     290             :     int ret;
     291             :     union input inp;
     292             :     struct output out;
     293             : 
     294           0 :     if (sid == NULL) {
     295           0 :         return EINVAL;
     296             :     }
     297             : 
     298           0 :     inp.id = id;
     299             : 
     300           0 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, &out);
     301           0 :     if (ret == EOK) {
     302           0 :         *sid = out.d.str;
     303           0 :         *type = out.type;
     304             :     }
     305             : 
     306           0 :     return ret;
     307             : }
     308             : 
     309           0 : int sss_nss_getnamebysid(const char *sid, char **fq_name,
     310             :                          enum sss_id_type *type)
     311             : {
     312             :     int ret;
     313             :     union input inp;
     314             :     struct output out;
     315             : 
     316           0 :     if (fq_name == NULL || sid == NULL || *sid == '\0') {
     317           0 :         return EINVAL;
     318             :     }
     319             : 
     320           0 :     inp.str = sid;
     321             : 
     322           0 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, &out);
     323           0 :     if (ret == EOK) {
     324           0 :         *fq_name = out.d.str;
     325           0 :         *type = out.type;
     326             :     }
     327             : 
     328           0 :     return ret;
     329             : }
     330             : 
     331           0 : int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type)
     332             : {
     333             :     int ret;
     334             :     union input inp;
     335             :     struct output out;
     336             : 
     337           0 :     if (id == NULL || id_type == NULL || sid == NULL || *sid == '\0') {
     338           0 :         return EINVAL;
     339             :     }
     340             : 
     341           0 :     inp.str = sid;
     342             : 
     343           0 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, &out);
     344           0 :     if (ret == EOK) {
     345           0 :         *id = out.d.id;
     346           0 :         *id_type = out.type;
     347             :     }
     348             : 
     349           0 :     return ret;
     350             : }
     351             : 
     352           1 : int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list,
     353             :                          enum sss_id_type *type)
     354             : {
     355             :     int ret;
     356             :     union input inp;
     357             :     struct output out;
     358             : 
     359           1 :     if (kv_list == NULL || fq_name == NULL || *fq_name == '\0') {
     360           0 :         return EINVAL;
     361             :     }
     362             : 
     363           1 :     inp.str = fq_name;
     364             : 
     365           1 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, &out);
     366           1 :     if (ret == EOK) {
     367           1 :         *kv_list = out.d.kv_list;
     368           1 :         *type = out.type;
     369             :     }
     370             : 
     371           1 :     return ret;
     372             : }
     373             : 
     374           0 : int sss_nss_getnamebycert(const char *cert, char **fq_name,
     375             :                           enum sss_id_type *type)
     376             : {
     377             :     int ret;
     378             :     union input inp;
     379             :     struct output out;
     380             : 
     381           0 :     if (fq_name == NULL || cert == NULL || *cert == '\0') {
     382           0 :         return EINVAL;
     383             :     }
     384             : 
     385           0 :     inp.str = cert;
     386             : 
     387           0 :     ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYCERT, &out);
     388           0 :     if (ret == EOK) {
     389           0 :         *fq_name = out.d.str;
     390           0 :         *type = out.type;
     391             :     }
     392             : 
     393           0 :     return ret;
     394             : }

Generated by: LCOV version 1.10