[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Thu Jan 4 04:09:02 UTC 2018


The branch, master has been updated
       via  36ab213 dns_server: Remove "max_payload" from dns_server
       via  35683a6 dns_server: Remove unused "dns_generate_options"
       via  cc3f9c2 dns_server: Remove unused "dns" parameter from ask_forwarder_send
       via  15748c3 ndr_dns: fix pushing unknown resource records
       via  300821b dns_server: Use dns_cli_request instead of direct udp
       via  0bb92d7 libdns: Add dns_cli_request
       via  6238830 libdns: dns/tcp client
       via  507c9b6 dsdb: Fix the build on 32-bit FreeBSD
       via  d8e30cb libdns: Fix a typo
       via  f7f15c2 tsocket: Fix typos
      from  11239f0 credentials: Simplify cli_credentials_get_server_gss_creds()

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


- Log -----------------------------------------------------------------
commit 36ab213ae66bbbdc95569452e409f50bc866e2f1
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 31 11:02:45 2017 +0100

    dns_server: Remove "max_payload" from dns_server
    
    This would have to be retrieved from the interface type we have I guess.
    
    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  4 05:08:02 CET 2018 on sn-devel-144

commit 35683a60e73f0544b4ee7e6853d09d0568d1c1ee
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 31 11:00:01 2017 +0100

    dns_server: Remove unused "dns_generate_options"
    
    This was part of the previous bugfix for 9632, which has been replaced
    by TCP fallback code. We can dig this up from git if needed.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit cc3f9c26ec05abb38d024c2a9f27f85f2cc92055
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Dec 31 10:59:40 2017 +0100

    dns_server: Remove unused "dns" parameter from ask_forwarder_send
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 15748c325c35c5e63ccff8cfcc4f3f555ebda77a
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 29 13:09:15 2017 +0100

    ndr_dns: fix pushing unknown resource records
    
    When pulling for example an RRSIG record, we end up with length!=0 *and*
    unexpected.length != 0, but with an unknown rrec. We should be able to
    marshall what we retrieved from the wire.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 300821b7934084f06b44b7a63a63db7cb544e8fa
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 29 11:11:59 2017 +0100

    dns_server: Use dns_cli_request instead of direct udp
    
    This skips adding the DNS option for a larger UDP packet size than
    512. This is a different fix for bug 9632.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 0bb92d7f377caffb2425cc7757b370bcf671e598
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 29 11:01:29 2017 +0100

    libdns: Add dns_cli_request
    
    First UDP, then TCP if truncation happened
    
    Signed-off-by: Volker Lendecke <vl at samba.org>

commit 623883083b5f9b5f07466fee99080c0c7f588551
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 28 22:35:46 2017 +0100

    libdns: dns/tcp client
    
    Same signature as the UDP client in the same file. This opens and closes
    the socket per request. In the future, we might want to create a
    persistent TCP connection for our internal DNS server's forwarder. That
    will require proper handling of in-flight requests. Something for
    another day.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 507c9b6906ace462692eb499b1e217b5ea131c04
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Dec 27 12:50:07 2017 +0100

    dsdb: Fix the build on 32-bit FreeBSD
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d8e30cb0aa3e014561fa5488e1cf30344cffe599
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 29 09:36:31 2017 +0100

    libdns: Fix a typo
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f7f15c25d2ce6e9f856e48c92009394222714d03
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 28 21:41:33 2017 +0100

    tsocket: Fix typos
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 lib/tsocket/tsocket.h                              |   4 +-
 libcli/dns/dns.c                                   | 410 ++++++++++++++++++++-
 libcli/dns/libdns.h                                |  30 +-
 libcli/dns/wscript_build                           |   2 +-
 librpc/ndr/ndr_dns.c                               |  11 +-
 source4/dns_server/dns_query.c                     |  69 +---
 source4/dns_server/dns_server.c                    |   2 -
 source4/dns_server/dns_server.h                    |   4 -
 source4/dns_server/dns_utils.c                     |  20 -
 source4/dsdb/samdb/ldb_modules/encrypted_secrets.c |  12 +-
 10 files changed, 466 insertions(+), 98 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h
index f52b746..dd0bd98 100644
--- a/lib/tsocket/tsocket.h
+++ b/lib/tsocket/tsocket.h
@@ -805,7 +805,7 @@ bool tstream_bsd_optimize_readv(struct tstream_context *stream,
  * @brief Connect async to a TCP endpoint and create a tstream_context for the
  * stream based communication.
  *
- * Use this function to connenct asynchronously to a remote ipv4 or ipv6 TCP
+ * Use this function to connect asynchronously to a remote ipv4 or ipv6 TCP
  * endpoint and create a tstream_context for the stream based communication.
  *
  * @param[in]  mem_ctx  The talloc memory context to use.
@@ -961,7 +961,7 @@ struct sockaddr;
  *
  * @param[in]  sa       The sockaddr structure to convert.
  *
- * @param[in]  sa_socklen   The lenth of the sockaddr sturucte.
+ * @param[in]  sa_socklen   The length of the sockaddr structure.
  *
  * @param[out] addr     The tsocket pointer to allocate and fill.
  *
diff --git a/libcli/dns/dns.c b/libcli/dns/dns.c
index 7d066d8..6404cb8 100644
--- a/libcli/dns/dns.c
+++ b/libcli/dns/dns.c
@@ -26,8 +26,10 @@
 #include "libcli/dns/libdns.h"
 #include "lib/util/tevent_unix.h"
 #include "lib/util/samba_util.h"
+#include "lib/util/debug.h"
 #include "libcli/util/error.h"
-#include "librpc/gen_ndr/dns.h"
+#include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/ndr_dns.h"
 
 struct dns_udp_request_state {
 	struct tevent_context *ev;
@@ -176,3 +178,409 @@ int dns_udp_request_recv(struct tevent_req *req,
 
 	return 0;
 }
+
+struct dns_tcp_request_state {
+	struct tevent_context *ev;
+	struct tstream_context *stream;
+	const uint8_t *query;
+	size_t query_len;
+
+	uint8_t dns_msglen_hdr[2];
+	struct iovec iov[2];
+
+	size_t nread;
+	uint8_t *reply;
+};
+
+static void dns_tcp_request_connected(struct tevent_req *subreq);
+static void dns_tcp_request_sent(struct tevent_req *subreq);
+static int dns_tcp_request_next_vector(struct tstream_context *stream,
+				       void *private_data,
+				       TALLOC_CTX *mem_ctx,
+				       struct iovec **_vector,
+				       size_t *_count);
+static void dns_tcp_request_received(struct tevent_req *subreq);
+
+struct tevent_req *dns_tcp_request_send(TALLOC_CTX *mem_ctx,
+					struct tevent_context *ev,
+					const char *server_addr_string,
+					const uint8_t *query,
+					size_t query_len)
+{
+	struct tevent_req *req, *subreq;
+	struct dns_tcp_request_state *state;
+	struct tsocket_address *local, *remote;
+	int ret;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct dns_tcp_request_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->ev = ev;
+	state->query = query;
+	state->query_len = query_len;
+
+	if (query_len > UINT16_MAX) {
+		tevent_req_error(req, EMSGSIZE);
+		return tevent_req_post(req, ev);
+	}
+
+	ret = tsocket_address_inet_from_strings(state, "ip", NULL, 0, &local);
+	if (ret != 0) {
+		tevent_req_error(req, errno);
+		return tevent_req_post(req, ev);
+	}
+
+	ret = tsocket_address_inet_from_strings(
+		state, "ip", server_addr_string, DNS_SERVICE_PORT, &remote);
+	if (ret != 0) {
+		tevent_req_error(req, errno);
+		return tevent_req_post(req, ev);
+	}
+
+	subreq = tstream_inet_tcp_connect_send(state, state->ev,
+					       local, remote);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, dns_tcp_request_connected, req);
+
+	return req;
+}
+
+static void dns_tcp_request_connected(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct dns_tcp_request_state *state = tevent_req_data(
+		req, struct dns_tcp_request_state);
+	int ret, err;
+
+	ret = tstream_inet_tcp_connect_recv(subreq, &err, state,
+					    &state->stream, NULL);
+	TALLOC_FREE(subreq);
+	if (ret == -1) {
+		tevent_req_error(req, err);
+		return;
+	}
+
+	RSSVAL(state->dns_msglen_hdr, 0, state->query_len);
+	state->iov[0] = (struct iovec) {
+		.iov_base = state->dns_msglen_hdr,
+		.iov_len = sizeof(state->dns_msglen_hdr)
+	};
+	state->iov[1] = (struct iovec) {
+		.iov_base = discard_const_p(void, state->query),
+		.iov_len = state->query_len
+	};
+
+	subreq = tstream_writev_send(state, state->ev, state->stream,
+				     state->iov, ARRAY_SIZE(state->iov));
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq, dns_tcp_request_sent, req);
+}
+
+static void dns_tcp_request_sent(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct dns_tcp_request_state *state = tevent_req_data(
+		req, struct dns_tcp_request_state);
+	int ret, err;
+
+	ret = tstream_writev_recv(subreq, &err);
+	TALLOC_FREE(subreq);
+	if (ret == -1) {
+		tevent_req_error(req, err);
+		return;
+	}
+
+	subreq = tstream_readv_pdu_send(state, state->ev, state->stream,
+					dns_tcp_request_next_vector, state);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq, dns_tcp_request_received, req);
+}
+
+static int dns_tcp_request_next_vector(struct tstream_context *stream,
+				       void *private_data,
+				       TALLOC_CTX *mem_ctx,
+				       struct iovec **_vector,
+				       size_t *_count)
+{
+	struct dns_tcp_request_state *state = talloc_get_type_abort(
+		private_data, struct dns_tcp_request_state);
+	struct iovec *vector;
+	uint16_t msglen;
+
+	if (state->nread == 0) {
+		vector = talloc_array(mem_ctx, struct iovec, 1);
+		if (vector == NULL) {
+			return -1;
+		}
+		vector[0] = (struct iovec) {
+			.iov_base = state->dns_msglen_hdr,
+			.iov_len = sizeof(state->dns_msglen_hdr)
+		};
+		state->nread = sizeof(state->dns_msglen_hdr);
+
+		*_vector = vector;
+		*_count = 1;
+		return 0;
+	}
+
+	if (state->nread == sizeof(state->dns_msglen_hdr)) {
+		msglen = RSVAL(state->dns_msglen_hdr, 0);
+
+		state->reply = talloc_array(state, uint8_t, msglen);
+		if (state->reply == NULL) {
+			return -1;
+		}
+
+		vector = talloc_array(mem_ctx, struct iovec, 1);
+		if (vector == NULL) {
+			return -1;
+		}
+		vector[0] = (struct iovec) {
+			.iov_base = state->reply,
+			.iov_len = msglen
+		};
+		state->nread += msglen;
+
+		*_vector = vector;
+		*_count = 1;
+		return 0;
+	}
+
+	*_vector = NULL;
+	*_count = 0;
+	return 0;
+}
+
+static void dns_tcp_request_received(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	int ret, err;
+
+	ret = tstream_readv_pdu_recv(subreq, &err);
+	TALLOC_FREE(subreq);
+	if (ret == -1) {
+		tevent_req_error(req, err);
+		return;
+	}
+
+	tevent_req_done(req);
+}
+
+int dns_tcp_request_recv(struct tevent_req *req,
+			 TALLOC_CTX *mem_ctx,
+			 uint8_t **reply,
+			 size_t *reply_len)
+{
+	struct dns_tcp_request_state *state = tevent_req_data(
+		req, struct dns_tcp_request_state);
+	int err;
+
+	if (tevent_req_is_unix_error(req, &err)) {
+		tevent_req_received(req);
+		return err;
+	}
+
+	*reply_len = talloc_array_length(state->reply);
+	*reply = talloc_move(mem_ctx, &state->reply);
+	tevent_req_received(req);
+
+	return 0;
+}
+
+struct dns_cli_request_state {
+	struct tevent_context *ev;
+	const char *nameserver;
+
+	uint16_t req_id;
+
+	DATA_BLOB query;
+
+	struct dns_name_packet *reply;
+};
+
+static void dns_cli_request_udp_done(struct tevent_req *subreq);
+static void dns_cli_request_tcp_done(struct tevent_req *subreq);
+
+struct tevent_req *dns_cli_request_send(TALLOC_CTX *mem_ctx,
+					struct tevent_context *ev,
+					const char *nameserver,
+					const char *name,
+					enum dns_qclass qclass,
+					enum dns_qtype qtype)
+{
+	struct tevent_req *req, *subreq;
+	struct dns_cli_request_state *state;
+	struct dns_name_question question;
+	struct dns_name_packet out_packet;
+	enum ndr_err_code ndr_err;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct dns_cli_request_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->ev = ev;
+	state->nameserver = nameserver;
+
+	DBG_DEBUG("Asking %s for %s/%d/%d via UDP\n", nameserver,
+		  name, (int)qclass, (int)qtype);
+
+	generate_random_buffer((uint8_t *)&state->req_id,
+			       sizeof(state->req_id));
+
+	question = (struct dns_name_question) {
+		.name = discard_const_p(char, name),
+		.question_type = qtype, .question_class = qclass
+	};
+
+	out_packet = (struct dns_name_packet) {
+		.id = state->req_id,
+		.operation = DNS_OPCODE_QUERY | DNS_FLAG_RECURSION_DESIRED,
+		.qdcount = 1,
+		.questions = &question
+	};
+
+	ndr_err = ndr_push_struct_blob(
+		&state->query, state, &out_packet,
+		(ndr_push_flags_fn_t)ndr_push_dns_name_packet);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		tevent_req_error(req, ndr_map_error2errno(ndr_err));
+		return tevent_req_post(req, ev);
+	}
+
+	subreq = dns_udp_request_send(state, state->ev, state->nameserver,
+				      state->query.data, state->query.length);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, dns_cli_request_udp_done, req);
+	return req;
+}
+
+static void dns_cli_request_udp_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct dns_cli_request_state *state = tevent_req_data(
+		req, struct dns_cli_request_state);
+	DATA_BLOB reply;
+	enum ndr_err_code ndr_err;
+	int ret;
+
+	ret = dns_udp_request_recv(subreq, state, &reply.data, &reply.length);
+	TALLOC_FREE(subreq);
+	if (tevent_req_error(req, ret)) {
+		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));
+		return;
+	}
+	TALLOC_FREE(reply.data);
+
+	if (state->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);
+		return;
+	}
+
+	DBG_DEBUG("Reply was truncated, retrying TCP\n");
+
+	TALLOC_FREE(state->reply);
+
+	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);
+}
+
+static void dns_cli_request_tcp_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct dns_cli_request_state *state = tevent_req_data(
+		req, struct dns_cli_request_state);
+	DATA_BLOB reply;
+	enum ndr_err_code ndr_err;
+	int ret;
+
+	ret = dns_tcp_request_recv(subreq, state, &reply.data, &reply.length);
+	TALLOC_FREE(subreq);
+	if (tevent_req_error(req, ret)) {
+		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));
+		return;
+	}
+	TALLOC_FREE(reply.data);
+
+	if (state->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;
+	}
+
+	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);
+}
+
+int dns_cli_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+			 struct dns_name_packet **reply)
+{
+	struct dns_cli_request_state *state = tevent_req_data(
+		req, struct dns_cli_request_state);
+	int err;
+
+	if (tevent_req_is_unix_error(req, &err)) {
+		return err;
+	}
+	*reply = talloc_move(mem_ctx, &state->reply);
+	return 0;
+}
diff --git a/libcli/dns/libdns.h b/libcli/dns/libdns.h
index 7ea2eb6..1b7c404 100644
--- a/libcli/dns/libdns.h
+++ b/libcli/dns/libdns.h
@@ -22,6 +22,10 @@
 #ifndef __LIBDNS_H__
 #define __LIBDNS_H__
 
