aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2014-11-04 15:20:11 +0100
committerAndreas Schneider <asn@samba.org>2014-11-27 15:58:53 +0100
commite88e4a55b2723aee7bd07f4182486eb4abee024d (patch)
tree8db454845bd9230fb96e4c9b470fdbb7f56aa146
parent2388096ae7c0c7924a44cca94290ed7da06498d0 (diff)
downloadresolv_wrapper-e88e4a55b2723aee7bd07f4182486eb4abee024d.tar.gz
resolv_wrapper-e88e4a55b2723aee7bd07f4182486eb4abee024d.tar.xz
resolv_wrapper-e88e4a55b2723aee7bd07f4182486eb4abee024d.zip
rwrap: Handle trailing dot in dns names.
Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Guenther Deschner <gd@samba.org>
-rw-r--r--src/resolv_wrapper.c28
-rw-r--r--tests/test_dns_fake.c35
2 files changed, 55 insertions, 8 deletions
diff --git a/src/resolv_wrapper.c b/src/resolv_wrapper.c
index 07ec85c..3b94a36 100644
--- a/src/resolv_wrapper.c
+++ b/src/resolv_wrapper.c
@@ -558,6 +558,8 @@ static int rwrap_res_fake_hosts(const char *hostfile,
int rc = ENOENT;
char *key = NULL;
char *value = NULL;
+ char *query_name = NULL;
+ size_t qlen = strlen(query);
RWRAP_LOG(RWRAP_LOG_TRACE,
"Searching in fake hosts file %s\n", hostfile);
@@ -570,6 +572,15 @@ static int rwrap_res_fake_hosts(const char *hostfile,
return -1;
}
+ if (qlen > 0 && query[qlen-1] == '.') {
+ qlen--;
+ }
+
+ query_name = strndup(query, qlen);
+ if (query_name == NULL) {
+ return -1;
+ }
+
while (fgets(buf, sizeof(buf), fp) != NULL) {
char *rec_type;
char *q;
@@ -593,23 +604,23 @@ static int rwrap_res_fake_hosts(const char *hostfile,
continue;
}
- if (TYPE_MATCH(type, ns_t_a, rec_type, "A", key, query)) {
+ if (TYPE_MATCH(type, ns_t_a, rec_type, "A", key, query_name)) {
rc = rwrap_fake_a(key, value, answer, anslen);
break;
} else if (TYPE_MATCH(type, ns_t_aaaa,
- rec_type, "AAAA", key, query)) {
+ rec_type, "AAAA", key, query_name)) {
rc = rwrap_fake_aaaa(key, value, answer, anslen);
break;
} else if (TYPE_MATCH(type, ns_t_srv,
- rec_type, "SRV", key, query)) {
+ rec_type, "SRV", key, query_name)) {
rc = rwrap_fake_srv(key, value, answer, anslen);
break;
} else if (TYPE_MATCH(type, ns_t_soa,
- rec_type, "SOA", key, query)) {
+ rec_type, "SOA", key, query_name)) {
rc = rwrap_fake_soa(key, value, answer, anslen);
break;
} else if (TYPE_MATCH(type, ns_t_cname,
- rec_type, "CNAME", key, query)) {
+ rec_type, "CNAME", key, query_name)) {
rc = rwrap_fake_cname(key, value, answer, anslen);
break;
}
@@ -618,19 +629,20 @@ static int rwrap_res_fake_hosts(const char *hostfile,
switch (rc) {
case 0:
RWRAP_LOG(RWRAP_LOG_TRACE,
- "Successfully faked answer for [%s]\n", query);
+ "Successfully faked answer for [%s]\n", query_name);
break;
case -1:
RWRAP_LOG(RWRAP_LOG_ERROR,
- "Error faking answer for [%s]\n", query);
+ "Error faking answer for [%s]\n", query_name);
break;
case ENOENT:
RWRAP_LOG(RWRAP_LOG_TRACE,
- "Record for [%s] not found\n", query);
+ "Record for [%s] not found\n", query_name);
rc = rwrap_fake_empty_query(key, type, answer, anslen);
break;
}
+ free(query_name);
fclose(fp);
return rc;
}
diff --git a/tests/test_dns_fake.c b/tests/test_dns_fake.c
index b890060..0098e9a 100644
--- a/tests/test_dns_fake.c
+++ b/tests/test_dns_fake.c
@@ -118,6 +118,40 @@ static void test_res_fake_a_query_case_insensitive(void **state)
res_nclose(&dnsstate);
}
+static void test_res_fake_a_query_trailing_dot(void **state)
+{
+ int rv;
+ struct __res_state dnsstate;
+ unsigned char answer[ANSIZE];
+ char addr[INET_ADDRSTRLEN];
+ ns_msg handle;
+ ns_rr rr; /* expanded resource record */
+
+ (void) state; /* unused */
+
+ memset(&dnsstate, 0, sizeof(struct __res_state));
+ rv = res_ninit(&dnsstate);
+ assert_int_equal(rv, 0);
+
+ rv = res_nquery(&dnsstate, "cwrap.org.", ns_c_in, ns_t_a,
+ answer, ANSIZE);
+ assert_int_not_equal(rv, -1);
+
+ ns_initparse(answer, 256, &handle);
+ /* The query must finish w/o an error, have one answer and the answer
+ * must be a parseable RR of type A and have the address that our
+ * fake hosts file contains
+ */
+ assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
+ assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
+ assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
+ assert_int_equal(ns_rr_type(rr), ns_t_a);
+ assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr), addr, 256));
+ assert_string_equal(addr, "127.0.0.21");
+
+ res_nclose(&dnsstate);
+}
+
static void test_res_fake_a_query_notfound(void **state)
{
int rv;
@@ -427,6 +461,7 @@ int main(void)
const UnitTest tests[] = {
unit_test(test_res_fake_a_query),
unit_test(test_res_fake_a_query_case_insensitive),
+ unit_test(test_res_fake_a_query_trailing_dot),
unit_test(test_res_fake_a_query_notfound),
unit_test(test_res_fake_aaaa_query),
unit_test(test_res_fake_aaaa_query_notfound),