Branch data Line data Source code
1 : : /*
2 : : SSSD
3 : :
4 : : NSS Configuratoin DB
5 : :
6 : : Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
7 : :
8 : : This program is free software; you can redistribute it and/or modify
9 : : it under the terms of the GNU General Public License as published by
10 : : the Free Software Foundation; either version 3 of the License, or
11 : : (at your option) any later version.
12 : :
13 : : This program is distributed in the hope that it will be useful,
14 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : GNU General Public License for more details.
17 : :
18 : : You should have received a copy of the GNU General Public License
19 : : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include "config.h"
23 : :
24 : : #include <ctype.h>
25 : : #include "util/util.h"
26 : : #include "confdb/confdb.h"
27 : : #include "confdb/confdb_private.h"
28 : : #include "util/strtonum.h"
29 : : #include "db/sysdb.h"
30 : :
31 : : #define CONFDB_ZERO_CHECK_OR_JUMP(var, ret, err, label) do { \
32 : : if (!var) { \
33 : : ret = err; \
34 : : goto label; \
35 : : } \
36 : : } while(0)
37 : :
38 : 5875 : static char *prepend_cn(char *str, int *slen, const char *comp, int clen)
39 : : {
40 : : char *ret;
41 : :
42 : 5875 : ret = talloc_realloc(NULL, str, char, *slen + 4 + clen + 1);
43 [ + - ]: 5875 : if (!ret)
44 : : return NULL;
45 : :
46 : : /* move current string to the end */
47 : 5875 : memmove(&ret[clen +4], ret, *slen+1); /* includes termination */
48 : 5875 : memcpy(ret, "cn=", 3);
49 : 5875 : memcpy(&ret[3], comp, clen);
50 : 5875 : ret[clen+3] = ',';
51 : :
52 : 5875 : *slen = *slen + 4 + clen;
53 : :
54 : 5875 : return ret;
55 : : }
56 : :
57 : 3946 : int parse_section(TALLOC_CTX *mem_ctx, const char *section,
58 : : char **sec_dn, const char **rdn_name)
59 : : {
60 : : TALLOC_CTX *tmp_ctx;
61 : 3946 : char *dn = NULL;
62 : : char *p;
63 : : const char *s;
64 : : int l, ret;
65 : :
66 : : /* section must be a non null string and must not start with '/' */
67 [ + - ][ + - ]: 3946 : if (!section || !*section || *section == '/') return EINVAL;
[ + - ]
68 : :
69 : 3946 : tmp_ctx = talloc_new(mem_ctx);
70 [ + - ]: 3946 : if (!tmp_ctx) return ENOMEM;
71 : :
72 : 3946 : s = section;
73 : 3946 : l = 0;
74 [ + - ]: 9821 : while ((p = strchrnul(s, '/'))) {
75 [ + + ]: 9821 : if (l == 0) {
76 : 3946 : dn = talloc_asprintf(tmp_ctx, "cn=%s", s);
77 : 3946 : l = 3 + (p-s);
78 : 3946 : dn[l] = '\0';
79 : : } else {
80 : 5875 : dn = prepend_cn(dn, &l, s, p-s);
81 : : }
82 [ + - ]: 9821 : if (!dn) {
83 : : ret = ENOMEM;
84 : : goto done;
85 : : }
86 [ + + ]: 9821 : if (*p == '\0') {
87 [ + + ]: 3946 : if (rdn_name) *rdn_name = s;
88 : : break; /* reached end */
89 : : }
90 : 5875 : s = p+1;
91 [ + - ]: 5875 : if (*s == '\0') { /* a section cannot end in '.' */
92 : : ret = EINVAL;
93 : : goto done;
94 : : }
95 : : }
96 : :
97 : 3946 : *sec_dn = talloc_steal(mem_ctx, dn);
98 : 3946 : ret = EOK;
99 : :
100 : : done:
101 : 3946 : talloc_free(tmp_ctx);
102 : : return ret;
103 : : }
104 : :
105 : 2610 : int confdb_add_param(struct confdb_ctx *cdb,
106 : : bool replace,
107 : : const char *section,
108 : : const char *attribute,
109 : : const char **values)
110 : : {
111 : 2610 : TALLOC_CTX *tmp_ctx = NULL;
112 : : struct ldb_message *msg;
113 : : struct ldb_result *res;
114 : : struct ldb_dn *dn;
115 : : char *secdn;
116 : : const char *rdn_name;
117 : : int ret, i;
118 : :
119 : 2610 : tmp_ctx = talloc_new(NULL);
120 [ + - ]: 2610 : if (!tmp_ctx) {
121 : : ret = ENOMEM;
122 : : goto done;
123 : : }
124 : :
125 : 2610 : ret = parse_section(tmp_ctx, section, &secdn, &rdn_name);
126 [ + - ]: 2610 : if (ret != EOK) {
127 : : goto done;
128 : : }
129 : :
130 : 2610 : dn = ldb_dn_new(tmp_ctx, cdb->ldb, secdn);
131 [ + - ]: 2610 : CONFDB_ZERO_CHECK_OR_JUMP(dn, ret, EIO, done);
132 : :
133 : 2610 : ret = ldb_search(cdb->ldb, tmp_ctx, &res,
134 : : dn, LDB_SCOPE_BASE, NULL, NULL);
135 [ + - ]: 2610 : if (ret != LDB_SUCCESS) {
136 : : ret = EIO;
137 : : goto done;
138 : : }
139 : :
140 : 2610 : msg = ldb_msg_new(tmp_ctx);
141 [ + - ]: 2610 : CONFDB_ZERO_CHECK_OR_JUMP(msg, ret, ENOMEM, done);
142 : :
143 : 2610 : msg->dn = talloc_steal(msg, dn);
144 [ + - ]: 2610 : CONFDB_ZERO_CHECK_OR_JUMP(msg->dn, ret, ENOMEM, done);
145 : :
146 [ + + ]: 2610 : if (res->count == 0) { /* add a new message */
147 : 8 : errno = 0;
148 : :
149 : : /* cn first */
150 : 8 : ret = ldb_msg_add_string(msg, "cn", rdn_name);
151 [ + - ]: 8 : if (ret != LDB_SUCCESS) {
152 [ # # ]: 0 : if (errno) ret = errno;
153 : : else ret = EIO;
154 : : goto done;
155 : : }
156 : :
157 : : /* now the requested attribute */
158 [ + + ]: 16 : for (i = 0; values[i]; i++) {
159 : 8 : ret = ldb_msg_add_string(msg, attribute, values[i]);
160 [ - + ]: 8 : if (ret != LDB_SUCCESS) {
161 [ # # ]: 0 : if (errno) ret = errno;
162 : : else ret = EIO;
163 : : goto done;
164 : : }
165 : : }
166 : :
167 : 8 : ret = ldb_add(cdb->ldb, msg);
168 [ + - ]: 8 : if (ret != LDB_SUCCESS) {
169 : : ret = EIO;
170 : : goto done;
171 : : }
172 : :
173 : : } else {
174 : : int optype;
175 : 2602 : errno = 0;
176 : :
177 : : /* mark this as a replacement */
178 [ - + ]: 2602 : if (replace) optype = LDB_FLAG_MOD_REPLACE;
179 : 0 : else optype = LDB_FLAG_MOD_ADD;
180 : 2602 : ret = ldb_msg_add_empty(msg, attribute, optype, NULL);
181 [ + - ]: 2602 : if (ret != LDB_SUCCESS) {
182 [ # # ]: 0 : if (errno) ret = errno;
183 : : else ret = EIO;
184 : : goto done;
185 : : }
186 : :
187 : : /* now the requested attribute */
188 [ + + ]: 5204 : for (i = 0; values[i]; i++) {
189 : 2602 : ret = ldb_msg_add_string(msg, attribute, values[i]);
190 [ - + ]: 2602 : if (ret != LDB_SUCCESS) {
191 [ # # ]: 0 : if (errno) ret = errno;
192 : : else ret = EIO;
193 : : goto done;
194 : : }
195 : : }
196 : :
197 : 2602 : ret = ldb_modify(cdb->ldb, msg);
198 [ + - ]: 2602 : if (ret != LDB_SUCCESS) {
199 : : ret = EIO;
200 : : goto done;
201 : : }
202 : : }
203 : :
204 : : ret = EOK;
205 : :
206 : : done:
207 : 2610 : talloc_free(tmp_ctx);
208 [ - + ]: 2610 : if (ret != EOK) {
209 [ # # ][ # # ]: 0 : DEBUG(1, ("Failed to add [%s] to [%s], error [%d] (%s)\n",
[ # # ][ # # ]
[ # # ]
210 : : attribute, section, ret, strerror(ret)));
211 : : }
212 : 2610 : return ret;
213 : : }
214 : :
215 : 1336 : int confdb_get_param(struct confdb_ctx *cdb,
216 : : TALLOC_CTX *mem_ctx,
217 : : const char *section,
218 : : const char *attribute,
219 : : char ***values)
220 : : {
221 : : TALLOC_CTX *tmp_ctx;
222 : : struct ldb_result *res;
223 : : struct ldb_dn *dn;
224 : : char *secdn;
225 : 1336 : const char *attrs[] = { attribute, NULL };
226 : : char **vals;
227 : : struct ldb_message_element *el;
228 : : int ret, i;
229 : :
230 : 1336 : tmp_ctx = talloc_new(mem_ctx);
231 [ + - ]: 1336 : if (!tmp_ctx)
232 : : return ENOMEM;
233 : :
234 : 1336 : ret = parse_section(tmp_ctx, section, &secdn, NULL);
235 [ + - ]: 1336 : if (ret != EOK) {
236 : : goto done;
237 : : }
238 : :
239 : 1336 : dn = ldb_dn_new(tmp_ctx, cdb->ldb, secdn);
240 [ + - ]: 1336 : if (!dn) {
241 : : ret = EIO;
242 : : goto done;
243 : : }
244 : :
245 : 1336 : ret = ldb_search(cdb->ldb, tmp_ctx, &res,
246 : : dn, LDB_SCOPE_BASE, attrs, NULL);
247 [ + - ]: 1336 : if (ret != LDB_SUCCESS) {
248 : : ret = EIO;
249 : : goto done;
250 : : }
251 [ + - ]: 1336 : if (res->count > 1) {
252 : : ret = EIO;
253 : : goto done;
254 : : }
255 : :
256 : 1336 : vals = talloc_zero(mem_ctx, char *);
257 : 1336 : ret = EOK;
258 : :
259 [ + + ]: 1336 : if (res->count > 0) {
260 : 1157 : el = ldb_msg_find_element(res->msgs[0], attribute);
261 [ + + ][ + - ]: 1157 : if (el && el->num_values > 0) {
262 : 681 : vals = talloc_realloc(mem_ctx, vals, char *, el->num_values +1);
263 [ + - ]: 681 : if (!vals) {
264 : : ret = ENOMEM;
265 : : goto done;
266 : : }
267 : : /* should always be strings so this should be safe */
268 [ + + ]: 1362 : for (i = 0; i < el->num_values; i++) {
269 : 681 : struct ldb_val v = el->values[i];
270 : 681 : vals[i] = talloc_strndup(vals, (char *)v.data, v.length);
271 [ + - ]: 681 : if (!vals[i]) {
272 : : ret = ENOMEM;
273 : : goto done;
274 : : }
275 : : }
276 : 681 : vals[i] = NULL;
277 : : }
278 : : }
279 : :
280 : 1336 : *values = vals;
281 : :
282 : : done:
283 : 1336 : talloc_free(tmp_ctx);
284 [ - + ]: 1336 : if (ret != EOK) {
285 [ # # ][ # # ]: 1336 : DEBUG(1, ("Failed to get [%s] from [%s], error [%d] (%s)\n",
[ # # ][ # # ]
[ # # ]
286 : : attribute, section, ret, strerror(ret)));
287 : : }
288 : : return ret;
289 : : }
290 : :
291 : 0 : int confdb_set_bool(struct confdb_ctx *cdb,
292 : : const char *section,
293 : : const char *attribute,
294 : : bool val)
295 : : {
296 : : TALLOC_CTX *tmp_ctx;
297 : : struct ldb_dn *dn;
298 : : char *secdn;
299 : : struct ldb_message *msg;
300 : : int ret, lret;
301 : :
302 : 0 : tmp_ctx = talloc_new(NULL);
303 [ # # ]: 0 : if (!tmp_ctx)
304 : : return ENOMEM;
305 : :
306 : 0 : ret = parse_section(tmp_ctx, section, &secdn, NULL);
307 [ # # ]: 0 : if (ret != EOK) {
308 : : goto done;
309 : : }
310 : :
311 : 0 : dn = ldb_dn_new(tmp_ctx, cdb->ldb, secdn);
312 [ # # ]: 0 : if (!dn) {
313 : : ret = EIO;
314 : : goto done;
315 : : }
316 : :
317 : 0 : msg = ldb_msg_new(tmp_ctx);
318 [ # # ]: 0 : if (!msg) {
319 : : ret = ENOMEM;
320 : : goto done;
321 : : }
322 : :
323 : 0 : msg->dn = dn;
324 : :
325 : 0 : lret = ldb_msg_add_empty(msg, attribute, LDB_FLAG_MOD_REPLACE, NULL);
326 [ # # ]: 0 : if (lret != LDB_SUCCESS) {
327 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_MINOR_FAILURE,
[ # # ][ # # ]
[ # # ]
328 : : ("ldb_msg_add_empty failed: [%s]\n", ldb_strerror(lret)));
329 : : ret = EIO;
330 : : goto done;
331 : : }
332 : :
333 [ # # ]: 0 : if (val) {
334 : 0 : lret = ldb_msg_add_string(msg, attribute, "True");
335 : : } else {
336 : 0 : lret = ldb_msg_add_string(msg, attribute, "False");
337 : : }
338 [ # # ]: 0 : if (lret != LDB_SUCCESS) {
339 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_MINOR_FAILURE,
[ # # ][ # # ]
[ # # ]
340 : : ("ldb_msg_add_string failed: [%s]\n", ldb_strerror(lret)));
341 : : ret = EIO;
342 : : goto done;
343 : : }
344 : :
345 : :
346 : 0 : lret = ldb_modify(cdb->ldb, msg);
347 [ # # ]: 0 : if (lret != LDB_SUCCESS) {
348 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_MINOR_FAILURE,
[ # # ][ # # ]
[ # # ]
349 : : ("ldb_modify failed: [%s]\n", ldb_strerror(lret)));
350 : : ret = EIO;
351 : : goto done;
352 : : }
353 : :
354 : : ret = EOK;
355 : :
356 : : done:
357 : 0 : talloc_free(tmp_ctx);
358 [ # # ]: 0 : if (ret != EOK) {
359 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
360 : : ("Failed to set [%s] from [%s], error [%d] (%s)\n",
361 : : attribute, section, ret, strerror(ret)));
362 : : }
363 : : return ret;
364 : : }
365 : :
366 : 0 : int confdb_get_string(struct confdb_ctx *cdb, TALLOC_CTX *ctx,
367 : : const char *section, const char *attribute,
368 : : const char *defstr, char **result)
369 : : {
370 : 0 : char **values = NULL;
371 : : char *restr;
372 : : int ret;
373 : :
374 : 0 : ret = confdb_get_param(cdb, ctx, section, attribute, &values);
375 [ # # ]: 0 : if (ret != EOK) {
376 : : goto failed;
377 : : }
378 : :
379 [ # # ]: 0 : if (values[0]) {
380 [ # # ]: 0 : if (values[1] != NULL) {
381 : : /* too many values */
382 : : ret = EINVAL;
383 : : goto failed;
384 : : }
385 : 0 : restr = talloc_steal(ctx, values[0]);
386 : : } else {
387 : : /* Did not return a value, so use the default */
388 : :
389 [ # # ]: 0 : if (defstr == NULL) { /* No default given */
390 : 0 : *result = NULL;
391 : 0 : talloc_free(values);
392 : : return EOK;
393 : : }
394 : :
395 : : /* Copy the default string */
396 : 0 : restr = talloc_strdup(ctx, defstr);
397 : : }
398 [ # # ]: 0 : if (!restr) {
399 : : ret = ENOMEM;
400 : : goto failed;
401 : : }
402 : :
403 : 0 : talloc_free(values);
404 : :
405 : 0 : *result = restr;
406 : : return EOK;
407 : :
408 : : failed:
409 : 0 : talloc_free(values);
410 [ # # ][ # # ]: 0 : DEBUG(1, ("Failed to get [%s] from [%s], error [%d] (%s)\n",
[ # # ][ # # ]
[ # # ]
411 : : attribute, section, ret, strerror(ret)));
412 : : return ret;
413 : : }
414 : :
415 : 693 : int confdb_get_int(struct confdb_ctx *cdb,
416 : : const char *section, const char *attribute,
417 : : int defval, int *result)
418 : : {
419 : 693 : char **values = NULL;
420 : : long val;
421 : : int ret;
422 : : TALLOC_CTX *tmp_ctx;
423 : :
424 : 693 : tmp_ctx = talloc_new(NULL);
425 [ + - ]: 693 : if (tmp_ctx == NULL) {
426 : : ret = ENOMEM;
427 : : goto failed;
428 : : }
429 : :
430 : 693 : ret = confdb_get_param(cdb, tmp_ctx, section, attribute, &values);
431 [ + - ]: 693 : if (ret != EOK) {
432 : : goto failed;
433 : : }
434 : :
435 [ + + ]: 693 : if (values[0]) {
436 [ + - ]: 38 : if (values[1] != NULL) {
437 : : /* too many values */
438 : : ret = EINVAL;
439 : : goto failed;
440 : : }
441 : :
442 : 38 : errno = 0;
443 : 38 : val = strtol(values[0], NULL, 0);
444 [ + - ]: 38 : if (errno) {
445 : : ret = errno;
446 : : goto failed;
447 : : }
448 : :
449 [ + - ]: 38 : if (val < INT_MIN || val > INT_MAX) {
450 : : ret = ERANGE;
451 : : goto failed;
452 : : }
453 : :
454 : : } else {
455 : 655 : val = defval;
456 : : }
457 : :
458 : 693 : talloc_free(tmp_ctx);
459 : :
460 : 693 : *result = (int)val;
461 : : return EOK;
462 : :
463 : : failed:
464 : 0 : talloc_free(tmp_ctx);
465 [ # # ][ # # ]: 693 : DEBUG(1, ("Failed to read [%s] from [%s], error [%d] (%s)\n",
[ # # ][ # # ]
[ # # ]
466 : : attribute, section, ret, strerror(ret)));
467 : : return ret;
468 : : }
469 : :
470 : 0 : long confdb_get_long(struct confdb_ctx *cdb,
471 : : const char *section, const char *attribute,
472 : : long defval, long *result)
473 : : {
474 : 0 : char **values = NULL;
475 : : long val;
476 : : int ret;
477 : : TALLOC_CTX *tmp_ctx;
478 : :
479 : 0 : tmp_ctx = talloc_new(NULL);
480 [ # # ]: 0 : if (tmp_ctx == NULL) {
481 : : ret = ENOMEM;
482 : : goto failed;
483 : : }
484 : :
485 : 0 : ret = confdb_get_param(cdb, tmp_ctx, section, attribute, &values);
486 [ # # ]: 0 : if (ret != EOK) {
487 : : goto failed;
488 : : }
489 : :
490 [ # # ]: 0 : if (values[0]) {
491 [ # # ]: 0 : if (values[1] != NULL) {
492 : : /* too many values */
493 : : ret = EINVAL;
494 : : goto failed;
495 : : }
496 : :
497 : 0 : errno = 0;
498 : 0 : val = strtol(values[0], NULL, 0);
499 [ # # ]: 0 : if (errno) {
500 : : ret = errno;
501 : : goto failed;
502 : : }
503 : :
504 : : } else {
505 : : val = defval;
506 : : }
507 : :
508 : 0 : talloc_free(tmp_ctx);
509 : :
510 : 0 : *result = val;
511 : : return EOK;
512 : :
513 : : failed:
514 : 0 : talloc_free(tmp_ctx);
515 [ # # ][ # # ]: 0 : DEBUG(1, ("Failed to read [%s] from [%s], error [%d] (%s)\n",
[ # # ][ # # ]
[ # # ]
516 : : attribute, section, ret, strerror(ret)));
517 : 0 : return ret;
518 : : }
519 : :
520 : 0 : int confdb_get_bool(struct confdb_ctx *cdb,
521 : : const char *section, const char *attribute,
522 : : bool defval, bool *result)
523 : : {
524 : 0 : char **values = NULL;
525 : : bool val;
526 : : int ret;
527 : : TALLOC_CTX *tmp_ctx;
528 : :
529 : 0 : tmp_ctx = talloc_new(NULL);
530 [ # # ]: 0 : if (tmp_ctx == NULL) {
531 : : ret = ENOMEM;
532 : : goto failed;
533 : : }
534 : :
535 : 0 : ret = confdb_get_param(cdb, tmp_ctx, section, attribute, &values);
536 [ # # ]: 0 : if (ret != EOK) {
537 : : goto failed;
538 : : }
539 : :
540 [ # # ]: 0 : if (values[0]) {
541 [ # # ]: 0 : if (values[1] != NULL) {
542 : : /* too many values */
543 : : ret = EINVAL;
544 : : goto failed;
545 : : }
546 : :
547 [ # # ]: 0 : if (strcasecmp(values[0], "FALSE") == 0) {
548 : : val = false;
549 : :
550 [ # # ]: 0 : } else if (strcasecmp(values[0], "TRUE") == 0) {
551 : : val = true;
552 : :
553 : : } else {
554 : :
555 [ # # ][ # # ]: 0 : DEBUG(2, ("Value is not a boolean!\n"));
[ # # ][ # # ]
[ # # ]
556 : : ret = EINVAL;
557 : : goto failed;
558 : : }
559 : :
560 : : } else {
561 : : val = defval;
562 : : }
563 : :
564 : 0 : talloc_free(tmp_ctx);
565 : :
566 : 0 : *result = val;
567 : : return EOK;
568 : :
569 : : failed:
570 : 0 : talloc_free(tmp_ctx);
571 [ # # ][ # # ]: 0 : DEBUG(1, ("Failed to read [%s] from [%s], error [%d] (%s)\n",
[ # # ][ # # ]
[ # # ]
572 : : attribute, section, ret, strerror(ret)));
573 : : return ret;
574 : : }
575 : :
576 : : /* WARNING: Unlike other similar functions, this one does NOT take a default,
577 : : * and returns ENOENT if the attribute was not found ! */
578 : 643 : int confdb_get_string_as_list(struct confdb_ctx *cdb, TALLOC_CTX *ctx,
579 : : const char *section, const char *attribute,
580 : : char ***result)
581 : : {
582 : 643 : char **values = NULL;
583 : : int ret;
584 : :
585 : 643 : ret = confdb_get_param(cdb, ctx, section, attribute, &values);
586 [ + - ]: 643 : if (ret != EOK) {
587 : : goto done;
588 : : }
589 : :
590 [ + - ][ + - ]: 643 : if (values && values[0]) {
591 [ + - ]: 643 : if (values[1] != NULL) {
592 : : /* too many values */
593 : : ret = EINVAL;
594 : : goto done;
595 : : }
596 : : } else {
597 : : /* Did not return a value */
598 : : ret = ENOENT;
599 : : goto done;
600 : : }
601 : :
602 : 643 : ret = split_on_separator(ctx, values[0], ',', true, result, NULL);
603 : :
604 : : done:
605 : 643 : talloc_free(values);
606 [ - + ]: 643 : if (ret != EOK && ret != ENOENT) {
607 [ # # ][ # # ]: 0 : DEBUG(2, ("Failed to get [%s] from [%s], error [%d] (%s)\n",
[ # # ][ # # ]
[ # # ]
608 : : attribute, section, ret, strerror(ret)));
609 : : }
610 : 643 : return ret;
611 : : }
612 : :
613 : 643 : int confdb_init(TALLOC_CTX *mem_ctx,
614 : : struct confdb_ctx **cdb_ctx,
615 : : const char *confdb_location)
616 : : {
617 : : struct confdb_ctx *cdb;
618 : 643 : int ret = EOK;
619 : : mode_t old_umask;
620 : :
621 : 643 : cdb = talloc_zero(mem_ctx, struct confdb_ctx);
622 [ + - ]: 643 : if (!cdb)
623 : : return ENOMEM;
624 : :
625 : : /* Because confdb calls use sync ldb calls, we create a separate event
626 : : * context here. This will prevent the ldb sync calls to start nested
627 : : * events.
628 : : * NOTE: this means that we *cannot* do async calls and return in confdb
629 : : * unless we convert all calls and hook back to the main event context.
630 : : */
631 : :
632 : 643 : cdb->pev = tevent_context_init(cdb);
633 [ - + ]: 643 : if (!cdb->pev) {
634 : 0 : talloc_free(cdb);
635 : 0 : return EIO;
636 : : }
637 : :
638 : 643 : cdb->ldb = ldb_init(cdb, cdb->pev);
639 [ - + ]: 643 : if (!cdb->ldb) {
640 : 0 : talloc_free(cdb);
641 : 0 : return EIO;
642 : : }
643 : :
644 : 643 : ret = ldb_set_debug(cdb->ldb, ldb_debug_messages, NULL);
645 [ - + ]: 643 : if (ret != LDB_SUCCESS) {
646 [ # # ][ # # ]: 0 : DEBUG(0,("Could not set up debug fn.\n"));
[ # # ][ # # ]
[ # # ]
647 : 0 : talloc_free(cdb);
648 : 0 : return EIO;
649 : : }
650 : :
651 : 643 : old_umask = umask(0177);
652 : :
653 : 643 : ret = ldb_connect(cdb->ldb, confdb_location, 0, NULL);
654 : 643 : umask(old_umask);
655 [ - + ]: 643 : if (ret != LDB_SUCCESS) {
656 [ # # ][ # # ]: 0 : DEBUG(0, ("Unable to open config database [%s]\n",
[ # # ][ # # ]
[ # # ]
657 : : confdb_location));
658 : 0 : talloc_free(cdb);
659 : 0 : return EIO;
660 : : }
661 : :
662 : 643 : *cdb_ctx = cdb;
663 : :
664 : 643 : return EOK;
665 : : }
666 : :
667 : 6430 : static errno_t get_entry_as_uint32(struct ldb_message *msg,
668 : : uint32_t *return_value,
669 : : const char *entry,
670 : : uint32_t default_value)
671 : : {
672 : 6430 : const char *tmp = NULL;
673 : : char *endptr;
674 : 6430 : uint32_t u32ret = 0;
675 : :
676 : 6430 : *return_value = 0;
677 : :
678 [ + - ]: 6430 : if (!msg || !entry) {
679 : : return EFAULT;
680 : : }
681 : :
682 : 6430 : tmp = ldb_msg_find_attr_as_string(msg, entry, NULL);
683 [ + - ]: 6430 : if (tmp == NULL) {
684 : 6430 : *return_value = default_value;
685 : : return EOK;
686 : : }
687 : :
688 [ # # ]: 0 : if ((*tmp == '-') || (*tmp == '\0')) {
689 : : return EINVAL;
690 : : }
691 : :
692 : 0 : u32ret = strtouint32 (tmp, &endptr, 10);
693 [ # # ]: 0 : if (errno) {
694 : : return errno;
695 : : }
696 : :
697 [ # # ]: 0 : if (*endptr != '\0') {
698 : : /* Not all of the string was a valid number */
699 : : return EINVAL;
700 : : }
701 : :
702 : 6430 : *return_value = u32ret;
703 : : return EOK;
704 : : }
705 : :
706 : 3858 : static errno_t get_entry_as_bool(struct ldb_message *msg,
707 : : bool *return_value,
708 : : const char *entry,
709 : : bool default_value)
710 : : {
711 : 3858 : const char *tmp = NULL;
712 : :
713 : 3858 : *return_value = 0;
714 : :
715 [ + - ]: 3858 : if (!msg || !entry) {
716 : : return EFAULT;
717 : : }
718 : :
719 : 3858 : tmp = ldb_msg_find_attr_as_string(msg, entry, NULL);
720 [ + + ][ - + ]: 3858 : if (tmp == NULL || *tmp == '\0') {
721 : 2572 : *return_value = default_value;
722 : 2572 : return EOK;
723 : : }
724 : :
725 [ - + ]: 1286 : if (strcasecmp(tmp, "FALSE") == 0) {
726 : 0 : *return_value = 0;
727 : : }
728 [ + - ]: 1286 : else if (strcasecmp(tmp, "TRUE") == 0) {
729 : 3858 : *return_value = 1;
730 : : }
731 : : else {
732 : : return EINVAL;
733 : : }
734 : :
735 : : return EOK;
736 : : }
737 : :
738 : :
739 : : /* The default UID/GID for domains is 1. This wouldn't work well with
740 : : * the local provider */
741 : 643 : static uint32_t confdb_get_min_id(struct sss_domain_info *domain)
742 : : {
743 : 643 : uint32_t defval = SSSD_MIN_ID;
744 : :
745 [ + - ][ + - ]: 643 : if (domain && strcasecmp(domain->provider, "local") == 0) {
746 : 643 : defval = SSSD_LOCAL_MINID;
747 : : }
748 : :
749 : 643 : return defval;
750 : : }
751 : :
752 : 643 : static int confdb_get_domain_internal(struct confdb_ctx *cdb,
753 : : TALLOC_CTX *mem_ctx,
754 : : const char *name,
755 : : struct sss_domain_info **_domain)
756 : : {
757 : : struct sss_domain_info *domain;
758 : : struct ldb_result *res;
759 : : TALLOC_CTX *tmp_ctx;
760 : : struct ldb_dn *dn;
761 : : const char *tmp;
762 : : int ret, val;
763 : : uint32_t entry_cache_timeout;
764 : :
765 : 643 : tmp_ctx = talloc_new(mem_ctx);
766 [ + - ]: 643 : if (!tmp_ctx) return ENOMEM;
767 : :
768 : 643 : dn = ldb_dn_new_fmt(tmp_ctx, cdb->ldb,
769 : : "cn=%s,%s", name, CONFDB_DOMAIN_BASEDN);
770 [ + - ]: 643 : if (!dn) {
771 : : ret = ENOMEM;
772 : : goto done;
773 : : }
774 : :
775 : 643 : ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn,
776 : : LDB_SCOPE_BASE, NULL, NULL);
777 [ + - ]: 643 : if (ret != LDB_SUCCESS) {
778 : : ret = EIO;
779 : : goto done;
780 : : }
781 : :
782 [ - + ]: 643 : if (res->count != 1) {
783 [ # # ][ # # ]: 0 : DEBUG(0, ("Unknown domain [%s]\n", name));
[ # # ][ # # ]
[ # # ]
784 : : ret = ENOENT;
785 : : goto done;
786 : : }
787 : :
788 : 643 : domain = talloc_zero(mem_ctx, struct sss_domain_info);
789 [ + - ]: 643 : if (!domain) {
790 : : ret = ENOMEM;
791 : : goto done;
792 : : }
793 : :
794 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0], "cn", NULL);
795 [ - + ]: 643 : if (!tmp) {
796 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid configuration entry, fatal error!\n"));
[ # # ][ # # ]
[ # # ]
797 : : ret = EINVAL;
798 : : goto done;
799 : : }
800 : 643 : domain->name = talloc_strdup(domain, tmp);
801 [ + - ]: 643 : if (!domain->name) {
802 : : ret = ENOMEM;
803 : : goto done;
804 : : }
805 : 643 : domain->conn_name = domain->name;
806 : :
807 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0],
808 : : CONFDB_DOMAIN_ID_PROVIDER,
809 : : NULL);
810 [ + - ]: 643 : if (tmp) {
811 : 643 : domain->provider = talloc_strdup(domain, tmp);
812 [ + - ]: 643 : if (!domain->provider) {
813 : : ret = ENOMEM;
814 : : goto done;
815 : : }
816 : : }
817 : : else {
818 [ # # ][ # # ]: 0 : DEBUG(0, ("Domain [%s] does not specify an ID provider, disabling!\n",
[ # # ][ # # ]
[ # # ]
819 : : domain->name));
820 : : ret = EINVAL;
821 : : goto done;
822 : : }
823 : :
824 [ - + ]: 643 : if (strcasecmp(domain->provider, "files") == 0) {
825 : : /* The files provider is not valid anymore */
826 [ # # ][ # # ]: 0 : DEBUG(0, ("The \"files\" provider is invalid\n"));
[ # # ][ # # ]
[ # # ]
827 : : ret = EINVAL;
828 : : goto done;
829 : : }
830 : :
831 [ + - ]: 643 : if (strcasecmp(domain->provider, "local") == 0) {
832 : : /* If this is the local provider, we need to ensure that
833 : : * no other provider was specified for other types, since
834 : : * the local provider cannot load them.
835 : : */
836 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0],
837 : : CONFDB_DOMAIN_AUTH_PROVIDER,
838 : : NULL);
839 [ - + ][ # # ]: 643 : if (tmp && strcasecmp(tmp, "local") != 0) {
840 [ # # ][ # # ]: 0 : DEBUG(0, ("Local ID provider does not support [%s] as an AUTH provider.\n", tmp));
[ # # ][ # # ]
[ # # ]
841 : : ret = EINVAL;
842 : : goto done;
843 : : }
844 : :
845 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0],
846 : : CONFDB_DOMAIN_ACCESS_PROVIDER,
847 : : NULL);
848 [ - + ][ # # ]: 643 : if (tmp && strcasecmp(tmp, "permit") != 0) {
849 [ # # ][ # # ]: 0 : DEBUG(0, ("Local ID provider does not support [%s] as an ACCESS provider.\n", tmp));
[ # # ][ # # ]
[ # # ]
850 : : ret = EINVAL;
851 : : goto done;
852 : : }
853 : :
854 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0],
855 : : CONFDB_DOMAIN_CHPASS_PROVIDER,
856 : : NULL);
857 [ - + ][ # # ]: 643 : if (tmp && strcasecmp(tmp, "local") != 0) {
858 [ # # ][ # # ]: 0 : DEBUG(0, ("Local ID provider does not support [%s] as a CHPASS provider.\n", tmp));
[ # # ][ # # ]
[ # # ]
859 : : ret = EINVAL;
860 : : goto done;
861 : : }
862 : : }
863 : :
864 : 643 : domain->timeout = ldb_msg_find_attr_as_int(res->msgs[0],
865 : : CONFDB_DOMAIN_TIMEOUT, 0);
866 : :
867 : : /* Determine if this domain can be enumerated */
868 : :
869 : : /* TEMP: test if the old bitfield conf value is used and warn it has been
870 : : * superceeded. */
871 : 643 : val = ldb_msg_find_attr_as_int(res->msgs[0], CONFDB_DOMAIN_ENUMERATE, 0);
872 [ - + ]: 643 : if (val > 0) { /* ok there was a number in here */
873 [ # # ][ # # ]: 0 : DEBUG(0, ("Warning: enumeration parameter in %s still uses integers! "
[ # # ][ # # ]
[ # # ]
874 : : "Enumeration is now a boolean and takes true/false values. "
875 : : "Interpreting as true\n", domain->name));
876 : 0 : domain->enumerate = true;
877 : : } else { /* assume the new format */
878 : 643 : ret = get_entry_as_bool(res->msgs[0], &domain->enumerate,
879 : : CONFDB_DOMAIN_ENUMERATE, 0);
880 [ - + ]: 643 : if(ret != EOK) {
881 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid value for %s\n", CONFDB_DOMAIN_ENUMERATE));
[ # # ][ # # ]
[ # # ]
882 : : goto done;
883 : : }
884 : : }
885 [ - + ]: 643 : if (!domain->enumerate) {
886 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("No enumeration for [%s]!\n", domain->name));
[ # # ][ # # ]
[ # # ]
887 : : }
888 : :
889 : : /* Determine if user/group names will be Fully Qualified
890 : : * in NSS interfaces */
891 : 643 : ret = get_entry_as_bool(res->msgs[0], &domain->fqnames, CONFDB_DOMAIN_FQ, 0);
892 [ - + ]: 643 : if(ret != EOK) {
893 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid value for %s\n", CONFDB_DOMAIN_FQ));
[ # # ][ # # ]
[ # # ]
894 : : goto done;
895 : : }
896 : :
897 : 643 : ret = get_entry_as_bool(res->msgs[0], &domain->ignore_group_members,
898 : : CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS, 0);
899 [ - + ]: 643 : if(ret != EOK) {
900 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
901 : : ("Invalid value for %s\n",
902 : : CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS));
903 : : goto done;
904 : : }
905 : :
906 : 643 : ret = get_entry_as_uint32(res->msgs[0], &domain->id_min,
907 : : CONFDB_DOMAIN_MINID,
908 : : confdb_get_min_id(domain));
909 [ - + ]: 643 : if (ret != EOK) {
910 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid value for minId\n"));
[ # # ][ # # ]
[ # # ]
911 : : ret = EINVAL;
912 : : goto done;
913 : : }
914 : :
915 : 643 : ret = get_entry_as_uint32(res->msgs[0], &domain->id_max,
916 : : CONFDB_DOMAIN_MAXID, 0);
917 [ - + ]: 643 : if (ret != EOK) {
918 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid value for maxId\n"));
[ # # ][ # # ]
[ # # ]
919 : : ret = EINVAL;
920 : : goto done;
921 : : }
922 : :
923 [ - + ][ # # ]: 643 : if (domain->id_max && (domain->id_max < domain->id_min)) {
924 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid domain range\n"));
[ # # ][ # # ]
[ # # ]
925 : : ret = EINVAL;
926 : : goto done;
927 : : }
928 : :
929 : : /* Do we allow to cache credentials */
930 : 643 : ret = get_entry_as_bool(res->msgs[0], &domain->cache_credentials,
931 : : CONFDB_DOMAIN_CACHE_CREDS, 0);
932 [ - + ]: 643 : if(ret != EOK) {
933 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid value for %s\n", CONFDB_DOMAIN_CACHE_CREDS));
[ # # ][ # # ]
[ # # ]
934 : : goto done;
935 : : }
936 : :
937 : 643 : ret = get_entry_as_bool(res->msgs[0], &domain->legacy_passwords,
938 : : CONFDB_DOMAIN_LEGACY_PASS, 0);
939 [ - + ]: 643 : if(ret != EOK) {
940 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid value for %s\n", CONFDB_DOMAIN_LEGACY_PASS));
[ # # ][ # # ]
[ # # ]
941 : : goto done;
942 : : }
943 : :
944 : : /* Get the global entry cache timeout setting */
945 : 643 : ret = get_entry_as_uint32(res->msgs[0], &entry_cache_timeout,
946 : : CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT, 5400);
947 [ - + ]: 643 : if (ret != EOK) {
948 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
949 : : ("Invalid value for [%s]\n",
950 : : CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT));
951 : : goto done;
952 : : }
953 : :
954 : : /* Override the user cache timeout, if specified */
955 : 643 : ret = get_entry_as_uint32(res->msgs[0], &domain->user_timeout,
956 : : CONFDB_DOMAIN_USER_CACHE_TIMEOUT,
957 : : entry_cache_timeout);
958 [ - + ]: 643 : if (ret != EOK) {
959 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
960 : : ("Invalid value for [%s]\n",
961 : : CONFDB_DOMAIN_USER_CACHE_TIMEOUT));
962 : : goto done;
963 : : }
964 : :
965 : : /* Override the group cache timeout, if specified */
966 : 643 : ret = get_entry_as_uint32(res->msgs[0], &domain->group_timeout,
967 : : CONFDB_DOMAIN_GROUP_CACHE_TIMEOUT,
968 : : entry_cache_timeout);
969 [ - + ]: 643 : if (ret != EOK) {
970 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
971 : : ("Invalid value for [%s]\n",
972 : : CONFDB_DOMAIN_GROUP_CACHE_TIMEOUT));
973 : : goto done;
974 : : }
975 : :
976 : : /* Override the netgroup cache timeout, if specified */
977 : 643 : ret = get_entry_as_uint32(res->msgs[0], &domain->netgroup_timeout,
978 : : CONFDB_DOMAIN_NETGROUP_CACHE_TIMEOUT,
979 : : entry_cache_timeout);
980 [ - + ]: 643 : if (ret != EOK) {
981 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
982 : : ("Invalid value for [%s]\n",
983 : : CONFDB_DOMAIN_NETGROUP_CACHE_TIMEOUT));
984 : : goto done;
985 : : }
986 : :
987 : : /* Override the service cache timeout, if specified */
988 : 643 : ret = get_entry_as_uint32(res->msgs[0], &domain->service_timeout,
989 : : CONFDB_DOMAIN_SERVICE_CACHE_TIMEOUT,
990 : : entry_cache_timeout);
991 [ - + ]: 643 : if (ret != EOK) {
992 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
993 : : ("Invalid value for [%s]\n",
994 : : CONFDB_DOMAIN_SERVICE_CACHE_TIMEOUT));
995 : : goto done;
996 : : }
997 : :
998 : : /* Override the autofs cache timeout, if specified */
999 : 643 : ret = get_entry_as_uint32(res->msgs[0], &domain->autofsmap_timeout,
1000 : : CONFDB_DOMAIN_AUTOFS_CACHE_TIMEOUT,
1001 : : entry_cache_timeout);
1002 [ - + ]: 643 : if (ret != EOK) {
1003 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
1004 : : ("Invalid value for [%s]\n",
1005 : : CONFDB_DOMAIN_AUTOFS_CACHE_TIMEOUT));
1006 : : goto done;
1007 : : }
1008 : :
1009 : : /* Override the sudo cache timeout, if specified */
1010 : 643 : ret = get_entry_as_uint32(res->msgs[0], &domain->sudo_timeout,
1011 : : CONFDB_DOMAIN_SUDO_CACHE_TIMEOUT,
1012 : : entry_cache_timeout);
1013 [ - + ]: 643 : if (ret != EOK) {
1014 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
1015 : : ("Invalid value for [%s]\n",
1016 : : CONFDB_DOMAIN_SUDO_CACHE_TIMEOUT));
1017 : : goto done;
1018 : : }
1019 : :
1020 : : /* Set the PAM warning time, if specified */
1021 : 643 : val = ldb_msg_find_attr_as_int(res->msgs[0],
1022 : : CONFDB_DOMAIN_PWD_EXPIRATION_WARNING,
1023 : : -1);
1024 [ - + ]: 643 : if (val > 0) {
1025 : : /* The value is in days, transform it to seconds */
1026 : 0 : val *= 24 * 3600;
1027 : : } else {
1028 : 643 : ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY,
1029 : : CONFDB_PAM_PWD_EXPIRATION_WARNING,
1030 : : -1, &val);
1031 [ - + ]: 643 : if (ret != EOK) {
1032 [ # # ][ # # ]: 0 : DEBUG(1, ("Failed to read PAM expiration warning, not fatal.\n"));
[ # # ][ # # ]
[ # # ]
1033 : 0 : val = -1;
1034 : : }
1035 : : }
1036 : 643 : domain->pwd_expiration_warning = val;
1037 : :
1038 : 643 : ret = get_entry_as_uint32(res->msgs[0], &domain->override_gid,
1039 : : CONFDB_DOMAIN_OVERRIDE_GID, 0);
1040 [ - + ]: 643 : if (ret != EOK) {
1041 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid value for [%s]\n", CONFDB_DOMAIN_OVERRIDE_GID));
[ # # ][ # # ]
[ # # ]
1042 : : goto done;
1043 : : }
1044 : :
1045 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0],
1046 : : CONFDB_NSS_OVERRIDE_HOMEDIR, NULL);
1047 [ - + ]: 643 : if (tmp != NULL) {
1048 : 0 : domain->override_homedir = talloc_strdup(domain, tmp);
1049 [ # # ]: 0 : if (!domain->override_homedir) {
1050 : : ret = ENOMEM;
1051 : : goto done;
1052 : : }
1053 : : }
1054 : :
1055 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0],
1056 : : CONFDB_NSS_FALLBACK_HOMEDIR, NULL);
1057 [ - + ]: 643 : if (tmp != NULL) {
1058 : 0 : domain->fallback_homedir = talloc_strdup(domain, tmp);
1059 [ # # ]: 0 : if (!domain->fallback_homedir) {
1060 : : ret = ENOMEM;
1061 : : goto done;
1062 : : }
1063 : : }
1064 : :
1065 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0],
1066 : : CONFDB_DOMAIN_SUBDOMAIN_HOMEDIR,
1067 : : CONFDB_DOMAIN_DEFAULT_SUBDOMAIN_HOMEDIR);
1068 [ + - ]: 643 : if (tmp != NULL) {
1069 : 643 : domain->subdomain_homedir = talloc_strdup(domain, tmp);
1070 [ + - ]: 643 : if (!domain->subdomain_homedir) {
1071 : : ret = ENOMEM;
1072 : : goto done;
1073 : : }
1074 : : }
1075 : :
1076 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0],
1077 : : CONFDB_NSS_OVERRIDE_SHELL, NULL);
1078 [ - + ]: 643 : if (tmp != NULL) {
1079 : 0 : domain->override_shell = talloc_strdup(domain, tmp);
1080 [ # # ]: 0 : if (!domain->override_shell) {
1081 : : ret = ENOMEM;
1082 : : goto done;
1083 : : }
1084 : : }
1085 : :
1086 : 643 : tmp = ldb_msg_find_attr_as_string(res->msgs[0],
1087 : : CONFDB_NSS_DEFAULT_SHELL, NULL);
1088 [ - + ]: 643 : if (tmp != NULL) {
1089 : 0 : domain->default_shell = talloc_strdup(domain, tmp);
1090 [ # # ]: 0 : if (!domain->default_shell) {
1091 : : ret = ENOMEM;
1092 : : goto done;
1093 : : }
1094 : : }
1095 : :
1096 : 643 : ret = get_entry_as_bool(res->msgs[0], &domain->case_sensitive,
1097 : : CONFDB_DOMAIN_CASE_SENSITIVE, true);
1098 [ - + ]: 643 : if(ret != EOK) {
1099 [ # # ][ # # ]: 0 : DEBUG(0, ("Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE));
[ # # ][ # # ]
[ # # ]
1100 : : goto done;
1101 : : }
1102 [ - + ][ # # ]: 643 : if (domain->case_sensitive == false &&
1103 : 0 : strcasecmp(domain->provider, "local") == 0) {
1104 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE,
[ # # ][ # # ]
[ # # ]
1105 : : ("Local ID provider does not support the case insensitive flag\n"));
1106 : : ret = EINVAL;
1107 : : goto done;
1108 : : }
1109 : :
1110 : 643 : *_domain = domain;
1111 : 643 : ret = EOK;
1112 : : done:
1113 : 643 : talloc_free(tmp_ctx);
1114 : : return ret;
1115 : : }
1116 : :
1117 : 643 : int confdb_get_domains(struct confdb_ctx *cdb,
1118 : : struct sss_domain_info **domains)
1119 : : {
1120 : : TALLOC_CTX *tmp_ctx;
1121 : 643 : struct sss_domain_info *domain, *prevdom = NULL;
1122 : : char **domlist;
1123 : : int ret, i;
1124 : :
1125 [ - + ]: 643 : if (cdb->doms) {
1126 : 0 : *domains = cdb->doms;
1127 : : return EOK;
1128 : : }
1129 : :
1130 : 643 : tmp_ctx = talloc_new(NULL);
1131 [ + - ]: 643 : if (!tmp_ctx) return ENOMEM;
1132 : :
1133 : 643 : ret = confdb_get_string_as_list(cdb, tmp_ctx,
1134 : : CONFDB_MONITOR_CONF_ENTRY,
1135 : : CONFDB_MONITOR_ACTIVE_DOMAINS,
1136 : : &domlist);
1137 [ - + ]: 643 : if (ret == ENOENT) {
1138 [ # # ][ # # ]: 0 : DEBUG(0, ("No domains configured, fatal error!\n"));
[ # # ][ # # ]
[ # # ]
1139 : : goto done;
1140 : : }
1141 [ + - ]: 643 : if (ret != EOK ) {
1142 [ # # ][ # # ]: 0 : DEBUG(0, ("Fatal error retrieving domains list!\n"));
[ # # ][ # # ]
[ # # ]
1143 : : goto done;
1144 : : }
1145 : :
1146 [ + + ]: 1286 : for (i = 0; domlist[i]; i++) {
1147 : 643 : ret = confdb_get_domain_internal(cdb, cdb, domlist[i], &domain);
1148 [ - + ]: 643 : if (ret) {
1149 [ # # ][ # # ]: 0 : DEBUG(0, ("Error (%d [%s]) retrieving domain [%s], skipping!\n",
[ # # ][ # # ]
[ # # ]
1150 : : ret, strerror(ret), domlist[i]));
1151 : 0 : continue;
1152 : : }
1153 : :
1154 [ + - ]: 643 : if (cdb->doms == NULL) {
1155 : 643 : cdb->doms = domain;
1156 : 643 : prevdom = cdb->doms;
1157 : : } else {
1158 : 0 : prevdom->next = domain;
1159 : 0 : prevdom = domain;
1160 : : }
1161 : : }
1162 : :
1163 [ - + ]: 643 : if (cdb->doms == NULL) {
1164 [ # # ][ # # ]: 0 : DEBUG(0, ("No properly configured domains, fatal error!\n"));
[ # # ][ # # ]
[ # # ]
1165 : : ret = ENOENT;
1166 : : goto done;
1167 : : }
1168 : :
1169 : 643 : *domains = cdb->doms;
1170 : 643 : ret = EOK;
1171 : :
1172 : : done:
1173 : 643 : talloc_free(tmp_ctx);
1174 : : return ret;
1175 : : }
1176 : :
1177 : 643 : int confdb_get_domain(struct confdb_ctx *cdb,
1178 : : const char *name,
1179 : : struct sss_domain_info **_domain)
1180 : : {
1181 : : struct sss_domain_info *dom, *doms;
1182 : : int ret;
1183 : :
1184 : 643 : ret = confdb_get_domains(cdb, &doms);
1185 [ + - ]: 643 : if (ret != EOK) {
1186 : : return ret;
1187 : : }
1188 : :
1189 [ + - ]: 1286 : for (dom = doms; dom; dom = dom->next) {
1190 [ + - ]: 643 : if (strcasecmp(dom->name, name) == 0) {
1191 : 643 : *_domain = dom;
1192 : : return EOK;
1193 : : }
1194 : : }
1195 : :
1196 : : return ENOENT;
1197 : : }
|