+#include "lib/util/data_blob.h"
+#include "lib/util/time.h"
+#include "librpc/gen_ndr/dns.h"
+
 /** Send an dns request to a dns server using UDP
  *
  *@param mem_ctx        talloc memory context to use
@@ -39,7 +43,7 @@ struct tevent_req *dns_udp_request_send(TALLOC_CTX *mem_ctx,
 
 /** Get the dns response from a dns server via UDP
  *
- *@param req       tevent_req struct returned from dns_request_send
+ *@param req       tevent_req struct returned from dns_udp_request_send
  *@param mem_ctx   talloc memory context to use for the reply string
  *@param reply     buffer that will be allocated and filled with the dns reply
  *@param reply_len length of the reply buffer
@@ -50,4 +54,28 @@ int dns_udp_request_recv(struct tevent_req *req,
 			 uint8_t **reply,
 			 size_t *reply_len);
 
+struct tevent_req *dns_tcp_request_send(TALLOC_CTX *mem_ctx,
+					struct tevent_context *ev,
+					const char *server_addr_string,
+					const uint8_t *query,
+					size_t query_len);
+int dns_tcp_request_recv(struct tevent_req *req,
+			 TALLOC_CTX *mem_ctx,
+			 uint8_t **reply,
+			 size_t *reply_len);
+
+/*
+ * DNS request with fallback to TCP on truncation
+ */
+
+struct tevent_req *dns_cli_request_send(TALLOC_CTX *mem_ctx,
+					struct tevent_context *ev,
+					const char *nameserver,
+					const char *name,
+					enum dns_qclass qclass,
+					enum dns_qtype qtype);
+int dns_cli_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+			 struct dns_name_packet **reply);
+
+


-- 
Samba Shared Repository



More information about the samba-cvs mailing list