LCOV - code coverage report
Current view: top level - providers/ldap - sdap_range.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 14 56 25.0 %
Date: 2016-06-29 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Authors:
       5             :         Stephen Gallagher <sgallagh@redhat.com>
       6             : 
       7             :     Copyright (C) 2012 Red Hat
       8             : 
       9             :     This program is free software; you can redistribute it and/or modify
      10             :     it under the terms of the GNU General Public License as published by
      11             :     the Free Software Foundation; either version 3 of the License, or
      12             :     (at your option) any later version.
      13             : 
      14             :     This program is distributed in the hope that it will be useful,
      15             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :     GNU General Public License for more details.
      18             : 
      19             :     You should have received a copy of the GNU General Public License
      20             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "providers/ldap/sdap_range.h"
      24             : #include "util/util.h"
      25             : #include "util/strtonum.h"
      26             : 
      27             : #define SDAP_RANGE_STRING "range="
      28             : 
      29          12 : errno_t sdap_parse_range(TALLOC_CTX *mem_ctx,
      30             :                          const char *attr_desc,
      31             :                          char **base_attr,
      32             :                          uint32_t *range_offset,
      33             :                          bool disable_range_retrieval)
      34             : {
      35             :     errno_t ret;
      36             :     TALLOC_CTX *tmp_ctx;
      37             :     char *endptr;
      38             :     char *end_range;
      39             :     char *base;
      40          12 :     size_t rangestringlen = sizeof(SDAP_RANGE_STRING) - 1;
      41             : 
      42          12 :     *range_offset = 0;
      43             : 
      44          12 :     tmp_ctx = talloc_new(NULL);
      45          12 :     if (!tmp_ctx) return ENOMEM;
      46             : 
      47             :     /* The base_attr is the portion before the semicolon (if it exists) */
      48          12 :     endptr = strchr(attr_desc, ';');
      49          12 :     if (endptr == NULL) {
      50             :         /* Not a ranged attribute. Just copy the attribute desc */
      51          12 :         *base_attr = talloc_strdup(mem_ctx, attr_desc);
      52          12 :         if (!*base_attr) {
      53           0 :             ret = ENOMEM;
      54             :         } else {
      55          12 :             ret = EOK;
      56             :         }
      57          12 :         DEBUG(SSSDBG_TRACE_INTERNAL,
      58             :               "No sub-attributes for [%s]\n", attr_desc);
      59          12 :         goto done;
      60             :     }
      61             : 
      62             :     /* This is a complex attribute. First get the base attribute name */
      63           0 :     base = talloc_strndup(tmp_ctx, attr_desc,
      64           0 :                           endptr - attr_desc);
      65           0 :     if (!base) {
      66           0 :         ret = ENOMEM;
      67           0 :         goto done;
      68             :     }
      69           0 :     DEBUG(SSSDBG_TRACE_LIBS,
      70             :           "Base attribute of [%s] is [%s]\n",
      71             :            attr_desc, base);
      72             : 
      73             :     /* Next, determine if this is a ranged attribute */
      74           0 :     if (strncmp(endptr+1, SDAP_RANGE_STRING, rangestringlen) != 0) {
      75             :         /* This is some other sub-attribute. We'll just return the whole
      76             :          * thing in case it's dealt with elsewhere.
      77             :          */
      78           0 :         *base_attr = talloc_strdup(mem_ctx, attr_desc);
      79           0 :         if (!*base_attr) {
      80           0 :             ret = ENOMEM;
      81             :         } else {
      82           0 :             ret = EOK;
      83             :         }
      84           0 :         DEBUG(SSSDBG_TRACE_LIBS,
      85             :               "[%s] contains sub-attribute other than a range, returning whole\n",
      86             :                attr_desc);
      87           0 :         goto done;
      88           0 :     } else if (disable_range_retrieval) {
      89             :         /* This is range sub-attribute, but we want to ignore it.
      90             :          */
      91           0 :         *base_attr = talloc_strdup(mem_ctx, attr_desc);
      92           0 :         if (!*base_attr) {
      93           0 :             ret = ENOMEM;
      94             :         } else {
      95           0 :             ret = ECANCELED;
      96             :         }
      97           0 :         goto done;
      98             :     }
      99             : 
     100             :     /* Get the end of the range */
     101           0 :     end_range = strchr(endptr + rangestringlen +1, '-');
     102           0 :     if (!end_range) {
     103           0 :         ret = EINVAL;
     104           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     105             :               "Cannot find hyphen in [%s]\n",
     106             :                endptr + rangestringlen +1);
     107           0 :         goto done;
     108             :     }
     109           0 :     end_range++; /* advance past the hyphen */
     110             : 
     111           0 :     if (*end_range == '*') {
     112             :         /* this was the last iteration of range retrievals */
     113           0 :         *base_attr = talloc_steal(mem_ctx, base);
     114           0 :         *range_offset = 0;
     115           0 :         DEBUG(SSSDBG_TRACE_LIBS,
     116             :               "[%s] contained the last set of values for this attribute\n",
     117             :                attr_desc);
     118           0 :         ret = EOK;
     119           0 :         goto done;
     120             :     }
     121             : 
     122           0 :     *range_offset = strtouint32(end_range, &endptr, 10);
     123           0 :     if (*endptr != '\0') {
     124           0 :         *range_offset = 0;
     125           0 :         ret = errno;
     126           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     127             :               "[%s] did not parse as an unsigned integer: [%s]\n",
     128             :                end_range, strerror(ret));
     129           0 :         goto done;
     130             :     }
     131           0 :     (*range_offset)++;
     132             : 
     133           0 :     *base_attr = talloc_steal(mem_ctx, base);
     134           0 :     DEBUG(SSSDBG_TRACE_LIBS,
     135             :           "Parsed range values: [%s][%d]\n",
     136             :            base, *range_offset);
     137             : 
     138           0 :     ret = EAGAIN;
     139             : done:
     140          12 :     talloc_free(tmp_ctx);
     141          12 :     return ret;
     142             : }

Generated by: LCOV version 1.10