LCOV - code coverage report
Current view: top level - util - util.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 209 287 72.8 %
Date: 2012-11-29 Functions: 6 15 40.0 %
Branches: 126 234 53.8 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :     Authors:
       3                 :            :         Simo Sorce <ssorce@redhat.com>
       4                 :            : 
       5                 :            :     Copyright (C) 2009 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 <ctype.h>
      22                 :            : #include <netdb.h>
      23                 :            : #include <poll.h>
      24                 :            : 
      25                 :            : #include "talloc.h"
      26                 :            : #include "util/util.h"
      27                 :            : #include "util/sss_utf8.h"
      28                 :            : #include "dhash.h"
      29                 :            : 
      30                 :            : /* split a string into an allocated array of strings.
      31                 :            :  * the separator is a string, and is case-sensitive.
      32                 :            :  * optionally single values can be trimmed of of spaces and tabs */
      33                 :        655 : int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
      34                 :            :                        const char sep, bool trim, char ***_list, int *size)
      35                 :            : {
      36                 :            :     const char *t, *p, *n;
      37                 :            :     size_t l, len;
      38                 :            :     char **list, **r;
      39                 :        655 :     const char sep_str[2] = { sep, '\0'};
      40                 :            : 
      41 [ +  + ][ +  + ]:        655 :     if (!str || !*str || !_list) return EINVAL;
                 [ +  - ]
      42                 :            : 
      43                 :        653 :     t = str;
      44                 :            : 
      45                 :        653 :     list = NULL;
      46                 :        653 :     l = 0;
      47                 :            : 
      48                 :            :     /* trim leading whitespace */
      49         [ +  - ]:        653 :     if (trim)
      50         [ -  + ]:        653 :         while (isspace(*t)) t++;
      51                 :            : 
      52                 :            :     /* find substrings separated by the separator */
      53 [ +  - ][ +  + ]:        677 :     while (t && (p = strpbrk(t, sep_str))) {
      54                 :         24 :         len = p - t;
      55                 :         24 :         n = p + 1; /* save next string starting point */
      56         [ +  - ]:         24 :         if (trim) {
      57                 :            :             /* strip whitespace after the separator
      58                 :            :              * so it's not in the next token */
      59         [ +  + ]:         35 :             while (isspace(*t)) {
      60                 :         11 :                 t++;
      61                 :         11 :                 len--;
      62         [ +  - ]:         35 :                 if (len == 0) break;
      63                 :            :             }
      64                 :         24 :             p--;
      65                 :            :             /* strip whitespace before the separator
      66                 :            :              * so it's not in the current token */
      67 [ +  - ][ +  + ]:         27 :             while (len > 0 && (isspace(*p))) {
      68                 :          3 :                 len--;
      69                 :          3 :                 p--;
      70                 :            :             }
      71                 :            :         }
      72                 :            : 
      73                 :            :         /* Add the token to the array, +2 b/c of the trailing NULL */
      74                 :         24 :         r = talloc_realloc(mem_ctx, list, char *, l + 2);
      75         [ -  + ]:         24 :         if (!r) {
      76                 :          0 :             talloc_free(list);
      77                 :            :             return ENOMEM;
      78                 :            :         } else {
      79                 :         24 :             list = r;
      80                 :            :         }
      81                 :            : 
      82         [ -  + ]:         24 :         if (len == 0) {
      83                 :          0 :             list[l] = talloc_strdup(list, "");
      84                 :            :         } else {
      85                 :         24 :             list[l] = talloc_strndup(list, t, len);
      86                 :            :         }
      87         [ -  + ]:         24 :         if (!list[l]) {
      88                 :          0 :             talloc_free(list);
      89                 :            :             return ENOMEM;
      90                 :            :         }
      91                 :         24 :         l++;
      92                 :            : 
      93                 :         24 :         t = n; /* move to next string */
      94                 :            :     }
      95                 :            : 
      96                 :            :     /* Handle the last remaining token */
      97         [ +  - ]:        653 :     if (t) {
      98                 :        653 :         r = talloc_realloc(mem_ctx, list, char *, l + 2);
      99         [ -  + ]:        653 :         if (!r) {
     100                 :          0 :             talloc_free(list);
     101                 :            :             return ENOMEM;
     102                 :            :         } else {
     103                 :        653 :             list = r;
     104                 :            :         }
     105                 :            : 
     106         [ +  - ]:        653 :         if (trim) {
     107                 :            :             /* trim leading whitespace */
     108                 :        653 :             len = strlen(t);
     109         [ +  + ]:        658 :             while (isspace(*t)) {
     110                 :          5 :                 t++;
     111                 :          5 :                 len--;
     112         [ +  - ]:          5 :                 if (len == 0) break;
     113                 :            :             }
     114                 :            :             /* trim trailing whitespace */
     115                 :        653 :             p = t + len - 1;
     116 [ +  + ][ +  + ]:        655 :             while (len > 0 && (isspace(*p))) {
     117                 :          2 :                 len--;
     118                 :          2 :                 p--;
     119                 :            :             }
     120                 :            : 
     121         [ +  + ]:        653 :             if (len == 0) {
     122                 :          1 :                 list[l] = talloc_strdup(list, "");
     123                 :            :             } else {
     124                 :        652 :                 list[l] = talloc_strndup(list, t, len);
     125                 :            :             }
     126                 :            :         } else {
     127                 :          0 :             list[l] = talloc_strdup(list, t);
     128                 :            :         }
     129         [ -  + ]:        653 :         if (!list[l]) {
     130                 :          0 :             talloc_free(list);
     131                 :            :             return ENOMEM;
     132                 :            :         }
     133                 :        653 :         l++;
     134                 :            :     }
     135                 :            : 
     136                 :        653 :     list[l] = NULL; /* terminate list */
     137                 :            : 
     138         [ +  + ]:        653 :     if (size) *size = l;
     139                 :        655 :     *_list = list;
     140                 :            : 
     141                 :            :     return EOK;
     142                 :            : }
     143                 :            : 
     144                 :          0 : static void free_args(char **args)
     145                 :            : {
     146                 :            :     int i;
     147                 :            : 
     148         [ #  # ]:          0 :     if (args) {
     149         [ #  # ]:          0 :         for (i = 0; args[i]; i++) free(args[i]);
     150                 :          0 :         free(args);
     151                 :            :     }
     152                 :          0 : }
     153                 :            : 
     154                 :            : /* parse a string into arguments.
     155                 :            :  * arguments are separated by a space
     156                 :            :  * '\' is an escape character and can be used only to escape
     157                 :            :  * itself or the white space.
     158                 :            :  */
     159                 :          8 : char **parse_args(const char *str)
     160                 :            : {
     161                 :            :     const char *p;
     162                 :            :     char **ret, **r;
     163                 :            :     char *tmp;
     164                 :            :     int num;
     165                 :            :     int i;
     166                 :            :     bool e, w;
     167                 :            : 
     168                 :          8 :     tmp = malloc(strlen(str) + 1);
     169         [ +  - ]:          8 :     if (!tmp) return NULL;
     170                 :            : 
     171                 :            :     ret = NULL;
     172                 :            :     num = 0;
     173                 :            :     i = 0;
     174                 :            :     e = false;
     175                 :            :     w = false;
     176                 :            :     p = str;
     177         [ +  + ]:         71 :     while (*p) {
     178         [ +  + ]:         63 :         if (*p == '\\') {
     179                 :          2 :             w = false;
     180         [ -  + ]:          2 :             if (e) {
     181                 :            :                 /* if we were already escaping, add a '\' literal */
     182                 :          0 :                 tmp[i] = '\\';
     183                 :          0 :                 i++;
     184                 :          0 :                 e = false;
     185                 :            :             } else {
     186                 :            :                 /* otherwise just start escaping */
     187                 :            :                 e = true;
     188                 :            :             }
     189         [ +  + ]:         61 :         } else if (isspace(*p)) {
     190         [ +  + ]:         25 :             if (e) {
     191                 :            :                 /* Add escaped whitespace literally */
     192                 :          2 :                 tmp[i] = *p;
     193                 :          2 :                 i++;
     194                 :          2 :                 e = false;
     195         [ +  + ]:         23 :             } else if (w == false) {
     196                 :            :                 /* If previous character was non-whitespace, arg break */
     197                 :         13 :                 tmp[i] = '\0';
     198                 :         13 :                 i++;
     199                 :         13 :                 w = true;
     200                 :            :             }
     201                 :            :             /* previous char was whitespace as well, skip it */
     202                 :            :         } else {
     203                 :         36 :             w = false;
     204         [ -  + ]:         36 :             if (e) {
     205                 :            :                 /* Prepend escaped chars with a literal \ */
     206                 :          0 :                 tmp[i] = '\\';
     207                 :          0 :                 i++;
     208                 :          0 :                 e = false;
     209                 :            :             }
     210                 :            :             /* Copy character from the source string */
     211                 :         36 :             tmp[i] = *p;
     212                 :         36 :             i++;
     213                 :            :         }
     214                 :            : 
     215                 :         63 :         p++;
     216                 :            : 
     217                 :            :         /* check if this was the last char */
     218         [ +  + ]:         63 :         if (*p == '\0') {
     219         [ -  + ]:          8 :             if (e) {
     220                 :          0 :                 tmp[i] = '\\';
     221                 :          0 :                 i++;
     222                 :          0 :                 e = false;
     223                 :            :             }
     224                 :          8 :             tmp[i] = '\0';
     225                 :          8 :             i++;
     226                 :            :         }
     227 [ +  + ][ +  + ]:         63 :         if (tmp[i-1] != '\0' || strlen(tmp) == 0) {
     228                 :            :             /* check next char and skip multiple spaces */
     229                 :         37 :             continue;
     230                 :            :         }
     231                 :            : 
     232                 :         26 :         r = realloc(ret, (num + 2) * sizeof(char *));
     233         [ +  - ]:         26 :         if (!r) goto fail;
     234                 :         26 :         ret = r;
     235                 :         26 :         ret[num+1] = NULL;
     236                 :         26 :         ret[num] = strdup(tmp);
     237         [ +  - ]:         26 :         if (!ret[num]) goto fail;
     238                 :         26 :         num++;
     239                 :         63 :         i = 0;
     240                 :            :     }
     241                 :            : 
     242                 :          8 :     free(tmp);
     243                 :          8 :     return ret;
     244                 :            : 
     245                 :            : fail:
     246                 :          0 :     free(tmp);
     247                 :          0 :     free_args(ret);
     248                 :          8 :     return NULL;
     249                 :            : }
     250                 :            : 
     251                 :          0 : char **dup_string_list(TALLOC_CTX *memctx, const char **str_list)
     252                 :            : {
     253                 :          0 :     int i = 0;
     254                 :          0 :     int j = 0;
     255                 :            :     char **dup_list;
     256                 :            : 
     257         [ #  # ]:          0 :     if (!str_list) {
     258                 :            :         return NULL;
     259                 :            :     }
     260                 :            : 
     261                 :            :     /* Find the size of the list */
     262         [ #  # ]:          0 :     while (str_list[i]) i++;
     263                 :            : 
     264                 :          0 :     dup_list = talloc_array(memctx, char *, i+1);
     265         [ #  # ]:          0 :     if (!dup_list) {
     266                 :            :         return NULL;
     267                 :            :     }
     268                 :            : 
     269                 :            :     /* Copy the elements */
     270         [ #  # ]:          0 :     for (j = 0; j < i; j++) {
     271                 :          0 :         dup_list[j] = talloc_strdup(dup_list, str_list[j]);
     272         [ #  # ]:          0 :         if (!dup_list[j]) {
     273                 :          0 :             talloc_free(dup_list);
     274                 :          0 :             return NULL;
     275                 :            :         }
     276                 :            :     }
     277                 :            : 
     278                 :            :     /* NULL-terminate the list */
     279                 :          0 :     dup_list[i] = NULL;
     280                 :            : 
     281                 :          0 :     return dup_list;
     282                 :            : }
     283                 :            : 
     284                 :            : /* Take two string lists (terminated on a NULL char*)
     285                 :            :  * and return up to three arrays of strings based on
     286                 :            :  * shared ownership.
     287                 :            :  *
     288                 :            :  * Pass NULL to any return type you don't care about
     289                 :            :  */
     290                 :         15 : errno_t diff_string_lists(TALLOC_CTX *memctx,
     291                 :            :                           char **_list1,
     292                 :            :                           char **_list2,
     293                 :            :                           char ***_list1_only,
     294                 :            :                           char ***_list2_only,
     295                 :            :                           char ***_both_lists)
     296                 :            : {
     297                 :            :     int error;
     298                 :            :     errno_t ret;
     299                 :            :     int i;
     300                 :         15 :     int i2 = 0;
     301                 :         15 :     int i12 = 0;
     302                 :            :     hash_table_t *table;
     303                 :            :     hash_key_t key;
     304                 :            :     hash_value_t value;
     305                 :         15 :     char **list1 = NULL;
     306                 :         15 :     char **list2 = NULL;
     307                 :         15 :     char **list1_only = NULL;
     308                 :         15 :     char **list2_only = NULL;
     309                 :         15 :     char **both_lists = NULL;
     310                 :            :     unsigned long count;
     311                 :            :     hash_key_t *keys;
     312                 :            : 
     313                 :         15 :     TALLOC_CTX *tmp_ctx = talloc_new(memctx);
     314         [ +  - ]:         15 :     if (!tmp_ctx) {
     315                 :            :         return ENOMEM;
     316                 :            :     }
     317                 :            : 
     318         [ -  + ]:         15 :     if (!_list1) {
     319                 :          0 :         list1 = talloc_array(tmp_ctx, char *, 1);
     320         [ #  # ]:          0 :         if (!list1) {
     321                 :          0 :             talloc_free(tmp_ctx);
     322                 :            :             return ENOMEM;
     323                 :            :         }
     324                 :          0 :         list1[0] = NULL;
     325                 :            :     }
     326                 :            :     else {
     327                 :            :         list1 = _list1;
     328                 :            :     }
     329                 :            : 
     330         [ +  + ]:         15 :     if (!_list2) {
     331                 :          1 :         list2 = talloc_array(tmp_ctx, char *, 1);
     332         [ -  + ]:          1 :         if (!list2) {
     333                 :          0 :             talloc_free(tmp_ctx);
     334                 :            :             return ENOMEM;
     335                 :            :         }
     336                 :          1 :         list2[0] = NULL;
     337                 :            :     }
     338                 :            :     else {
     339                 :            :         list2 = _list2;
     340                 :            :     }
     341                 :            : 
     342                 :         15 :     error = hash_create(10, &table, NULL, NULL);
     343         [ -  + ]:         15 :     if (error != HASH_SUCCESS) {
     344                 :          0 :         talloc_free(tmp_ctx);
     345                 :            :         return EIO;
     346                 :            :     }
     347                 :            : 
     348                 :         15 :     key.type = HASH_KEY_STRING;
     349                 :         15 :     value.type = HASH_VALUE_UNDEF;
     350                 :            : 
     351                 :            :     /* Add all entries from list 1 into a hash table */
     352                 :         15 :     i = 0;
     353         [ +  + ]:         62 :     while (list1[i]) {
     354                 :         47 :         key.str = talloc_strdup(tmp_ctx, list1[i]);
     355                 :         47 :         error = hash_enter(table, &key, &value);
     356         [ +  - ]:         47 :         if (error != HASH_SUCCESS) {
     357                 :            :             ret = EIO;
     358                 :            :             goto done;
     359                 :            :         }
     360                 :         47 :         i++;
     361                 :            :     }
     362                 :            : 
     363                 :            :     /* Iterate through list 2 and remove matching items */
     364                 :            :     i = 0;
     365         [ +  + ]:         51 :     while (list2[i]) {
     366                 :         36 :         key.str = talloc_strdup(tmp_ctx, list2[i]);
     367                 :         36 :         error = hash_delete(table, &key);
     368         [ +  + ]:         36 :         if (error == HASH_SUCCESS) {
     369         [ +  + ]:         29 :             if (_both_lists) {
     370                 :            :                 /* String was present in both lists */
     371                 :         23 :                 i12++;
     372                 :         23 :                 both_lists = talloc_realloc(tmp_ctx, both_lists, char *, i12+1);
     373         [ +  - ]:         23 :                 if (!both_lists) {
     374                 :            :                     ret = ENOMEM;
     375                 :            :                     goto done;
     376                 :            :                 }
     377                 :         23 :                 both_lists[i12-1] = talloc_strdup(both_lists, list2[i]);
     378         [ +  - ]:         23 :                 if (!both_lists[i12-1]) {
     379                 :            :                     ret = ENOMEM;
     380                 :            :                     goto done;
     381                 :            :                 }
     382                 :            : 
     383                 :         23 :                 both_lists[i12] = NULL;
     384                 :            :             }
     385                 :            :         }
     386         [ +  - ]:          7 :         else if (error == HASH_ERROR_KEY_NOT_FOUND) {
     387         [ +  + ]:          7 :             if (_list2_only) {
     388                 :            :                 /* String was present only in list2 */
     389                 :          6 :                 i2++;
     390                 :          6 :                 list2_only = talloc_realloc(tmp_ctx, list2_only,
     391                 :            :                                             char *, i2+1);
     392         [ +  - ]:          6 :                 if (!list2_only) {
     393                 :            :                     ret = ENOMEM;
     394                 :            :                     goto done;
     395                 :            :                 }
     396                 :          6 :                 list2_only[i2-1] = talloc_strdup(list2_only, list2[i]);
     397         [ +  - ]:          6 :                 if (!list2_only[i2-1]) {
     398                 :            :                     ret = ENOMEM;
     399                 :            :                     goto done;
     400                 :            :                 }
     401                 :            : 
     402                 :          6 :                 list2_only[i2] = NULL;
     403                 :            :             }
     404                 :            :         }
     405                 :            :         else {
     406                 :            :             /* An error occurred */
     407                 :            :             ret = EIO;
     408                 :            :             goto done;
     409                 :            :         }
     410                 :         36 :         i++;
     411                 :            :     }
     412                 :            : 
     413                 :            :     /* Get the leftover entries in the hash table */
     414         [ +  + ]:         15 :     if (_list1_only) {
     415                 :         14 :         error = hash_keys(table, &count, &keys);
     416         [ +  - ]:         14 :         if (error != HASH_SUCCESS) {
     417                 :            :             ret = EIO;
     418                 :            :             goto done;
     419                 :            :         }
     420                 :            : 
     421                 :         14 :         list1_only = talloc_array(tmp_ctx, char *, count+1);
     422         [ +  - ]:         14 :         if (!list1_only) {
     423                 :            :             ret = ENOMEM;
     424                 :            :             goto done;
     425                 :            :         }
     426                 :            : 
     427         [ +  + ]:         23 :         for (i = 0; i < count; i++) {
     428                 :          9 :             list1_only[i] = talloc_strdup(list1_only, keys[i].str);
     429         [ +  - ]:          9 :             if (!list1_only[i]) {
     430                 :            :                 ret = ENOMEM;
     431                 :            :                 goto done;
     432                 :            :             }
     433                 :            :         }
     434                 :         14 :         list1_only[count] = NULL;
     435                 :            : 
     436                 :         14 :         free(keys);
     437                 :            : 
     438                 :         14 :         *_list1_only = talloc_steal(memctx, list1_only);
     439                 :            :     }
     440                 :            : 
     441         [ +  + ]:         15 :     if (_list2_only) {
     442         [ +  + ]:         14 :         if (list2_only) {
     443                 :          4 :             *_list2_only = talloc_steal(memctx, list2_only);
     444                 :            :         }
     445                 :            :         else {
     446                 :         10 :             *_list2_only = talloc_array(memctx, char *, 1);
     447         [ +  - ]:         10 :             if (!(*_list2_only)) {
     448                 :            :                 ret = ENOMEM;
     449                 :            :                 goto done;
     450                 :            :             }
     451                 :         10 :             *_list2_only[0] = NULL;
     452                 :            :         }
     453                 :            :     }
     454                 :            : 
     455         [ +  + ]:         15 :     if (_both_lists) {
     456         [ +  + ]:         12 :         if (both_lists) {
     457                 :         10 :             *_both_lists = talloc_steal(memctx, both_lists);
     458                 :            :         }
     459                 :            :         else {
     460                 :          2 :             *_both_lists = talloc_array(memctx, char *, 1);
     461         [ +  - ]:          2 :             if (!(*_both_lists)) {
     462                 :            :                 ret = ENOMEM;
     463                 :            :                 goto done;
     464                 :            :             }
     465                 :          2 :             *_both_lists[0] = NULL;
     466                 :            :         }
     467                 :            :     }
     468                 :            : 
     469                 :            :     ret = EOK;
     470                 :            : 
     471                 :            : done:
     472                 :         15 :     hash_destroy(table);
     473                 :         15 :     talloc_free(tmp_ctx);
     474                 :            :     return ret;
     475                 :            : }
     476                 :            : 
     477                 :          0 : static void *hash_talloc(const size_t size, void *pvt)
     478                 :            : {
     479                 :          0 :     return talloc_size(pvt, size);
     480                 :            : }
     481                 :            : 
     482                 :          0 : static void hash_talloc_free(void *ptr, void *pvt)
     483                 :            : {
     484                 :          0 :     talloc_free(ptr);
     485                 :          0 : }
     486                 :            : 
     487                 :          0 : errno_t sss_hash_create_ex(TALLOC_CTX *mem_ctx,
     488                 :            :                            unsigned long count,
     489                 :            :                            hash_table_t **tbl,
     490                 :            :                            unsigned int directory_bits,
     491                 :            :                            unsigned int segment_bits,
     492                 :            :                            unsigned long min_load_factor,
     493                 :            :                            unsigned long max_load_factor,
     494                 :            :                            hash_delete_callback *delete_callback,
     495                 :            :                            void *delete_private_data)
     496                 :            : {
     497                 :            :     errno_t ret;
     498                 :            :     hash_table_t *table;
     499                 :            :     int hret;
     500                 :            : 
     501                 :            :     TALLOC_CTX *internal_ctx;
     502                 :          0 :     internal_ctx = talloc_new(NULL);
     503         [ #  # ]:          0 :     if (!internal_ctx) {
     504                 :            :         return ENOMEM;
     505                 :            :     }
     506                 :            : 
     507                 :          0 :     hret = hash_create_ex(count, &table, directory_bits, segment_bits,
     508                 :            :                           min_load_factor, max_load_factor,
     509                 :            :                           hash_talloc, hash_talloc_free, internal_ctx,
     510                 :            :                           delete_callback, delete_private_data);
     511      [ #  #  # ]:          0 :     switch (hret) {
     512                 :            :     case HASH_SUCCESS:
     513                 :            :         /* Steal the table pointer onto the mem_ctx,
     514                 :            :          * then make the internal_ctx a child of
     515                 :            :          * table.
     516                 :            :          *
     517                 :            :          * This way, we can clean up the values when
     518                 :            :          * we talloc_free() the table
     519                 :            :          */
     520                 :          0 :         *tbl = talloc_steal(mem_ctx, table);
     521                 :          0 :         talloc_steal(table, internal_ctx);
     522                 :            :         return EOK;
     523                 :            : 
     524                 :            :     case HASH_ERROR_NO_MEMORY:
     525                 :            :         ret = ENOMEM;
     526                 :            :         break;
     527                 :            :     default:
     528                 :          0 :         ret = EIO;
     529                 :            :     }
     530                 :            : 
     531 [ #  # ][ #  # ]:          0 :     DEBUG(0, ("Could not create hash table: [%d][%s]\n",
         [ #  # ][ #  # ]
                 [ #  # ]
     532                 :            :               hret, hash_error_string(hret)));
     533                 :            : 
     534                 :          0 :     talloc_free(internal_ctx);
     535                 :            :     return ret;
     536                 :            : }
     537                 :            : 
     538                 :          0 : errno_t sss_hash_create(TALLOC_CTX *mem_ctx, unsigned long count,
     539                 :            :                         hash_table_t **tbl)
     540                 :            : {
     541                 :          0 :     return sss_hash_create_ex(mem_ctx, count, tbl, 0, 0, 0, 0, NULL, NULL);
     542                 :            : }
     543                 :            : 
     544                 :        438 : errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
     545                 :            :                             const char *input,
     546                 :            :                             char **sanitized)
     547                 :            : {
     548                 :            :     char *output;
     549                 :        438 :     size_t i = 0;
     550                 :        438 :     size_t j = 0;
     551                 :            : 
     552                 :            :     /* Assume the worst-case. We'll resize it later, once */
     553                 :        438 :     output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1);
     554         [ +  - ]:        438 :     if (!output) {
     555                 :            :         return ENOMEM;
     556                 :            :     }
     557                 :            : 
     558         [ +  + ]:      15475 :     while (input[i]) {
     559   [ +  +  +  +  :      15037 :         switch(input[i]) {
                      + ]
     560                 :            :         case '*':
     561                 :         13 :             output[j++] = '\\';
     562                 :         13 :             output[j++] = '2';
     563                 :         13 :             output[j++] = 'a';
     564                 :         13 :             break;
     565                 :            :         case '(':
     566                 :          9 :             output[j++] = '\\';
     567                 :          9 :             output[j++] = '2';
     568                 :          9 :             output[j++] = '8';
     569                 :          9 :             break;
     570                 :            :         case ')':
     571                 :          9 :             output[j++] = '\\';
     572                 :          9 :             output[j++] = '2';
     573                 :          9 :             output[j++] = '9';
     574                 :          9 :             break;
     575                 :            :         case '\\':
     576                 :         18 :             output[j++] = '\\';
     577                 :         18 :             output[j++] = '5';
     578                 :         18 :             output[j++] = 'c';
     579                 :         18 :             break;
     580                 :            :         default:
     581                 :      14988 :             output[j++] = input[i];
     582                 :            :         }
     583                 :            : 
     584                 :      15037 :         i++;
     585                 :            :     }
     586                 :        438 :     output[j] = '\0';
     587                 :        438 :     *sanitized = talloc_realloc(mem_ctx, output, char, j+1);
     588         [ -  + ]:        438 :     if (!*sanitized) {
     589                 :          0 :         talloc_free(output);
     590                 :        438 :         return ENOMEM;
     591                 :            :     }
     592                 :            : 
     593                 :            :     return EOK;
     594                 :            : }
     595                 :            : 
     596                 :            : char *
     597                 :          0 : sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr)
     598                 :            : {
     599         [ #  # ]:          0 :     return family == AF_INET6 ? talloc_asprintf(mem_ctx, "[%s]", addr) :
     600                 :            :                                 talloc_strdup(mem_ctx, addr);
     601                 :            : }
     602                 :            : 
     603                 :            : /* out->len includes terminating '\0' */
     604                 :          0 : void to_sized_string(struct sized_string *out, const char *in)
     605                 :            : {
     606                 :          0 :     out->str = in;
     607         [ #  # ]:          0 :     if (out->str) {
     608                 :          0 :         out->len = strlen(out->str) + 1;
     609                 :            :     } else {
     610                 :          0 :         out->len = 0;
     611                 :            :     }
     612                 :          0 : }
     613                 :            : 
     614                 :            : /* This function only removes first and last
     615                 :            :  * character if the first character was '['.
     616                 :            :  *
     617                 :            :  * NOTE: This means, that ipv6addr must NOT be followed
     618                 :            :  * by port number.
     619                 :            :  */
     620                 :            : errno_t
     621                 :          0 : remove_ipv6_brackets(char *ipv6addr)
     622                 :            : {
     623                 :            :     size_t len;
     624                 :            : 
     625 [ #  # ][ #  # ]:          0 :     if (ipv6addr && ipv6addr[0] == '[') {
     626                 :          0 :         len = strlen(ipv6addr);
     627         [ #  # ]:          0 :         if (len < 3) {
     628                 :            :             return EINVAL;
     629                 :            :         }
     630                 :            : 
     631                 :          0 :         memmove(ipv6addr, &ipv6addr[1], len - 2);
     632                 :          0 :         ipv6addr[len -2] = '\0';
     633                 :            :     }
     634                 :            : 
     635                 :            :     return EOK;
     636                 :            : }
     637                 :            : 
     638                 :          4 : errno_t add_string_to_list(TALLOC_CTX *mem_ctx, const char *string,
     639                 :            :                            char ***list_p)
     640                 :            : {
     641                 :            :     size_t c;
     642                 :          4 :     char **old_list = NULL;
     643                 :          4 :     char **new_list = NULL;
     644                 :            : 
     645         [ +  + ]:          4 :     if (string == NULL || list_p == NULL) {
     646 [ +  - ][ +  - ]:          1 :         DEBUG(SSSDBG_OP_FAILURE, ("Missing string or list.\n"));
         [ -  + ][ #  # ]
                 [ #  # ]
     647                 :            :         return EINVAL;
     648                 :            :     }
     649                 :            : 
     650                 :          3 :     old_list = *list_p;
     651                 :            : 
     652         [ +  + ]:          3 :     if (old_list == NULL) {
     653                 :            :         /* If the input is a NULL list a new one is created with the new
     654                 :            :          * string and the terminating NULL element. */
     655                 :          1 :         c = 0;
     656                 :          1 :         new_list = talloc_array(mem_ctx, char *, 2);
     657                 :            :     } else {
     658         [ +  + ]:          3 :         for (c = 0; old_list[c] != NULL; c++);
     659                 :            :         /* Allocate one extra space for the new service and one for
     660                 :            :          * the terminating NULL
     661                 :            :          */
     662                 :          2 :         new_list = talloc_realloc(mem_ctx, old_list, char *, c + 2);
     663                 :            :     }
     664                 :            : 
     665         [ -  + ]:          3 :     if (new_list == NULL) {
     666 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_OP_FAILURE, ("talloc_array/talloc_realloc failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     667                 :            :         return ENOMEM;
     668                 :            :     }
     669                 :            : 
     670                 :          3 :     new_list[c] = talloc_strdup(new_list, string);
     671         [ -  + ]:          3 :     if (new_list[c] == NULL) {
     672 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     673                 :          0 :         talloc_free(new_list);
     674                 :          0 :         return ENOMEM;
     675                 :            :     }
     676                 :            : 
     677                 :          3 :     new_list[c + 1] = NULL;
     678                 :            : 
     679                 :          3 :     *list_p = new_list;
     680                 :            : 
     681                 :          4 :     return EOK;
     682                 :            : }
     683                 :            : 
     684                 :          9 : bool string_in_list(const char *string, char **list, bool case_sensitive)
     685                 :            : {
     686                 :            :     size_t c;
     687                 :            :     int(*compare)(const char *s1, const char *s2);
     688                 :            : 
     689 [ +  + ][ +  + ]:          9 :     if (string == NULL || list == NULL || *list == NULL) {
     690                 :            :         return false;
     691                 :            :     }
     692                 :            : 
     693         [ +  + ]:          4 :     compare = case_sensitive ? strcmp : strcasecmp;
     694                 :            : 
     695         [ +  + ]:         17 :     for (c = 0; list[c] != NULL; c++) {
     696         [ +  + ]:          8 :         if (compare(string, list[c]) == 0) {
     697                 :            :             return true;
     698                 :            :         }
     699                 :            :     }
     700                 :            : 
     701                 :            :     return false;
     702                 :            : }

Generated by: LCOV version 1.9