fail_over_srv.c revision 8df69bbc58c2f4d3f0b34be9756d9ddf24b1db6d
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder/*
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder Authors:
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder Pavel Březina <pbrezina@redhat.com>
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder Copyright (C) 2013 Red Hat
4db455e0782c3be2bf1eaf8822ed20968a756444Klaus Luettich
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder This program is free software; you can redistribute it and/or modify
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder it under the terms of the GNU General Public License as published by
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder the Free Software Foundation; either version 3 of the License, or
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder (at your option) any later version.
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder This program is distributed in the hope that it will be useful,
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke GNU General Public License for more details.
df6ca59bbc7bd5371359e385e028f069752c54dfChristian Maeder
df6ca59bbc7bd5371359e385e028f069752c54dfChristian Maeder You should have received a copy of the GNU General Public License
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke along with this program. If not, see <http://www.gnu.org/licenses/>.
4e9e95ba35a68f3c767bc0b23ebf9e904e442517Christian Maeder*/
4e9e95ba35a68f3c767bc0b23ebf9e904e442517Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke#include <strings.h>
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke#include <talloc.h>
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder#include <tevent.h>
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder#include "util/util.h"
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder#include "resolv/async_resolv.h"
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder#include "providers/fail_over_srv.h"
edf037c0435876acc993b362eecb0abd6179f31fKlaus Luettich
c13568ba2a02ef26ef164dfa432efc0a01cfa1b8Thiemo Wiedemeyerstruct fo_discover_srv_state {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke char *dns_domain;
a1058b6caa394964f2c33b1a52af205a144abd38Razvan Pascanu struct fo_server_info *servers;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder size_t num_servers;
4e9e95ba35a68f3c767bc0b23ebf9e904e442517Christian Maeder uint32_t ttl;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder};
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maederstatic void fo_discover_srv_done(struct tevent_req *subreq);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maederstruct tevent_req *fo_discover_srv_send(TALLOC_CTX *mem_ctx,
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder struct tevent_context *ev,
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder struct resolv_ctx *resolv_ctx,
c13568ba2a02ef26ef164dfa432efc0a01cfa1b8Thiemo Wiedemeyer const char *service,
59df9fde01e758ecf656fcb389183f1cb9d16815Christian Maeder const char *protocol,
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder const char **discovery_domains)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder{
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder struct fo_discover_srv_state *state = NULL;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder struct tevent_req *req = NULL;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder struct tevent_req *subreq = NULL;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder errno_t ret;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder req = tevent_req_create(mem_ctx, &state, struct fo_discover_srv_state);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (req == NULL) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder return NULL;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder }
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder subreq = resolv_discover_srv_send(state, ev, resolv_ctx, service,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke protocol, discovery_domains);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (subreq == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = ENOMEM;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder goto immediately;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder }
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder tevent_req_set_callback(subreq, fo_discover_srv_done, req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder return req;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maederimmediately:
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder tevent_req_error(req, ret);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder tevent_req_post(req, ev);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder return req;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder}
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_discover_srv_done(struct tevent_req *subreq)
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder{
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_srv_state *state = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct tevent_req *req = NULL;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder struct ares_srv_reply *reply_list = NULL;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder struct ares_srv_reply *record = NULL;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder int i;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder errno_t ret;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder req = tevent_req_callback_data(subreq, struct tevent_req);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder state = tevent_req_data(req, struct fo_discover_srv_state);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ret = resolv_discover_srv_recv(state, subreq,
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder &reply_list, &state->ttl, &state->dns_domain);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder talloc_zfree(subreq);
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder if (ret == ENOENT) {
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder ret = ERR_SRV_NOT_FOUND;
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder goto done;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder } else if (ret == EIO) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = ERR_SRV_LOOKUP_ERROR;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto done;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder } else if (ret != EOK) {
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder goto done;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, "Got answer. Processing...\n");
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke /* sort and store the answer */
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder ret = resolv_sort_srv_reply(&reply_list);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret != EOK) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Could not sort the answers from DNS "
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder "[%d]: %s\n", ret, strerror(ret));
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto done;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->num_servers = 0;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder for (record = reply_list; record != NULL; record = record->next) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->num_servers++;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, "Got %zu servers\n", state->num_servers);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->servers = talloc_array(state, struct fo_server_info,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->num_servers);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (state->servers == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = ENOMEM;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto done;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder for (record = reply_list, i = 0;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder record != NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder record = record->next, i++) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->servers[i].host = talloc_steal(state->servers, record->host);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->servers[i].port = record->port;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->servers[i].priority = record->priority;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder talloc_zfree(reply_list);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ret = EOK;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnkedone:
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret != EOK) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_error(req, ret);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke tevent_req_done(req);
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder}
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maedererrno_t fo_discover_srv_recv(TALLOC_CTX *mem_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct tevent_req *req,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder char **_dns_domain,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder uint32_t *_ttl,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke struct fo_server_info **_servers,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder size_t *_num_servers)
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke{
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_srv_state *state = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state = tevent_req_data(req, struct fo_discover_srv_state);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder TEVENT_REQ_RETURN_ON_ERROR(req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (_dns_domain != NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (_servers != NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_servers = talloc_steal(mem_ctx, state->servers);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (_ttl != NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_ttl = state->ttl;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder if (_num_servers != NULL) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke *_num_servers = state->num_servers;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return EOK;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke}
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstruct fo_discover_servers_state {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct tevent_context *ev;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct resolv_ctx *resolv_ctx;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *service;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *protocol;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *primary_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *backup_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder char *dns_domain;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke uint32_t ttl;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_server_info *primary_servers;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke size_t num_primary_servers;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder struct fo_server_info *backup_servers;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke size_t num_backup_servers;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder};
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maederstatic void fo_discover_servers_primary_done(struct tevent_req *subreq);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_discover_servers_backup_done(struct tevent_req *subreq);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstruct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct tevent_context *ev,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct resolv_ctx *resolv_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *service,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke const char *protocol,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke const char *primary_domain,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *backup_domain)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder{
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_servers_state *state = NULL;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder struct tevent_req *req = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct tevent_req *subreq = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke const char **domains = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke errno_t ret;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder req = tevent_req_create(mem_ctx, &state,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_servers_state);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (req == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (primary_domain == NULL) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (backup_domain == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->primary_servers = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->num_primary_servers = 0;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->backup_servers = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->num_backup_servers = 0;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->dns_domain = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->ttl = 0;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = EOK;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto immediately;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke } else {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder primary_domain = backup_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder backup_domain = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->ev = ev;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke state->resolv_ctx = resolv_ctx;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->service = talloc_strdup(state, service);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (state->service == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = ENOMEM;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto immediately;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->protocol = talloc_strdup(state, protocol);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (state->protocol == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = ENOMEM;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto immediately;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->primary_domain = talloc_strdup(state, primary_domain);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (state->primary_domain == NULL) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ret = ENOMEM;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke goto immediately;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke state->backup_domain = talloc_strdup(state, backup_domain);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (state->backup_domain == NULL && backup_domain != NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = ENOMEM;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto immediately;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, "Looking up primary servers\n");
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke domains = talloc_zero_array(state, const char *, 3);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (domains == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = ENOMEM;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke goto immediately;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder domains[0] = state->primary_domain;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke domains[1] = state->backup_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder subreq = fo_discover_srv_send(state, ev, resolv_ctx,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke state->service, state->protocol, domains);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (subreq == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = ENOMEM;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke goto immediately;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_set_callback(subreq, fo_discover_servers_primary_done, req);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return req;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederimmediately:
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_error(req, ret);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_post(req, ev);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke return req;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder}
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_discover_servers_primary_done(struct tevent_req *subreq)
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke{
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_servers_state *state = NULL;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder struct tevent_req *req = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char **domains = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder errno_t ret;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke req = tevent_req_callback_data(subreq, struct tevent_req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state = tevent_req_data(req, struct fo_discover_servers_state);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = fo_discover_srv_recv(state, subreq,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke &state->dns_domain,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder &state->ttl,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder &state->primary_servers,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder &state->num_primary_servers);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke talloc_zfree(subreq);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (ret != EOK) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve primary servers "
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder "[%d]: %s\n", ret, sss_strerror(ret));
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret != ERR_SRV_NOT_FOUND && ret != ERR_SRV_LOOKUP_ERROR) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke /* abort on system error */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto done;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke }
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (state->backup_domain == NULL) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke /* if there is no backup domain, we are done */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, "No backup domain specified\n");
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto done;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (state->dns_domain != NULL
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder && strcasecmp(state->dns_domain, state->backup_domain) == 0) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder /* If there was no error and dns_domain is the same as backup domain,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder * it means that we were unable to resolve SRV in primary domain, but
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder * SRV from backup domain was resolved and those servers are considered
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder * to be primary. We are done. */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->backup_servers = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->num_backup_servers = 0;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = EOK;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke goto done;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
72f14a81f43b46483faa0fad38b7b067f50fa5aeChristian Maeder DEBUG(SSSDBG_TRACE_FUNC, "Looking up backup servers\n");
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder domains = talloc_zero_array(state, const char *, 2);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (domains == NULL) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ret = ENOMEM;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto done;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder domains[0] = state->backup_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder subreq = fo_discover_srv_send(state, state->ev, state->resolv_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->service, state->protocol, domains);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (subreq == NULL) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ret = ENOMEM;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto done;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_set_callback(subreq, fo_discover_servers_backup_done, req);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = EAGAIN;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederdone:
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret == EOK) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke tevent_req_done(req);
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder } else if (ret != EAGAIN) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke tevent_req_error(req, ret);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke return;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke}
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_discover_servers_backup_done(struct tevent_req *subreq)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder{
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_discover_servers_state *state = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct tevent_req *req = NULL;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder errno_t ret;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder req = tevent_req_callback_data(subreq, struct tevent_req);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke state = tevent_req_data(req, struct fo_discover_servers_state);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = fo_discover_srv_recv(state, subreq, NULL,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder NULL, &state->backup_servers,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke &state->num_backup_servers);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder talloc_zfree(subreq);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret != EOK) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE, "Unable to retrieve backup servers "
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder "[%d]: %s\n", ret, sss_strerror(ret));
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret == ERR_SRV_NOT_FOUND || ret == ERR_SRV_LOOKUP_ERROR) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder /* we have successfully fetched primary servers, so we will
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder * finish the request normally on non system error */
bfbd1330a39a7b36177655ddc66c8ba00ba8c1abChristian Maeder ret = EOK;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
bfbd1330a39a7b36177655ddc66c8ba00ba8c1abChristian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret != EOK) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_error(req, ret);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_done(req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder}
bfbd1330a39a7b36177655ddc66c8ba00ba8c1abChristian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maedererrno_t fo_discover_servers_recv(TALLOC_CTX *mem_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct tevent_req *req,
bfbd1330a39a7b36177655ddc66c8ba00ba8c1abChristian Maeder char **_dns_domain,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder uint32_t *_ttl,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_server_info **_primary_servers,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder size_t *_num_primary_servers,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_server_info **_backup_servers,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder size_t *_num_backup_servers)
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke{
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke struct fo_discover_servers_state *state = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke state = tevent_req_data(req, struct fo_discover_servers_state);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder TEVENT_REQ_RETURN_ON_ERROR(req);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (_primary_servers) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke *_primary_servers = talloc_steal(mem_ctx, state->primary_servers);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (_num_primary_servers) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_num_primary_servers = state->num_primary_servers;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (_backup_servers) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_backup_servers = talloc_steal(mem_ctx, state->backup_servers);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (_num_backup_servers) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_num_backup_servers = state->num_backup_servers;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (_dns_domain) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (_ttl) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder *_ttl = state->ttl;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return EOK;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder}
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstruct fo_resolve_srv_dns_ctx {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct resolv_ctx *resolv_ctx;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder enum restrict_family family_order;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder enum host_database *host_dbs;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder char *hostname;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder char *sssd_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder char *detected_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder};
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstruct fo_resolve_srv_dns_state {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke struct tevent_context *ev;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_resolve_srv_dns_ctx *ctx;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *service;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *protocol;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *discovery_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder char *dns_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder uint32_t ttl;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_server_info *servers;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke size_t num_servers;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder};
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_resolve_srv_dns_domain_done(struct tevent_req *subreq);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic errno_t fo_resolve_srv_dns_discover(struct tevent_req *req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_resolve_srv_dns_done(struct tevent_req *subreq);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstruct fo_resolve_srv_dns_ctx *
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederfo_resolve_srv_dns_ctx_init(TALLOC_CTX *mem_ctx,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke struct resolv_ctx *resolv_ctx,
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder enum restrict_family family_order,
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder enum host_database *host_dbs,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *hostname,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *sssd_domain)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder{
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke struct fo_resolve_srv_dns_ctx *ctx = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ctx = talloc_zero(mem_ctx, struct fo_resolve_srv_dns_ctx);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (ctx == NULL) {
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder return NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ctx->resolv_ctx = resolv_ctx;
c13568ba2a02ef26ef164dfa432efc0a01cfa1b8Thiemo Wiedemeyer ctx->family_order = family_order;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ctx->host_dbs = host_dbs;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ctx->hostname = talloc_strdup(ctx, hostname);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (ctx->hostname == NULL) {
c13568ba2a02ef26ef164dfa432efc0a01cfa1b8Thiemo Wiedemeyer goto fail;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ctx->sssd_domain = talloc_strdup(ctx, sssd_domain);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (ctx->sssd_domain == NULL) {
c13568ba2a02ef26ef164dfa432efc0a01cfa1b8Thiemo Wiedemeyer goto fail;
c13568ba2a02ef26ef164dfa432efc0a01cfa1b8Thiemo Wiedemeyer }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return ctx;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederfail:
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder talloc_free(ctx);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder}
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstruct tevent_req *fo_resolve_srv_dns_send(TALLOC_CTX *mem_ctx,
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder struct tevent_context *ev,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *service,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *protocol,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char *discovery_domain,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder void *pvt)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder{
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder struct fo_resolve_srv_dns_state *state = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_resolve_srv_dns_ctx *ctx = NULL;
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder struct tevent_req *req = NULL;
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder struct tevent_req *subreq = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder errno_t ret;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder req = tevent_req_create(mem_ctx, &state, struct fo_resolve_srv_dns_state);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (req == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ctx = talloc_get_type(pvt, struct fo_resolve_srv_dns_ctx);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ctx == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = EINVAL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto immediately;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->ev = ev;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->ctx = ctx;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->service = service;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->protocol = protocol;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (discovery_domain == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->discovery_domain = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder } else {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state->discovery_domain = discovery_domain;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder if (discovery_domain == NULL && ctx->detected_domain == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder /* we will try to detect proper discovery domain */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder subreq = resolv_get_domain_send(state, state->ev, ctx->resolv_ctx,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ctx->hostname, ctx->host_dbs,
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ctx->family_order);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (subreq == NULL) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = ENOMEM;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto immediately;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder }
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke tevent_req_set_callback(subreq, fo_resolve_srv_dns_domain_done, req);
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder } else {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder /* we will use either provided or previously detected
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder * discovery domain */
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = fo_resolve_srv_dns_discover(req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret != EAGAIN) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto immediately;
da955132262baab309a50fdffe228c9efe68251dCui Jian }
64325303fc09fc4d88ced49be11ff2d29966422aCui Jian }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return req;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnkeimmediately:
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder if (ret == EOK) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_done(req);
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder } else {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_error(req, ret);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder tevent_req_post(req, ev);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke return req;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder}
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederstatic void fo_resolve_srv_dns_domain_done(struct tevent_req *subreq)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder{
a6f3aafabdb36f0bb079e09de67818fde83f2c92Klaus Luettich struct fo_resolve_srv_dns_state *state = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke struct tevent_req *req = NULL;
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke errno_t ret;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke req = tevent_req_callback_data(subreq, struct tevent_req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder state = tevent_req_data(req, struct fo_resolve_srv_dns_state);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder ret = resolv_get_domain_recv(state->ctx, subreq,
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder &state->ctx->detected_domain);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke talloc_zfree(subreq);
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke if (ret != EOK) {
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder goto done;
a6f3aafabdb36f0bb079e09de67818fde83f2c92Klaus Luettich }
9035db0b84603cb494e48ec767f138641d389ca0Christian Maeder
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke ret = fo_resolve_srv_dns_discover(req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maederdone:
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder if (ret == EOK) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke tevent_req_done(req);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder } else if (ret != EAGAIN) {
e0f486fea42710332c1447a57dc3b05fe5f82109Achim Mahnke tevent_req_error(req, ret);
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder }
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder return;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder}
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maederstatic errno_t fo_resolve_srv_dns_discover(struct tevent_req *req)
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder{
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct fo_resolve_srv_dns_state *state = NULL;
412e440f8acdbae3df0e2fd12ff078f3f23a2799Christian Maeder struct fo_resolve_srv_dns_ctx *ctx = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder struct tevent_req *subreq = NULL;
595f414df7684baf190cecdf4a9e0765a0cdf800Christian Maeder const char **domains = NULL;
errno_t ret;
state = tevent_req_data(req, struct fo_resolve_srv_dns_state);
ctx = state->ctx;
domains = talloc_zero_array(state, const char *, 3);
if (domains == NULL) {
ret = ENOMEM;
goto done;
}
if (state->discovery_domain == NULL) {
/* we will use detected domain with SSSD domain as fallback */
domains[0] = talloc_strdup(domains, ctx->detected_domain);
if (domains[0] == NULL) {
ret = ENOMEM;
goto done;
}
if (strcasecmp(ctx->detected_domain, ctx->sssd_domain) != 0) {
domains[1] = talloc_strdup(domains, ctx->sssd_domain);
if (domains[1] == NULL) {
ret = ENOMEM;
goto done;
}
}
} else {
/* We will use only discovery domain that was provided via plugin
* interface. We don't have to dup here because it is already on
* state. */
domains[0] = state->discovery_domain;
}
subreq = fo_discover_srv_send(state, state->ev, ctx->resolv_ctx,
state->service, state->protocol, domains);
if (subreq == NULL) {
ret = ENOMEM;
goto done;
}
tevent_req_set_callback(subreq, fo_resolve_srv_dns_done, req);
ret = EAGAIN;
done:
if (ret != EAGAIN) {
talloc_free(domains);
}
return ret;
}
static void fo_resolve_srv_dns_done(struct tevent_req *subreq)
{
struct fo_resolve_srv_dns_state *state = NULL;
struct tevent_req *req = NULL;
errno_t ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct fo_resolve_srv_dns_state);
ret = fo_discover_srv_recv(state, subreq,
&state->dns_domain, &state->ttl,
&state->servers, &state->num_servers);
talloc_zfree(subreq);
if (ret != EOK) {
goto done;
}
done:
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
tevent_req_done(req);
}
errno_t fo_resolve_srv_dns_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
char **_dns_domain,
uint32_t *_ttl,
struct fo_server_info **_primary_servers,
size_t *_num_primary_servers,
struct fo_server_info **_backup_servers,
size_t *_num_backup_servers)
{
struct fo_resolve_srv_dns_state *state = NULL;
state = tevent_req_data(req, struct fo_resolve_srv_dns_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
if (_primary_servers) {
*_primary_servers = talloc_steal(mem_ctx, state->servers);
}
if (_num_primary_servers) {
*_num_primary_servers = state->num_servers;
}
/* backup servers are not supported by simple srv lookup */
if (_backup_servers) {
*_backup_servers = NULL;
}
if (_num_backup_servers) {
*_num_backup_servers = 0;
}
if (_dns_domain) {
*_dns_domain = talloc_steal(mem_ctx, state->dns_domain);
}
if (_ttl) {
*_ttl = state->ttl;
}
return EOK;
}