[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Tue Jan 15 10:17:03 UTC 2019


The branch, master has been updated
       via  f2d8308c22c addns: Async ads_dns_lookup_ns
       via  4b4ae005b20 addns: Async ads_dns_lookup_srv
       via  9563fcf6ffa samba_dnsupdate: With dns_hub, we don't need resolv_wrap
       via  99b775336b7 selftest: Use dns_hub's resolv.conf
       via  5f02a6af948 selftest: Add dns_hub deps
       via  62584f3d081 selftest: setup_dns_hub
       via  61e64791294 selftest: add central dns forwarder
       via  a8191f88ca8 libcli/dns: Add dns_res_rec_get_sockaddr
       via  dbbce1a4545 libcli/dns: clidns must depend on ndr_standard, not on NDR_DNS
       via  237c06aad81 libcli/dns: Make "clidns" a library
       via  b7418203eeb dns_lookup: Let make test override the resolv.conf location
       via  5f393deb309 libcli/dns: Add dns_lookup
       via  e9e4aeafc0c libcli/dns: Add resolv.conf parsing
       via  ff2dbe24b80 dns_update: samba_dnsupdate's exit code is not an errno
       via  a7e28a7eb56 addns: Centralize siteless lookup fallback
      from  12398a2d1dd vfs_fileid: fix get_connectpath_ino

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


- Log -----------------------------------------------------------------
commit f2d8308c22c8d6feb6b4396f69feabcdbcb5b99c
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Jan 3 16:22:24 2018 +0100

    addns: Async ads_dns_lookup_ns
    
    Use dns_lookup_send/recv to get NS records
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Tue Jan 15 11:16:00 CET 2019 on sn-devel-144

commit 4b4ae005b2029d55ad95809a535d13eb5ff51174
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Jan 3 13:26:54 2018 +0100

    addns: Async ads_dns_lookup_srv
    
    Use dns_lookup_send/recv to get SRV records. This avoids synchronous libresolv
    calls and provides the infrastructure to get dsgetdcname async.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 9563fcf6ffae4a6d3595a1207513bbf0742203f4
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jan 3 16:44:45 2019 +0100

    samba_dnsupdate: With dns_hub, we don't need resolv_wrap
    
    Best viewed with git show -b
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 99b775336b72c6a7d0ce121b2eeb027901482a6d
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Jan 2 21:24:34 2019 +0100

    selftest: Use dns_hub's resolv.conf
    
    Pass it as RESOLV_CONF envvar everywhere
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5f02a6af948bacebd659b4356ea7bc6d3b2419f3
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Jan 2 14:18:44 2019 +0100

    selftest: Add dns_hub deps
    
    All the DCs want the dns forwarder
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 62584f3d081a3318841ec16855dbf4396d3fc0aa
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Feb 6 09:46:41 2018 +0100

    selftest: setup_dns_hub
    
    Start the central dns forwarder on interface 64
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 61e64791294f0ef6597c9fc5359221f915de542f
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jan 12 15:53:03 2018 +0100

    selftest: add central dns forwarder
    
    This is a small DNS server that has hard redirects to the different domain
    controllers based on domain names. This is required because future commits will
    avoid calling into libresolv's code which resolv_wrapper takes care of.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a8191f88ca82cc259b593d69980df76c3c30b1fa
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jan 10 16:54:41 2019 +0100

    libcli/dns: Add dns_res_rec_get_sockaddr
    
    Pull the address from a res_rec if it's there
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit dbbce1a4545714cff0dad9e8c011800d0a66376e
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jan 4 16:05:35 2018 +0100

    libcli/dns: clidns must depend on ndr_standard, not on NDR_DNS
    
    Otherwise we can't link this into other libraries
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 237c06aad817f495fe57fcf2df434e4852c878cd
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jan 4 17:06:53 2018 +0100

    libcli/dns: Make "clidns" a library
    
    This will be linked into the SAMBA_LIBRARY "addns" in the next step. Because
    the other user, "dnsserver_common", is also a library, we can't link this as a
    subsystem anymore.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b7418203eebafd4027abc45e27b411dfc51c1f3e
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jan 4 20:58:05 2018 +0100

    dns_lookup: Let make test override the resolv.conf location
    
    Make this a separate commit: That is the feature that libc unfortunately does
    not give us.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5f393deb3095ac0c0b0a6d57e7182c104b061404
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Jan 2 13:56:56 2018 +0100

    libcli/dns: Add dns_lookup
    
    Wrapper function to parse resolv.conf and talk to multiple nameservers. This is
    the code where we might want to add a "working nameserver" cache. glibc always
    looks at the first configured nameserver. If that's dead, glibc runs into a
    timeout and only then asks the second one that might succeed. When more than
    one dns query is to be performed, these timeouts add up.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e9e4aeafc0cf7030dbd885710d6e8a179110f9ce
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jan 1 19:35:46 2018 +0100

    libcli/dns: Add resolv.conf parsing
    
    Right now this only looks at the nameserver setting. It is initally made for
    asynchronous AD DC lookup routines, where we don't need the "search", "domain"
    and other settings. When we convert general "net", "smbclient" and others to
    use this, we might either add "domain" handling to this code or look at
    something like c-ares which already does it.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ff2dbe24b80b24bdb4897d0152e76ed3931048f2
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Dec 19 14:16:38 2018 +0100

    dns_update: samba_dnsupdate's exit code is not an errno
    
    This avoids confusing messages, samba_dnsupdate returns the number of
    failed updates
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a7e28a7eb56dc3279af52a6edd50cc59c771f1f1
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Jan 11 14:18:53 2019 +0100

    addns: Centralize siteless lookup fallback
    
    We had the same logic 3 times, coalesce into one
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 lib/addns/dnsquery.c                               | 906 +++++++--------------
 lib/addns/dnsquery.h                               |  16 +
 lib/addns/wscript_build                            |   2 +-
 libcli/dns/dns_lookup.c                            | 374 +++++++++
 libcli/dns/dns_lookup.h                            |  48 ++
 libcli/dns/{dns.h => dns_lookuptest.c}             |  75 +-
 libcli/dns/resolvconf.c                            | 123 +++
 .../libads/krb5_errs.h => libcli/dns/resolvconf.h  |  25 +-
 libcli/dns/resolvconftest.c                        |  82 ++
 libcli/dns/wscript_build                           |  21 +-
 .../samba/tests/dns_forwarder_helpers/dns_hub.py   | 156 ++++
 selftest/target/Samba.pm                           |   2 +
 selftest/target/Samba3.pm                          |   4 +
 selftest/target/Samba4.pm                          | 159 +++-
 .../{test_pthreadpool.sh => test_resolvconf.sh}    |   8 +-
 source3/selftest/tests.py                          |   4 +
 source4/dsdb/dns/dns_update.c                      |   4 +-
 source4/scripting/bin/samba_dnsupdate              |  37 +-
 18 files changed, 1324 insertions(+), 722 deletions(-)
 create mode 100644 libcli/dns/dns_lookup.c
 create mode 100644 libcli/dns/dns_lookup.h
 copy libcli/dns/{dns.h => dns_lookuptest.c} (52%)
 create mode 100644 libcli/dns/resolvconf.c
 copy source3/libads/krb5_errs.h => libcli/dns/resolvconf.h (63%)
 create mode 100644 libcli/dns/resolvconftest.c
 create mode 100755 python/samba/tests/dns_forwarder_helpers/dns_hub.py
 copy source3/script/tests/{test_pthreadpool.sh => test_resolvconf.sh} (54%)


Changeset truncated at 500 lines:

diff --git a/lib/addns/dnsquery.c b/lib/addns/dnsquery.c
index 4e2aaf4f3be..e5600367c4b 100644
--- a/lib/addns/dnsquery.c
+++ b/lib/addns/dnsquery.c
@@ -21,6 +21,9 @@
 #include "includes.h"
 #include "lib/util/util_net.h"
 #include "lib/util/tsort.h"
+#include "librpc/gen_ndr/dns.h"
+#include "libcli/dns/dns_lookup.h"
+#include "lib/util/tevent_ntstatus.h"
 #include "dnsquery.h"
 
 /* AIX resolv.h uses 'class' in struct ns_rr */
@@ -73,193 +76,6 @@
 #  define T_SRV 	33
 #endif
 
-/*********************************************************************
-*********************************************************************/
-
-static bool ads_dns_parse_query( TALLOC_CTX *ctx, uint8_t *start, uint8_t *end,
-                          uint8_t **ptr, struct dns_query *q )
-{
-	uint8_t *p = *ptr;
-	char hostname[MAX_DNS_NAME_LENGTH];
-	int namelen;
-
-	ZERO_STRUCTP( q );
-
-	if ( !start || !end || !q || !*ptr)
-		return false;
-
-	/* See RFC 1035 for details. If this fails, then return. */
-
-	namelen = dn_expand( start, end, p, hostname, sizeof(hostname) );
-	if ( namelen < 0 ) {
-		return false;
-	}
-	p += namelen;
-	q->hostname = talloc_strdup( ctx, hostname );
-
-	/* check that we have space remaining */
-
-	if ( PTR_DIFF(p+4, end) > 0 )
-		return false;
-
-	q->type     = RSVAL( p, 0 );
-	q->in_class = RSVAL( p, 2 );
-	p += 4;
-
-	*ptr = p;
-
-	return true;
-}
-
-/*********************************************************************
-*********************************************************************/
-
-static bool ads_dns_parse_rr( TALLOC_CTX *ctx, uint8_t *start, uint8_t *end,
-                       uint8_t **ptr, struct dns_rr *rr )
-{
-	uint8_t *p = *ptr;
-	char hostname[MAX_DNS_NAME_LENGTH];
-	int namelen;
-
-	if ( !start || !end || !rr || !*ptr)
-		return -1;
-
-	ZERO_STRUCTP( rr );
-	/* pull the name from the answer */
-
-	namelen = dn_expand( start, end, p, hostname, sizeof(hostname) );
-	if ( namelen < 0 ) {
-		return -1;
-	}
-	p += namelen;
-	rr->hostname = talloc_strdup( ctx, hostname );
-
-	/* check that we have space remaining */
-
-	if ( PTR_DIFF(p+10, end) > 0 )
-		return false;
-
-	/* pull some values and then skip onto the string */
-
-	rr->type     = RSVAL(p, 0);
-	rr->in_class = RSVAL(p, 2);
-	rr->ttl      = RIVAL(p, 4);
-	rr->rdatalen = RSVAL(p, 8);
-
-	p += 10;
-
-	/* sanity check the available space */
-
-	if ( PTR_DIFF(p+rr->rdatalen, end ) > 0 ) {
-		return false;
-
-	}
-
-	/* save a point to the rdata for this section */
-
-	rr->rdata = p;
-	p += rr->rdatalen;
-
-	*ptr = p;
-
-	return true;
-}
-
-/*********************************************************************
-*********************************************************************/
-
-static bool ads_dns_parse_rr_srv( TALLOC_CTX *ctx, uint8_t *start, uint8_t *end,
-                       uint8_t **ptr, struct dns_rr_srv *srv )
-{
-	struct dns_rr rr;
-	uint8_t *p;
-	char dcname[MAX_DNS_NAME_LENGTH];
-	int namelen;
-
-	if ( !start || !end || !srv || !*ptr)
-		return -1;
-
-	/* Parse the RR entry.  Coming out of the this, ptr is at the beginning
-	   of the next record */
-
-	if ( !ads_dns_parse_rr( ctx, start, end, ptr, &rr ) ) {
-		DEBUG(1,("ads_dns_parse_rr_srv: Failed to parse RR record\n"));
-		return false;
-	}
-
-	if ( rr.type != T_SRV ) {
-		DEBUG(1,("ads_dns_parse_rr_srv: Bad answer type (%d)\n",
-					rr.type));
-		return false;
-	}
-
-	p = rr.rdata;
-
-	srv->priority = RSVAL(p, 0);
-	srv->weight   = RSVAL(p, 2);
-	srv->port     = RSVAL(p, 4);
-
-	p += 6;
-
-	namelen = dn_expand( start, end, p, dcname, sizeof(dcname) );
-	if ( namelen < 0 ) {
-		DEBUG(1,("ads_dns_parse_rr_srv: Failed to uncompress name!\n"));
-		return false;
-	}
-
-	srv->hostname = talloc_strdup( ctx, dcname );
-
-	DEBUG(10,("ads_dns_parse_rr_srv: Parsed %s [%u, %u, %u]\n",
-		  srv->hostname,
-		  srv->priority,
-		  srv->weight,
-		  srv->port));
-
-	return true;
-}
-
-/*********************************************************************
-*********************************************************************/
-
-static bool ads_dns_parse_rr_ns( TALLOC_CTX *ctx, uint8_t *start, uint8_t *end,
-                       uint8_t **ptr, struct dns_rr_ns *nsrec )
-{
-	struct dns_rr rr;
-	uint8_t *p;
-	char nsname[MAX_DNS_NAME_LENGTH];
-	int namelen;
-
-	if ( !start || !end || !nsrec || !*ptr)
-		return -1;
-
-	/* Parse the RR entry.  Coming out of the this, ptr is at the beginning
-	   of the next record */
-
-	if ( !ads_dns_parse_rr( ctx, start, end, ptr, &rr ) ) {
-		DEBUG(1,("ads_dns_parse_rr_ns: Failed to parse RR record\n"));
-		return false;
-	}
-
-	if ( rr.type != T_NS ) {
-		DEBUG(1,("ads_dns_parse_rr_ns: Bad answer type (%d)\n",
-					rr.type));
-		return false;
-	}
-
-	p = rr.rdata;
-
-	/* ame server hostname */
-
-	namelen = dn_expand( start, end, p, nsname, sizeof(nsname) );
-	if ( namelen < 0 ) {
-		DEBUG(1,("ads_dns_parse_rr_ns: Failed to uncompress name!\n"));
-		return false;
-	}
-	nsrec->hostname = talloc_strdup( ctx, nsname );
-
-	return true;
-}
-
 /*********************************************************************
  Sort SRV record list based on weight and priority.  See RFC 2782.
 *********************************************************************/
@@ -285,104 +101,146 @@ static int dnssrvcmp( struct dns_rr_srv *a, struct dns_rr_srv *b )
 	return 1;
 }
 
