Line data Source code
1 : /*
2 : SSSD
3 :
4 : Authors:
5 : Stephen Gallagher <sgallagh@redhat.com>
6 :
7 : Copyright (C) 2012 Red Hat
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 : #include <ctype.h>
23 :
24 : #include "providers/ad/ad_common.h"
25 : #include "providers/ad/ad_opts.h"
26 : #include "providers/dp_dyndns.h"
27 :
28 : struct ad_server_data {
29 : bool gc;
30 : };
31 :
32 : errno_t ad_set_search_bases(struct sdap_options *id_opts);
33 : static errno_t ad_set_sdap_options(struct ad_options *ad_opts,
34 : struct sdap_options *id_opts);
35 :
36 : static struct sdap_options *
37 19 : ad_create_default_sdap_options(TALLOC_CTX *mem_ctx)
38 : {
39 : struct sdap_options *id_opts;
40 : errno_t ret;
41 :
42 19 : id_opts = talloc_zero(mem_ctx, struct sdap_options);
43 19 : if (!id_opts) {
44 0 : return NULL;
45 : }
46 :
47 19 : ret = dp_copy_defaults(id_opts,
48 : ad_def_ldap_opts,
49 : SDAP_OPTS_BASIC,
50 : &id_opts->basic);
51 19 : if (ret != EOK) {
52 0 : goto fail;
53 : }
54 :
55 : /* Get sdap option maps */
56 :
57 : /* General Attribute Map */
58 19 : ret = sdap_copy_map(id_opts,
59 : ad_2008r2_attr_map,
60 : SDAP_AT_GENERAL,
61 : &id_opts->gen_map);
62 19 : if (ret != EOK) {
63 0 : goto fail;
64 : }
65 :
66 : /* User map */
67 19 : ret = sdap_copy_map(id_opts,
68 : ad_2008r2_user_map,
69 : SDAP_OPTS_USER,
70 : &id_opts->user_map);
71 19 : if (ret != EOK) {
72 0 : goto fail;
73 : }
74 19 : id_opts->user_map_cnt = SDAP_OPTS_USER;
75 :
76 : /* Group map */
77 19 : ret = sdap_copy_map(id_opts,
78 : ad_2008r2_group_map,
79 : SDAP_OPTS_GROUP,
80 : &id_opts->group_map);
81 19 : if (ret != EOK) {
82 0 : goto fail;
83 : }
84 :
85 : /* Netgroup map */
86 19 : ret = sdap_copy_map(id_opts,
87 : ad_netgroup_map,
88 : SDAP_OPTS_NETGROUP,
89 : &id_opts->netgroup_map);
90 19 : if (ret != EOK) {
91 0 : goto fail;
92 : }
93 :
94 : /* Services map */
95 19 : ret = sdap_copy_map(id_opts,
96 : ad_service_map,
97 : SDAP_OPTS_SERVICES,
98 : &id_opts->service_map);
99 19 : if (ret != EOK) {
100 0 : goto fail;
101 : }
102 :
103 19 : return id_opts;
104 :
105 : fail:
106 0 : talloc_free(id_opts);
107 0 : return NULL;
108 : }
109 :
110 : struct ad_options *
111 19 : ad_create_default_options(TALLOC_CTX *mem_ctx)
112 : {
113 : struct ad_options *ad_options;
114 : errno_t ret;
115 :
116 19 : ad_options = talloc_zero(mem_ctx, struct ad_options);
117 19 : if (ad_options == NULL) return NULL;
118 :
119 19 : ret = dp_copy_defaults(ad_options,
120 : ad_basic_opts,
121 : AD_OPTS_BASIC,
122 : &ad_options->basic);
123 19 : if (ret != EOK) {
124 0 : talloc_free(ad_options);
125 0 : return NULL;
126 : }
127 :
128 19 : ad_options->id = ad_create_default_sdap_options(ad_options);
129 19 : if (ad_options->id == NULL) {
130 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD LDAP options\n");
131 0 : talloc_free(ad_options);
132 0 : return NULL;
133 : }
134 :
135 19 : return ad_options;
136 : }
137 :
138 : static errno_t
139 18 : set_common_ad_trust_opts(struct ad_options *ad_options,
140 : const char *realm,
141 : const char *ad_domain,
142 : const char *hostname)
143 : {
144 : errno_t ret;
145 :
146 18 : ret = dp_opt_set_string(ad_options->basic, AD_KRB5_REALM, realm);
147 18 : if (ret != EOK) {
148 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD krb5 realm\n");
149 0 : return ret;
150 : }
151 :
152 18 : ret = dp_opt_set_string(ad_options->basic, AD_DOMAIN, ad_domain);
153 18 : if (ret != EOK) {
154 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD domain\n");
155 0 : return ret;
156 : }
157 :
158 18 : ret = dp_opt_set_string(ad_options->basic, AD_HOSTNAME, hostname);
159 18 : if (ret != EOK) {
160 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD hostname\n");
161 0 : return ret;
162 : }
163 :
164 18 : return EOK;
165 : }
166 :
167 : struct ad_options *
168 9 : ad_create_2way_trust_options(TALLOC_CTX *mem_ctx,
169 : const char *realm,
170 : const char *ad_domain,
171 : const char *hostname)
172 : {
173 : struct ad_options *ad_options;
174 : errno_t ret;
175 :
176 9 : ad_options = ad_create_default_options(mem_ctx);
177 9 : if (ad_options == NULL) return NULL;
178 :
179 9 : ret = set_common_ad_trust_opts(ad_options, realm, ad_domain, hostname);
180 9 : if (ret != EOK) {
181 0 : talloc_free(ad_options);
182 0 : return NULL;
183 : }
184 :
185 9 : ret = ad_set_sdap_options(ad_options, ad_options->id);
186 9 : if (ret != EOK) {
187 0 : talloc_free(ad_options);
188 0 : return NULL;
189 : }
190 :
191 9 : return ad_options;
192 : }
193 :
194 : struct ad_options *
195 9 : ad_create_1way_trust_options(TALLOC_CTX *mem_ctx,
196 : const char *ad_domain,
197 : const char *hostname,
198 : const char *keytab,
199 : const char *sasl_authid)
200 : {
201 : struct ad_options *ad_options;
202 : const char *realm;
203 : errno_t ret;
204 :
205 9 : ad_options = ad_create_default_options(mem_ctx);
206 9 : if (ad_options == NULL) return NULL;
207 :
208 9 : realm = get_uppercase_realm(ad_options, ad_domain);
209 9 : if (!realm) {
210 0 : talloc_free(ad_options);
211 0 : return NULL;
212 : }
213 :
214 9 : ret = set_common_ad_trust_opts(ad_options, realm,
215 : ad_domain, hostname);
216 9 : if (ret != EOK) {
217 0 : talloc_free(ad_options);
218 0 : return NULL;
219 : }
220 :
221 : /* Set AD_KEYTAB to the special 1way keytab */
222 9 : ret = dp_opt_set_string(ad_options->basic, AD_KEYTAB, keytab);
223 9 : if (ret != EOK) {
224 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot set trust keytab\n");
225 0 : talloc_free(ad_options);
226 0 : return NULL;
227 : }
228 :
229 : /* Set SDAP_SASL_AUTHID to the trust principal */
230 9 : ret = dp_opt_set_string(ad_options->id->basic,
231 : SDAP_SASL_AUTHID, sasl_authid);
232 9 : if (ret != EOK) {
233 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot set SASL authid\n");
234 0 : talloc_free(ad_options);
235 0 : return NULL;
236 : }
237 :
238 9 : ret = ad_set_sdap_options(ad_options, ad_options->id);
239 9 : if (ret != EOK) {
240 0 : talloc_free(ad_options);
241 0 : return NULL;
242 : }
243 :
244 9 : return ad_options;
245 : }
246 :
247 : static errno_t
248 0 : ad_create_sdap_options(TALLOC_CTX *mem_ctx,
249 : struct confdb_ctx *cdb,
250 : const char *conf_path,
251 : struct sdap_options **_id_opts)
252 : {
253 : struct sdap_options *id_opts;
254 : errno_t ret;
255 :
256 0 : id_opts = talloc_zero(mem_ctx, struct sdap_options);
257 0 : if (!id_opts) {
258 0 : ret = ENOMEM;
259 0 : goto done;
260 : }
261 :
262 0 : ret = dp_get_options(id_opts, cdb, conf_path,
263 : ad_def_ldap_opts,
264 : SDAP_OPTS_BASIC,
265 : &id_opts->basic);
266 0 : if (ret != EOK) {
267 0 : goto done;
268 : }
269 :
270 : /* Get sdap option maps */
271 :
272 : /* General Attribute Map */
273 0 : ret = sdap_get_map(id_opts,
274 : cdb, conf_path,
275 : ad_2008r2_attr_map,
276 : SDAP_AT_GENERAL,
277 : &id_opts->gen_map);
278 0 : if (ret != EOK) {
279 0 : goto done;
280 : }
281 :
282 : /* User map */
283 0 : ret = sdap_get_map(id_opts,
284 : cdb, conf_path,
285 : ad_2008r2_user_map,
286 : SDAP_OPTS_USER,
287 : &id_opts->user_map);
288 0 : if (ret != EOK) {
289 0 : goto done;
290 : }
291 :
292 0 : ret = sdap_extend_map_with_list(id_opts, id_opts,
293 : SDAP_USER_EXTRA_ATTRS,
294 : id_opts->user_map,
295 : SDAP_OPTS_USER,
296 : &id_opts->user_map,
297 : &id_opts->user_map_cnt);
298 0 : if (ret != EOK) {
299 0 : goto done;
300 : }
301 :
302 : /* Group map */
303 0 : ret = sdap_get_map(id_opts,
304 : cdb, conf_path,
305 : ad_2008r2_group_map,
306 : SDAP_OPTS_GROUP,
307 : &id_opts->group_map);
308 0 : if (ret != EOK) {
309 0 : goto done;
310 : }
311 :
312 : /* Netgroup map */
313 0 : ret = sdap_get_map(id_opts,
314 : cdb, conf_path,
315 : ad_netgroup_map,
316 : SDAP_OPTS_NETGROUP,
317 : &id_opts->netgroup_map);
318 0 : if (ret != EOK) {
319 0 : goto done;
320 : }
321 :
322 : /* Services map */
323 0 : ret = sdap_get_map(id_opts,
324 : cdb, conf_path,
325 : ad_service_map,
326 : SDAP_OPTS_SERVICES,
327 : &id_opts->service_map);
328 0 : if (ret != EOK) {
329 0 : goto done;
330 : }
331 :
332 0 : ret = EOK;
333 0 : *_id_opts = id_opts;
334 : done:
335 0 : return ret;
336 : }
337 :
338 : errno_t
339 0 : ad_get_common_options(TALLOC_CTX *mem_ctx,
340 : struct confdb_ctx *cdb,
341 : const char *conf_path,
342 : struct sss_domain_info *dom,
343 : struct ad_options **_opts)
344 : {
345 : errno_t ret;
346 : int gret;
347 0 : struct ad_options *opts = NULL;
348 : char *domain;
349 : char *server;
350 : char *realm;
351 : char *ad_hostname;
352 : char hostname[HOST_NAME_MAX + 1];
353 : char *case_sensitive_opt;
354 : const char *opt_override;
355 :
356 0 : opts = talloc_zero(mem_ctx, struct ad_options);
357 0 : if (!opts) return ENOMEM;
358 :
359 0 : ret = dp_get_options(opts, cdb, conf_path,
360 : ad_basic_opts,
361 : AD_OPTS_BASIC,
362 : &opts->basic);
363 0 : if (ret != EOK) {
364 0 : goto done;
365 : }
366 :
367 : /* If the AD domain name wasn't explicitly set, assume that it
368 : * matches the SSSD domain name
369 : */
370 0 : domain = dp_opt_get_string(opts->basic, AD_DOMAIN);
371 0 : if (!domain) {
372 0 : ret = dp_opt_set_string(opts->basic, AD_DOMAIN, dom->name);
373 0 : if (ret != EOK) {
374 0 : goto done;
375 : }
376 0 : domain = dom->name;
377 : }
378 :
379 : /* Did we get an explicit server name, or are we discovering it? */
380 0 : server = dp_opt_get_string(opts->basic, AD_SERVER);
381 0 : if (!server) {
382 0 : DEBUG(SSSDBG_CONF_SETTINGS,
383 : "No AD server set, will use service discovery!\n");
384 : }
385 :
386 : /* Set the machine's hostname to the local host name if it
387 : * wasn't explicitly specified.
388 : */
389 0 : ad_hostname = dp_opt_get_string(opts->basic, AD_HOSTNAME);
390 0 : if (ad_hostname == NULL) {
391 0 : gret = gethostname(hostname, HOST_NAME_MAX);
392 0 : if (gret != 0) {
393 0 : ret = errno;
394 0 : DEBUG(SSSDBG_FATAL_FAILURE,
395 : "gethostname failed [%s].\n",
396 : strerror(ret));
397 0 : goto done;
398 : }
399 0 : hostname[HOST_NAME_MAX] = '\0';
400 0 : DEBUG(SSSDBG_CONF_SETTINGS,
401 : "Setting ad_hostname to [%s].\n", hostname);
402 0 : ret = dp_opt_set_string(opts->basic, AD_HOSTNAME, hostname);
403 0 : if (ret != EOK) {
404 0 : DEBUG(SSSDBG_FATAL_FAILURE,
405 : "Setting ad_hostname failed [%s].\n",
406 : strerror(ret));
407 0 : goto done;
408 : }
409 : }
410 :
411 :
412 : /* Always use the upper-case AD domain for the kerberos realm */
413 0 : realm = get_uppercase_realm(opts, domain);
414 0 : if (!realm) {
415 0 : ret = ENOMEM;
416 0 : goto done;
417 : }
418 :
419 0 : ret = dp_opt_set_string(opts->basic, AD_KRB5_REALM, realm);
420 0 : if (ret != EOK) {
421 0 : goto done;
422 : }
423 :
424 : /* Active Directory is always case-insensitive */
425 0 : ret = confdb_get_string(cdb, mem_ctx, conf_path,
426 : CONFDB_DOMAIN_CASE_SENSITIVE, "false",
427 : &case_sensitive_opt);
428 0 : if (ret != EOK) {
429 0 : DEBUG(SSSDBG_CRIT_FAILURE, "condb_get_string failed.\n");
430 0 : goto done;
431 : }
432 :
433 0 : if (strcasecmp(case_sensitive_opt, "true") == 0) {
434 0 : DEBUG(SSSDBG_CRIT_FAILURE,
435 : "Warning: AD domain can not be set as case-sensitive.\n");
436 0 : dom->case_sensitive = false;
437 0 : dom->case_preserve = false;
438 0 : } else if (strcasecmp(case_sensitive_opt, "false") == 0) {
439 0 : dom->case_sensitive = false;
440 0 : dom->case_preserve = false;
441 0 : } else if (strcasecmp(case_sensitive_opt, "preserving") == 0) {
442 0 : dom->case_sensitive = false;
443 0 : dom->case_preserve = true;
444 : } else {
445 0 : DEBUG(SSSDBG_FATAL_FAILURE,
446 : "Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE);
447 0 : goto done;
448 : }
449 :
450 0 : opt_override = dom->case_preserve ? "preserving" : "false";
451 :
452 : /* Set this in the confdb so that the responders pick it
453 : * up when they start up.
454 : */
455 0 : ret = confdb_set_string(cdb, conf_path, "case_sensitive", opt_override);
456 0 : if (ret != EOK) {
457 0 : DEBUG(SSSDBG_CRIT_FAILURE,
458 : "Could not set domain option case_sensitive: [%s]\n",
459 : strerror(ret));
460 0 : goto done;
461 : }
462 :
463 0 : DEBUG(SSSDBG_CONF_SETTINGS,
464 : "Setting domain option case_sensitive to [%s]\n", opt_override);
465 :
466 0 : ret = EOK;
467 0 : *_opts = opts;
468 :
469 : done:
470 0 : if (ret != EOK) {
471 0 : talloc_zfree(opts);
472 : }
473 0 : return ret;
474 : }
475 :
476 : static void
477 : ad_resolve_callback(void *private_data, struct fo_server *server);
478 :
479 : static errno_t
480 12 : _ad_servers_init(struct ad_service *service,
481 : struct be_ctx *bectx,
482 : const char *fo_service,
483 : const char *fo_gc_service,
484 : const char *servers,
485 : const char *ad_domain,
486 : bool primary)
487 : {
488 : size_t i;
489 12 : errno_t ret = 0;
490 : char **list;
491 : struct ad_server_data *sdata;
492 : TALLOC_CTX *tmp_ctx;
493 :
494 12 : tmp_ctx = talloc_new(NULL);
495 12 : if (!tmp_ctx) return ENOMEM;
496 :
497 : /* Split the server list */
498 12 : ret = split_on_separator(tmp_ctx, servers, ',', true, true, &list, NULL);
499 12 : if (ret != EOK) {
500 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse server list!\n");
501 0 : goto done;
502 : }
503 :
504 : /* Add each of these servers to the failover service */
505 24 : for (i = 0; list[i]; i++) {
506 12 : if (be_fo_is_srv_identifier(list[i])) {
507 12 : if (!primary) {
508 0 : DEBUG(SSSDBG_MINOR_FAILURE,
509 : "Failed to add server [%s] to failover service: "
510 : "SRV resolution only allowed for primary servers!\n",
511 : list[i]);
512 0 : continue;
513 : }
514 :
515 12 : sdata = talloc(service, struct ad_server_data);
516 12 : if (sdata == NULL) {
517 0 : ret = ENOMEM;
518 0 : goto done;
519 : }
520 12 : sdata->gc = true;
521 :
522 12 : ret = be_fo_add_srv_server(bectx, fo_gc_service, "gc",
523 : ad_domain, BE_FO_PROTO_TCP,
524 : false, sdata);
525 12 : if (ret != EOK) {
526 0 : DEBUG(SSSDBG_FATAL_FAILURE,
527 : "Failed to add service discovery to failover: [%s]\n",
528 : strerror(ret));
529 0 : goto done;
530 : }
531 :
532 12 : sdata = talloc(service, struct ad_server_data);
533 12 : if (sdata == NULL) {
534 0 : ret = ENOMEM;
535 0 : goto done;
536 : }
537 12 : sdata->gc = false;
538 :
539 12 : ret = be_fo_add_srv_server(bectx, fo_service, "ldap",
540 : ad_domain, BE_FO_PROTO_TCP,
541 : false, sdata);
542 12 : if (ret != EOK) {
543 0 : DEBUG(SSSDBG_FATAL_FAILURE,
544 : "Failed to add service discovery to failover: [%s]\n",
545 : strerror(ret));
546 0 : goto done;
547 : }
548 :
549 12 : DEBUG(SSSDBG_CONF_SETTINGS, "Added service discovery for AD\n");
550 12 : continue;
551 : }
552 :
553 : /* It could be ipv6 address in square brackets. Remove
554 : * the brackets if needed. */
555 0 : ret = remove_ipv6_brackets(list[i]);
556 0 : if (ret != EOK) {
557 0 : goto done;
558 : }
559 :
560 0 : sdata = talloc(service, struct ad_server_data);
561 0 : if (sdata == NULL) {
562 0 : ret = ENOMEM;
563 0 : goto done;
564 : }
565 0 : sdata->gc = true;
566 :
567 0 : ret = be_fo_add_server(bectx, fo_gc_service, list[i], 0, sdata, primary);
568 0 : if (ret && ret != EEXIST) {
569 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n");
570 0 : goto done;
571 : }
572 :
573 0 : sdata = talloc(service, struct ad_server_data);
574 0 : if (sdata == NULL) {
575 0 : ret = ENOMEM;
576 0 : goto done;
577 : }
578 0 : sdata->gc = false;
579 :
580 0 : ret = be_fo_add_server(bectx, fo_service, list[i], 0, sdata, primary);
581 0 : if (ret && ret != EEXIST) {
582 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n");
583 0 : goto done;
584 : }
585 :
586 0 : DEBUG(SSSDBG_CONF_SETTINGS, "Added failover server %s\n", list[i]);
587 : }
588 : done:
589 12 : talloc_free(tmp_ctx);
590 12 : return ret;
591 : }
592 :
593 : static inline errno_t
594 12 : ad_primary_servers_init(struct ad_service *service,
595 : struct be_ctx *bectx, const char *servers,
596 : const char *fo_service, const char *fo_gc_service,
597 : const char *ad_domain)
598 : {
599 12 : return _ad_servers_init(service, bectx, fo_service,
600 : fo_gc_service, servers, ad_domain, true);
601 : }
602 :
603 : static inline errno_t
604 0 : ad_backup_servers_init(struct ad_service *service,
605 : struct be_ctx *bectx, const char *servers,
606 : const char *fo_service, const char *fo_gc_service,
607 : const char *ad_domain)
608 : {
609 0 : return _ad_servers_init(service, bectx, fo_service,
610 : fo_gc_service, servers, ad_domain, false);
611 : }
612 :
613 0 : static int ad_user_data_cmp(void *ud1, void *ud2)
614 : {
615 : struct ad_server_data *sd1, *sd2;
616 :
617 0 : sd1 = talloc_get_type(ud1, struct ad_server_data);
618 0 : sd2 = talloc_get_type(ud2, struct ad_server_data);
619 0 : if (sd1 == NULL || sd2 == NULL) {
620 0 : DEBUG(SSSDBG_TRACE_FUNC, "No user data\n");
621 0 : return sd1 == sd2 ? 0 : 1;
622 : }
623 :
624 0 : DEBUG(SSSDBG_TRACE_LIBS, "Comparing %s with %s\n",
625 : sd1->gc ? "GC" : "LDAP",
626 : sd2->gc ? "GC" : "LDAP");
627 :
628 0 : if (sd1->gc == sd2->gc) {
629 0 : return 0;
630 : }
631 :
632 0 : return 1;
633 : }
634 :
635 0 : static void ad_online_cb(void *pvt)
636 : {
637 0 : struct ad_service *service = talloc_get_type(pvt, struct ad_service);
638 :
639 0 : if (service == NULL) {
640 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid private pointer\n");
641 0 : return;
642 : }
643 :
644 0 : DEBUG(SSSDBG_TRACE_FUNC, "The AD provider is online\n");
645 : }
646 :
647 : errno_t
648 12 : ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
649 : const char *primary_servers,
650 : const char *backup_servers,
651 : const char *krb5_realm,
652 : const char *ad_service,
653 : const char *ad_gc_service,
654 : const char *ad_domain,
655 : struct ad_service **_service)
656 : {
657 : errno_t ret;
658 : TALLOC_CTX *tmp_ctx;
659 : struct ad_service *service;
660 :
661 12 : tmp_ctx = talloc_new(mem_ctx);
662 12 : if (!tmp_ctx) return ENOMEM;
663 :
664 12 : service = talloc_zero(tmp_ctx, struct ad_service);
665 12 : if (!service) {
666 0 : ret = ENOMEM;
667 0 : goto done;
668 : }
669 :
670 12 : service->sdap = talloc_zero(service, struct sdap_service);
671 12 : service->gc = talloc_zero(service, struct sdap_service);
672 12 : if (!service->sdap || !service->gc) {
673 0 : ret = ENOMEM;
674 0 : goto done;
675 : }
676 :
677 12 : service->sdap->name = talloc_strdup(service->sdap, ad_service);
678 12 : service->gc->name = talloc_strdup(service->gc, ad_gc_service);
679 12 : if (!service->sdap->name || !service->gc->name) {
680 0 : ret = ENOMEM;
681 0 : goto done;
682 : }
683 :
684 12 : service->krb5_service = talloc_zero(service, struct krb5_service);
685 12 : if (!service->krb5_service) {
686 0 : ret = ENOMEM;
687 0 : goto done;
688 : }
689 :
690 12 : ret = be_fo_add_service(bectx, ad_service, ad_user_data_cmp);
691 12 : if (ret != EOK) {
692 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n");
693 0 : goto done;
694 : }
695 :
696 12 : ret = be_fo_add_service(bectx, ad_gc_service, ad_user_data_cmp);
697 12 : if (ret != EOK) {
698 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create GC failover service!\n");
699 0 : goto done;
700 : }
701 :
702 12 : service->krb5_service->name = talloc_strdup(service->krb5_service,
703 : ad_service);
704 12 : if (!service->krb5_service->name) {
705 0 : ret = ENOMEM;
706 0 : goto done;
707 : }
708 12 : service->sdap->kinit_service_name = service->krb5_service->name;
709 12 : service->gc->kinit_service_name = service->krb5_service->name;
710 :
711 12 : if (!krb5_realm) {
712 0 : DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm set\n");
713 0 : ret = EINVAL;
714 0 : goto done;
715 : }
716 24 : service->krb5_service->realm =
717 12 : talloc_strdup(service->krb5_service, krb5_realm);
718 12 : if (!service->krb5_service->realm) {
719 0 : ret = ENOMEM;
720 0 : goto done;
721 : }
722 :
723 12 : if (!primary_servers) {
724 12 : DEBUG(SSSDBG_CONF_SETTINGS,
725 : "No primary servers defined, using service discovery\n");
726 12 : primary_servers = BE_SRV_IDENTIFIER;
727 : }
728 :
729 12 : ret = ad_primary_servers_init(service, bectx,
730 : primary_servers, ad_service,
731 : ad_gc_service, ad_domain);
732 12 : if (ret != EOK) {
733 0 : goto done;
734 : }
735 :
736 12 : if (backup_servers) {
737 0 : ret = ad_backup_servers_init(service, bectx,
738 : backup_servers, ad_service,
739 : ad_gc_service, ad_domain);
740 0 : if (ret != EOK) {
741 0 : goto done;
742 : }
743 : }
744 :
745 12 : ret = be_add_online_cb(bectx, bectx, ad_online_cb, service, NULL);
746 12 : if (ret != EOK) {
747 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up AD online callback\n");
748 0 : goto done;
749 : }
750 :
751 12 : ret = be_fo_service_add_callback(mem_ctx, bectx, ad_service,
752 : ad_resolve_callback, service);
753 12 : if (ret != EOK) {
754 0 : DEBUG(SSSDBG_FATAL_FAILURE,
755 : "Failed to add failover callback! [%s]\n", strerror(ret));
756 0 : goto done;
757 : }
758 :
759 12 : ret = be_fo_service_add_callback(mem_ctx, bectx, ad_gc_service,
760 : ad_resolve_callback, service);
761 12 : if (ret != EOK) {
762 0 : DEBUG(SSSDBG_FATAL_FAILURE,
763 : "Failed to add failover callback! [%s]\n", strerror(ret));
764 0 : goto done;
765 : }
766 :
767 12 : *_service = talloc_steal(mem_ctx, service);
768 :
769 12 : ret = EOK;
770 :
771 : done:
772 12 : talloc_free(tmp_ctx);
773 12 : return ret;
774 : }
775 :
776 : static void
777 0 : ad_resolve_callback(void *private_data, struct fo_server *server)
778 : {
779 : errno_t ret;
780 : TALLOC_CTX *tmp_ctx;
781 : struct ad_service *service;
782 : struct resolv_hostent *srvaddr;
783 : struct sockaddr_storage *sockaddr;
784 : char *address;
785 : const char *safe_address;
786 : char *new_uri;
787 : int new_port;
788 : const char *srv_name;
789 0 : struct ad_server_data *sdata = NULL;
790 :
791 0 : tmp_ctx = talloc_new(NULL);
792 0 : if (!tmp_ctx) {
793 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
794 0 : return;
795 : }
796 :
797 0 : sdata = fo_get_server_user_data(server);
798 0 : if (fo_is_srv_lookup(server) == false && sdata == NULL) {
799 0 : DEBUG(SSSDBG_CRIT_FAILURE, "No user data?\n");
800 0 : ret = EINVAL;
801 0 : goto done;
802 : }
803 :
804 0 : service = talloc_get_type(private_data, struct ad_service);
805 0 : if (!service) {
806 0 : ret = EINVAL;
807 0 : goto done;
808 : }
809 :
810 0 : srvaddr = fo_get_server_hostent(server);
811 0 : if (!srvaddr) {
812 0 : DEBUG(SSSDBG_CRIT_FAILURE,
813 : "No hostent available for server (%s)\n",
814 : fo_get_server_str_name(server));
815 0 : ret = EINVAL;
816 0 : goto done;
817 : }
818 :
819 0 : address = resolv_get_string_address(tmp_ctx, srvaddr);
820 0 : if (address == NULL) {
821 0 : DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_string_address failed.\n");
822 0 : ret = EIO;
823 0 : goto done;
824 : }
825 :
826 0 : srv_name = fo_get_server_name(server);
827 0 : if (srv_name == NULL) {
828 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not get server host name\n");
829 0 : ret = EINVAL;
830 0 : goto done;
831 : }
832 :
833 0 : new_uri = talloc_asprintf(service->sdap, "ldap://%s", srv_name);
834 0 : if (!new_uri) {
835 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy URI\n");
836 0 : ret = ENOMEM;
837 0 : goto done;
838 : }
839 0 : DEBUG(SSSDBG_CONF_SETTINGS, "Constructed uri '%s'\n", new_uri);
840 :
841 0 : sockaddr = resolv_get_sockaddr_address(tmp_ctx, srvaddr, LDAP_PORT);
842 0 : if (sockaddr == NULL) {
843 0 : DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_sockaddr_address failed.\n");
844 0 : ret = EIO;
845 0 : goto done;
846 : }
847 :
848 : /* free old one and replace with new one */
849 0 : talloc_zfree(service->sdap->uri);
850 0 : service->sdap->uri = new_uri;
851 0 : talloc_zfree(service->sdap->sockaddr);
852 0 : service->sdap->sockaddr = talloc_steal(service->sdap, sockaddr);
853 :
854 0 : talloc_zfree(service->gc->uri);
855 0 : talloc_zfree(service->gc->sockaddr);
856 0 : if (sdata && sdata->gc) {
857 0 : new_port = fo_get_server_port(server);
858 0 : new_port = (new_port == 0) ? AD_GC_PORT : new_port;
859 :
860 0 : service->gc->uri = talloc_asprintf(service->gc, "%s:%d",
861 : new_uri, new_port);
862 :
863 0 : service->gc->sockaddr = resolv_get_sockaddr_address(service->gc,
864 : srvaddr,
865 : new_port);
866 : } else {
867 : /* Make sure there always is an URI even if we know that this
868 : * server doesn't support GC. That way the lookup would go through
869 : * just not return anything
870 : */
871 0 : service->gc->uri = talloc_strdup(service->gc, service->sdap->uri);
872 0 : service->gc->sockaddr = talloc_memdup(service->gc, service->sdap->sockaddr,
873 : sizeof(struct sockaddr_storage));
874 : }
875 :
876 0 : if (!service->gc->uri) {
877 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to append to URI\n");
878 0 : ret = ENOMEM;
879 0 : goto done;
880 : }
881 0 : DEBUG(SSSDBG_CONF_SETTINGS, "Constructed GC uri '%s'\n", service->gc->uri);
882 :
883 0 : if (service->gc->sockaddr == NULL) {
884 0 : DEBUG(SSSDBG_CRIT_FAILURE,
885 : "resolv_get_sockaddr_address failed.\n");
886 0 : ret = EIO;
887 0 : goto done;
888 : }
889 :
890 : /* Only write kdcinfo files for local servers */
891 0 : if ((sdata == NULL || sdata->gc == false) &&
892 0 : service->krb5_service->write_kdcinfo) {
893 : /* Write krb5 info files */
894 0 : safe_address = sss_escape_ip_address(tmp_ctx,
895 : srvaddr->family,
896 : address);
897 0 : if (safe_address == NULL) {
898 0 : DEBUG(SSSDBG_CRIT_FAILURE, "sss_escape_ip_address failed.\n");
899 0 : ret = ENOMEM;
900 0 : goto done;
901 : }
902 :
903 0 : ret = write_krb5info_file(service->krb5_service->realm, safe_address,
904 : SSS_KRB5KDC_FO_SRV);
905 0 : if (ret != EOK) {
906 0 : DEBUG(SSSDBG_MINOR_FAILURE,
907 : "write_krb5info_file failed, authentication might fail.\n");
908 : }
909 : }
910 :
911 0 : ret = EOK;
912 : done:
913 0 : if (ret != EOK) {
914 0 : DEBUG(SSSDBG_CRIT_FAILURE,
915 : "Error: [%s]\n", strerror(ret));
916 : }
917 0 : talloc_free(tmp_ctx);
918 0 : return;
919 : }
920 :
921 : static errno_t
922 18 : ad_set_sdap_options(struct ad_options *ad_opts,
923 : struct sdap_options *id_opts)
924 : {
925 : errno_t ret;
926 : char *krb5_realm;
927 : char *keytab_path;
928 :
929 : /* We only support Kerberos password policy with AD, so
930 : * force that on.
931 : */
932 18 : ret = dp_opt_set_string(id_opts->basic,
933 : SDAP_PWD_POLICY,
934 : PWD_POL_OPT_MIT);
935 18 : if (ret != EOK) {
936 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Could not set password policy\n");
937 0 : goto done;
938 : }
939 :
940 : /* Set the Kerberos Realm for GSSAPI */
941 18 : krb5_realm = dp_opt_get_string(ad_opts->basic, AD_KRB5_REALM);
942 18 : if (!krb5_realm) {
943 : /* Should be impossible, this is set in ad_get_common_options() */
944 0 : DEBUG(SSSDBG_FATAL_FAILURE, "No Kerberos realm\n");
945 0 : ret = EINVAL;
946 0 : goto done;
947 : }
948 :
949 18 : ret = dp_opt_set_string(id_opts->basic, SDAP_KRB5_REALM, krb5_realm);
950 18 : if (ret != EOK) goto done;
951 18 : DEBUG(SSSDBG_CONF_SETTINGS,
952 : "Option %s set to %s\n",
953 : id_opts->basic[SDAP_KRB5_REALM].opt_name,
954 : krb5_realm);
955 :
956 18 : keytab_path = dp_opt_get_string(ad_opts->basic, AD_KEYTAB);
957 18 : if (keytab_path) {
958 9 : ret = dp_opt_set_string(id_opts->basic, SDAP_KRB5_KEYTAB,
959 : keytab_path);
960 9 : if (ret != EOK) goto done;
961 9 : DEBUG(SSSDBG_CONF_SETTINGS,
962 : "Option %s set to %s\n",
963 : id_opts->basic[SDAP_KRB5_KEYTAB].opt_name,
964 : keytab_path);
965 : }
966 :
967 18 : ret = sdap_set_sasl_options(id_opts,
968 : dp_opt_get_string(ad_opts->basic,
969 : AD_HOSTNAME),
970 : dp_opt_get_string(ad_opts->basic,
971 : AD_KRB5_REALM),
972 : keytab_path);
973 18 : if (ret != EOK) {
974 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot set the SASL-related options\n");
975 0 : goto done;
976 : }
977 :
978 : /* fix schema to AD */
979 18 : id_opts->schema_type = SDAP_SCHEMA_AD;
980 :
981 18 : ad_opts->id = id_opts;
982 18 : ret = EOK;
983 : done:
984 18 : return ret;
985 : }
986 :
987 : errno_t
988 0 : ad_get_id_options(struct ad_options *ad_opts,
989 : struct confdb_ctx *cdb,
990 : const char *conf_path,
991 : struct sdap_options **_opts)
992 : {
993 : struct sdap_options *id_opts;
994 : errno_t ret;
995 :
996 0 : ret = ad_create_sdap_options(ad_opts, cdb, conf_path, &id_opts);
997 0 : if (ret != EOK) {
998 0 : return ENOMEM;
999 : }
1000 :
1001 0 : ret = ad_set_sdap_options(ad_opts, id_opts);
1002 0 : if (ret != EOK) {
1003 0 : talloc_free(id_opts);
1004 0 : return ret;
1005 : }
1006 :
1007 0 : ret = sdap_domain_add(id_opts,
1008 0 : ad_opts->id_ctx->sdap_id_ctx->be->domain,
1009 : NULL);
1010 0 : if (ret != EOK) {
1011 0 : talloc_free(id_opts);
1012 0 : return ret;
1013 : }
1014 :
1015 : /* Set up search bases if they were assigned explicitly */
1016 0 : ret = ad_set_search_bases(id_opts);
1017 0 : if (ret != EOK) {
1018 0 : talloc_free(id_opts);
1019 0 : return ret;
1020 : }
1021 :
1022 0 : *_opts = id_opts;
1023 0 : return EOK;
1024 : }
1025 :
1026 : errno_t
1027 0 : ad_set_search_bases(struct sdap_options *id_opts)
1028 : {
1029 : errno_t ret;
1030 : char *default_search_base;
1031 : size_t o;
1032 0 : const int search_base_options[] = { SDAP_USER_SEARCH_BASE,
1033 : SDAP_GROUP_SEARCH_BASE,
1034 : SDAP_NETGROUP_SEARCH_BASE,
1035 : SDAP_SERVICE_SEARCH_BASE,
1036 : -1 };
1037 :
1038 : /* AD servers provide defaultNamingContext, so we will
1039 : * rely on that to specify the search base unless it has
1040 : * been specifically overridden.
1041 : */
1042 :
1043 0 : default_search_base =
1044 0 : dp_opt_get_string(id_opts->basic, SDAP_SEARCH_BASE);
1045 :
1046 0 : if (default_search_base) {
1047 : /* set search bases if they are not */
1048 0 : for (o = 0; search_base_options[o] != -1; o++) {
1049 0 : if (NULL == dp_opt_get_string(id_opts->basic,
1050 : search_base_options[o])) {
1051 0 : ret = dp_opt_set_string(id_opts->basic,
1052 : search_base_options[o],
1053 : default_search_base);
1054 0 : if (ret != EOK) {
1055 0 : goto done;
1056 : }
1057 0 : DEBUG(SSSDBG_CONF_SETTINGS,
1058 : "Option %s set to %s\n",
1059 : id_opts->basic[search_base_options[o]].opt_name,
1060 : dp_opt_get_string(id_opts->basic,
1061 : search_base_options[o]));
1062 : }
1063 : }
1064 : } else {
1065 0 : DEBUG(SSSDBG_CONF_SETTINGS,
1066 : "Search base not set. SSSD will attempt to discover it later, "
1067 : "when connecting to the LDAP server.\n");
1068 : }
1069 :
1070 : /* Default search */
1071 0 : ret = sdap_parse_search_base(id_opts, id_opts->basic,
1072 : SDAP_SEARCH_BASE,
1073 0 : &id_opts->sdom->search_bases);
1074 0 : if (ret != EOK && ret != ENOENT) goto done;
1075 :
1076 : /* User search */
1077 0 : ret = sdap_parse_search_base(id_opts, id_opts->basic,
1078 : SDAP_USER_SEARCH_BASE,
1079 0 : &id_opts->sdom->user_search_bases);
1080 0 : if (ret != EOK && ret != ENOENT) goto done;
1081 :
1082 : /* Group search base */
1083 0 : ret = sdap_parse_search_base(id_opts, id_opts->basic,
1084 : SDAP_GROUP_SEARCH_BASE,
1085 0 : &id_opts->sdom->group_search_bases);
1086 0 : if (ret != EOK && ret != ENOENT) goto done;
1087 :
1088 : /* Netgroup search */
1089 0 : ret = sdap_parse_search_base(id_opts, id_opts->basic,
1090 : SDAP_NETGROUP_SEARCH_BASE,
1091 0 : &id_opts->sdom->netgroup_search_bases);
1092 0 : if (ret != EOK && ret != ENOENT) goto done;
1093 :
1094 : /* Service search */
1095 0 : ret = sdap_parse_search_base(id_opts, id_opts->basic,
1096 : SDAP_SERVICE_SEARCH_BASE,
1097 0 : &id_opts->sdom->service_search_bases);
1098 0 : if (ret != EOK && ret != ENOENT) goto done;
1099 :
1100 0 : ret = EOK;
1101 : done:
1102 0 : return ret;
1103 : }
1104 :
1105 : errno_t
1106 0 : ad_get_auth_options(TALLOC_CTX *mem_ctx,
1107 : struct ad_options *ad_opts,
1108 : struct be_ctx *bectx,
1109 : struct dp_option **_opts)
1110 : {
1111 : errno_t ret;
1112 : struct dp_option *krb5_options;
1113 : const char *ad_servers;
1114 : const char *krb5_realm;
1115 :
1116 0 : TALLOC_CTX *tmp_ctx = talloc_new(NULL);
1117 0 : if (!tmp_ctx) return ENOMEM;
1118 :
1119 : /* Get krb5 options */
1120 0 : ret = dp_get_options(tmp_ctx, bectx->cdb, bectx->conf_path,
1121 : ad_def_krb5_opts, KRB5_OPTS,
1122 : &krb5_options);
1123 0 : if (ret != EOK) {
1124 0 : DEBUG(SSSDBG_CRIT_FAILURE,
1125 : "Could not read Kerberos options from the configuration\n");
1126 0 : goto done;
1127 : }
1128 :
1129 0 : ad_servers = dp_opt_get_string(ad_opts->basic, AD_SERVER);
1130 :
1131 : /* Force the krb5_servers to match the ad_servers */
1132 0 : ret = dp_opt_set_string(krb5_options, KRB5_KDC, ad_servers);
1133 0 : if (ret != EOK) goto done;
1134 0 : DEBUG(SSSDBG_CONF_SETTINGS,
1135 : "Option %s set to %s\n",
1136 : krb5_options[KRB5_KDC].opt_name,
1137 : ad_servers);
1138 :
1139 : /* Set krb5 realm */
1140 : /* Set the Kerberos Realm for GSSAPI */
1141 0 : krb5_realm = dp_opt_get_string(ad_opts->basic, AD_KRB5_REALM);
1142 0 : if (!krb5_realm) {
1143 : /* Should be impossible, this is set in ad_get_common_options() */
1144 0 : DEBUG(SSSDBG_FATAL_FAILURE, "No Kerberos realm\n");
1145 0 : ret = EINVAL;
1146 0 : goto done;
1147 : }
1148 :
1149 : /* Force the kerberos realm to match the AD_KRB5_REALM (which may have
1150 : * been upper-cased in ad_common_options()
1151 : */
1152 0 : ret = dp_opt_set_string(krb5_options, KRB5_REALM, krb5_realm);
1153 0 : if (ret != EOK) goto done;
1154 0 : DEBUG(SSSDBG_CONF_SETTINGS,
1155 : "Option %s set to %s\n",
1156 : krb5_options[KRB5_REALM].opt_name,
1157 : krb5_realm);
1158 :
1159 : /* Set flag that controls whether we want to write the
1160 : * kdcinfo files at all
1161 : */
1162 0 : ad_opts->service->krb5_service->write_kdcinfo = \
1163 0 : dp_opt_get_bool(krb5_options, KRB5_USE_KDCINFO);
1164 0 : DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n",
1165 : krb5_options[KRB5_USE_KDCINFO].opt_name,
1166 : ad_opts->service->krb5_service->write_kdcinfo ? "true" : "false");
1167 :
1168 0 : *_opts = talloc_steal(mem_ctx, krb5_options);
1169 :
1170 0 : ret = EOK;
1171 :
1172 : done:
1173 0 : talloc_free(tmp_ctx);
1174 0 : return ret;
1175 : }
1176 :
1177 0 : errno_t ad_get_dyndns_options(struct be_ctx *be_ctx,
1178 : struct ad_options *ad_opts)
1179 : {
1180 : errno_t ret;
1181 :
1182 0 : ret = be_nsupdate_init(ad_opts, be_ctx, ad_dyndns_opts,
1183 : &ad_opts->dyndns_ctx);
1184 0 : if (ret != EOK) {
1185 0 : DEBUG(SSSDBG_OP_FAILURE,
1186 : "Cannot initialize AD dyndns opts [%d]: %s\n",
1187 : ret, sss_strerror(ret));
1188 0 : return ret;
1189 : }
1190 :
1191 0 : return EOK;
1192 : }
1193 :
1194 :
1195 : struct ad_id_ctx *
1196 12 : ad_id_ctx_init(struct ad_options *ad_opts, struct be_ctx *bectx)
1197 : {
1198 : struct sdap_id_ctx *sdap_ctx;
1199 : struct ad_id_ctx *ad_ctx;
1200 :
1201 12 : ad_ctx = talloc_zero(ad_opts, struct ad_id_ctx);
1202 12 : if (ad_ctx == NULL) {
1203 0 : return NULL;
1204 : }
1205 12 : ad_ctx->ad_options = ad_opts;
1206 :
1207 12 : sdap_ctx = sdap_id_ctx_new(ad_ctx, bectx, ad_opts->service->sdap);
1208 12 : if (sdap_ctx == NULL) {
1209 0 : talloc_free(ad_ctx);
1210 0 : return NULL;
1211 : }
1212 12 : ad_ctx->sdap_id_ctx = sdap_ctx;
1213 12 : ad_ctx->ldap_ctx = sdap_ctx->conn;
1214 :
1215 12 : ad_ctx->gc_ctx = sdap_id_ctx_conn_add(sdap_ctx, ad_opts->service->gc);
1216 12 : if (ad_ctx->gc_ctx == NULL) {
1217 0 : talloc_free(ad_ctx);
1218 0 : return NULL;
1219 : }
1220 :
1221 12 : return ad_ctx;
1222 : }
1223 :
1224 : struct sdap_id_conn_ctx *
1225 10 : ad_get_dom_ldap_conn(struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom)
1226 : {
1227 : struct sdap_id_conn_ctx *conn;
1228 : struct sdap_domain *sdom;
1229 : struct ad_id_ctx *subdom_id_ctx;
1230 :
1231 10 : sdom = sdap_domain_get(ad_ctx->sdap_id_ctx->opts, dom);
1232 10 : if (sdom == NULL || sdom->pvt == NULL) {
1233 0 : DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n",
1234 : dom->name);
1235 0 : return NULL;
1236 : }
1237 10 : subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
1238 10 : conn = subdom_id_ctx->ldap_ctx;
1239 :
1240 10 : if (IS_SUBDOMAIN(sdom->dom) == true && conn != NULL) {
1241 : /* Regardless of connection types, a subdomain error must not be
1242 : * allowed to set the whole back end offline, rather report an error
1243 : * and let the caller deal with it (normally disable the subdomain
1244 : */
1245 5 : conn->ignore_mark_offline = true;
1246 : }
1247 :
1248 10 : return conn;
1249 : }
1250 :
1251 : struct sdap_id_conn_ctx **
1252 4 : ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx,
1253 : struct sss_domain_info *dom)
1254 : {
1255 : struct sdap_id_conn_ctx **clist;
1256 4 : int cindex = 0;
1257 :
1258 4 : clist = talloc_zero_array(mem_ctx, struct sdap_id_conn_ctx *, 3);
1259 4 : if (clist == NULL) return NULL;
1260 :
1261 : /* Always try GC first */
1262 4 : if (dp_opt_get_bool(ad_ctx->ad_options->basic, AD_ENABLE_GC)) {
1263 2 : clist[cindex] = ad_ctx->gc_ctx;
1264 2 : clist[cindex]->ignore_mark_offline = true;
1265 2 : cindex++;
1266 : }
1267 :
1268 4 : clist[cindex] = ad_get_dom_ldap_conn(ad_ctx, dom);
1269 :
1270 4 : return clist;
1271 : }
1272 :
1273 : struct sdap_id_conn_ctx **
1274 2 : ad_ldap_conn_list(TALLOC_CTX *mem_ctx,
1275 : struct ad_id_ctx *ad_ctx,
1276 : struct sss_domain_info *dom)
1277 : {
1278 : struct sdap_id_conn_ctx **clist;
1279 :
1280 2 : clist = talloc_zero_array(mem_ctx, struct sdap_id_conn_ctx *, 2);
1281 2 : if (clist == NULL) {
1282 0 : return NULL;
1283 : }
1284 :
1285 2 : clist[0] = ad_get_dom_ldap_conn(ad_ctx, dom);
1286 :
1287 2 : clist[1] = NULL;
1288 2 : return clist;
1289 : }
1290 :
1291 : struct sdap_id_conn_ctx **
1292 2 : ad_user_conn_list(TALLOC_CTX *mem_ctx,
1293 : struct ad_id_ctx *ad_ctx,
1294 : struct sss_domain_info *dom)
1295 : {
1296 : struct sdap_id_conn_ctx **clist;
1297 2 : int cindex = 0;
1298 :
1299 2 : clist = talloc_zero_array(ad_ctx, struct sdap_id_conn_ctx *, 3);
1300 2 : if (clist == NULL) {
1301 0 : return NULL;
1302 : }
1303 :
1304 : /* Try GC first for users from trusted domains, but go to LDAP
1305 : * for users from non-trusted domains to get all POSIX attrs
1306 : */
1307 2 : if (dp_opt_get_bool(ad_ctx->ad_options->basic, AD_ENABLE_GC)
1308 2 : && IS_SUBDOMAIN(dom)) {
1309 1 : clist[cindex] = ad_ctx->gc_ctx;
1310 1 : clist[cindex]->ignore_mark_offline = true;
1311 1 : cindex++;
1312 : }
1313 :
1314 : /* Users from primary domain can be just downloaded from LDAP.
1315 : * The domain's LDAP connection also works as a fallback
1316 : */
1317 2 : clist[cindex] = ad_get_dom_ldap_conn(ad_ctx, dom);
1318 :
1319 2 : return clist;
1320 : }
|