Line data Source code
1 : /*
2 : Authors:
3 : Pavel Březina <pbrezina@redhat.com>
4 :
5 : Copyright (C) 2013 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 <strings.h>
22 : #include <talloc.h>
23 : #include <tevent.h>
24 :
25 : #include "util/util.h"
26 : #include "resolv/async_resolv.h"
27 : #include "providers/fail_over_srv.h"
28 :
29 : struct fo_discover_srv_state {
30 : char *dns_domain;
31 : struct fo_server_info *servers;
32 : size_t num_servers;
33 : uint32_t ttl;
34 : };
35 :
36 : static void fo_discover_srv_done(struct tevent_req *subreq);
37 :
38 8 : struct tevent_req *fo_discover_srv_send(TALLOC_CTX *mem_ctx,
39 : struct tevent_context *ev,
40 : struct resolv_ctx *resolv_ctx,
41 : const char *service,
42 : const char *protocol,
43 : const char **discovery_domains)
44 : {
45 8 : struct fo_discover_srv_state *state = NULL;
46 8 : struct tevent_req *req = NULL;
47 8 : struct tevent_req *subreq = NULL;
48 : errno_t ret;
49 :
50 8 : req = tevent_req_create(mem_ctx, &state, struct fo_discover_srv_state);
51 8 : if (req == NULL) {
52 0 : DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
53 0 : return NULL;
54 : }
55 :
56 8 : subreq = resolv_discover_srv_send(state, ev, resolv_ctx, service,
57 : protocol, discovery_domains);
58 8 : if (subreq == NULL) {
59 0 : ret = ENOMEM;
60 0 : goto immediately;
61 : }
62 :
63 8 : tevent_req_set_callback(subreq, fo_discover_srv_done, req);
64 :
65 8 : return req;
66 :
67 : immediately:
68 0 : tevent_req_error(req, ret);
69 0 : tevent_req_post(req, ev);
70 :
71 0 : return req;
72 : }
73 :
74 8 : static void fo_discover_srv_done(struct tevent_req *subreq)
75 : {
76 8 : struct fo_discover_srv_state *state = NULL;
77 8 : struct tevent_req *req = NULL;
78 8 : struct ares_srv_reply *reply_list = NULL;
79 8 : struct ares_srv_reply *record = NULL;
80 : int i;
81 : errno_t ret;
82 :
83 8 : req = tevent_req_callback_data(subreq, struct tevent_req);
84 8 : state = tevent_req_data(req, struct fo_discover_srv_state);
85 :
86 8 : ret = resolv_discover_srv_recv(state, subreq,
87 : &reply_list, &state->ttl, &state->dns_domain);
88 8 : talloc_zfree(subreq);
89 8 : if (ret == ENOENT) {
90 0 : ret = ERR_SRV_NOT_FOUND;
91 0 : goto done;
92 8 : } else if (ret == EIO) {
93 0 : ret = ERR_SRV_LOOKUP_ERROR;
94 0 : goto done;
95 8 : } else if (ret != EOK) {
96 0 : goto done;
97 : }
98 :
99 8 : DEBUG(SSSDBG_TRACE_FUNC, "Got answer. Processing...\n");
100 :
101 : /* sort and store the answer */
102 8 : ret = resolv_sort_srv_reply(&reply_list);
103 8 : if (ret != EOK) {
104 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not sort the answers from DNS "
105 : "[%d]: %s\n", ret, strerror(ret));
106 0 : goto done;
107 : }
108 :
109 8 : state->num_servers = 0;
110 24 : for (record = reply_list; record != NULL; record = record->next) {
111 16 : state->num_servers++;
112 : }
113 :
114 8 : DEBUG(SSSDBG_TRACE_FUNC, "Got %zu servers\n", state->num_servers);
115 :
116 8 : state->servers = talloc_array(state, struct fo_server_info,
117 : state->num_servers);
118 8 : if (state->servers == NULL) {
119 0 : ret = ENOMEM;
120 0 : goto done;
121 : }
122 :
123 32 : for (record = reply_list, i = 0;
124 : record != NULL;
125 16 : record = record->next, i++) {
126 16 : state->servers[i].host = talloc_steal(state->servers, record->host);
127 16 : state->servers[i].port = record->port;
128 16 : state->servers[i].priority = record->priority;
129 : }
130 :
131 8 : talloc_zfree(reply_list);
132 :
133 8 : ret = EOK;
134 :
135 : done:
136 8 : if (ret != EOK) {
137 0 : tevent_req_error(req, ret);
138 8 : return;
139 : }
140 :
141 8 : tevent_req_done(req);
142 : }
143 :
144 8 : errno_t fo_discover_srv_recv(TALLOC_CTX *mem_ctx,
145 : struct tevent_req *req,
146 : char **_dns_domain,
147 : uint32_t *_ttl,
148 : struct fo_server_info **_servers,
149 : size_t *_num_servers)
150 : {
151 8 : struct fo_discover_srv_state *state = NULL;
152 8 : state = tevent_req_data(req, struct fo_discover_srv_state);
153 :
154 8 : TEVENT_REQ_RETURN_ON_ERROR(req);
155 :
156 8 : if (_dns_domain != NULL) {
157 8 : *_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
158 : }
159 :
160 8 : if (_servers != NULL) {
161 8 : *_servers = talloc_steal(mem_ctx, state->servers);
162 : }
163 :
164 8 : if (_ttl != NULL) {
165 8 : *_ttl = state->ttl;
166 : }
167 :
168 8 : if (_num_servers != NULL) {
169 8 : *_num_servers = state->num_servers;
170 : }
171 :
172 8 : return EOK;
173 : }
174 :
175 : struct fo_discover_servers_state {
176 : struct tevent_context *ev;
177 : struct resolv_ctx *resolv_ctx;
178 : const char *service;
179 : const char *protocol;
180 : const char *primary_domain;
181 : const char *backup_domain;
182 :
183 : char *dns_domain;
184 : uint32_t ttl;
185 : struct fo_server_info *primary_servers;
186 : size_t num_primary_servers;
187 : struct fo_server_info *backup_servers;
188 : size_t num_backup_servers;
189 : };
190 :
191 : static void fo_discover_servers_primary_done(struct tevent_req *subreq);
192 : static void fo_discover_servers_backup_done(struct tevent_req *subreq);
193 :
194 0 : struct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx,
195 : struct tevent_context *ev,
196 : struct resolv_ctx *resolv_ctx,
197 : const char *service,
198 : const char *protocol,
199 : const char *primary_domain,
200 : const char *backup_domain)
201 : {
202 0 : struct fo_discover_servers_state *state = NULL;
203 0 : struct tevent_req *req = NULL;
204 0 : struct tevent_req *subreq = NULL;
205 0 : const char **domains = NULL;
206 : errno_t ret;
207 :
208 0 : req = tevent_req_create(mem_ctx, &state,
209 : struct fo_discover_servers_state);
210 0 : if (req == NULL) {
211 0 : DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
212 0 : return NULL;
213 : }
214 :
215 0 : if (primary_domain == NULL) {
216 0 : if (backup_domain == NULL) {
217 0 : state->primary_servers = NULL;
218 0 : state->num_primary_servers = 0;
219 0 : state->backup_servers = NULL;
220 0 : state->num_backup_servers = 0;
221 0 : state->dns_domain = NULL;
222 0 : state->ttl = 0;
223 :
224 0 : ret = EOK;
225 0 : goto immediately;
226 : } else {
227 0 : primary_domain = backup_domain;
228 0 : backup_domain = NULL;
229 : }
230 : }
231 :
232 0 : state->ev = ev;
233 0 : state->resolv_ctx = resolv_ctx;
234 :
235 0 : state->service = talloc_strdup(state, service);
236 0 : if (state->service == NULL) {
237 0 : ret = ENOMEM;
238 0 : goto immediately;
239 : }
240 :
241 0 : state->protocol = talloc_strdup(state, protocol);
242 0 : if (state->protocol == NULL) {
243 0 : ret = ENOMEM;
244 0 : goto immediately;
245 : }
246 :
247 0 : state->primary_domain = talloc_strdup(state, primary_domain);
248 0 : if (state->primary_domain == NULL) {
249 0 : ret = ENOMEM;
250 0 : goto immediately;
251 : }
252 :
253 0 : state->backup_domain = talloc_strdup(state, backup_domain);
254 0 : if (state->backup_domain == NULL && backup_domain != NULL) {
255 0 : ret = ENOMEM;
256 0 : goto immediately;
257 : }
258 :
259 0 : DEBUG(SSSDBG_TRACE_FUNC, "Looking up primary servers\n");
260 :
261 0 : domains = talloc_zero_array(state, const char *, 3);
262 0 : if (domains == NULL) {
263 0 : ret = ENOMEM;
264 0 : goto immediately;
265 : }
266 :
267 0 : domains[0] = state->primary_domain;
268 0 : domains[1] = state->backup_domain;
269 :
270 0 : subreq = fo_discover_srv_send(state, ev, resolv_ctx,
271 0 : state->service, state->protocol, domains);
272 0 : if (subreq == NULL) {
273 0 : ret = ENOMEM;
274 0 : goto immediately;
275 : }
276 :
277 0 : tevent_req_set_callback(subreq, fo_discover_servers_primary_done, req);
278 :
279 0 : return req;
280 :
281 : immediately:
282 0 : tevent_req_error(req, ret);
283 0 : tevent_req_post(req, ev);
284 :
285 0 : return req;
286 : }
287 :
288 0 : static void fo_discover_servers_primary_done(struct tevent_req *subreq)
289 : {
290 0 : struct fo_discover_servers_state *state = NULL;
291 0 : struct tevent_req *req = NULL;
292 0 : const char **domains = NULL;
293 : errno_t ret;
294 :
295 0 : req = tevent_req_callback_data(subreq, struct tevent_req);
296 0 : state = tevent_req_data(req, struct fo_discover_servers_state);
297 :
298 0 : ret = fo_discover_srv_recv(state, subreq,
299 : &state->dns_domain,
300 : &state->ttl,
301 : &state->primary_servers,
302 : &state->num_primary_servers);
303 0 : talloc_zfree(subreq);
304 0 : if (ret != EOK) {
305 0 : DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve primary servers "
306 : "[%d]: %s\n", ret, sss_strerror(ret));
307 0 : if (ret != ERR_SRV_NOT_FOUND && ret != ERR_SRV_LOOKUP_ERROR) {
308 : /* abort on system error */
309 0 : goto done;
310 : }
311 : }
312 :
313 0 : if (state->backup_domain == NULL) {
314 : /* if there is no backup domain, we are done */
315 0 : DEBUG(SSSDBG_TRACE_FUNC, "No backup domain specified\n");
316 0 : goto done;
317 : }
318 :
319 0 : if (state->dns_domain != NULL
320 0 : && strcasecmp(state->dns_domain, state->backup_domain) == 0) {
321 : /* If there was no error and dns_domain is the same as backup domain,
322 : * it means that we were unable to resolve SRV in primary domain, but
323 : * SRV from backup domain was resolved and those servers are considered
324 : * to be primary. We are done. */
325 0 : state->backup_servers = NULL;
326 0 : state->num_backup_servers = 0;
327 :
328 0 : ret = EOK;
329 0 : goto done;
330 : }
331 :
332 0 : DEBUG(SSSDBG_TRACE_FUNC, "Looking up backup servers\n");
333 :
334 0 : domains = talloc_zero_array(state, const char *, 2);
335 0 : if (domains == NULL) {
336 0 : ret = ENOMEM;
337 0 : goto done;
338 : }
339 :
340 0 : domains[0] = state->backup_domain;
341 :
342 0 : subreq = fo_discover_srv_send(state, state->ev, state->resolv_ctx,
343 : state->service, state->protocol, domains);
344 0 : if (subreq == NULL) {
345 0 : ret = ENOMEM;
346 0 : goto done;
347 : }
348 :
349 0 : tevent_req_set_callback(subreq, fo_discover_servers_backup_done, req);
350 :
351 0 : ret = EAGAIN;
352 :
353 : done:
354 0 : if (ret == EOK) {
355 0 : tevent_req_done(req);
356 0 : } else if (ret != EAGAIN) {
357 0 : tevent_req_error(req, ret);
358 : }
359 :
360 0 : return;
361 : }
362 :
363 0 : static void fo_discover_servers_backup_done(struct tevent_req *subreq)
364 : {
365 0 : struct fo_discover_servers_state *state = NULL;
366 0 : struct tevent_req *req = NULL;
367 : errno_t ret;
368 :
369 0 : req = tevent_req_callback_data(subreq, struct tevent_req);
370 0 : state = tevent_req_data(req, struct fo_discover_servers_state);
371 :
372 0 : ret = fo_discover_srv_recv(state, subreq, NULL,
373 : NULL, &state->backup_servers,
374 : &state->num_backup_servers);
375 0 : talloc_zfree(subreq);
376 0 : if (ret != EOK) {
377 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Unable to retrieve backup servers "
378 : "[%d]: %s\n", ret, sss_strerror(ret));
379 0 : if (ret == ERR_SRV_NOT_FOUND || ret == ERR_SRV_LOOKUP_ERROR) {
380 : /* we have successfully fetched primary servers, so we will
381 : * finish the request normally on non system error */
382 0 : ret = EOK;
383 : }
384 : }
385 :
386 0 : if (ret != EOK) {
387 0 : tevent_req_error(req, ret);
388 0 : return;
389 : }
390 :
391 0 : tevent_req_done(req);
392 : }
393 :
394 0 : errno_t fo_discover_servers_recv(TALLOC_CTX *mem_ctx,
395 : struct tevent_req *req,
396 : char **_dns_domain,
397 : uint32_t *_ttl,
398 : struct fo_server_info **_primary_servers,
399 : size_t *_num_primary_servers,
400 : struct fo_server_info **_backup_servers,
401 : size_t *_num_backup_servers)
402 : {
403 0 : struct fo_discover_servers_state *state = NULL;
404 0 : state = tevent_req_data(req, struct fo_discover_servers_state);
405 :
406 0 : TEVENT_REQ_RETURN_ON_ERROR(req);
407 :
408 0 : if (_primary_servers) {
409 0 : *_primary_servers = talloc_steal(mem_ctx, state->primary_servers);
410 : }
411 :
412 0 : if (_num_primary_servers) {
413 0 : *_num_primary_servers = state->num_primary_servers;
414 : }
415 :
416 0 : if (_backup_servers) {
417 0 : *_backup_servers = talloc_steal(mem_ctx, state->backup_servers);
418 : }
419 :
420 0 : if (_num_backup_servers) {
421 0 : *_num_backup_servers = state->num_backup_servers;
422 : }
423 :
424 0 : if (_dns_domain) {
425 0 : *_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
426 : }
427 :
428 0 : if (_ttl) {
429 0 : *_ttl = state->ttl;
430 : }
431 :
432 :
433 0 : return EOK;
434 : }
435 :
436 : struct fo_resolve_srv_dns_ctx {
437 : struct resolv_ctx *resolv_ctx;
438 : enum restrict_family family_order;
439 : enum host_database *host_dbs;
440 : char *hostname;
441 : char *sssd_domain;
442 : char *detected_domain;
443 : };
444 :
445 : struct fo_resolve_srv_dns_state {
446 : struct tevent_context *ev;
447 : struct fo_resolve_srv_dns_ctx *ctx;
448 : const char *service;
449 : const char *protocol;
450 : const char *discovery_domain;
451 :
452 : char *dns_domain;
453 : uint32_t ttl;
454 : struct fo_server_info *servers;
455 : size_t num_servers;
456 : };
457 :
458 : static void fo_resolve_srv_dns_domain_done(struct tevent_req *subreq);
459 : static errno_t fo_resolve_srv_dns_discover(struct tevent_req *req);
460 : static void fo_resolve_srv_dns_done(struct tevent_req *subreq);
461 :
462 : struct fo_resolve_srv_dns_ctx *
463 3 : fo_resolve_srv_dns_ctx_init(TALLOC_CTX *mem_ctx,
464 : struct resolv_ctx *resolv_ctx,
465 : enum restrict_family family_order,
466 : enum host_database *host_dbs,
467 : const char *hostname,
468 : const char *sssd_domain)
469 : {
470 3 : struct fo_resolve_srv_dns_ctx *ctx = NULL;
471 :
472 3 : ctx = talloc_zero(mem_ctx, struct fo_resolve_srv_dns_ctx);
473 3 : if (ctx == NULL) {
474 0 : return NULL;
475 : }
476 :
477 3 : ctx->resolv_ctx = resolv_ctx;
478 3 : ctx->family_order = family_order;
479 3 : ctx->host_dbs = host_dbs;
480 :
481 3 : ctx->hostname = talloc_strdup(ctx, hostname);
482 3 : if (ctx->hostname == NULL) {
483 0 : goto fail;
484 : }
485 :
486 3 : ctx->sssd_domain = talloc_strdup(ctx, sssd_domain);
487 3 : if (ctx->sssd_domain == NULL) {
488 0 : goto fail;
489 : }
490 :
491 3 : return ctx;
492 :
493 : fail:
494 0 : talloc_free(ctx);
495 0 : return NULL;
496 : }
497 :
498 8 : struct tevent_req *fo_resolve_srv_dns_send(TALLOC_CTX *mem_ctx,
499 : struct tevent_context *ev,
500 : const char *service,
501 : const char *protocol,
502 : const char *discovery_domain,
503 : void *pvt)
504 : {
505 8 : struct fo_resolve_srv_dns_state *state = NULL;
506 8 : struct fo_resolve_srv_dns_ctx *ctx = NULL;
507 8 : struct tevent_req *req = NULL;
508 8 : struct tevent_req *subreq = NULL;
509 : errno_t ret;
510 :
511 8 : req = tevent_req_create(mem_ctx, &state, struct fo_resolve_srv_dns_state);
512 8 : if (req == NULL) {
513 0 : DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
514 0 : return NULL;
515 : }
516 :
517 8 : ctx = talloc_get_type(pvt, struct fo_resolve_srv_dns_ctx);
518 8 : if (ctx == NULL) {
519 0 : ret = EINVAL;
520 0 : goto immediately;
521 : }
522 :
523 8 : state->ev = ev;
524 8 : state->ctx = ctx;
525 8 : state->service = service;
526 8 : state->protocol = protocol;
527 :
528 8 : if (discovery_domain == NULL) {
529 0 : state->discovery_domain = NULL;
530 : } else {
531 8 : state->discovery_domain = discovery_domain;
532 : }
533 :
534 8 : if (discovery_domain == NULL && ctx->detected_domain == NULL) {
535 : /* we will try to detect proper discovery domain */
536 0 : subreq = resolv_get_domain_send(state, state->ev, ctx->resolv_ctx,
537 0 : ctx->hostname, ctx->host_dbs,
538 : ctx->family_order);
539 0 : if (subreq == NULL) {
540 0 : ret = ENOMEM;
541 0 : goto immediately;
542 : }
543 :
544 0 : tevent_req_set_callback(subreq, fo_resolve_srv_dns_domain_done, req);
545 : } else {
546 : /* we will use either provided or previously detected
547 : * discovery domain */
548 8 : ret = fo_resolve_srv_dns_discover(req);
549 8 : if (ret != EAGAIN) {
550 0 : goto immediately;
551 : }
552 : }
553 :
554 8 : return req;
555 :
556 : immediately:
557 0 : if (ret == EOK) {
558 0 : tevent_req_done(req);
559 : } else {
560 0 : tevent_req_error(req, ret);
561 : }
562 0 : tevent_req_post(req, ev);
563 :
564 0 : return req;
565 : }
566 :
567 0 : static void fo_resolve_srv_dns_domain_done(struct tevent_req *subreq)
568 : {
569 0 : struct fo_resolve_srv_dns_state *state = NULL;
570 0 : struct tevent_req *req = NULL;
571 : errno_t ret;
572 :
573 0 : req = tevent_req_callback_data(subreq, struct tevent_req);
574 0 : state = tevent_req_data(req, struct fo_resolve_srv_dns_state);
575 :
576 0 : ret = resolv_get_domain_recv(state->ctx, subreq,
577 0 : &state->ctx->detected_domain);
578 0 : talloc_zfree(subreq);
579 0 : if (ret != EOK) {
580 0 : goto done;
581 : }
582 :
583 0 : ret = fo_resolve_srv_dns_discover(req);
584 :
585 : done:
586 0 : if (ret == EOK) {
587 0 : tevent_req_done(req);
588 0 : } else if (ret != EAGAIN) {
589 0 : tevent_req_error(req, ret);
590 : }
591 :
592 0 : return;
593 : }
594 :
595 8 : static errno_t fo_resolve_srv_dns_discover(struct tevent_req *req)
596 : {
597 8 : struct fo_resolve_srv_dns_state *state = NULL;
598 8 : struct fo_resolve_srv_dns_ctx *ctx = NULL;
599 8 : struct tevent_req *subreq = NULL;
600 8 : const char **domains = NULL;
601 : errno_t ret;
602 :
603 8 : state = tevent_req_data(req, struct fo_resolve_srv_dns_state);
604 8 : ctx = state->ctx;
605 :
606 8 : domains = talloc_zero_array(state, const char *, 3);
607 8 : if (domains == NULL) {
608 0 : ret = ENOMEM;
609 0 : goto done;
610 : }
611 :
612 8 : if (state->discovery_domain == NULL) {
613 : /* we will use detected domain with SSSD domain as fallback */
614 0 : domains[0] = talloc_strdup(domains, ctx->detected_domain);
615 0 : if (domains[0] == NULL) {
616 0 : ret = ENOMEM;
617 0 : goto done;
618 : }
619 :
620 0 : if (strcasecmp(ctx->detected_domain, ctx->sssd_domain) != 0) {
621 0 : domains[1] = talloc_strdup(domains, ctx->sssd_domain);
622 0 : if (domains[1] == NULL) {
623 0 : ret = ENOMEM;
624 0 : goto done;
625 : }
626 : }
627 : } else {
628 : /* We will use only discovery domain that was provided via plugin
629 : * interface. We don't have to dup here because it is already on
630 : * state. */
631 8 : domains[0] = state->discovery_domain;
632 : }
633 :
634 8 : subreq = fo_discover_srv_send(state, state->ev, ctx->resolv_ctx,
635 : state->service, state->protocol, domains);
636 8 : if (subreq == NULL) {
637 0 : ret = ENOMEM;
638 0 : goto done;
639 : }
640 :
641 8 : tevent_req_set_callback(subreq, fo_resolve_srv_dns_done, req);
642 :
643 8 : ret = EAGAIN;
644 :
645 : done:
646 8 : if (ret != EAGAIN) {
647 0 : talloc_free(domains);
648 : }
649 :
650 8 : return ret;
651 : }
652 :
653 8 : static void fo_resolve_srv_dns_done(struct tevent_req *subreq)
654 : {
655 8 : struct fo_resolve_srv_dns_state *state = NULL;
656 8 : struct tevent_req *req = NULL;
657 : errno_t ret;
658 :
659 8 : req = tevent_req_callback_data(subreq, struct tevent_req);
660 8 : state = tevent_req_data(req, struct fo_resolve_srv_dns_state);
661 :
662 8 : ret = fo_discover_srv_recv(state, subreq,
663 : &state->dns_domain, &state->ttl,
664 : &state->servers, &state->num_servers);
665 8 : talloc_zfree(subreq);
666 8 : if (ret != EOK) {
667 0 : goto done;
668 : }
669 :
670 : done:
671 8 : if (ret != EOK) {
672 0 : tevent_req_error(req, ret);
673 8 : return;
674 : }
675 :
676 8 : tevent_req_done(req);
677 : }
678 :
679 8 : errno_t fo_resolve_srv_dns_recv(TALLOC_CTX *mem_ctx,
680 : struct tevent_req *req,
681 : char **_dns_domain,
682 : uint32_t *_ttl,
683 : struct fo_server_info **_primary_servers,
684 : size_t *_num_primary_servers,
685 : struct fo_server_info **_backup_servers,
686 : size_t *_num_backup_servers)
687 : {
688 8 : struct fo_resolve_srv_dns_state *state = NULL;
689 8 : state = tevent_req_data(req, struct fo_resolve_srv_dns_state);
690 :
691 8 : TEVENT_REQ_RETURN_ON_ERROR(req);
692 :
693 8 : if (_primary_servers) {
694 8 : *_primary_servers = talloc_steal(mem_ctx, state->servers);
695 : }
696 :
697 8 : if (_num_primary_servers) {
698 8 : *_num_primary_servers = state->num_servers;
699 : }
700 :
701 : /* backup servers are not supported by simple srv lookup */
702 8 : if (_backup_servers) {
703 8 : *_backup_servers = NULL;
704 : }
705 :
706 8 : if (_num_backup_servers) {
707 8 : *_num_backup_servers = 0;
708 : }
709 :
710 8 : if (_dns_domain) {
711 8 : *_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
712 : }
713 :
714 8 : if (_ttl) {
715 8 : *_ttl = state->ttl;
716 : }
717 :
718 8 : return EOK;
719 : }
|