-/*********************************************************************
- Simple wrapper for a DNS query
-*********************************************************************/
+struct ads_dns_lookup_srv_state {
+	struct dns_rr_srv *srvs;
+	size_t num_srvs;
+};
 
-#define DNS_FAILED_WAITTIME          30
+static void ads_dns_lookup_srv_done(struct tevent_req *subreq);
 
-static NTSTATUS dns_send_req( TALLOC_CTX *ctx, const char *name, int q_type,
-                              uint8_t **buf, int *resp_length )
+struct tevent_req *ads_dns_lookup_srv_send(TALLOC_CTX *mem_ctx,
+					   struct tevent_context *ev,
+					   const char *name)
 {
-	uint8_t *buffer = NULL;
-	size_t buf_len = 0;
-	int resp_len = NS_PACKETSZ;
-	static time_t last_dns_check = 0;
-	static NTSTATUS last_dns_status = NT_STATUS_OK;
-	time_t now = time_mono(NULL);
-
-	/* Try to prevent bursts of DNS lookups if the server is down */
-
-	/* Protect against large clock changes */
-
-	if ( last_dns_check > now )
-		last_dns_check = 0;
-
-	/* IF we had a DNS timeout or a bad server and we are still
-	   in the 30 second cache window, just return the previous
-	   status and save the network timeout. */
-
-	if ( (NT_STATUS_EQUAL(last_dns_status,NT_STATUS_IO_TIMEOUT) ||
-	      NT_STATUS_EQUAL(last_dns_status,NT_STATUS_CONNECTION_REFUSED)) &&
-	     (last_dns_check+DNS_FAILED_WAITTIME) > now )
-	{
-		DEBUG(10,("dns_send_req: last dns check returning cached status (%s)\n",
-			  nt_errstr(last_dns_status) ));
-		return last_dns_status;
+	struct tevent_req *req, *subreq;
+	struct ads_dns_lookup_srv_state *state;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct ads_dns_lookup_srv_state);
+	if (req == NULL) {
+		return NULL;
 	}
 
-	/* Send the Query */
-	do {
-		if ( buffer )
-			TALLOC_FREE( buffer );
-
-		buf_len = resp_len * sizeof(uint8_t);
-
-		if (buf_len) {
-			if ((buffer = talloc_array(ctx, uint8_t, buf_len))
-					== NULL ) {
-				DEBUG(0,("dns_send_req: "
-					"talloc() failed!\n"));
-				last_dns_status = NT_STATUS_NO_MEMORY;
-				last_dns_check = time_mono(NULL);
-				return last_dns_status;
-			}
+	subreq = dns_lookup_send(
+		state,
+		ev,
+		NULL,
+		name,
+		DNS_QCLASS_IN,
+		DNS_QTYPE_SRV);
+
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, ads_dns_lookup_srv_done, req);
+	return req;
+}
+
+static void ads_dns_lookup_srv_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct ads_dns_lookup_srv_state *state = tevent_req_data(
+		req, struct ads_dns_lookup_srv_state);
+	int ret;
+	struct dns_name_packet *reply;
+	uint16_t i, idx;
+
+	ret = dns_lookup_recv(subreq, state, &reply);
+	TALLOC_FREE(subreq);
+	if (ret != 0) {
+		tevent_req_nterror(req, map_nt_error_from_unix_common(ret));
+		return;
+	}
+
+	for (i=0; i<reply->ancount; i++) {
+		if (reply->answers[i].rr_type == DNS_QTYPE_SRV) {
+			state->num_srvs += 1;
 		}
+	}
 
-		if ((resp_len = res_query(name, C_IN, q_type, buffer, buf_len))
-				< 0 ) {
-			DEBUG(3,("dns_send_req: "
-				"Failed to resolve %s (%s)\n",
-				name, strerror(errno)));
-			TALLOC_FREE( buffer );
-			last_dns_status = NT_STATUS_UNSUCCESSFUL;
+	state->srvs = talloc_array(state, struct dns_rr_srv, state->num_srvs);
+	if (tevent_req_nomem(state->srvs, req)) {
+		return;
+	}
 
-			if (errno == ETIMEDOUT) {
-				last_dns_status = NT_STATUS_IO_TIMEOUT;
-			}
-			if (errno == ECONNREFUSED) {
-				last_dns_status = NT_STATUS_CONNECTION_REFUSED;
-			}
-			last_dns_check = time_mono(NULL);
-			return last_dns_status;
+	idx = 0;
+
+	for (i=0; i<reply->ancount; i++) {
+		struct dns_res_rec *an = &reply->answers[i];
+		struct dns_rr_srv *dst = &state->srvs[idx];
+		struct dns_srv_record *src;
+
+		if (an->rr_type != DNS_QTYPE_SRV) {
+			continue;
 		}
+		src = &an->rdata.srv_record;
+
+		*dst = (struct dns_rr_srv) {
+			.hostname = talloc_move(state->srvs, &src->target),
+			.priority = src->priority,
+			.weight = src->weight,
+			.port = src->port,
+		};
+		idx += 1;
+	}
+
+	for (i=0; i<reply->arcount; i++) {
+		struct dns_res_rec *ar = &reply->additional[i];
+		struct sockaddr_storage addr;
+		bool ok;
+		size_t j;
+
+		ok = dns_res_rec_get_sockaddr(ar, &addr);
+		if (!ok) {
+			continue;
+		}
+
+		for (j=0; j<state->num_srvs; j++) {
+			struct dns_rr_srv *srv = &state->srvs[j];
+			struct sockaddr_storage *tmp;
 
-		/* On AIX, Solaris, and possibly some older glibc systems (e.g. SLES8)
-		   truncated replies never give back a resp_len > buflen
-		   which ends up causing DNS resolve failures on large tcp DNS replies */
-
-		if (buf_len == resp_len) {
-			if (resp_len == MAX_DNS_PACKET_SIZE) {
-				DEBUG(1,("dns_send_req: DNS reply too large when resolving %s\n",
-					name));
-				TALLOC_FREE( buffer );
-				last_dns_status = NT_STATUS_BUFFER_TOO_SMALL;
-				last_dns_check = time_mono(NULL);
-				return last_dns_status;
+			if (strcmp(srv->hostname, ar->name) != 0) {
+				continue;
 			}
 
-			resp_len = MIN(resp_len*2, MAX_DNS_PACKET_SIZE);
+			tmp = talloc_realloc(
+				state->srvs,
+				srv->ss_s,
+				struct sockaddr_storage,
+				srv->num_ips+1);
+
+			if (tevent_req_nomem(tmp, req)) {
+				return;
+			}
+			srv->ss_s = tmp;
+
+			srv->ss_s[srv->num_ips] = addr;
+			srv->num_ips += 1;
 		}
+	}
 
+	TYPESAFE_QSORT(state->srvs, state->num_srvs, dnssrvcmp);
 
-	} while ( buf_len < resp_len && resp_len <= MAX_DNS_PACKET_SIZE );
+	tevent_req_done(req);
+}
 
-	*buf = buffer;
-	*resp_length = resp_len;
+NTSTATUS ads_dns_lookup_srv_recv(struct tevent_req *req,
+				 TALLOC_CTX *mem_ctx,
+				 struct dns_rr_srv **srvs,
+				 size_t *num_srvs)
+{
+	struct ads_dns_lookup_srv_state *state = tevent_req_data(
+		req, struct ads_dns_lookup_srv_state);
+	NTSTATUS status;
 
-	last_dns_check = time_mono(NULL);
-	last_dns_status = NT_STATUS_OK;
-	return last_dns_status;
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+	*srvs = talloc_move(mem_ctx, &state->srvs);
+	*num_srvs = state->num_srvs;
+	tevent_req_received(req);
+	return NT_STATUS_OK;
 }
 
 /*********************************************************************
@@ -394,183 +252,138 @@ NTSTATUS ads_dns_lookup_srv(TALLOC_CTX *ctx,
 				struct dns_rr_srv **dclist,
 				int *numdcs)
 {
-	uint8_t *buffer = NULL;
-	int resp_len = 0;
-	struct dns_rr_srv *dcs = NULL;
-	int query_count, answer_count, auth_count, additional_count;
-	uint8_t *p = buffer;
-	int rrnum;
-	int idx = 0;
-	NTSTATUS status;
-
-	if ( !ctx || !name || !dclist ) {
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	/* Send the request.  May have to loop several times in case
-	   of large replies */
+	struct tevent_context *ev;
+	struct tevent_req *req;
+	NTSTATUS status = NT_STATUS_NO_MEMORY;
+	size_t num_srvs;
+
+	ev = samba_tevent_context_init(ctx);
+	if (ev == NULL) {
+		goto fail;
+	}
+	req = ads_dns_lookup_srv_send(ev, ev, name);
+	if (req == NULL) {
+		goto fail;
+	}
+	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+		goto fail;
+	}
+	status = ads_dns_lookup_srv_recv(req, ctx, dclist, &num_srvs);
+	*numdcs = num_srvs;	/* size_t->int */
+fail:
+	TALLOC_FREE(ev);
+	return status;
+}
 
-	status = dns_send_req( ctx, name, T_SRV, &buffer, &resp_len );
-	if ( !NT_STATUS_IS_OK(status) ) {
-		DEBUG(3,("ads_dns_lookup_srv: Failed to send DNS query (%s)\n",
-			nt_errstr(status)));
-		return status;
-	}
-	p = buffer;
-
-	/* For some insane reason, the ns_initparse() et. al. routines are only
-	   available in libresolv.a, and not the shared lib.  Who knows why....
-	   So we have to parse the DNS reply ourselves */
-
-	/* Pull the answer RR's count from the header.
-	 * Use the NMB ordering macros */
-
-	query_count      = RSVAL( p, 4 );
-	answer_count     = RSVAL( p, 6 );
-	auth_count       = RSVAL( p, 8 );
-	additional_count = RSVAL( p, 10 );
-
-	DEBUG(4,("ads_dns_lookup_srv: "
-		"%d records returned in the answer section.\n",


-- 
Samba Shared Repository



More information about the samba-cvs mailing list