ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina/*
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina Authors:
d98fdd80331e93cd698281341360a3ce3e30afbePavel Březina Pavel Březina <pbrezina@redhat.com>
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina Copyright (C) 2013 Red Hat
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina This program is free software; you can redistribute it and/or modify
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina it under the terms of the GNU General Public License as published by
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina the Free Software Foundation; either version 3 of the License, or
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina (at your option) any later version.
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina This program is distributed in the hope that it will be useful,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina GNU General Public License for more details.
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina You should have received a copy of the GNU General Public License
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina*/
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina#include <string.h>
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina#include <talloc.h>
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina#include <tevent.h>
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina#include <unistd.h>
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina#include "util/util.h"
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina#include "resolv/async_resolv.h"
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březinastruct resolv_get_domain_state {
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina char *fqdn;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina char *hostname;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina};
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březinastatic void resolv_get_domain_done(struct tevent_req *subreq);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březinastruct tevent_req *
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březinaresolv_get_domain_send(TALLOC_CTX *mem_ctx,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct tevent_context *ev,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct resolv_ctx *resolv_ctx,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina const char *hostname,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina enum host_database *host_dbs,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina enum restrict_family family_order)
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina{
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct resolv_get_domain_state *state = NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct tevent_req *req = NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct tevent_req *subreq = NULL;
bf6f1b3d49e17b1adf0448c0b06e94b1e52ddffdLukas Slebodnik char system_hostname[HOST_NAME_MAX + 1];
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina errno_t ret;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina req = tevent_req_create(mem_ctx, &state,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct resolv_get_domain_state);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina return NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina }
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina if (hostname == NULL) {
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina /* use system hostname */
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina ret = gethostname(system_hostname, HOST_NAME_MAX);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina if (ret) {
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "gethostname() failed: [%d]: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina goto immediately;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina }
bf6f1b3d49e17b1adf0448c0b06e94b1e52ddffdLukas Slebodnik system_hostname[HOST_NAME_MAX] = '\0';
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina hostname = system_hostname;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina }
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina state->fqdn = NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina state->hostname = talloc_strdup(state, hostname);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina if (state->hostname == NULL) {
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina ret = ENOMEM;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina goto immediately;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina }
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "Host name is: %s\n", state->hostname);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina subreq = resolv_gethostbyname_send(state, ev, resolv_ctx, state->hostname,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina family_order, host_dbs);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina if (subreq == NULL) {
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina talloc_zfree(req);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina return NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina }
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina tevent_req_set_callback(subreq, resolv_get_domain_done, req);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina return req;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březinaimmediately:
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina tevent_req_error(req, ret);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina tevent_req_post(req, ev);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina return req;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina}
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březinastatic void resolv_get_domain_done(struct tevent_req *subreq)
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina{
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct resolv_get_domain_state *state = NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct tevent_req *req = NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct resolv_hostent *rhostent;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina int resolv_status;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina errno_t ret;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina state = tevent_req_data(req, struct resolv_get_domain_state);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina ret = resolv_gethostbyname_recv(subreq, req, &resolv_status,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina NULL, &rhostent);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina talloc_zfree(subreq);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina if (ret != EOK) {
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not get fully qualified name for host name %s "
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina "error [%d]: %s, resolver returned: [%d]: %s\n",
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina state->hostname, ret, strerror(ret), resolv_status,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov resolv_strerror(resolv_status));
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina state->fqdn = state->hostname;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina } else {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_LIBS, "The FQDN is: %s\n", rhostent->name);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina state->fqdn = talloc_steal(state, rhostent->name);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina talloc_zfree(rhostent);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina }
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina tevent_req_done(req);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina}
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březinaerrno_t resolv_get_domain_recv(TALLOC_CTX *mem_ctx,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct tevent_req *req,
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina char **_dns_domain)
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina{
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina struct resolv_get_domain_state *state = NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina char *dns_domain = NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina char *domptr = NULL;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina state = tevent_req_data(req, struct resolv_get_domain_state);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina domptr = strchr(state->fqdn, '.');
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina if (domptr == NULL || (*(domptr+1) == '\0')) {
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina /* If the FQDN did not contain a dot or the dot was the last character
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina * (broken DNS server perhaps) */
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina dns_domain = state->fqdn;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina } else {
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina dns_domain = domptr + 1;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina }
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina *_dns_domain = talloc_strdup(mem_ctx, dns_domain);
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina if (*_dns_domain == NULL) {
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina return ENOMEM;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina }
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina return EOK;
ca261795ce61c41d7e62217ccb2ee913923040ffPavel Březina}
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinastruct resolv_discover_srv_state {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct tevent_context *ev;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct resolv_ctx *resolv_ctx;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina const char *service;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina const char *protocol;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina const char **discovery_domains;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina int domain_index;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct ares_srv_reply *reply_list;
bf54fbed126ec3d459af40ea370ffadacd31c76dJakub Hrozek uint32_t ttl;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina};
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinastatic errno_t resolv_discover_srv_next_domain(struct tevent_req *req);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinastatic void resolv_discover_srv_done(struct tevent_req *subreq);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinastruct tevent_req *resolv_discover_srv_send(TALLOC_CTX *mem_ctx,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct tevent_context *ev,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct resolv_ctx *resolv_ctx,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina const char *service,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina const char *protocol,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina const char **discovery_domains)
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina{
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct resolv_discover_srv_state *state = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct tevent_req *req = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina errno_t ret;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina req = tevent_req_create(mem_ctx, &state,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct resolv_discover_srv_state);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (req == NULL) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina return NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (resolv_ctx == NULL || service == NULL || protocol == NULL
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina || discovery_domains == NULL) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina ret = EINVAL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina goto immediately;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->ev = ev;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->resolv_ctx = resolv_ctx;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->discovery_domains = discovery_domains;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->service = service;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->protocol = protocol;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->domain_index = 0;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina ret = resolv_discover_srv_next_domain(req);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (ret != EAGAIN) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina goto immediately;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina return req;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinaimmediately:
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (ret == EOK) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina tevent_req_done(req);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina } else {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina tevent_req_error(req, ret);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina tevent_req_post(req, ev);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina return req;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina}
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinastatic errno_t resolv_discover_srv_next_domain(struct tevent_req *req)
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina{
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct resolv_discover_srv_state *state = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct tevent_req *subreq = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina const char *domain = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina char *query = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina errno_t ret;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state = tevent_req_data(req, struct resolv_discover_srv_state);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina domain = state->discovery_domains[state->domain_index];
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (domain == NULL) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina ret = EOK;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina goto done;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina query = talloc_asprintf(state, "_%s._%s.%s", state->service,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->protocol, domain);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (query == NULL) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina ret = ENOMEM;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina goto done;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "SRV resolution of service '%s'. Will use DNS "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "discovery domain '%s'\n", state->service, domain);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina subreq = resolv_getsrv_send(state, state->ev,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->resolv_ctx, query);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (subreq == NULL) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina ret = ENOMEM;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina goto done;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina tevent_req_set_callback(subreq, resolv_discover_srv_done, req);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->domain_index++;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina ret = EAGAIN;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinadone:
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (ret != EAGAIN) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina talloc_free(query);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina return ret;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina}
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinastatic void resolv_discover_srv_done(struct tevent_req *subreq)
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina{
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct resolv_discover_srv_state *state = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct tevent_req *req = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina int status;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina errno_t ret;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina req = tevent_req_callback_data(subreq, struct tevent_req);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state = tevent_req_data(req, struct resolv_discover_srv_state);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
bf54fbed126ec3d459af40ea370ffadacd31c76dJakub Hrozek ret = resolv_getsrv_recv(state, subreq, &status, NULL,
bf54fbed126ec3d459af40ea370ffadacd31c76dJakub Hrozek &state->reply_list, &state->ttl);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina talloc_zfree(subreq);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (ret != EOK) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "SRV query failed [%d]: %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov status, resolv_strerror(status));
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (status == ARES_ENOTFOUND) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina /* continue with next discovery domain */
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina ret = resolv_discover_srv_next_domain(req);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (ret == EOK) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina /* there are no more domains to try */
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina ret = ENOENT;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina goto done;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina /* critical error when fetching SRV record */
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina ret = EIO;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina goto done;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinadone:
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (ret == EOK) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina tevent_req_done(req);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina } else if (ret != EAGAIN) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina tevent_req_error(req, ret);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina return;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina}
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březinaerrno_t resolv_discover_srv_recv(TALLOC_CTX *mem_ctx,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct tevent_req *req,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct ares_srv_reply **_reply_list,
bf54fbed126ec3d459af40ea370ffadacd31c76dJakub Hrozek uint32_t *_ttl,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina char **_dns_domain)
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina{
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina struct resolv_discover_srv_state *state = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina char *domain = NULL;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state = tevent_req_data(req, struct resolv_discover_srv_state);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina TEVENT_REQ_RETURN_ON_ERROR(req);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (_dns_domain != NULL) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina /* domain_index now points to selected domain + 1 */
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina domain = talloc_strdup(mem_ctx,
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina state->discovery_domains[state->domain_index - 1]);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (domain == NULL) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina return ENOMEM;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina *_dns_domain = domain;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina if (_reply_list != NULL) {
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina *_reply_list = talloc_steal(mem_ctx, state->reply_list);
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina }
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina
842fe49b8c53d84b7f5b7cf67338abb038b5a617Jakub Hrozek if (_ttl != NULL) {
bf54fbed126ec3d459af40ea370ffadacd31c76dJakub Hrozek *_ttl = state->ttl;
bf54fbed126ec3d459af40ea370ffadacd31c76dJakub Hrozek }
bf54fbed126ec3d459af40ea370ffadacd31c76dJakub Hrozek
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina return EOK;
673d4c1932fa4ab1496499207d8627970d0b7561Pavel Březina}