[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Thu Jan 20 18:02:01 UTC 2022


The branch, master has been updated
       via  f60780c8b63 libcli/dns: Fix TCP fallback
      from  d1891a0c4f6 autobuild: Fix path for libwbclient ldd checks

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit f60780c8b633ece61c952122aee4f313edb26010
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jan 20 12:23:43 2022 +0100

    libcli/dns: Fix TCP fallback
    
    A customer has come across a DNS server that really just cuts a SRV
    reply if it's too long. This makes the packet invalid according to
    ndr_pull and according to wireshark. DNS_FLAG_TRUNCATION is however
    set. As this seems to be legal according to the DNS RFCs, we need to
    hand-parse the first two uint16's and look whether DNS_FLAG_TRUNCATION
    is set.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Jan 20 18:01:41 UTC 2022 on sn-devel-184

-----------------------------------------------------------------------

Summary of changes:
 libcli/dns/dns.c | 56 +++++++++++++++++++++++++++++++-------------------------
 1 file changed, 31 insertions(+), 25 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/dns/dns.c b/libcli/dns/dns.c
index 483697145ad..943b4d5b33e 100644
--- a/libcli/dns/dns.c
+++ b/libcli/dns/dns.c
@@ -475,6 +475,7 @@ static void dns_cli_request_udp_done(struct tevent_req *subreq)
 		req, struct dns_cli_request_state);
 	DATA_BLOB reply;
 	enum ndr_err_code ndr_err;
+	uint16_t reply_id, operation;
 	int ret;
 
 	ret = dns_udp_request_recv(subreq, state, &reply.data, &reply.length);
@@ -483,46 +484,51 @@ static void dns_cli_request_udp_done(struct tevent_req *subreq)
 		return;
 	}
 
-	state->reply = talloc(state, struct dns_name_packet);
-	if (tevent_req_nomem(state->reply, req)) {
-		return;
-	}
-
-	ndr_err = ndr_pull_struct_blob(
-		&reply, state->reply, state->reply,
-		(ndr_pull_flags_fn_t)ndr_pull_dns_name_packet);
-	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		tevent_req_error(req, ndr_map_error2errno(ndr_err));
+	if (reply.length < 4) {
+		DBG_DEBUG("Short DNS packet: length=%zu\n", reply.length);
+		tevent_req_error(req, EINVAL);
 		return;
 	}
-	TALLOC_FREE(reply.data);
 
-	if (state->reply->id != state->req_id) {
+	reply_id = PULL_BE_U16(reply.data, 0);
+	if (reply_id != state->req_id) {
 		DBG_DEBUG("Got id %"PRIu16", expected %"PRIu16"\n",
 			  state->reply->id, state->req_id);
 		tevent_req_error(req, ENOMSG);
 		return;
 	}
 
-	if ((state->reply->operation & DNS_FLAG_TRUNCATION) == 0) {
-		DBG_DEBUG("Got op=%x %"PRIu16"/%"PRIu16"/%"PRIu16"/%"PRIu16
-			  " recs\n", (int)state->reply->operation,
-			  state->reply->qdcount, state->reply->ancount,
-			  state->reply->nscount, state->reply->nscount);
-		tevent_req_done(req);
+	operation = PULL_BE_U16(reply.data, 2);
+	if ((operation & DNS_FLAG_TRUNCATION) != 0) {
+		DBG_DEBUG("Reply was truncated, retrying TCP\n");
+		subreq = dns_tcp_request_send(
+			state,
+			state->ev,
+			state->nameserver,
+			state->query.data,
+			state->query.length);
+		if (tevent_req_nomem(subreq, req)) {
+			return;
+		}
+		tevent_req_set_callback(subreq, dns_cli_request_tcp_done, req);
 		return;
 	}
 
-	DBG_DEBUG("Reply was truncated, retrying TCP\n");
-
-	TALLOC_FREE(state->reply);
+	state->reply = talloc(state, struct dns_name_packet);
+	if (tevent_req_nomem(state->reply, req)) {
+		return;
+	}
 
-	subreq = dns_tcp_request_send(state, state->ev, state->nameserver,
-				      state->query.data, state->query.length);
-	if (tevent_req_nomem(subreq, req)) {
+	ndr_err = ndr_pull_struct_blob(
+		&reply, state->reply, state->reply,
+		(ndr_pull_flags_fn_t)ndr_pull_dns_name_packet);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		tevent_req_error(req, ndr_map_error2errno(ndr_err));
 		return;
 	}
-	tevent_req_set_callback(subreq, dns_cli_request_tcp_done, req);
+	TALLOC_FREE(reply.data);
+
+	tevent_req_done(req);
 }
 
 static void dns_cli_request_tcp_done(struct tevent_req *subreq)


-- 
Samba Shared Repository



More information about the samba-cvs mailing list