diff options
author | Andreas Schneider <asn@samba.org> | 2014-11-04 15:20:11 +0100 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2014-11-27 15:58:53 +0100 |
commit | e88e4a55b2723aee7bd07f4182486eb4abee024d (patch) | |
tree | 8db454845bd9230fb96e4c9b470fdbb7f56aa146 | |
parent | 2388096ae7c0c7924a44cca94290ed7da06498d0 (diff) | |
download | resolv_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.c | 28 | ||||
-rw-r--r-- | tests/test_dns_fake.c | 35 |
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), |