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