summaryrefslogtreecommitdiffstats
path: root/server/resolv
diff options
context:
space:
mode:
Diffstat (limited to 'server/resolv')
-rw-r--r--server/resolv/ares/ares_data.c140
-rw-r--r--server/resolv/ares/ares_data.h68
-rw-r--r--server/resolv/ares/ares_dns.h91
-rw-r--r--server/resolv/ares/ares_parse_srv_reply.c183
-rw-r--r--server/resolv/ares/ares_parse_srv_reply.h35
-rw-r--r--server/resolv/ares/ares_parse_txt_reply.c204
-rw-r--r--server/resolv/ares/ares_parse_txt_reply.h33
-rw-r--r--server/resolv/async_resolv.c1062
-rw-r--r--server/resolv/async_resolv.h95
9 files changed, 0 insertions, 1911 deletions
diff --git a/server/resolv/ares/ares_data.c b/server/resolv/ares/ares_data.c
deleted file mode 100644
index 1cccaa55c..000000000
--- a/server/resolv/ares/ares_data.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* $Id: ares_data.c,v 1.2 2009-11-20 09:06:33 yangtse Exp $ */
-
-/* Copyright (C) 2009 by Daniel Stenberg
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#include "ares.h"
-#include "ares_data.h"
-
-/*
-** ares_free_data() - c-ares external API function.
-**
-** This function must be used by the application to free data memory that
-** has been internally allocated by some c-ares function and for which a
-** pointer has already been returned to the calling application. The list
-** of c-ares functions returning pointers that must be free'ed using this
-** function is:
-**
-** ares_parse_srv_reply()
-** ares_parse_txt_reply()
-*/
-
-void _ares_free_data(void *dataptr)
-{
- struct ares_data *ptr;
-
- if (!dataptr)
- return;
-
- ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
-
- if (ptr->mark != ARES_DATATYPE_MARK)
- return;
-
- switch (ptr->type)
- {
- case ARES_DATATYPE_SRV_REPLY:
-
- if (ptr->data.srv_reply.next)
- _ares_free_data(ptr->data.srv_reply.next);
- if (ptr->data.srv_reply.host)
- free(ptr->data.srv_reply.host);
- break;
-
- case ARES_DATATYPE_TXT_REPLY:
-
- if (ptr->data.txt_reply.next)
- _ares_free_data(ptr->data.txt_reply.next);
- if (ptr->data.txt_reply.txt)
- free(ptr->data.txt_reply.txt);
- break;
-
- default:
- return;
- }
-
- free(ptr);
-}
-
-
-/*
-** ares_malloc_data() - c-ares internal helper function.
-**
-** This function allocates memory for a c-ares private ares_data struct
-** for the specified ares_datatype, initializes c-ares private fields
-** and zero initializes those which later might be used from the public
-** API. It returns an interior pointer which can be passed by c-ares
-** functions to the calling application, and that must be free'ed using
-** c-ares external API function ares_free_data().
-*/
-
-void *_ares_malloc_data(ares_datatype type)
-{
- struct ares_data *ptr;
-
- ptr = malloc(sizeof(struct ares_data));
- if (!ptr)
- return NULL;
-
- switch (type)
- {
- case ARES_DATATYPE_SRV_REPLY:
- ptr->data.srv_reply.next = NULL;
- ptr->data.srv_reply.host = NULL;
- ptr->data.srv_reply.priority = 0;
- ptr->data.srv_reply.weight = 0;
- ptr->data.srv_reply.port = 0;
- break;
-
- case ARES_DATATYPE_TXT_REPLY:
- ptr->data.txt_reply.next = NULL;
- ptr->data.txt_reply.txt = NULL;
- ptr->data.txt_reply.length = 0;
- break;
-
- default:
- free(ptr);
- return NULL;
- }
-
- ptr->mark = ARES_DATATYPE_MARK;
- ptr->type = type;
-
- return &ptr->data;
-}
-
-
-/*
-** ares_get_datatype() - c-ares internal helper function.
-**
-** This function returns the ares_datatype of the data stored in a
-** private ares_data struct when given the public API pointer.
-*/
-
-ares_datatype ares_get_datatype(void * dataptr)
-{
- struct ares_data *ptr;
-
- ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
-
- if (ptr->mark == ARES_DATATYPE_MARK)
- return ptr->type;
-
- return ARES_DATATYPE_UNKNOWN;
-}
diff --git a/server/resolv/ares/ares_data.h b/server/resolv/ares/ares_data.h
deleted file mode 100644
index d3606314e..000000000
--- a/server/resolv/ares/ares_data.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* $Id: ares_data.h,v 1.2 2009-11-23 12:03:33 yangtse Exp $ */
-
-/* Copyright (C) 2009 by Daniel Stenberg
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-#ifndef HAVE_ARES_DATA
-#include "resolv/ares/ares_parse_txt_reply.h"
-#include "resolv/ares/ares_parse_srv_reply.h"
-#endif /* HAVE_ARES_DATA */
-
-typedef enum {
- ARES_DATATYPE_UNKNOWN = 1, /* unknown data type - introduced in 1.7.0 */
- ARES_DATATYPE_SRV_REPLY, /* struct ares_srv_reply - introduced in 1.7.0 */
- ARES_DATATYPE_TXT_REPLY, /* struct ares_txt_reply - introduced in 1.7.0 */
-#if 0
- ARES_DATATYPE_ADDR6TTL, /* struct ares_addrttl */
- ARES_DATATYPE_ADDRTTL, /* struct ares_addr6ttl */
- ARES_DATATYPE_HOSTENT, /* struct hostent */
- ARES_DATATYPE_OPTIONS, /* struct ares_options */
-#endif
- ARES_DATATYPE_LAST /* not used - introduced in 1.7.0 */
-} ares_datatype;
-
-#define ARES_DATATYPE_MARK 0xbead
-
-/*
- * ares_data struct definition is internal to c-ares and shall not
- * be exposed by the public API in order to allow future changes
- * and extensions to it without breaking ABI. This will be used
- * internally by c-ares as the container of multiple types of data
- * dynamically allocated for which a reference will be returned
- * to the calling application.
- *
- * c-ares API functions returning a pointer to c-ares internally
- * allocated data will actually be returning an interior pointer
- * into this ares_data struct.
- *
- * All this is 'invisible' to the calling application, the only
- * requirement is that this kind of data must be free'ed by the
- * calling application using ares_free_data() with the pointer
- * it has received from a previous c-ares function call.
- */
-
-struct ares_data {
- ares_datatype type; /* Actual data type identifier. */
- unsigned int mark; /* Private ares_data signature. */
- union {
- struct ares_txt_reply txt_reply;
- struct ares_srv_reply srv_reply;
- } data;
-};
-
-void *_ares_malloc_data(ares_datatype type);
-void _ares_free_data(void *dataptr);
-
-ares_datatype ares_get_datatype(void * dataptr);
diff --git a/server/resolv/ares/ares_dns.h b/server/resolv/ares/ares_dns.h
deleted file mode 100644
index c0a9dda65..000000000
--- a/server/resolv/ares/ares_dns.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* $Id: ares_dns.h,v 1.8 2007-02-16 14:22:08 yangtse Exp $ */
-
-/* Copyright 1998 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-#ifndef ARES__DNS_H
-#define ARES__DNS_H
-
-#define DNS__16BIT(p) (((p)[0] << 8) | (p)[1])
-#define DNS__32BIT(p) (((p)[0] << 24) | ((p)[1] << 16) | \
- ((p)[2] << 8) | (p)[3])
-
-#define DNS__SET16BIT(p, v) (((p)[0] = (unsigned char)(((v) >> 8) & 0xff)), \
- ((p)[1] = (unsigned char)((v) & 0xff)))
-#define DNS__SET32BIT(p, v) (((p)[0] = (unsigned char)(((v) >> 24) & 0xff)), \
- ((p)[1] = (unsigned char)(((v) >> 16) & 0xff)), \
- ((p)[2] = (unsigned char)(((v) >> 8) & 0xff)), \
- ((p)[3] = (unsigned char)((v) & 0xff)))
-
-#if 0
-/* we cannot use this approach on systems where we can't access 16/32 bit
- data on un-aligned addresses */
-#define DNS__16BIT(p) ntohs(*(unsigned short*)(p))
-#define DNS__32BIT(p) ntohl(*(unsigned long*)(p))
-#define DNS__SET16BIT(p, v) *(unsigned short*)(p) = htons(v)
-#define DNS__SET32BIT(p, v) *(unsigned long*)(p) = htonl(v)
-#endif
-
-/* Macros for parsing a DNS header */
-#define DNS_HEADER_QID(h) DNS__16BIT(h)
-#define DNS_HEADER_QR(h) (((h)[2] >> 7) & 0x1)
-#define DNS_HEADER_OPCODE(h) (((h)[2] >> 3) & 0xf)
-#define DNS_HEADER_AA(h) (((h)[2] >> 2) & 0x1)
-#define DNS_HEADER_TC(h) (((h)[2] >> 1) & 0x1)
-#define DNS_HEADER_RD(h) ((h)[2] & 0x1)
-#define DNS_HEADER_RA(h) (((h)[3] >> 7) & 0x1)
-#define DNS_HEADER_Z(h) (((h)[3] >> 4) & 0x7)
-#define DNS_HEADER_RCODE(h) ((h)[3] & 0xf)
-#define DNS_HEADER_QDCOUNT(h) DNS__16BIT((h) + 4)
-#define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6)
-#define DNS_HEADER_NSCOUNT(h) DNS__16BIT((h) + 8)
-#define DNS_HEADER_ARCOUNT(h) DNS__16BIT((h) + 10)
-
-/* Macros for constructing a DNS header */
-#define DNS_HEADER_SET_QID(h, v) DNS__SET16BIT(h, v)
-#define DNS_HEADER_SET_QR(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 7))
-#define DNS_HEADER_SET_OPCODE(h, v) ((h)[2] |= (unsigned char)(((v) & 0xf) << 3))
-#define DNS_HEADER_SET_AA(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 2))
-#define DNS_HEADER_SET_TC(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 1))
-#define DNS_HEADER_SET_RD(h, v) ((h)[2] |= (unsigned char)((v) & 0x1))
-#define DNS_HEADER_SET_RA(h, v) ((h)[3] |= (unsigned char)(((v) & 0x1) << 7))
-#define DNS_HEADER_SET_Z(h, v) ((h)[3] |= (unsigned char)(((v) & 0x7) << 4))
-#define DNS_HEADER_SET_RCODE(h, v) ((h)[3] |= (unsigned char)((v) & 0xf))
-#define DNS_HEADER_SET_QDCOUNT(h, v) DNS__SET16BIT((h) + 4, v)
-#define DNS_HEADER_SET_ANCOUNT(h, v) DNS__SET16BIT((h) + 6, v)
-#define DNS_HEADER_SET_NSCOUNT(h, v) DNS__SET16BIT((h) + 8, v)
-#define DNS_HEADER_SET_ARCOUNT(h, v) DNS__SET16BIT((h) + 10, v)
-
-/* Macros for parsing the fixed part of a DNS question */
-#define DNS_QUESTION_TYPE(q) DNS__16BIT(q)
-#define DNS_QUESTION_CLASS(q) DNS__16BIT((q) + 2)
-
-/* Macros for constructing the fixed part of a DNS question */
-#define DNS_QUESTION_SET_TYPE(q, v) DNS__SET16BIT(q, v)
-#define DNS_QUESTION_SET_CLASS(q, v) DNS__SET16BIT((q) + 2, v)
-
-/* Macros for parsing the fixed part of a DNS resource record */
-#define DNS_RR_TYPE(r) DNS__16BIT(r)
-#define DNS_RR_CLASS(r) DNS__16BIT((r) + 2)
-#define DNS_RR_TTL(r) DNS__32BIT((r) + 4)
-#define DNS_RR_LEN(r) DNS__16BIT((r) + 8)
-
-/* Macros for constructing the fixed part of a DNS resource record */
-#define DNS_RR_SET_TYPE(r) DNS__SET16BIT(r, v)
-#define DNS_RR_SET_CLASS(r) DNS__SET16BIT((r) + 2, v)
-#define DNS_RR_SET_TTL(r) DNS__SET32BIT((r) + 4, v)
-#define DNS_RR_SET_LEN(r) DNS__SET16BIT((r) + 8, v)
-
-#endif /* ARES__DNS_H */
diff --git a/server/resolv/ares/ares_parse_srv_reply.c b/server/resolv/ares/ares_parse_srv_reply.c
deleted file mode 100644
index 086c4dba0..000000000
--- a/server/resolv/ares/ares_parse_srv_reply.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- SSSD
-
- Async resolver - SRV records parsing
-
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) Red Hat, Inc 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * This code is based on other c-ares parsing licensed as follows:
-
- * Copyright 1998 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <arpa/nameser.h>
-#include <stdlib.h>
-#include <string.h>
-#include "ares.h"
-/* this drags in some private macros c-ares uses */
-#include "ares_dns.h"
-#include "ares_data.h"
-
-#include "ares_parse_srv_reply.h"
-
-int _ares_parse_srv_reply (const unsigned char *abuf, int alen,
- struct ares_srv_reply **srv_out)
-{
- unsigned int qdcount, ancount, i;
- const unsigned char *aptr, *vptr;
- int status, rr_type, rr_class, rr_len;
- long len;
- char *hostname = NULL, *rr_name = NULL;
- struct ares_srv_reply *srv_head = NULL;
- struct ares_srv_reply *srv_last = NULL;
- struct ares_srv_reply *srv_curr;
-
- /* Set *srv_out to NULL for all failure cases. */
- *srv_out = NULL;
-
- /* Give up if abuf doesn't have room for a header. */
- if (alen < HFIXEDSZ)
- return ARES_EBADRESP;
-
- /* Fetch the question and answer count from the header. */
- qdcount = DNS_HEADER_QDCOUNT (abuf);
- ancount = DNS_HEADER_ANCOUNT (abuf);
- if (qdcount != 1)
- return ARES_EBADRESP;
- if (ancount == 0)
- return ARES_ENODATA;
-
- /* Expand the name from the question, and skip past the question. */
- aptr = abuf + HFIXEDSZ;
- status = ares_expand_name (aptr, abuf, alen, &hostname, &len);
- if (status != ARES_SUCCESS)
- return status;
-
- if (aptr + len + QFIXEDSZ > abuf + alen)
- {
- free (hostname);
- return ARES_EBADRESP;
- }
- aptr += len + QFIXEDSZ;
-
- /* Examine each answer resource record (RR) in turn. */
- for (i = 0; i < (int) ancount; i++)
- {
- /* Decode the RR up to the data field. */
- status = ares_expand_name (aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- {
- break;
- }
- aptr += len;
- if (aptr + RRFIXEDSZ > abuf + alen)
- {
- status = ARES_EBADRESP;
- break;
- }
- rr_type = DNS_RR_TYPE (aptr);
- rr_class = DNS_RR_CLASS (aptr);
- rr_len = DNS_RR_LEN (aptr);
- aptr += RRFIXEDSZ;
-
- /* Check if we are really looking at a SRV record */
- if (rr_class == C_IN && rr_type == T_SRV)
- {
- /* parse the SRV record itself */
- if (rr_len < 6)
- {
- status = ARES_EBADRESP;
- break;
- }
-
- /* Allocate storage for this SRV answer appending it to the list */
- srv_curr = _ares_malloc_data(ARES_DATATYPE_SRV_REPLY);
- if (!srv_curr)
- {
- status = ARES_ENOMEM;
- break;
- }
- if (srv_last)
- {
- srv_last->next = srv_curr;
- }
- else
- {
- srv_head = srv_curr;
- }
- srv_last = srv_curr;
-
- vptr = aptr;
- srv_curr->priority = ntohs (*((const unsigned short *)vptr));
- vptr += sizeof(const unsigned short);
- srv_curr->weight = ntohs (*((const unsigned short *)vptr));
- vptr += sizeof(const unsigned short);
- srv_curr->port = ntohs (*((const unsigned short *)vptr));
- vptr += sizeof(const unsigned short);
-
- status = ares_expand_name (vptr, abuf, alen, &srv_curr->host, &len);
- if (status != ARES_SUCCESS)
- break;
- }
-
- /* Don't lose memory in the next iteration */
- free(rr_name);
- rr_name = NULL;
-
- /* Move on to the next record */
- aptr += rr_len;
- }
-
- if (hostname)
- free (hostname);
- if (rr_name)
- free (rr_name);
-
- /* clean up on error */
- if (status != ARES_SUCCESS)
- {
- if (srv_head)
- _ares_free_data (srv_head);
- return status;
- }
-
- /* everything looks fine, return the data */
- *srv_out = srv_head;
-
- return ARES_SUCCESS;
-}
diff --git a/server/resolv/ares/ares_parse_srv_reply.h b/server/resolv/ares/ares_parse_srv_reply.h
deleted file mode 100644
index 29c6e08d1..000000000
--- a/server/resolv/ares/ares_parse_srv_reply.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __ARES_PARSE_SRV_REPLY_H__
-#define __ARES_PARSE_SRV_REPLY_H__
-
-struct ares_srv_reply {
- struct ares_srv_reply *next;
- char *host;
- unsigned short priority;
- unsigned short weight;
- unsigned short port;
-};
-
-int _ares_parse_srv_reply (const unsigned char *abuf, int alen,
- struct ares_srv_reply **srv_out);
-
-#endif /* __ARES_PARSE_SRV_REPLY_H__ */
diff --git a/server/resolv/ares/ares_parse_txt_reply.c b/server/resolv/ares/ares_parse_txt_reply.c
deleted file mode 100644
index d710e8f98..000000000
--- a/server/resolv/ares/ares_parse_txt_reply.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- SSSD
-
- Async resolver - TXT records parsing
-
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) Red Hat, Inc 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * This code is based on other c-ares parsing licensed as follows:
-
- * Copyright 1998 by the Massachusetts Institute of Technology.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- * M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- */
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <arpa/nameser.h>
-#include <stdlib.h>
-#include <string.h>
-#include "ares.h"
-/* this drags in some private macros c-ares uses */
-#include "ares_dns.h"
-#include "ares_data.h"
-
-#include "ares_parse_txt_reply.h"
-
-int _ares_parse_txt_reply (const unsigned char *abuf, int alen,
- struct ares_txt_reply **txt_out)
-{
- size_t substr_len, str_len;
- unsigned int qdcount, ancount, i;
- const unsigned char *aptr;
- const unsigned char *strptr;
- int status, rr_type, rr_class, rr_len;
- long len;
- char *hostname = NULL, *rr_name = NULL;
- struct ares_txt_reply *txt_head = NULL;
- struct ares_txt_reply *txt_last = NULL;
- struct ares_txt_reply *txt_curr;
-
- /* Set *txt_out to NULL for all failure cases. */
- *txt_out = NULL;
-
- /* Give up if abuf doesn't have room for a header. */
- if (alen < HFIXEDSZ)
- return ARES_EBADRESP;
-
- /* Fetch the question and answer count from the header. */
- qdcount = DNS_HEADER_QDCOUNT(abuf);
- ancount = DNS_HEADER_ANCOUNT(abuf);
- if (qdcount != 1)
- return ARES_EBADRESP;
- if (ancount == 0)
- return ARES_ENODATA;
-
- /* Expand the name from the question, and skip past the question. */
- aptr = abuf + HFIXEDSZ;
- status = ares_expand_name(aptr, abuf, alen, &hostname, &len);
- if (status != ARES_SUCCESS)
- return status;
-
- if (aptr + len + QFIXEDSZ > abuf + alen)
- {
- free (hostname);
- return ARES_EBADRESP;
- }
- aptr += len + QFIXEDSZ;
-
- /* Examine each answer resource record (RR) in turn. */
- for (i = 0; i < (int) ancount; i++)
- {
- /* Decode the RR up to the data field. */
- status = ares_expand_name(aptr, abuf, alen, &rr_name, &len);
- if (status != ARES_SUCCESS)
- {
- break;
- }
- aptr += len;
- if (aptr + RRFIXEDSZ > abuf + alen)
- {
- status = ARES_EBADRESP;
- break;
- }
- rr_type = DNS_RR_TYPE(aptr);
- rr_class = DNS_RR_CLASS(aptr);
- rr_len = DNS_RR_LEN(aptr);
- aptr += RRFIXEDSZ;
-
- /* Check if we are really looking at a TXT record */
- if (rr_class == C_IN && rr_type == T_TXT)
- {
- /* Allocate storage for this TXT answer appending it to the list */
- txt_curr = _ares_malloc_data(ARES_DATATYPE_TXT_REPLY);
- if (!txt_curr)
- {
- status = ARES_ENOMEM;
- break;
- }
- if (txt_last)
- {
- txt_last->next = txt_curr;
- }
- else
- {
- txt_head = txt_curr;
- }
- txt_last = txt_curr;
-
- /*
- * There may be multiple substrings in a single TXT record. Each
- * substring may be up to 255 characters in length, with a
- * "length byte" indicating the size of the substring payload.
- * RDATA contains both the length-bytes and payloads of all
- * substrings contained therein.
- */
-
- /* Compute total length to allow a single memory allocation */
- strptr = aptr;
- while (strptr < (aptr + rr_len))
- {
- substr_len = (unsigned char)*strptr;
- txt_curr->length += substr_len;
- strptr += substr_len + 1;
- }
-
- /* Including null byte */
- txt_curr->txt = malloc (txt_curr->length + 1);
- if (txt_curr->txt == NULL)
- {
- status = ARES_ENOMEM;
- break;
- }
-
- /* Step through the list of substrings, concatenating them */
- str_len = 0;
- strptr = aptr;
- while (strptr < (aptr + rr_len))
- {
- substr_len = (unsigned char)*strptr;
- strptr++;
- memcpy ((char *) txt_curr->txt + str_len, strptr, substr_len);
- str_len += substr_len;
- strptr += substr_len;
- }
- /* Make sure we NULL-terminate */
- *((char *) txt_curr->txt + txt_curr->length) = '\0';
- }
-
- /* Don't lose memory in the next iteration */
- free(rr_name);
- rr_name = NULL;
-
- /* Move on to the next record */
- aptr += rr_len;
- }
-
- if (hostname)
- free (hostname);
- if (rr_name)
- free (rr_name);
-
- /* clean up on error */
- if (status != ARES_SUCCESS)
- {
- if (txt_head)
- _ares_free_data (txt_head);
- return status;
- }
-
- /* everything looks fine, return the data */
- *txt_out = txt_head;
-
- return ARES_SUCCESS;
-}
diff --git a/server/resolv/ares/ares_parse_txt_reply.h b/server/resolv/ares/ares_parse_txt_reply.h
deleted file mode 100644
index 216e2c0d1..000000000
--- a/server/resolv/ares/ares_parse_txt_reply.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __ARES_PARSE_TXT_REPLY_H__
-#define __ARES_PARSE_TXT_REPLY_H__
-
-struct ares_txt_reply {
- struct ares_txt_reply *next;
- unsigned char *txt;
- size_t length; /* length excludes null termination */
-};
-
-int _ares_parse_txt_reply(const unsigned char* abuf, int alen,
- struct ares_txt_reply **txt_out);
-
-#endif /* __ARES_PARSE_TXT_REPLY_H__ */
diff --git a/server/resolv/async_resolv.c b/server/resolv/async_resolv.c
deleted file mode 100644
index 70d8d11e4..000000000
--- a/server/resolv/async_resolv.c
+++ /dev/null
@@ -1,1062 +0,0 @@
-/*
- SSSD
-
- Async resolver
-
- Authors:
- Martin Nagy <mnagy@redhat.com>
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) Red Hat, Inc 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sys/select.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-
-#include <ares.h>
-#include <talloc.h>
-#include <tevent.h>
-
-#include <errno.h>
-#include <netdb.h>
-#include <stddef.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "config.h"
-#include "resolv/async_resolv.h"
-#include "util/dlinklist.h"
-#include "util/util.h"
-
-#ifndef HAVE_ARES_DATA
-#define ares_parse_srv_reply(abuf, alen, srv_out) \
- _ares_parse_srv_reply(abuf, alen, srv_out)
-#define ares_parse_txt_reply(abuf, alen, txt_out) \
- _ares_parse_txt_reply(abuf, alen, txt_out)
-#define ares_free_data(dataptr) \
- _ares_free_data(dataptr)
-#define ares_malloc_data(data) \
- _ares_malloc_data(data)
-#endif /* HAVE_ARES_DATA */
-
-struct fd_watch {
- struct fd_watch *prev;
- struct fd_watch *next;
-
- int fd;
- struct resolv_ctx *ctx;
- struct tevent_fd *fde;
-};
-
-struct resolv_ctx {
- /* Contexts are linked so we can keep track of them and re-create
- * the ares channels in all of them at once if we need to. */
- struct resolv_ctx *prev;
- struct resolv_ctx *next;
-
- struct tevent_context *ev_ctx;
- ares_channel channel;
-
- /* List of file descriptors that are watched by tevent. */
- struct fd_watch *fds;
-
- /* Time in milliseconds before canceling a DNS request */
- int timeout;
-
- /* The timeout watcher periodically calls ares_process_fd() to check
- * if our pending requests didn't timeout. */
- int pending_requests;
- struct tevent_timer *timeout_watcher;
-};
-
-struct resolv_ctx *context_list;
-
-static int
-return_code(int ares_code)
-{
- switch (ares_code) {
- case ARES_SUCCESS:
- return EOK;
- case ARES_ENOMEM:
- return ENOMEM;
- case ARES_EFILE:
- default:
- return EIO;
- }
-}
-
-const char *
-resolv_strerror(int ares_code)
-{
- return ares_strerror(ares_code);
-}
-
-static int
-fd_watch_destructor(struct fd_watch *f)
-{
- DLIST_REMOVE(f->ctx->fds, f);
- f->fd = -1;
-
- return 0;
-}
-
-static void
-fd_input_available(struct tevent_context *ev, struct tevent_fd *fde,
- uint16_t flags, void *data)
-{
- struct fd_watch *watch = talloc_get_type(data, struct fd_watch);
-
- if (watch->ctx->channel == NULL) {
- DEBUG(1, ("Invalid ares channel - this is likely a bug\n"));
- return;
- }
-
- if (flags & TEVENT_FD_READ) {
- ares_process_fd(watch->ctx->channel, watch->fd, ARES_SOCKET_BAD);
- }
- if (flags & TEVENT_FD_WRITE) {
- ares_process_fd(watch->ctx->channel, ARES_SOCKET_BAD, watch->fd);
- }
-}
-
-static void
-check_fd_timeouts(struct tevent_context *ev, struct tevent_timer *te,
- struct timeval current_time, void *private_data);
-
-static void
-add_timeout_timer(struct tevent_context *ev, struct resolv_ctx *ctx)
-{
- struct timeval tv = { 0 };
- struct timeval *tvp;
-
- tvp = ares_timeout(ctx->channel, NULL, &tv);
-
- if (tvp == NULL) {
- tvp = &tv;
- }
-
- /* Enforce a minimum of 1 second. */
- if (tvp->tv_sec < 1) {
- tv = tevent_timeval_current_ofs(1, 0);
- } else {
- tv = tevent_timeval_current_ofs(tvp->tv_sec, tvp->tv_usec);
- }
-
- ctx->timeout_watcher = tevent_add_timer(ev, ctx, tv, check_fd_timeouts,
- ctx);
- if (ctx->timeout_watcher == NULL) {
- DEBUG(1, ("Out of memory\n"));
- }
-}
-
-static void
-check_fd_timeouts(struct tevent_context *ev, struct tevent_timer *te,
- struct timeval current_time, void *private_data)
-{
- struct resolv_ctx *ctx = talloc_get_type(private_data, struct resolv_ctx);
-
- DEBUG(9, ("Checking for DNS timeouts\n"));
-
- /* NULLify the timeout_watcher so we don't
- * free it in the _done() function if it
- * gets called. Now that we're already in
- * the handler, tevent will take care of
- * freeing it when it returns.
- */
- ctx->timeout_watcher = NULL;
-
- ares_process_fd(ctx->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
-
- if (ctx->pending_requests > 0) {
- add_timeout_timer(ev, ctx);
- }
-}
-
-static void
-schedule_timeout_watcher(struct tevent_context *ev, struct resolv_ctx *ctx)
-{
- ctx->pending_requests++;
- if (ctx->timeout_watcher) {
- return;
- }
-
- DEBUG(9, ("Scheduling DNS timeout watcher\n"));
- add_timeout_timer(ev, ctx);
-}
-
-static void
-unschedule_timeout_watcher(struct resolv_ctx *ctx)
-{
- if (ctx->pending_requests <= 0) {
- DEBUG(1, ("Pending DNS requests mismatch\n"));
- return;
- }
-
- ctx->pending_requests--;
- if (ctx->pending_requests == 0) {
- DEBUG(9, ("Unscheduling DNS timeout watcher\n"));
- talloc_zfree(ctx->timeout_watcher);
- }
-}
-
-static void fd_event_add(struct resolv_ctx *ctx, int s, int flags);
-static void fd_event_close(struct resolv_ctx *ctx, int s);
-
-/*
- * When ares is ready to read or write to a file descriptor, it will
- * call this callback. If both read and write are 0, it means that ares
- * will soon close the socket. We are mainly using this function to register
- * new file descriptors with tevent.
- */
-static void
-fd_event(void *data, int s, int fd_read, int fd_write)
-{
- struct resolv_ctx *ctx = talloc_get_type(data, struct resolv_ctx);
- struct fd_watch *watch;
- int flags;
-
- /* The socket is about to get closed. */
- if (fd_read == 0 && fd_write == 0) {
- fd_event_close(ctx, s);
- return;
- }
-
- flags = fd_read ? TEVENT_FD_READ : 0;
- flags |= fd_write ? TEVENT_FD_WRITE : 0;
-
- /* Are we already watching this file descriptor? */
- watch = ctx->fds;
- while (watch) {
- if (watch->fd == s) {
- tevent_fd_set_flags(watch->fde, flags);
- return;
- }
- watch = watch->next;
- }
-
- fd_event_add(ctx, s, flags);
-}
-
-static void
-fd_event_add(struct resolv_ctx *ctx, int s, int flags)
-{
- struct fd_watch *watch;
-
- /* The file descriptor is new, register it with tevent. */
- watch = talloc(ctx, struct fd_watch);
- if (watch == NULL) {
- DEBUG(1, ("Out of memory allocating fd_watch structure\n"));
- return;
- }
- talloc_set_destructor(watch, fd_watch_destructor);
-
- watch->fd = s;
- watch->ctx = ctx;
-
- watch->fde = tevent_add_fd(ctx->ev_ctx, watch, s, flags,
- fd_input_available, watch);
- if (watch->fde == NULL) {
- DEBUG(1, ("tevent_add_fd() failed\n"));
- talloc_free(watch);
- return;
- }
- DLIST_ADD(ctx->fds, watch);
-}
-
-static void
-fd_event_close(struct resolv_ctx *ctx, int s)
-{
- struct fd_watch *watch;
-
- /* Remove the socket from list */
- watch = ctx->fds;
- while (watch) {
- if (watch->fd == s) {
- talloc_free(watch);
- return;
- }
- watch = watch->next;
- }
-}
-
-static int
-resolv_ctx_destructor(struct resolv_ctx *ctx)
-{
- ares_channel channel;
-
- DLIST_REMOVE(context_list, ctx);
-
- if (ctx->channel == NULL) {
- DEBUG(1, ("Ares channel already destroyed?\n"));
- return -1;
- }
-
- /* Set ctx->channel to NULL first, so that callbacks that get
- * ARES_EDESTRUCTION won't retry. */
- channel = ctx->channel;
- ctx->channel = NULL;
- ares_destroy(channel);
-
- return 0;
-}
-
-static int
-recreate_ares_channel(struct resolv_ctx *ctx)
-{
- int ret;
- ares_channel new_channel;
- ares_channel old_channel;
- struct ares_options options;
-
- DEBUG(4, ("Initializing new c-ares channel\n"));
- /* FIXME: the options would contain
- * the nameservers to contact, the domains
- * to search, timeout... => get from confdb
- */
- options.sock_state_cb = fd_event;
- options.sock_state_cb_data = ctx;
- options.timeout = ctx->timeout * 1000;
- options.tries = 1;
- ret = ares_init_options(&new_channel, &options,
- ARES_OPT_SOCK_STATE_CB |
- ARES_OPT_TIMEOUTMS |
- ARES_OPT_TRIES);
- if (ret != ARES_SUCCESS) {
- DEBUG(1, ("Failed to initialize ares channel: %s\n",
- resolv_strerror(ret)));
- return return_code(ret);
- }
-
- old_channel = ctx->channel;
- ctx->channel = new_channel;
- if (old_channel != NULL) {
- DEBUG(4, ("Destroying the old c-ares channel\n"));
- ares_destroy(old_channel);
- }
-
- return EOK;
-}
-
-int
-resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx,
- int timeout, struct resolv_ctx **ctxp)
-{
- int ret;
- struct resolv_ctx *ctx;
-
- ctx = talloc_zero(mem_ctx, struct resolv_ctx);
- if (ctx == NULL)
- return ENOMEM;
-
- ctx->ev_ctx = ev_ctx;
- ctx->timeout = timeout;
-
- ret = recreate_ares_channel(ctx);
- if (ret != EOK) {
- goto done;
- }
-
- DLIST_ADD(context_list, ctx);
- talloc_set_destructor(ctx, resolv_ctx_destructor);
-
- *ctxp = ctx;
- return EOK;
-
-done:
- talloc_free(ctx);
- return ret;
-}
-
-void
-resolv_reread_configuration(void)
-{
- struct resolv_ctx *ctx;
-
- DEBUG(4, ("Recreating all c-ares channels\n"));
- DLIST_FOR_EACH(ctx, context_list) {
- recreate_ares_channel(ctx);
- }
-}
-
-struct hostent *
-resolv_copy_hostent(TALLOC_CTX *mem_ctx, struct hostent *src)
-{
- struct hostent *ret;
- int len;
- int i;
-
- ret = talloc_zero(mem_ctx, struct hostent);
- if (ret == NULL) {
- return NULL;
- }
-
- if (src->h_name != NULL) {
- ret->h_name = talloc_strdup(ret, src->h_name);
- if (ret->h_name == NULL) {
- goto fail;
- }
- }
- if (src->h_aliases != NULL) {
- for (len = 0; src->h_aliases[len] != NULL; len++);
- ret->h_aliases = talloc_size(ret, sizeof(char *) * (len + 1));
- if (ret->h_aliases == NULL) {
- goto fail;
- }
- for (i = 0; i < len; i++) {
- ret->h_aliases[i] = talloc_strdup(ret->h_aliases, src->h_aliases[i]);
- if (ret->h_aliases[i] == NULL) {
- goto fail;
- }
- }
- ret->h_aliases[len] = NULL;
- }
- ret->h_addrtype = src->h_addrtype;
- ret->h_length = src->h_length;
- if (src->h_addr_list != NULL) {
- for (len = 0; src->h_addr_list[len] != NULL; len++);
- ret->h_addr_list = talloc_size(ret, sizeof(char *) * (len + 1));
- if (ret->h_addr_list == NULL) {
- goto fail;
- }
- for (i = 0; i < len; i++) {
- ret->h_addr_list[i] = talloc_memdup(ret->h_addr_list,
- src->h_addr_list[i],
- ret->h_length);
- if (ret->h_addr_list[i] == NULL) {
- goto fail;
- }
- }
- ret->h_addr_list[len] = NULL;
- }
-
- return ret;
-
-fail:
- talloc_free(ret);
- return NULL;
-}
-
-/*******************************************************************
- * Get host by name. *
- *******************************************************************/
-
-struct gethostbyname_state {
- struct resolv_ctx *resolv_ctx;
- /* Part of the query. */
- const char *name;
- int family;
- /* These are returned by ares. The hostent struct will be freed
- * when the user callback returns. */
- struct hostent *hostent;
- int status;
- int timeouts;
- int retrying;
-};
-
-static void
-ares_gethostbyname_wakeup(struct tevent_req *req);
-
-struct tevent_req *
-resolv_gethostbyname_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- struct resolv_ctx *ctx, const char *name)
-{
- struct tevent_req *req, *subreq;
- struct gethostbyname_state *state;
- struct timeval tv = { 0, 0 };
-
- DEBUG(4, ("Trying to resolve A record of '%s'\n", name));
-
- if (ctx->channel == NULL) {
- DEBUG(1, ("Invalid ares channel - this is likely a bug\n"));
- return NULL;
- }
-
- req = tevent_req_create(mem_ctx, &state, struct gethostbyname_state);
- if (req == NULL)
- return NULL;
-
- state->resolv_ctx = ctx;
- state->name = name;
- state->family = AF_INET;
- state->hostent = NULL;
- state->status = 0;
- state->timeouts = 0;
- state->retrying = 0;
-
- /* We need to have a wrapper around ares_gethostbyname(), because
- * ares_gethostbyname() can in some cases call it's callback immediately.
- * This would not let our caller to set a callback for req. */
- subreq = tevent_wakeup_send(req, ev, tv);
- if (subreq == NULL) {
- DEBUG(1, ("Failed to add critical timer to run next operation!\n"));
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, ares_gethostbyname_wakeup, req);
- schedule_timeout_watcher(ev, ctx);
-
- return req;
-}
-
-static void
-resolv_gethostbyname6_done(void *arg, int status, int timeouts, struct hostent *hostent);
-
-static void
-resolv_gethostbyname_done(void *arg, int status, int timeouts, struct hostent *hostent)
-{
- struct tevent_req *req = talloc_get_type(arg, struct tevent_req);
- struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state);
-
- if (state->retrying == 0 && status == ARES_EDESTRUCTION
- && state->resolv_ctx->channel != NULL) {
- state->retrying = 1;
- ares_gethostbyname(state->resolv_ctx->channel, state->name,
- state->family, resolv_gethostbyname_done, req);
- return;
- }
-
- unschedule_timeout_watcher(state->resolv_ctx);
-
- if (hostent != NULL) {
- state->hostent = resolv_copy_hostent(req, hostent);
- if (state->hostent == NULL) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- } else {
- state->hostent = NULL;
- }
- state->status = status;
- state->timeouts = timeouts;
-
- if (status != ARES_SUCCESS) {
- if (status == ARES_ENOTFOUND || status == ARES_ENODATA) {
- /* IPv4 failure. Try IPv6 */
- state->family = AF_INET6;
- state->retrying = 0;
- state->timeouts = 0;
- DEBUG(4, ("Trying to resolve AAAA record of '%s'\n",
- state->name));
- ares_gethostbyname(state->resolv_ctx->channel, state->name,
- state->family, resolv_gethostbyname6_done,
- req);
- return;
- }
-
- /* Any other error indicates a server error,
- * so don't bother trying again
- */
- tevent_req_error(req, return_code(status));
- }
- else {
- tevent_req_done(req);
- }
-}
-
-static void
-resolv_gethostbyname6_done(void *arg, int status, int timeouts, struct hostent *hostent)
-{
- struct tevent_req *req = talloc_get_type(arg, struct tevent_req);
- struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state);
-
- if (state->retrying == 0 && status == ARES_EDESTRUCTION) {
- state->retrying = 1;
- ares_gethostbyname(state->resolv_ctx->channel, state->name,
- state->family, resolv_gethostbyname6_done, req);
- return;
- }
-
- if (hostent != NULL) {
- state->hostent = resolv_copy_hostent(req, hostent);
- if (state->hostent == NULL) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- } else {
- state->hostent = NULL;
- }
- state->status = status;
- state->timeouts = timeouts;
-
- if (status != ARES_SUCCESS) {
- tevent_req_error(req, return_code(status));
- }
- else {
- tevent_req_done(req);
- }
-}
-
-int
-resolv_gethostbyname_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- int *status, int *timeouts,
- struct hostent **hostent)
-{
- struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state);
-
- /* Fill in even in case of error as status contains the
- * c-ares return code */
- if (status) {
- *status = state->status;
- }
- if (timeouts) {
- *timeouts = state->timeouts;
- }
- if (hostent) {
- *hostent = talloc_steal(mem_ctx, state->hostent);
- }
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-static void
-ares_gethostbyname_wakeup(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct gethostbyname_state *state = tevent_req_data(req,
- struct gethostbyname_state);
-
- if (!tevent_wakeup_recv(subreq)) {
- return;
- }
- talloc_zfree(subreq);
-
- if (state->resolv_ctx->channel == NULL) {
- DEBUG(1, ("Invalid ares channel - this is likely a bug\n"));
- tevent_req_error(req, EIO);
- return;
- }
-
- ares_gethostbyname(state->resolv_ctx->channel, state->name,
- state->family, resolv_gethostbyname_done, req);
-}
-
-/* SRV and TXT parsing is not used anywhere in the code yet, so we disable it
- * for now
- */
-#ifdef BUILD_TXT_SRV
-
-/*
- * A simple helper function that will take an array of struct ares_srv_reply that
- * was allocated by malloc() in c-ares and copies it using talloc. The old one
- * is freed and the talloc one is put into 'reply_list' instead.
- */
-static int
-rewrite_talloc_srv_reply(TALLOC_CTX *mem_ctx, struct ares_srv_reply **reply_list)
-{
- struct ares_srv_reply *ptr = NULL;
- struct ares_srv_reply *new_list = NULL;
- struct ares_srv_reply *old_list = *reply_list;
-
- /* Nothing to do, but not an error */
- if (!old_list) {
- return EOK;
- }
-
- /* Copy the linked list */
- while (old_list) {
- /* Special case for the first node */
- if (!new_list) {
- new_list = talloc_zero(mem_ctx, struct ares_srv_reply);
- if (new_list == NULL) {
- ares_free_data(*reply_list);
- return ENOMEM;
- }
- ptr = new_list;
- } else {
- ptr->next = talloc_zero(new_list, struct ares_srv_reply);
- if (ptr->next == NULL) {
- ares_free_data(*reply_list);
- talloc_free(new_list);
- return ENOMEM;
- }
- ptr = ptr->next;
- }
-
- ptr->weight = old_list->weight;
- ptr->priority = old_list->priority;
- ptr->port = old_list->port;
- ptr->host = talloc_strdup(ptr, old_list->host);
- if (ptr->host == NULL) {
- ares_free_data(*reply_list);
- talloc_free(new_list);
- return ENOMEM;
- }
-
- old_list = old_list->next;
- }
-
- /* Free the old one (uses malloc). */
- ares_free_data(*reply_list);
-
- /* And now put our own new_list in place. */
- *reply_list = new_list;
-
- return EOK;
-}
-
-/*******************************************************************
- * Get SRV record *
- *******************************************************************/
-
-struct getsrv_state {
- struct resolv_ctx *resolv_ctx;
- /* the SRV query - for example _ldap._tcp.example.com */
- const char *query;
-
- /* parsed data returned by ares */
- struct ares_srv_reply *reply_list;
- int status;
- int timeouts;
- int retrying;
-};
-
-static void
-ares_getsrv_wakeup(struct tevent_req *subreq);
-
-struct tevent_req *
-resolv_getsrv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- struct resolv_ctx *ctx, const char *query)
-{
- struct tevent_req *req, *subreq;
- struct getsrv_state *state;
- struct timeval tv = { 0, 0 };
-
- DEBUG(4, ("Trying to resolve SRV record of '%s'\n", query));
-
- if (ctx->channel == NULL) {
- DEBUG(1, ("Invalid ares channel - this is likely a bug\n"));
- return NULL;
- }
-
- req = tevent_req_create(mem_ctx, &state, struct getsrv_state);
- if (req == NULL)
- return NULL;
-
- state->resolv_ctx = ctx;
- state->query = query;
- state->reply_list = NULL;
- state->status = 0;
- state->timeouts = 0;
- state->retrying = 0;
-
- subreq = tevent_wakeup_send(req, ev, tv);
- if (subreq == NULL) {
- DEBUG(1, ("Failed to add critical timer to run next operation!\n"));
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, ares_getsrv_wakeup, req);
- schedule_timeout_watcher(ev, ctx);
-
- return req;
-}
-
-static void
-resolv_getsrv_done(void *arg, int status, int timeouts, unsigned char *abuf, int alen)
-{
- struct tevent_req *req = talloc_get_type(arg, struct tevent_req);
- struct getsrv_state *state = tevent_req_data(req, struct getsrv_state);
- int ret;
- struct ares_srv_reply *reply_list;
-
- if (state->retrying == 0 && status == ARES_EDESTRUCTION
- && state->resolv_ctx->channel != NULL) {
- state->retrying = 1;
- ares_query(state->resolv_ctx->channel, state->query,
- ns_c_in, ns_t_srv, resolv_getsrv_done, req);
- return;
- }
-
- unschedule_timeout_watcher(state->resolv_ctx);
-
- state->status = status;
- state->timeouts = timeouts;
-
- if (status != ARES_SUCCESS) {
- tevent_req_error(req, return_code(status));
- ret = return_code(status);
- goto fail;
- }
-
- ret = ares_parse_srv_reply(abuf, alen, &reply_list);
- if (status != ARES_SUCCESS) {
- DEBUG(2, ("SRV record parsing failed: %d: %s\n", ret, ares_strerror(ret)));
- ret = return_code(ret);
- goto fail;
- }
- ret = rewrite_talloc_srv_reply(req, &reply_list);
- if (ret != EOK) {
- goto fail;
- }
- state->reply_list = reply_list;
-
- tevent_req_done(req);
- return;
-
-fail:
- state->reply_list = NULL;
- tevent_req_error(req, ret);
-}
-
-int
-resolv_getsrv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status,
- int *timeouts, struct ares_srv_reply **reply_list)
-{
- struct getsrv_state *state = tevent_req_data(req, struct getsrv_state);
-
- if (status)
- *status = state->status;
- if (timeouts)
- *timeouts = state->timeouts;
- if (reply_list)
- *reply_list = talloc_steal(mem_ctx, state->reply_list);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-static void
-ares_getsrv_wakeup(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct getsrv_state *state = tevent_req_data(req,
- struct getsrv_state);
-
- if (!tevent_wakeup_recv(subreq)) {
- return;
- }
- talloc_zfree(subreq);
-
- if (state->resolv_ctx->channel == NULL) {
- DEBUG(1, ("Invalid ares channel - this is likely a bug\n"));
- tevent_req_error(req, EIO);
- return;
- }
-
- ares_query(state->resolv_ctx->channel, state->query,
- ns_c_in, ns_t_srv, resolv_getsrv_done, req);
-}
-
-/*
- * A simple helper function that will take an array of struct txt_reply that
- * was allocated by malloc() in c-ares and copies it using talloc. The old one
- * is freed and the talloc one is put into 'reply_list' instead.
- */
-static int
-rewrite_talloc_txt_reply(TALLOC_CTX *mem_ctx, struct ares_txt_reply **reply_list)
-{
- struct ares_txt_reply *ptr = NULL;
- struct ares_txt_reply *new_list = NULL;
- struct ares_txt_reply *old_list = *reply_list;
-
- /* Nothing to do, but not an error */
- if (!old_list) {
- return EOK;
- }
-
- /* Copy the linked list */
- while (old_list) {
-
- /* Special case for the first node */
- if (!new_list) {
- new_list = talloc_zero(mem_ctx, struct ares_txt_reply);
- if (new_list == NULL) {
- ares_free_data(*reply_list);
- talloc_free(new_list);
- return ENOMEM;
- }
- ptr = new_list;
- } else {
- ptr->next = talloc_zero(new_list, struct ares_txt_reply);
- if (ptr->next == NULL) {
- ares_free_data(*reply_list);
- talloc_free(new_list);
- return ENOMEM;
- }
- ptr = ptr->next;
- }
-
- ptr->length = old_list->length;
- ptr->txt = talloc_memdup(ptr, old_list->txt,
- old_list->length);
- if (ptr->txt == NULL) {
- ares_free_data(*reply_list);
- talloc_free(new_list);
- return ENOMEM;
- }
-
- old_list = old_list->next;
- }
-
- ares_free_data(*reply_list);
-
- /* And now put our own new_list in place. */
- *reply_list = new_list;
-
- return EOK;
-}
-
-/*******************************************************************
- * Get TXT record *
- *******************************************************************/
-
-struct gettxt_state {
- struct resolv_ctx *resolv_ctx;
- /* the TXT query */
- const char *query;
-
- /* parsed data returned by ares */
- struct ares_txt_reply *reply_list;
- int status;
- int timeouts;
- int retrying;
-};
-
-static void
-ares_gettxt_wakeup(struct tevent_req *subreq);
-
-struct tevent_req *
-resolv_gettxt_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
- struct resolv_ctx *ctx, const char *query)
-{
- struct tevent_req *req, *subreq;
- struct gettxt_state *state;
- struct timeval tv = { 0, 0 };
-
- DEBUG(4, ("Trying to resolve TXT record of '%s'\n", query));
-
- if (ctx->channel == NULL) {
- DEBUG(1, ("Invalid ares channel - this is likely a bug\n"));
- return NULL;
- }
-
- req = tevent_req_create(mem_ctx, &state, struct gettxt_state);
- if (req == NULL)
- return NULL;
-
- state->resolv_ctx = ctx;
- state->query = query;
- state->reply_list = NULL;
- state->status = 0;
- state->timeouts = 0;
- state->retrying = 0;
-
- subreq = tevent_wakeup_send(req, ev, tv);
- if (subreq == NULL) {
- DEBUG(1, ("Failed to add critical timer to run next operation!\n"));
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, ares_gettxt_wakeup, req);
- schedule_timeout_watcher(ev, ctx);
-
- return req;
-}
-
-static void
-resolv_gettxt_done(void *arg, int status, int timeouts, unsigned char *abuf, int alen)
-{
- struct tevent_req *req = talloc_get_type(arg, struct tevent_req);
- struct gettxt_state *state = tevent_req_data(req, struct gettxt_state);
- int ret;
- struct ares_txt_reply *reply_list;
-
- if (state->retrying == 0 && status == ARES_EDESTRUCTION
- && state->resolv_ctx->channel != NULL) {
- state->retrying = 1;
- ares_query(state->resolv_ctx->channel, state->query,
- ns_c_in, ns_t_txt, resolv_gettxt_done, req);
- return;
- }
-
- unschedule_timeout_watcher(state->resolv_ctx);
-
- state->status = status;
- state->timeouts = timeouts;
-
- if (status != ARES_SUCCESS) {
- ret = return_code(status);
- goto fail;
- }
-
- ret = ares_parse_txt_reply(abuf, alen, &reply_list);
- if (status != ARES_SUCCESS) {
- DEBUG(2, ("TXT record parsing failed: %d: %s\n", ret, ares_strerror(ret)));
- ret = return_code(ret);
- goto fail;
- }
- ret = rewrite_talloc_txt_reply(req, &reply_list);
- if (ret != EOK) {
- goto fail;
- }
- state->reply_list = reply_list;
-
- tevent_req_done(req);
- return;
-
-fail:
- state->reply_list = NULL;
- tevent_req_error(req, ret);
-}
-
-int
-resolv_gettxt_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status,
- int *timeouts, struct ares_txt_reply **reply_list)
-{
- struct gettxt_state *state = tevent_req_data(req, struct gettxt_state);
-
- if (status)
- *status = state->status;
- if (timeouts)
- *timeouts = state->timeouts;
- if (reply_list)
- *reply_list = talloc_steal(mem_ctx, state->reply_list);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-static void
-ares_gettxt_wakeup(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct gettxt_state *state = tevent_req_data(req,
- struct gettxt_state);
-
- if (!tevent_wakeup_recv(subreq)) {
- return;
- }
- talloc_zfree(subreq);
-
- if (state->resolv_ctx->channel == NULL) {
- DEBUG(1, ("Invalid ares channel - this is likely a bug\n"));
- tevent_req_error(req, EIO);
- return;
- }
-
- ares_query(state->resolv_ctx->channel, state->query,
- ns_c_in, ns_t_txt, resolv_gettxt_done, req);
-}
-
-#endif
diff --git a/server/resolv/async_resolv.h b/server/resolv/async_resolv.h
deleted file mode 100644
index 2ba6449b2..000000000
--- a/server/resolv/async_resolv.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- SSSD
-
- Async resolver header
-
- Authors:
- Martin Nagy <mnagy@redhat.com>
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) Red Hat, Inc 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __ASYNC_RESOLV_H__
-#define __ASYNC_RESOLV_H__
-
-#include <netdb.h>
-#include <ares.h>
-
-#include "config.h"
-
-#ifndef HAVE_ARES_DATA
-#include "resolv/ares/ares_parse_srv_reply.h"
-#include "resolv/ares/ares_parse_txt_reply.h"
-#include "resolv/ares/ares_data.h"
-#endif /* HAVE_ARES_DATA */
-
-/*
- * An opaque structure which holds context for a module using the async
- * resolver. Is should be used as a "local-global" variable - in sssd,
- * every backend should have its own.
-
- * Do NOT free the context until there are any pending resolv_ calls
- */
-struct resolv_ctx;
-
-int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx,
- int timeout, struct resolv_ctx **ctxp);
-
-void resolv_reread_configuration(void);
-
-const char *resolv_strerror(int ares_code);
-
-struct hostent *resolv_copy_hostent(TALLOC_CTX *mem_ctx,
- struct hostent *src);
-
-/** Get host by name **/
-struct tevent_req *resolv_gethostbyname_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct resolv_ctx *ctx,
- const char *name);
-
-int resolv_gethostbyname_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- int *status,
- int *timeouts,
- struct hostent **hostent);
-
-/** Get SRV record **/
-struct tevent_req *resolv_getsrv_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct resolv_ctx *ctx,
- const char *query);
-
-int resolv_getsrv_recv(TALLOC_CTX *mem_ctx,
- struct tevent_req *req,
- int *status,
- int *timeouts,
- struct ares_srv_reply **reply_list);
-
-/** Get TXT record **/
-struct tevent_req *resolv_gettxt_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct resolv_ctx *ctx,
- const char *query);
-
-int resolv_gettxt_recv(TALLOC_CTX *mem_ctx,
- struct tevent_req *req,
- int *status,
- int *timeouts,
- struct ares_txt_reply **reply_list);
-
-#endif /* __ASYNC_RESOLV_H__ */