Line data Source code
1 : /*
2 : Authors:
3 : Sumit Bose <sbose@redhat.com>
4 :
5 : Copyright (C) 2012 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 <utime.h>
22 :
23 : #include "confdb/confdb.h"
24 : #include "db/sysdb.h"
25 : #include "util/util.h"
26 :
27 1 : struct sss_domain_info *get_domains_head(struct sss_domain_info *domain)
28 : {
29 1 : struct sss_domain_info *dom = NULL;
30 :
31 : /* get to the top level domain */
32 1 : for (dom = domain; dom->parent != NULL; dom = dom->parent);
33 :
34 1 : return dom;
35 : }
36 :
37 1757 : struct sss_domain_info *get_next_domain(struct sss_domain_info *domain,
38 : bool descend)
39 : {
40 : struct sss_domain_info *dom;
41 :
42 1757 : dom = domain;
43 4047 : while (dom) {
44 1791 : if (descend && dom->subdomains) {
45 141 : dom = dom->subdomains;
46 1650 : } else if (dom->next) {
47 1108 : dom = dom->next;
48 542 : } else if (descend && IS_SUBDOMAIN(dom) && dom->parent->next) {
49 43 : dom = dom->parent->next;
50 : } else {
51 499 : dom = NULL;
52 : }
53 :
54 1791 : if (dom && sss_domain_get_state(dom) != DOM_DISABLED) {
55 1258 : break;
56 : }
57 : }
58 :
59 1757 : return dom;
60 : }
61 :
62 0 : bool subdomain_enumerates(struct sss_domain_info *parent,
63 : const char *sd_name)
64 : {
65 0 : if (parent->sd_enumerate == NULL
66 0 : || parent->sd_enumerate[0] == NULL) {
67 0 : DEBUG(SSSDBG_MINOR_FAILURE,
68 : "Subdomain_enumerate not set\n");
69 0 : return false;
70 : }
71 :
72 0 : if (strcasecmp(parent->sd_enumerate[0], "all") == 0) {
73 0 : return true;
74 0 : } else if (strcasecmp(parent->sd_enumerate[0], "none") == 0) {
75 0 : return false;
76 : } else {
77 0 : for (int i=0; parent->sd_enumerate[i]; i++) {
78 0 : if (strcasecmp(parent->sd_enumerate[i], sd_name) == 0) {
79 0 : return true;
80 : }
81 : }
82 : }
83 :
84 0 : return false;
85 : }
86 :
87 184 : struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain,
88 : const char *name,
89 : bool match_any)
90 : {
91 184 : struct sss_domain_info *dom = domain;
92 :
93 184 : if (name == NULL) {
94 2 : return NULL;
95 : }
96 :
97 364 : while (dom && sss_domain_get_state(dom) == DOM_DISABLED) {
98 0 : dom = get_next_domain(dom, true);
99 : }
100 1157 : while (dom) {
101 920 : if (strcasecmp(dom->name, name) == 0 ||
102 731 : ((match_any == true) && (dom->flat_name != NULL) &&
103 333 : (strcasecmp(dom->flat_name, name) == 0))) {
104 127 : return dom;
105 : }
106 793 : dom = get_next_domain(dom, true);
107 : }
108 :
109 55 : return NULL;
110 : }
111 :
112 33 : struct sss_domain_info *find_domain_by_sid(struct sss_domain_info *domain,
113 : const char *sid)
114 : {
115 33 : struct sss_domain_info *dom = domain;
116 : size_t sid_len;
117 : size_t dom_sid_len;
118 :
119 33 : if (sid == NULL) {
120 2 : return NULL;
121 : }
122 :
123 31 : sid_len = strlen(sid);
124 :
125 62 : while (dom && sss_domain_get_state(dom) == DOM_DISABLED) {
126 0 : dom = get_next_domain(dom, true);
127 : }
128 :
129 202 : while (dom) {
130 168 : if (dom->domain_id != NULL) {
131 163 : dom_sid_len = strlen(dom->domain_id);
132 :
133 163 : if (strncasecmp(dom->domain_id, sid, dom_sid_len) == 0) {
134 28 : if (dom_sid_len == sid_len) {
135 : /* sid is domain sid */
136 28 : return dom;
137 : }
138 :
139 : /* sid is object sid, check if domain sid is align with
140 : * sid first subauthority component */
141 0 : if (sid[dom_sid_len] == '-') {
142 0 : return dom;
143 : }
144 : }
145 : }
146 :
147 140 : dom = get_next_domain(dom, true);
148 : }
149 :
150 3 : return NULL;
151 : }
152 :
153 : struct sss_domain_info*
154 0 : sss_get_domain_by_sid_ldap_fallback(struct sss_domain_info *domain,
155 : const char* sid)
156 : {
157 : /* LDAP provider doesn't know about sub-domains and hence can only
158 : * have one configured domain
159 : */
160 0 : if (strcmp(domain->provider, "ldap") == 0) {
161 0 : return domain;
162 : } else {
163 0 : return find_domain_by_sid(get_domains_head(domain), sid);
164 : }
165 : }
166 :
167 : struct sss_domain_info *
168 42 : find_domain_by_object_name(struct sss_domain_info *domain,
169 : const char *object_name)
170 : {
171 : TALLOC_CTX *tmp_ctx;
172 42 : struct sss_domain_info *dom = NULL;
173 42 : char *domainname = NULL;
174 : errno_t ret;
175 :
176 42 : tmp_ctx = talloc_new(NULL);
177 42 : if (tmp_ctx == NULL) {
178 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
179 0 : return NULL;
180 : }
181 :
182 42 : ret = sss_parse_name(tmp_ctx, domain->names, object_name,
183 : &domainname, NULL);
184 42 : if (ret != EOK) {
185 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name '%s' [%d]: %s\n",
186 : object_name, ret, sss_strerror(ret));
187 0 : goto done;
188 : }
189 :
190 42 : if (domainname == NULL) {
191 42 : dom = domain;
192 : } else {
193 0 : dom = find_domain_by_name(domain, domainname, true);
194 : }
195 :
196 : done:
197 42 : talloc_free(tmp_ctx);
198 42 : return dom;
199 : }
200 :
201 1081 : errno_t sssd_domain_init(TALLOC_CTX *mem_ctx,
202 : struct confdb_ctx *cdb,
203 : const char *domain_name,
204 : const char *db_path,
205 : struct sss_domain_info **_domain)
206 : {
207 : int ret;
208 : struct sss_domain_info *dom;
209 : struct sysdb_ctx *sysdb;
210 :
211 1081 : ret = confdb_get_domain(cdb, domain_name, &dom);
212 1081 : if (ret != EOK) {
213 0 : DEBUG(SSSDBG_OP_FAILURE, "Error retrieving domain configuration.\n");
214 0 : return ret;
215 : }
216 :
217 1081 : if (dom->sysdb != NULL) {
218 0 : DEBUG(SSSDBG_OP_FAILURE, "Sysdb context already initialized.\n");
219 0 : return EEXIST;
220 : }
221 :
222 1081 : ret = sysdb_domain_init(mem_ctx, dom, db_path, &sysdb);
223 1081 : if (ret != EOK) {
224 0 : DEBUG(SSSDBG_OP_FAILURE, "Error opening cache database.\n");
225 0 : return ret;
226 : }
227 :
228 1081 : dom->sysdb = talloc_steal(dom, sysdb);
229 :
230 1081 : *_domain = dom;
231 :
232 1081 : return EOK;
233 : }
234 :
235 : static errno_t
236 2 : sss_krb5_touch_config(void)
237 : {
238 2 : const char *config = NULL;
239 : errno_t ret;
240 :
241 2 : config = getenv("KRB5_CONFIG");
242 2 : if (config == NULL) {
243 2 : config = KRB5_CONF_PATH;
244 : }
245 :
246 2 : ret = utime(config, NULL);
247 2 : if (ret == -1) {
248 2 : ret = errno;
249 2 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change mtime of \"%s\" "
250 : "[%d]: %s\n", config, ret, strerror(ret));
251 2 : return ret;
252 : }
253 :
254 0 : return EOK;
255 : }
256 :
257 : errno_t
258 0 : sss_write_domain_mappings(struct sss_domain_info *domain)
259 : {
260 : struct sss_domain_info *dom;
261 : struct sss_domain_info *parent_dom;
262 : errno_t ret;
263 : errno_t err;
264 : TALLOC_CTX *tmp_ctx;
265 : const char *mapping_file;
266 : char *sanitized_domain;
267 0 : char *tmp_file = NULL;
268 0 : int fd = -1;
269 : mode_t old_mode;
270 0 : FILE *fstream = NULL;
271 : int i;
272 0 : bool capaths_started = false;
273 : char *uc_forest;
274 : char *uc_parent;
275 :
276 0 : if (domain == NULL || domain->name == NULL) {
277 0 : DEBUG(SSSDBG_CRIT_FAILURE, "No domain name provided\n");
278 0 : return EINVAL;
279 : }
280 :
281 0 : tmp_ctx = talloc_new(NULL);
282 0 : if (!tmp_ctx) return ENOMEM;
283 :
284 0 : sanitized_domain = talloc_strdup(tmp_ctx, domain->name);
285 0 : if (sanitized_domain == NULL) {
286 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
287 0 : return ENOMEM;
288 : }
289 :
290 : /* only alpha-numeric chars, dashes and underscores are allowed in
291 : * krb5 include directory */
292 0 : for (i = 0; sanitized_domain[i] != '\0'; i++) {
293 0 : if (!isalnum(sanitized_domain[i])
294 0 : && sanitized_domain[i] != '-' && sanitized_domain[i] != '_') {
295 0 : sanitized_domain[i] = '_';
296 : }
297 : }
298 :
299 0 : mapping_file = talloc_asprintf(tmp_ctx, "%s/domain_realm_%s",
300 : KRB5_MAPPING_DIR, sanitized_domain);
301 0 : if (!mapping_file) {
302 0 : ret = ENOMEM;
303 0 : goto done;
304 : }
305 :
306 0 : DEBUG(SSSDBG_FUNC_DATA, "Mapping file for domain [%s] is [%s]\n",
307 : domain->name, mapping_file);
308 :
309 0 : tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", mapping_file);
310 0 : if (tmp_file == NULL) {
311 0 : ret = ENOMEM;
312 0 : goto done;
313 : }
314 :
315 0 : old_mode = umask(SSS_DFL_UMASK);
316 0 : fd = mkstemp(tmp_file);
317 0 : umask(old_mode);
318 0 : if (fd < 0) {
319 0 : DEBUG(SSSDBG_OP_FAILURE,
320 : "creating the temp file [%s] for domain-realm mappings "
321 : "failed.\n", tmp_file);
322 0 : ret = EIO;
323 0 : talloc_zfree(tmp_ctx);
324 0 : goto done;
325 : }
326 :
327 0 : fstream = fdopen(fd, "a");
328 0 : if (!fstream) {
329 0 : ret = errno;
330 0 : DEBUG(SSSDBG_OP_FAILURE, "fdopen failed [%d]: %s\n",
331 : ret, strerror(ret));
332 0 : ret = close(fd);
333 0 : if (ret != 0) {
334 0 : ret = errno;
335 0 : DEBUG(SSSDBG_CRIT_FAILURE,
336 : "fclose failed [%d][%s].\n", ret, strerror(ret));
337 : /* Nothing to do here, just report the failure */
338 : }
339 0 : ret = EIO;
340 0 : goto done;
341 : }
342 :
343 0 : ret = fprintf(fstream, "[domain_realm]\n");
344 0 : if (ret < 0) {
345 0 : DEBUG(SSSDBG_OP_FAILURE, "fprintf failed\n");
346 0 : ret = EIO;
347 0 : goto done;
348 : }
349 :
350 0 : for (dom = get_next_domain(domain, true);
351 0 : dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
352 0 : dom = get_next_domain(dom, false)) {
353 0 : ret = fprintf(fstream, ".%s = %s\n%s = %s\n",
354 : dom->name, dom->realm, dom->name, dom->realm);
355 0 : if (ret < 0) {
356 0 : DEBUG(SSSDBG_CRIT_FAILURE, "fprintf failed\n");
357 0 : goto done;
358 : }
359 : }
360 :
361 0 : parent_dom = domain;
362 0 : uc_parent = get_uppercase_realm(tmp_ctx, parent_dom->name);
363 0 : if (uc_parent == NULL) {
364 0 : DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n");
365 0 : ret = ENOMEM;
366 0 : goto done;
367 : }
368 :
369 0 : for (dom = get_next_domain(domain, true);
370 0 : dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
371 0 : dom = get_next_domain(dom, false)) {
372 :
373 0 : if (dom->forest == NULL) {
374 0 : continue;
375 : }
376 :
377 0 : uc_forest = get_uppercase_realm(tmp_ctx, dom->forest);
378 0 : if (uc_forest == NULL) {
379 0 : DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n");
380 0 : ret = ENOMEM;
381 0 : goto done;
382 : }
383 :
384 0 : if (!capaths_started) {
385 0 : ret = fprintf(fstream, "[capaths]\n");
386 0 : if (ret < 0) {
387 0 : DEBUG(SSSDBG_OP_FAILURE, "fprintf failed\n");
388 0 : ret = EIO;
389 0 : goto done;
390 : }
391 0 : capaths_started = true;
392 : }
393 :
394 0 : ret = fprintf(fstream, "%s = {\n %s = %s\n}\n%s = {\n %s = %s\n}\n",
395 : dom->realm, uc_parent, uc_forest,
396 : uc_parent, dom->realm, uc_forest);
397 0 : if (ret < 0) {
398 0 : DEBUG(SSSDBG_CRIT_FAILURE, "fprintf failed\n");
399 0 : goto done;
400 : }
401 : }
402 :
403 0 : ret = fclose(fstream);
404 0 : fstream = NULL;
405 0 : if (ret != 0) {
406 0 : ret = errno;
407 0 : DEBUG(SSSDBG_CRIT_FAILURE,
408 : "fclose failed [%d][%s].\n", ret, strerror(ret));
409 0 : goto done;
410 : }
411 :
412 0 : ret = rename(tmp_file, mapping_file);
413 0 : if (ret == -1) {
414 0 : ret = errno;
415 0 : DEBUG(SSSDBG_CRIT_FAILURE,
416 : "rename failed [%d][%s].\n", ret, strerror(ret));
417 0 : goto done;
418 : }
419 :
420 0 : talloc_zfree(tmp_file);
421 :
422 0 : ret = chmod(mapping_file, 0644);
423 0 : if (ret == -1) {
424 0 : ret = errno;
425 0 : DEBUG(SSSDBG_CRIT_FAILURE,
426 : "fchmod failed [%d][%s].\n", ret, strerror(ret));
427 0 : goto done;
428 : }
429 :
430 0 : ret = EOK;
431 : done:
432 0 : err = sss_krb5_touch_config();
433 0 : if (err != EOK) {
434 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change last modification time "
435 : "of krb5.conf. Created mappings may not be loaded.\n");
436 : /* Ignore */
437 : }
438 :
439 0 : if (fstream) {
440 0 : err = fclose(fstream);
441 0 : if (err != 0) {
442 0 : err = errno;
443 0 : DEBUG(SSSDBG_CRIT_FAILURE,
444 : "fclose failed [%d][%s].\n", err, strerror(err));
445 : /* Nothing to do here, just report the failure */
446 : }
447 : }
448 :
449 0 : if (tmp_file) {
450 0 : err = unlink(tmp_file);
451 0 : if (err < 0) {
452 0 : err = errno;
453 0 : DEBUG(SSSDBG_MINOR_FAILURE,
454 : "Could not remove file [%s]: [%d]: %s\n",
455 : tmp_file, err, strerror(err));
456 : }
457 : }
458 0 : talloc_free(tmp_ctx);
459 0 : return ret;
460 : }
461 :
462 : /* Save domain names, do not descend. */
463 0 : errno_t get_dom_names(TALLOC_CTX *mem_ctx,
464 : struct sss_domain_info *start_dom,
465 : char ***_dom_names,
466 : int *_dom_names_count)
467 : {
468 : struct sss_domain_info *dom;
469 : TALLOC_CTX *tmp_ctx;
470 : char **dom_names;
471 : size_t count, i;
472 : errno_t ret;
473 :
474 0 : tmp_ctx = talloc_new(NULL);
475 0 : if (tmp_ctx == NULL) {
476 0 : ret = ENOMEM;
477 0 : goto done;
478 : }
479 :
480 : /* get count of domains*/
481 0 : count = 0;
482 0 : dom = start_dom;
483 0 : while (dom) {
484 0 : count++;
485 0 : dom = get_next_domain(dom, false);
486 : }
487 :
488 0 : dom_names = talloc_array(tmp_ctx, char*, count);
489 0 : if (dom_names == NULL) {
490 0 : ret = ENOMEM;
491 0 : goto done;
492 : }
493 :
494 : /* copy names */
495 0 : i = 0;
496 0 : dom = start_dom;
497 0 : while (dom) {
498 0 : dom_names[i] = talloc_strdup(dom_names, dom->name);
499 0 : if (dom_names[i] == NULL) {
500 0 : ret = ENOMEM;
501 0 : goto done;
502 : }
503 0 : dom = get_next_domain(dom, false);
504 0 : i++;
505 : }
506 :
507 0 : if (_dom_names != NULL ) {
508 0 : *_dom_names = talloc_steal(mem_ctx, dom_names);
509 : }
510 :
511 0 : if (_dom_names_count != NULL ) {
512 0 : *_dom_names_count = count;
513 : }
514 :
515 0 : ret = EOK;
516 :
517 : done:
518 0 : talloc_free(tmp_ctx);
519 0 : return ret;
520 : }
521 :
522 : #define LOCALAUTH_PLUGIN_CONFIG \
523 : "[plugins]\n" \
524 : " localauth = {\n" \
525 : " module = sssd:"APP_MODULES_PATH"/sssd_krb5_localauth_plugin.so\n" \
526 : " enable_only = sssd\n" \
527 : " }"
528 :
529 2 : static errno_t sss_write_krb5_localauth_snippet(const char *path)
530 : {
531 : #ifdef HAVE_KRB5_LOCALAUTH_PLUGIN
532 : int ret;
533 : errno_t err;
534 2 : TALLOC_CTX *tmp_ctx = NULL;
535 2 : char *tmp_file = NULL;
536 : const char *file_name;
537 2 : int fd = -1;
538 : mode_t old_mode;
539 : ssize_t written;
540 : size_t size;
541 :
542 2 : tmp_ctx = talloc_new(NULL);
543 2 : if (tmp_ctx == NULL) {
544 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
545 0 : return ENOMEM;
546 : }
547 :
548 2 : file_name = talloc_asprintf(tmp_ctx, "%s/localauth_plugin", path);
549 2 : if (file_name == NULL) {
550 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
551 0 : ret = ENOMEM;
552 0 : goto done;
553 : }
554 :
555 2 : DEBUG(SSSDBG_FUNC_DATA, "File for localauth plugin configuration is [%s]\n",
556 : file_name);
557 :
558 2 : tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", file_name);
559 2 : if (tmp_file == NULL) {
560 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
561 0 : ret = ENOMEM;
562 0 : goto done;
563 : }
564 :
565 2 : old_mode = umask(SSS_DFL_UMASK);
566 2 : fd = mkstemp(tmp_file);
567 2 : umask(old_mode);
568 2 : if (fd < 0) {
569 0 : DEBUG(SSSDBG_OP_FAILURE, "creating the temp file [%s] for "
570 : "domain-realm mappings failed.\n", tmp_file);
571 0 : ret = EIO;
572 0 : talloc_zfree(tmp_ctx);
573 0 : goto done;
574 : }
575 :
576 2 : size = sizeof(LOCALAUTH_PLUGIN_CONFIG) -1;
577 2 : written = sss_atomic_write_s(fd, discard_const(LOCALAUTH_PLUGIN_CONFIG),
578 : size);
579 2 : close(fd);
580 2 : if (written == -1) {
581 0 : ret = errno;
582 0 : DEBUG(SSSDBG_CRIT_FAILURE,
583 : "write failed [%d][%s]\n", ret, sss_strerror(ret));
584 0 : goto done;
585 : }
586 :
587 2 : if (written != size) {
588 0 : DEBUG(SSSDBG_CRIT_FAILURE,
589 : "Wrote %zd bytes expected %zu\n", written, size);
590 0 : ret = EIO;
591 0 : goto done;
592 : }
593 :
594 2 : ret = rename(tmp_file, file_name);
595 2 : if (ret == -1) {
596 0 : ret = errno;
597 0 : DEBUG(SSSDBG_CRIT_FAILURE,
598 : "rename failed [%d][%s].\n", ret, sss_strerror(ret));
599 0 : goto done;
600 : }
601 2 : tmp_file = NULL;
602 :
603 2 : ret = chmod(file_name, 0644);
604 2 : if (ret == -1) {
605 0 : ret = errno;
606 0 : DEBUG(SSSDBG_CRIT_FAILURE,
607 : "chmod failed [%d][%s].\n", ret, sss_strerror(ret));
608 0 : goto done;
609 : }
610 :
611 : done:
612 2 : if (tmp_file != NULL) {
613 0 : err = unlink(tmp_file);
614 0 : if (err == -1) {
615 0 : err = errno;
616 0 : DEBUG(SSSDBG_MINOR_FAILURE,
617 : "Could not remove file [%s]: [%d]: %s\n",
618 : tmp_file, err, sss_strerror(err));
619 : }
620 : }
621 :
622 2 : talloc_free(tmp_ctx);
623 2 : return ret;
624 : #else
625 : DEBUG(SSSDBG_TRACE_ALL, "Kerberos localauth plugin not available.\n");
626 : return EOK;
627 : #endif
628 : }
629 :
630 6 : errno_t sss_write_krb5_conf_snippet(const char *path)
631 : {
632 : errno_t ret;
633 : errno_t err;
634 :
635 6 : if (path != NULL && (*path == '\0' || strcasecmp(path, "none") == 0)) {
636 2 : DEBUG(SSSDBG_TRACE_FUNC, "Empty path, nothing to do.\n");
637 2 : return EOK;
638 : }
639 :
640 4 : if (path == NULL || *path != '/') {
641 2 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid or missing path [%s]-\n",
642 : path == NULL ? "missing" : path);
643 2 : return EINVAL;
644 : }
645 :
646 2 : ret = sss_write_krb5_localauth_snippet(path);
647 2 : if (ret != EOK) {
648 0 : DEBUG(SSSDBG_OP_FAILURE, "sss_write_krb5_localauth_snippet failed.\n");
649 0 : goto done;
650 : }
651 :
652 2 : ret = EOK;
653 :
654 : done:
655 2 : err = sss_krb5_touch_config();
656 2 : if (err != EOK) {
657 2 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change last modification time "
658 : "of krb5.conf. Created mappings may not be loaded.\n");
659 : /* Ignore */
660 : }
661 :
662 2 : return ret;
663 : }
664 :
665 1 : errno_t fix_domain_in_name_list(TALLOC_CTX *mem_ctx,
666 : struct sss_domain_info *dom,
667 : char **in, char ***_out)
668 : {
669 : int ret;
670 : size_t c;
671 : TALLOC_CTX *tmp_ctx;
672 : char **out;
673 : struct sss_domain_info *head;
674 : struct sss_domain_info *out_domain;
675 : char *in_name;
676 : char *in_domain;
677 :
678 1 : head = get_domains_head(dom);
679 :
680 1 : tmp_ctx = talloc_new(NULL);
681 1 : if (tmp_ctx == NULL) {
682 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
683 0 : return ENOMEM;
684 : }
685 :
686 : /* count elements */
687 1 : for (c = 0; in[c] != NULL; c++);
688 :
689 1 : out = talloc_zero_array(tmp_ctx, char *, c + 1);
690 1 : if (out == NULL) {
691 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
692 0 : ret = ENOMEM;
693 0 : goto done;
694 : }
695 :
696 3 : for (c = 0; in[c] != NULL; c++) {
697 2 : ret = sss_parse_name(tmp_ctx, head->names, in[c], &in_domain,
698 : &in_name);
699 2 : if (ret != EOK) {
700 0 : DEBUG(SSSDBG_OP_FAILURE, "sss_parse_name failed for [%s].\n",
701 : in[c]);
702 0 : goto done;
703 : }
704 :
705 2 : if (in_domain == NULL) {
706 0 : out[c] = talloc_strdup(out, in_name);
707 : } else {
708 2 : out_domain = find_domain_by_name(head, in_domain, true);
709 2 : if (out_domain == NULL) {
710 0 : DEBUG(SSSDBG_CRIT_FAILURE,
711 : "Cannot find domain with name [%s].\n", in_domain);
712 0 : ret = EINVAL;
713 0 : goto done;
714 : }
715 :
716 2 : out[c] = sss_get_domain_name(out, in_name, out_domain);
717 : }
718 :
719 2 : if (out[c] == NULL) {
720 0 : DEBUG(SSSDBG_OP_FAILURE, "%s failed.\n",
721 : in_domain == NULL ? "talloc_strdup" : "sss_tc_fqname");
722 0 : ret = ENOMEM;
723 0 : goto done;
724 : }
725 : }
726 :
727 1 : *_out = talloc_steal(mem_ctx, out);
728 :
729 1 : ret = EOK;
730 :
731 : done:
732 1 : talloc_free(tmp_ctx);
733 :
734 1 : return ret;
735 : }
736 :
737 1588 : enum sss_domain_state sss_domain_get_state(struct sss_domain_info *dom)
738 : {
739 1588 : return dom->state;
740 : }
741 :
742 16 : void sss_domain_set_state(struct sss_domain_info *dom,
743 : enum sss_domain_state state)
744 : {
745 16 : dom->state = state;
746 16 : }
|