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 : : }
|