summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2008-12-18 14:54:57 +0000
committerJelmer Vernooij <jelmer@samba.org>2008-12-18 14:54:57 +0000
commitd14c8604653d39dd25736279d34930ee7a3ae103 (patch)
tree626f700b9b42b798ed7459a5cba5cd27aca9753e /source4/libcli
parent0c0b9c738f0fc1bf8aa64533a5e4e0635b84f58f (diff)
parentfc31f2c5269fd405be96b9a036baf35a60141ccf (diff)
downloadsamba-d14c8604653d39dd25736279d34930ee7a3ae103.tar.gz
samba-d14c8604653d39dd25736279d34930ee7a3ae103.tar.bz2
samba-d14c8604653d39dd25736279d34930ee7a3ae103.zip
Merge branch 'master' of ssh://git.samba.org/data/git/samba into pyregistry
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/composite/composite.h2
-rw-r--r--source4/libcli/config.mk4
-rw-r--r--source4/libcli/ldap/ldap.c26
-rw-r--r--source4/libcli/ldap/ldap_client.c2
-rw-r--r--source4/libcli/ldap/ldap_controls.c115
-rw-r--r--source4/libcli/ldap/ldap_ndr.c1
-rw-r--r--source4/libcli/resolve/bcast.c32
-rw-r--r--source4/libcli/resolve/dns_ex.c532
-rw-r--r--source4/libcli/resolve/host.c209
-rw-r--r--source4/libcli/resolve/nbtlist.c53
-rw-r--r--source4/libcli/resolve/resolve.c45
-rw-r--r--source4/libcli/resolve/resolve.h22
-rw-r--r--source4/libcli/resolve/testsuite.c4
-rw-r--r--source4/libcli/resolve/wins.c33
-rw-r--r--source4/libcli/wrepl/winsrepl.c9
15 files changed, 780 insertions, 309 deletions
diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h
index 28cd6a88dc..25799d6a94 100644
--- a/source4/libcli/composite/composite.h
+++ b/source4/libcli/composite/composite.h
@@ -24,6 +24,8 @@
#include "libcli/raw/interfaces.h"
+struct event_context;
+
/*
this defines the structures associated with "composite"
requests. Composite requests are libcli requests that are internally
diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk
index 8c31077d8c..85cba421e2 100644
--- a/source4/libcli/config.mk
+++ b/source4/libcli/config.mk
@@ -117,8 +117,7 @@ LIBCLI_CLDAP_OBJ_FILES = $(libclisrcdir)/cldap/cldap.o
# PUBLIC_HEADERS += $(libclisrcdir)/cldap/cldap.h
[SUBSYSTEM::LIBCLI_WREPL]
-PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBCLI_RESOLVE LIBEVENTS \
- LIBPACKET LIBNDR
+PUBLIC_DEPENDENCIES = NDR_WINSREPL samba-socket LIBEVENTS LIBPACKET
LIBCLI_WREPL_OBJ_FILES = $(libclisrcdir)/wrepl/winsrepl.o
@@ -136,6 +135,7 @@ PRIVATE_DEPENDENCIES = LIBCLI_NBT LIBSAMBA-HOSTCONFIG LIBNETIF
LP_RESOLVE_OBJ_FILES = $(addprefix $(libclisrcdir)/resolve/, \
bcast.o nbtlist.o wins.o \
+ dns_ex.o \
host.o resolve_lp.o)
$(eval $(call proto_header_template,$(libclisrcdir)/resolve/lp_proto.h,$(LP_RESOLVE_OBJ_FILES:.o=.c)))
diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c
index 87c89daf9f..7a65cc5c27 100644
--- a/source4/libcli/ldap/ldap.c
+++ b/source4/libcli/ldap/ldap.c
@@ -504,9 +504,9 @@ static const char *blob2string_talloc(TALLOC_CTX *mem_ctx,
return result;
}
-static bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
- struct asn1_data *data,
- const char **result)
+bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
+ struct asn1_data *data,
+ const char **result)
{
DATA_BLOB string;
if (!asn1_read_OctetString(data, mem_ctx, &string))
@@ -894,7 +894,7 @@ failed:
return NULL;
}
-
+/* Decode a single LDAP attribute, possibly containing multiple values */
static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
struct ldb_message_element *attrib)
{
@@ -911,11 +911,11 @@ static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
}
-static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
- struct ldb_message_element **attributes,
- int *num_attributes)
+/* Decode a set of LDAP attributes, as found in the dereference control */
+void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+ struct ldb_message_element **attributes,
+ int *num_attributes)
{
- asn1_start_tag(data, ASN1_SEQUENCE(0));
while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
struct ldb_message_element attrib;
ZERO_STRUCT(attrib);
@@ -923,6 +923,16 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
add_attrib_to_array_talloc(mem_ctx, &attrib,
attributes, num_attributes);
}
+}
+
+/* Decode a set of LDAP attributes, as found in a search entry */
+void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+ struct ldb_message_element **attributes,
+ int *num_attributes)
+{
+ asn1_start_tag(data, ASN1_SEQUENCE(0));
+ ldap_decode_attribs_bare(mem_ctx, data,
+ attributes, num_attributes);
asn1_end_tag(data);
}
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index 7f43e16c95..082f6fa3e4 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -358,7 +358,7 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con
}
ctx = socket_connect_send(conn->sock, NULL, unix_addr,
- 0, lp_resolve_context(conn->lp_ctx), conn->event.event_ctx);
+ 0, conn->event.event_ctx);
ctx->async.fn = ldap_connect_recv_unix_conn;
ctx->async.private_data = state;
return result;
diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c
index 930d97c40d..109837c2bf 100644
--- a/source4/libcli/ldap/ldap_controls.c
+++ b/source4/libcli/ldap/ldap_controls.c
@@ -24,6 +24,7 @@
#include "libcli/ldap/ldap.h"
#include "lib/ldb/include/ldb.h"
#include "libcli/ldap/ldap_proto.h"
+#include "dsdb/samdb/samdb.h"
struct control_handler {
const char *oid;
@@ -1087,6 +1088,119 @@ static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out)
return true;
}
+static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
+{
+ struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control);
+ int i,j;
+ struct asn1_data *data = asn1_init(mem_ctx);
+
+ if (!data) return false;
+
+ if (!control) return false;
+
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+
+ for (i=0; control->dereference && control->dereference[i]; i++) {
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+ if (!asn1_write_OctetString(data, control->dereference[i]->source_attribute, strlen(control->dereference[i]->source_attribute))) {
+ return false;
+ }
+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+ for (j=0; control->dereference && control->dereference[i]->dereference_attribute[j]; j++) {
+ if (!asn1_write_OctetString(data, control->dereference[i]->dereference_attribute[j],
+ strlen(control->dereference[i]->dereference_attribute[j]))) {
+ return false;
+ }
+ }
+
+ asn1_pop_tag(data);
+ asn1_pop_tag(data);
+ }
+ asn1_pop_tag(data);
+
+ *out = data_blob_talloc(mem_ctx, data->data, data->length);
+ if (out->data == NULL) {
+ return false;
+ }
+ talloc_free(data);
+ return true;
+}
+
+static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void **out)
+{
+ struct asn1_data *data = asn1_init(mem_ctx);
+ struct dsdb_openldap_dereference_result_control *control;
+ struct dsdb_openldap_dereference_result **r = NULL;
+ int i = 0;
+ if (!data) return false;
+
+ control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
+ if (!control) return false;
+
+ if (!asn1_load(data, in)) {
+ return false;
+ }
+
+ control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
+ if (!control) {
+ return false;
+ }
+
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+
+ while (asn1_tag_remaining(data) > 0) {
+ r = talloc_realloc(control, r, struct dsdb_openldap_dereference_result *, i + 2);
+ if (!r) {
+ return false;
+ }
+ r[i] = talloc_zero(r, struct dsdb_openldap_dereference_result);
+ if (!r[i]) {
+ return false;
+ }
+
+ if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
+ return false;
+ }
+
+ asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute);
+ asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn);
+ if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
+ if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
+ return false;
+ }
+
+ ldap_decode_attribs_bare(r, data, &r[i]->attributes,
+ &r[i]->num_attributes);
+
+ if (!asn1_end_tag(data)) {
+ return false;
+ }
+ }
+ if (!asn1_end_tag(data)) {
+ return false;
+ }
+ i++;
+ r[i] = NULL;
+ }
+
+ if (!asn1_end_tag(data)) {
+ return false;
+ }
+
+ control->attributes = r;
+ *out = control;
+
+ return true;
+}
+
struct control_handler ldap_known_controls[] = {
{ "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request },
{ "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request },
@@ -1107,6 +1221,7 @@ struct control_handler ldap_known_controls[] = {
{ "1.3.6.1.4.1.7165.4.3.2", NULL, NULL },
/* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */
{ "1.3.6.1.4.1.7165.4.4.1", NULL, NULL },
+ { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference},
{ NULL, NULL, NULL }
};
diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c
index 5e938ea148..f0a11ba41f 100644
--- a/source4/libcli/ldap/ldap_ndr.c
+++ b/source4/libcli/ldap/ldap_ndr.c
@@ -21,7 +21,6 @@
*/
#include "includes.h"
-#include "lib/events/events.h"
#include "libcli/ldap/ldap.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/ndr_misc.h"
diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c
index 0a71ebed99..866ce7a152 100644
--- a/source4/libcli/resolve/bcast.c
+++ b/source4/libcli/resolve/bcast.c
@@ -37,7 +37,8 @@ struct resolve_bcast_data {
*/
struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
- void *userdata,
+ void *userdata, uint32_t flags,
+ uint16_t port,
struct nbt_name *name)
{
int num_interfaces;
@@ -63,7 +64,9 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx,
}
address_list[count] = NULL;
- c = resolve_name_nbtlist_send(mem_ctx, event_ctx, name, address_list, data->ifaces, data->nbt_port, data->nbt_timeout, true, false);
+ c = resolve_name_nbtlist_send(mem_ctx, event_ctx, flags, port, name,
+ address_list, data->ifaces, data->nbt_port,
+ data->nbt_timeout, true, false);
talloc_free(address_list);
return c;
@@ -74,9 +77,10 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx,
*/
NTSTATUS resolve_name_bcast_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
- NTSTATUS status = resolve_name_nbtlist_recv(c, mem_ctx, addrs);
+ NTSTATUS status = resolve_name_nbtlist_recv(c, mem_ctx, addrs, names);
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
/* this makes much more sense for a bcast name resolution
timeout */
@@ -85,26 +89,6 @@ NTSTATUS resolve_name_bcast_recv(struct composite_context *c,
return status;
}
-/*
- broadcast name resolution method - sync call
- */
-NTSTATUS resolve_name_bcast(struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- struct interface *ifaces,
- uint16_t nbt_port,
- int nbt_timeout,
- struct socket_address ***addrs)
-{
- struct resolve_bcast_data *data = talloc(mem_ctx, struct resolve_bcast_data);
- struct composite_context *c;
- data->ifaces = talloc_reference(data, ifaces);
- data->nbt_port = nbt_port;
- data->nbt_timeout = nbt_timeout;
-
- c = resolve_name_bcast_send(mem_ctx, NULL, data, name);
- return resolve_name_bcast_recv(c, mem_ctx, addrs);
-}
-
bool resolve_context_add_bcast_method(struct resolve_context *ctx, struct interface *ifaces, uint16_t nbt_port, int nbt_timeout)
{
struct resolve_bcast_data *data = talloc(ctx, struct resolve_bcast_data);
diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c
new file mode 100644
index 0000000000..948ad9f134
--- /dev/null
+++ b/source4/libcli/resolve/dns_ex.c
@@ -0,0 +1,532 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ async getaddrinfo()/dns_lookup() name resolution module
+
+ Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Stefan Metzmacher 2008
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ this module uses a fork() per getaddrinfo() or dns_looup() call.
+ At first that might seem crazy, but it is actually very fast,
+ and solves many of the tricky problems of keeping a child
+ hanging around in a librar (like what happens when the parent forks).
+ We use a talloc destructor to ensure that the child is cleaned up
+ when we have finished with this name resolution.
+*/
+
+#include "includes.h"
+#include "lib/events/events.h"
+#include "system/network.h"
+#include "system/filesys.h"
+#include "lib/socket/socket.h"
+#include "libcli/composite/composite.h"
+#include "librpc/gen_ndr/ndr_nbt.h"
+#include "libcli/resolve/resolve.h"
+#include "heimdal/lib/roken/resolve.h"
+
+struct dns_ex_state {
+ bool do_fallback;
+ uint32_t flags;
+ uint16_t port;
+ struct nbt_name name;
+ struct socket_address **addrs;
+ char **names;
+ pid_t child;
+ int child_fd;
+ struct fd_event *fde;
+ struct event_context *event_ctx;
+};
+
+/*
+ kill off a wayward child if needed. This allows us to stop an async
+ name resolution without leaving a potentially blocking call running
+ in a child
+*/
+static int dns_ex_destructor(struct dns_ex_state *state)
+{
+ int status;
+
+ kill(state->child, SIGTERM);
+ close(state->child_fd);
+ if (waitpid(state->child, &status, WNOHANG) == 0) {
+ kill(state->child, SIGKILL);
+ waitpid(state->child, &status, 0);
+ }
+
+ return 0;
+}
+
+/*
+ the blocking child
+*/
+static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
+{
+ struct dns_reply *reply;
+ struct resource_record *rr;
+ uint32_t count = 0;
+ uint32_t srv_valid = 0;
+ struct resource_record **srv_rr;
+ uint32_t addrs_valid = 0;
+ struct resource_record **addrs_rr;
+ char *addrs;
+ bool first;
+ uint32_t i;
+ bool do_srv = (state->flags & RESOLVE_NAME_FLAG_DNS_SRV);
+
+ /* this is the blocking call we are going to lots of trouble
+ to avoid in the parent */
+ reply = dns_lookup(state->name.name, do_srv?"SRV":"A");
+ if (!reply) {
+ goto done;
+ }
+
+ if (do_srv) {
+ dns_srv_order(reply);
+ }
+
+ /* Loop over all returned records and pick the "srv" records */
+ for (rr=reply->head; rr; rr=rr->next) {
+ /* we are only interested in the IN class */
+ if (rr->class != C_IN) {
+ continue;
+ }
+
+ if (do_srv) {
+ /* we are only interested in SRV records */
+ if (rr->type != T_SRV) {
+ continue;
+ }
+
+ /* verify we actually have a SRV record here */
+ if (!rr->u.srv) {
+ continue;
+ }
+
+ /* Verify we got a port */
+ if (rr->u.srv->port == 0) {
+ continue;
+ }
+ } else {
+ /* we are only interested in A records */
+ /* TODO: add AAAA support */
+ if (rr->type != T_A) {
+ continue;
+ }
+
+ /* verify we actually have a A record here */
+ if (!rr->u.a) {
+ continue;
+ }
+ }
+ count++;
+ }
+
+ if (count == 0) {
+ goto done;
+ }
+
+ srv_rr = talloc_zero_array(state,
+ struct resource_record *,
+ count);
+ if (!srv_rr) {
+ goto done;
+ }
+
+ addrs_rr = talloc_zero_array(state,
+ struct resource_record *,
+ count);
+ if (!addrs_rr) {
+ goto done;
+ }
+
+ /* Loop over all returned records and pick the records */
+ for (rr=reply->head;rr;rr=rr->next) {
+ /* we are only interested in the IN class */
+ if (rr->class != C_IN) {
+ continue;
+ }
+
+ if (do_srv) {
+ /* we are only interested in SRV records */
+ if (rr->type != T_SRV) {
+ continue;
+ }
+
+ /* verify we actually have a srv record here */
+ if (!rr->u.srv) {
+ continue;
+ }
+
+ /* Verify we got a port */
+ if (rr->u.srv->port == 0) {
+ continue;
+ }
+
+ srv_rr[srv_valid] = rr;
+ srv_valid++;
+ } else {
+ /* we are only interested in A records */
+ /* TODO: add AAAA support */
+ if (rr->type != T_A) {
+ continue;
+ }
+
+ /* verify we actually have a A record here */
+ if (!rr->u.a) {
+ continue;
+ }
+
+ addrs_rr[addrs_valid] = rr;
+ addrs_valid++;
+ }
+ }
+
+ for (i=0; i < srv_valid; i++) {
+ for (rr=reply->head;rr;rr=rr->next) {
+
+ if (rr->class != C_IN) {
+ continue;
+ }
+
+ /* we are only interested in SRV records */
+ if (rr->type != T_A) {
+ continue;
+ }
+
+ /* verify we actually have a srv record here */
+ if (strcmp(&srv_rr[i]->u.srv->target[0], rr->domain) != 0) {
+ continue;
+ }
+
+ addrs_rr[i] = rr;
+ addrs_valid++;
+ break;
+ }
+ }
+
+ if (addrs_valid == 0) {
+ goto done;
+ }
+
+ addrs = talloc_strdup(state, "");
+ if (!addrs) {
+ goto done;
+ }
+ first = true;
+ for (i=0; i < count; i++) {
+ uint16_t port;
+ if (!addrs_rr[i]) {
+ continue;
+ }
+
+ if (srv_rr[i] &&
+ (state->flags & RESOLVE_NAME_FLAG_OVERWRITE_PORT)) {
+ port = srv_rr[i]->u.srv->port;
+ } else {
+ port = state->port;
+ }
+
+ addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
+ first?"":",",
+ inet_ntoa(*addrs_rr[i]->u.a),
+ port,
+ addrs_rr[i]->domain);
+ if (!addrs) {
+ goto done;
+ }
+ first = false;
+ }
+
+ if (addrs) {
+ write(fd, addrs, talloc_get_size(addrs));
+ }
+
+done:
+ close(fd);
+}
+
+/*
+ the blocking child
+*/
+static void run_child_getaddrinfo(struct dns_ex_state *state, int fd)
+{
+ int ret;
+ struct addrinfo hints;
+ struct addrinfo *res;
+ struct addrinfo *res_list = NULL;
+ char *addrs;
+ bool first;
+
+ ZERO_STRUCT(hints);
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = AF_INET;/* TODO: add AF_INET6 support */
+ hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
+
+ ret = getaddrinfo(state->name.name, "0", &hints, &res_list);
+ if (ret == EAI_NODATA && state->do_fallback) {
+ /* getaddrinfo() doesn't handle CNAME records */
+ run_child_dns_lookup(state, fd);
+ return;
+ }
+ if (ret != 0) {
+ goto done;
+ }
+
+ addrs = talloc_strdup(state, "");
+ if (!addrs) {
+ goto done;
+ }
+ first = true;
+ for (res = res_list; res; res = res->ai_next) {
+ struct sockaddr_in *in;
+
+ if (res->ai_family != AF_INET) {
+ continue;
+ }
+ in = (struct sockaddr_in *)res->ai_addr;
+
+ addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
+ first?"":",",
+ inet_ntoa(in->sin_addr),
+ state->port,
+ state->name.name);
+ if (!addrs) {
+ goto done;
+ }
+ first = false;
+ }
+
+ if (addrs) {
+ write(fd, addrs, talloc_get_size(addrs));
+ }
+done:
+ if (res_list) {
+ freeaddrinfo(res_list);
+ }
+ close(fd);
+}
+
+/*
+ handle a read event on the pipe
+*/
+static void pipe_handler(struct event_context *ev, struct fd_event *fde,
+ uint16_t flags, void *private_data)
+{
+ struct composite_context *c = talloc_get_type(private_data, struct composite_context);
+ struct dns_ex_state *state = talloc_get_type(c->private_data,
+ struct dns_ex_state);
+ char *address;
+ uint32_t num_addrs, i;
+ char **addrs;
+ int ret;
+ int status;
+ int value = 0;
+
+ /* if we get any event from the child then we know that we
+ won't need to kill it off */
+ talloc_set_destructor(state, NULL);
+
+ if (ioctl(state->child_fd, FIONREAD, &value) != 0) {
+ value = 8192;
+ }
+
+ address = talloc_array(state, char, value+1);
+ if (address) {
+ /* yes, we don't care about EAGAIN or other niceities
+ here. They just can't happen with this parent/child
+ relationship, and even if they did then giving an error is
+ the right thing to do */
+ ret = read(state->child_fd, address, value);
+ } else {
+ ret = -1;
+ }
+ close(state->child_fd);
+ if (waitpid(state->child, &status, WNOHANG) == 0) {
+ kill(state->child, SIGKILL);
+ waitpid(state->child, &status, 0);
+ }
+
+ if (ret <= 0) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+
+ /* enusre the address looks good */
+ address[ret] = 0;
+
+ addrs = str_list_make(state, address, ",");
+ if (composite_nomem(addrs, c)) return;
+
+ num_addrs = str_list_length((const char * const *)addrs);
+
+ state->addrs = talloc_array(state, struct socket_address *,
+ num_addrs+1);
+ if (composite_nomem(state->addrs, c)) return;
+
+ state->names = talloc_array(state, char *, num_addrs+1);
+ if (composite_nomem(state->names, c)) return;
+
+ for (i=0; i < num_addrs; i++) {
+ uint32_t port = 0;
+ char *p = strrchr(addrs[i], ':');
+ char *n;
+
+ if (!p) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+
+ *p = '\0';
+ p++;
+
+ n = strrchr(p, '/');
+ if (!n) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+
+ *n = '\0';
+ n++;
+
+ if (strcmp(addrs[i], "0.0.0.0") == 0 ||
+ inet_addr(addrs[i]) == INADDR_NONE) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+ port = strtoul(p, NULL, 10);
+ if (port > UINT16_MAX) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return;
+ }
+ state->addrs[i] = socket_address_from_strings(state->addrs,
+ "ipv4",
+ addrs[i],
+ port);
+ if (composite_nomem(state->addrs[i], c)) return;
+
+ state->names[i] = talloc_strdup(state->names, n);
+ if (composite_nomem(state->names[i], c)) return;
+ }
+ state->addrs[i] = NULL;
+ state->names[i] = NULL;
+
+ composite_done(c);
+}
+
+/*
+ getaddrinfo() or dns_lookup() name resolution method - async send
+ */
+struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx,
+ struct event_context *event_ctx,
+ void *privdata,
+ uint32_t flags,
+ uint16_t port,
+ struct nbt_name *name,
+ bool do_fallback)
+{
+ struct composite_context *c;
+ struct dns_ex_state *state;
+ int fd[2] = { -1, -1 };
+ int ret;
+
+ c = composite_create(mem_ctx, event_ctx);
+ if (c == NULL) return NULL;
+
+ if (flags & RESOLVE_NAME_FLAG_FORCE_NBT) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return c;
+ }
+
+ state = talloc_zero(c, struct dns_ex_state);
+ if (composite_nomem(state, c)) return c;
+ c->private_data = state;
+
+ c->status = nbt_name_dup(state, name, &state->name);
+ if (!composite_is_ok(c)) return c;
+
+ /* setup a pipe to chat to our child */
+ ret = pipe(fd);
+ if (ret == -1) {
+ composite_error(c, map_nt_error_from_unix(errno));
+ return c;
+ }
+
+ state->do_fallback = do_fallback;
+ state->flags = flags;
+ state->port = port;
+
+ state->child_fd = fd[0];
+ state->event_ctx = c->event_ctx;
+
+ /* we need to put the child in our event context so
+ we know when the dns_lookup() has finished */
+ state->fde = event_add_fd(c->event_ctx, c, state->child_fd, EVENT_FD_READ,
+ pipe_handler, c);
+ if (composite_nomem(state->fde, c)) {
+ close(fd[0]);
+ close(fd[1]);
+ return c;
+ }
+
+ state->child = fork();
+ if (state->child == (pid_t)-1) {
+ composite_error(c, map_nt_error_from_unix(errno));
+ return c;
+ }
+
+ if (state->child == 0) {
+ close(fd[0]);
+ if (state->flags & RESOLVE_NAME_FLAG_FORCE_DNS) {
+ run_child_dns_lookup(state, fd[1]);
+ } else {
+ run_child_getaddrinfo(state, fd[1]);
+ }
+ _exit(0);
+ }
+ close(fd[1]);
+
+ /* cleanup wayward children */
+ talloc_set_destructor(state, dns_ex_destructor);
+
+ return c;
+}
+
+/*
+ getaddrinfo() or dns_lookup() name resolution method - recv side
+*/
+NTSTATUS resolve_name_dns_ex_recv(struct composite_context *c,
+ TALLOC_CTX *mem_ctx,
+ struct socket_address ***addrs,
+ char ***names)
+{
+ NTSTATUS status;
+
+ status = composite_wait(c);
+
+ if (NT_STATUS_IS_OK(status)) {
+ struct dns_ex_state *state = talloc_get_type(c->private_data,
+ struct dns_ex_state);
+ *addrs = talloc_steal(mem_ctx, state->addrs);
+ if (names) {
+ *names = talloc_steal(mem_ctx, state->names);
+ }
+ }
+
+ talloc_free(c);
+ return status;
+}
diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c
index 7b1aef803e..b7eaf4bef5 100644
--- a/source4/libcli/resolve/host.c
+++ b/source4/libcli/resolve/host.c
@@ -1,33 +1,25 @@
/*
Unix SMB/CIFS implementation.
- async gethostbyname() name resolution module
+ async "host" name resolution module
Copyright (C) Andrew Tridgell 2005
-
+ Copyright (C) Stefan Metzmacher 2008
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
- this module uses a fork() per gethostbyname() call. At first that
- might seem crazy, but it is actually very fast, and solves many of
- the tricky problems of keeping a child hanging around in a library
- (like what happens when the parent forks). We use a talloc
- destructor to ensure that the child is cleaned up when we have
- finished with this name resolution.
-*/
-
#include "includes.h"
#include "lib/events/events.h"
#include "system/network.h"
@@ -37,201 +29,28 @@
#include "librpc/gen_ndr/ndr_nbt.h"
#include "libcli/resolve/resolve.h"
-struct host_state {
- struct nbt_name name;
- struct socket_address **addrs;
- pid_t child;
- int child_fd;
- struct fd_event *fde;
- struct event_context *event_ctx;
-};
-
-
/*
- kill off a wayward child if needed. This allows us to stop an async
- name resolution without leaving a potentially blocking call running
- in a child
-*/
-static int host_destructor(struct host_state *state)
-{
- int status;
-
- kill(state->child, SIGTERM);
- close(state->child_fd);
- if (waitpid(state->child, &status, WNOHANG) == 0) {
- kill(state->child, SIGKILL);
- waitpid(state->child, &status, 0);
- }
-
- return 0;
-}
-
-/*
- the blocking child
-*/
-static void run_child(struct composite_context *c, int fd)
-{
- struct host_state *state = talloc_get_type(c->private_data, struct host_state);
- struct in_addr ip;
- const char *address;
-
- /* this is the blocking call we are going to lots of trouble
- to avoid in the parent */
- ip = interpret_addr2(state->name.name);
-
- address = inet_ntoa(ip);
- if (address != NULL) {
- write(fd, address, strlen(address)+1);
- }
- close(fd);
-}
-
-/*
- handle a read event on the pipe
-*/
-static void pipe_handler(struct event_context *ev, struct fd_event *fde,
- uint16_t flags, void *private_data)
-{
- struct composite_context *c = talloc_get_type(private_data, struct composite_context);
- struct host_state *state = talloc_get_type(c->private_data, struct host_state);
- char address[128];
- int ret;
- int status;
-
- /* if we get any event from the child then we know that we
- won't need to kill it off */
- talloc_set_destructor(state, NULL);
-
- /* yes, we don't care about EAGAIN or other niceities
- here. They just can't happen with this parent/child
- relationship, and even if they did then giving an error is
- the right thing to do */
- ret = read(state->child_fd, address, sizeof(address)-1);
- close(state->child_fd);
- if (waitpid(state->child, &status, WNOHANG) == 0) {
- kill(state->child, SIGKILL);
- waitpid(state->child, &status, 0);
- }
- if (ret <= 0) {
- composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return;
- }
-
- /* enusre the address looks good */
- address[ret] = 0;
- if (strcmp(address, "0.0.0.0") == 0 ||
- inet_addr(address) == INADDR_NONE) {
- composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return;
- }
-
- state->addrs = talloc_array(state, struct socket_address *, 2);
- if (composite_nomem(state->addrs, c)) return;
-
- state->addrs[0] = socket_address_from_strings(state->addrs,
- "ipv4",
- address,
- 0);
- if (composite_nomem(state->addrs[0], c)) return;
- state->addrs[1] = NULL;
-
- composite_done(c);
-}
-
-/*
- gethostbyname name resolution method - async send
+ getaddrinfo() (with fallback to dns_lookup()) name resolution method - async send
*/
struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
- void *privdata,
+ void *privdata, uint32_t flags,
+ uint16_t port,
struct nbt_name *name)
{
- struct composite_context *c;
- struct host_state *state;
- int fd[2] = { -1, -1 };
- int ret;
-
- c = composite_create(mem_ctx, event_ctx);
- if (c == NULL) return NULL;
-
- if (composite_nomem(c->event_ctx, c)) return c;
-
- state = talloc(c, struct host_state);
- if (composite_nomem(state, c)) return c;
- c->private_data = state;
-
- c->status = nbt_name_dup(state, name, &state->name);
- if (!composite_is_ok(c)) return c;
-
- /* setup a pipe to chat to our child */
- ret = pipe(fd);
- if (ret == -1) {
- composite_error(c, map_nt_error_from_unix(errno));
- return c;
- }
-
- state->child_fd = fd[0];
- state->event_ctx = c->event_ctx;
-
- /* we need to put the child in our event context so
- we know when the gethostbyname() has finished */
- state->fde = event_add_fd(c->event_ctx, c, state->child_fd, EVENT_FD_READ,
- pipe_handler, c);
- if (composite_nomem(state->fde, c)) {
- close(fd[0]);
- close(fd[1]);
- return c;
- }
-
- state->child = fork();
- if (state->child == (pid_t)-1) {
- composite_error(c, map_nt_error_from_unix(errno));
- return c;
- }
-
-
- if (state->child == 0) {
- close(fd[0]);
- run_child(c, fd[1]);
- _exit(0);
- }
- close(fd[1]);
-
- /* cleanup wayward children */
- talloc_set_destructor(state, host_destructor);
-
- return c;
+ return resolve_name_dns_ex_send(mem_ctx, event_ctx, NULL, flags,
+ port, name, true);
}
/*
- gethostbyname name resolution method - recv side
+ getaddrinfo() (with fallback to dns_lookup()) name resolution method - recv side
*/
NTSTATUS resolve_name_host_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
-{
- NTSTATUS status;
-
- status = composite_wait(c);
-
- if (NT_STATUS_IS_OK(status)) {
- struct host_state *state = talloc_get_type(c->private_data, struct host_state);
- *addrs = talloc_steal(mem_ctx, state->addrs);
- }
-
- talloc_free(c);
- return status;
-}
-
-/*
- gethostbyname name resolution method - sync call
- */
-NTSTATUS resolve_name_host(struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
- struct composite_context *c = resolve_name_host_send(mem_ctx, NULL, NULL, name);
- return resolve_name_host_recv(c, mem_ctx, addrs);
+ return resolve_name_dns_ex_recv(c, mem_ctx, addrs, names);
}
bool resolve_context_add_host_method(struct resolve_context *ctx)
diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c
index 9c53fcb7ec..734fd5a5bc 100644
--- a/source4/libcli/resolve/nbtlist.c
+++ b/source4/libcli/resolve/nbtlist.c
@@ -34,12 +34,15 @@
#include "libcli/resolve/resolve.h"
struct nbtlist_state {
+ uint16_t flags;
+ uint16_t port;
struct nbt_name name;
struct nbt_name_socket *nbtsock;
int num_queries;
struct nbt_name_request **queries;
struct nbt_name_query *io_queries;
struct socket_address **addrs;
+ char **names;
struct interface *ifaces;
};
@@ -81,14 +84,21 @@ static void nbtlist_handler(struct nbt_name_request *req)
q->out.num_addrs + 1);
if (composite_nomem(state->addrs, c)) return;
+ state->names = talloc_array(state, char *, q->out.num_addrs + 1);
+ if (composite_nomem(state->names, c)) return;
+
for (i=0;i<q->out.num_addrs;i++) {
state->addrs[i] = socket_address_from_strings(state->addrs,
"ipv4",
q->out.reply_addrs[i],
- 0);
+ state->port);
if (composite_nomem(state->addrs[i], c)) return;
+
+ state->names[i] = talloc_strdup(state->names, state->name.name);
+ if (composite_nomem(state->names[i], c)) return;
}
state->addrs[i] = NULL;
+ state->names[i] = NULL;
composite_done(c);
}
@@ -98,6 +108,8 @@ static void nbtlist_handler(struct nbt_name_request *req)
*/
struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
+ uint32_t flags,
+ uint16_t port,
struct nbt_name *name,
const char **address_list,
struct interface *ifaces,
@@ -113,12 +125,23 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx,
c = composite_create(mem_ctx, event_ctx);
if (c == NULL) return NULL;
- if (composite_nomem(c->event_ctx, c)) return c;
+ if (flags & RESOLVE_NAME_FLAG_FORCE_DNS) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return c;
+ }
+
+ if (strlen(name->name) > 15) {
+ composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ return c;
+ }
state = talloc(c, struct nbtlist_state);
if (composite_nomem(state, c)) return c;
c->private_data = state;
+ state->flags = flags;
+ state->port = port;
+
c->status = nbt_name_dup(state, name, &state->name);
if (!composite_is_ok(c)) return c;
@@ -180,7 +203,8 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx,
*/
NTSTATUS resolve_name_nbtlist_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
NTSTATUS status;
@@ -189,29 +213,12 @@ NTSTATUS resolve_name_nbtlist_recv(struct composite_context *c,
if (NT_STATUS_IS_OK(status)) {
struct nbtlist_state *state = talloc_get_type(c->private_data, struct nbtlist_state);
*addrs = talloc_steal(mem_ctx, state->addrs);
+ if (names) {
+ *names = talloc_steal(mem_ctx, state->names);
+ }
}
talloc_free(c);
return status;
}
-/*
- nbt list of addresses name resolution method - sync call
- */
-NTSTATUS resolve_name_nbtlist(struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- const char **address_list,
- struct interface *ifaces,
- uint16_t nbt_port,
- int nbt_timeout,
- bool broadcast, bool wins_lookup,
- struct socket_address ***addrs)
-{
- struct composite_context *c = resolve_name_nbtlist_send(mem_ctx, NULL,
- name, address_list,
- ifaces, nbt_port,
- nbt_timeout,
- broadcast, wins_lookup);
- return resolve_name_nbtlist_recv(c, mem_ctx, addrs);
-}
-
diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c
index 7d1c48cbee..752678abb8 100644
--- a/source4/libcli/resolve/resolve.c
+++ b/source4/libcli/resolve/resolve.c
@@ -21,7 +21,6 @@
*/
#include "includes.h"
-#include "lib/events/events.h"
#include "libcli/composite/composite.h"
#include "libcli/resolve/resolve.h"
#include "librpc/gen_ndr/ndr_nbt.h"
@@ -32,9 +31,12 @@
struct resolve_state {
struct resolve_context *ctx;
struct resolve_method *method;
+ uint32_t flags;
+ uint16_t port;
struct nbt_name name;
struct composite_context *creq;
struct socket_address **addrs;
+ char **names;
};
static struct composite_context *setup_next_method(struct composite_context *c);
@@ -84,7 +86,7 @@ static void resolve_handler(struct composite_context *creq)
struct resolve_state *state = talloc_get_type(c->private_data, struct resolve_state);
const struct resolve_method *method = state->method;
- c->status = method->recv_fn(creq, state, &state->addrs);
+ c->status = method->recv_fn(creq, state, &state->addrs, &state->names);
if (!NT_STATUS_IS_OK(c->status)) {
state->method = state->method->next;
@@ -112,7 +114,11 @@ static struct composite_context *setup_next_method(struct composite_context *c)
do {
if (state->method) {
- creq = state->method->send_fn(c, c->event_ctx, state->method->privdata, &state->name);
+ creq = state->method->send_fn(c, c->event_ctx,
+ state->method->privdata,
+ state->flags,
+ state->port,
+ &state->name);
}
if (creq == NULL && state->method) state->method = state->method->next;
@@ -130,6 +136,8 @@ static struct composite_context *setup_next_method(struct composite_context *c)
general name resolution - async send
*/
struct composite_context *resolve_name_all_send(struct resolve_context *ctx,
+ uint32_t flags,
+ uint16_t port,
struct nbt_name *name,
struct event_context *event_ctx)
{
@@ -149,6 +157,9 @@ struct composite_context *resolve_name_all_send(struct resolve_context *ctx,
if (composite_nomem(state, c)) return c;
c->private_data = state;
+ state->flags = flags;
+ state->port = port;
+
c->status = nbt_name_dup(state, name, &state->name);
if (!composite_is_ok(c)) return c;
@@ -165,6 +176,11 @@ struct composite_context *resolve_name_all_send(struct resolve_context *ctx,
inet_ntoa(ip), 0);
if (composite_nomem(state->addrs[0], c)) return c;
state->addrs[1] = NULL;
+ state->names = talloc_array(state, char *, 2);
+ if (composite_nomem(state->names, c)) return c;
+ state->names[0] = talloc_strdup(state->names, state->name.name);
+ if (composite_nomem(state->names[0], c)) return c;
+ state->names[1] = NULL;
composite_done(c);
return c;
}
@@ -185,7 +201,8 @@ struct composite_context *resolve_name_all_send(struct resolve_context *ctx,
*/
NTSTATUS resolve_name_all_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
NTSTATUS status;
@@ -194,30 +211,20 @@ NTSTATUS resolve_name_all_recv(struct composite_context *c,
if (NT_STATUS_IS_OK(status)) {
struct resolve_state *state = talloc_get_type(c->private_data, struct resolve_state);
*addrs = talloc_steal(mem_ctx, state->addrs);
+ if (names) {
+ *names = talloc_steal(mem_ctx, state->names);
+ }
}
talloc_free(c);
return status;
}
-/*
- general name resolution - sync call
- */
-NTSTATUS resolve_all_name(struct resolve_context *ctx,
- struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs,
- struct event_context *ev)
-{
- struct composite_context *c = resolve_name_all_send(ctx, name, ev);
- return resolve_name_all_recv(c, mem_ctx, addrs);
-}
-
struct composite_context *resolve_name_send(struct resolve_context *ctx,
struct nbt_name *name,
struct event_context *event_ctx)
{
- return resolve_name_all_send(ctx, name, event_ctx);
+ return resolve_name_all_send(ctx, 0, 0, name, event_ctx);
}
NTSTATUS resolve_name_recv(struct composite_context *c,
@@ -227,7 +234,7 @@ NTSTATUS resolve_name_recv(struct composite_context *c,
NTSTATUS status;
struct socket_address **addrs = NULL;
- status = resolve_name_all_recv(c, mem_ctx, &addrs);
+ status = resolve_name_all_recv(c, mem_ctx, &addrs, NULL);
if (NT_STATUS_IS_OK(status)) {
*reply_addr = talloc_steal(mem_ctx, addrs[0]->addr);
diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h
index 01fc930fce..b55ab83f2a 100644
--- a/source4/libcli/resolve/resolve.h
+++ b/source4/libcli/resolve/resolve.h
@@ -19,21 +19,35 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __RESOLVE_H__
-#define __RESOLVE_H__
+#ifndef __LIBCLI_RESOLVE_H__
+#define __LIBCLI_RESOLVE_H__
struct socket_address;
+struct event_context;
#include "../libcli/nbt/libnbt.h"
+
+/* force that only NBT name resolution is used */
+#define RESOLVE_NAME_FLAG_FORCE_NBT 0x00000001
+/* force that only DNS name resolution is used */
+#define RESOLVE_NAME_FLAG_FORCE_DNS 0x00000002
+/* tell the dns resolver to do a DNS SRV lookup */
+#define RESOLVE_NAME_FLAG_DNS_SRV 0x00000004
+/* allow the resolver to overwrite the given port, e.g. for DNS SRV */
+#define RESOLVE_NAME_FLAG_OVERWRITE_PORT 0x00000008
+
typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx,
struct event_context *,
void *privdata,
+ uint32_t flags,
+ uint16_t port,
struct nbt_name *);
typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *creq,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs);
+ struct socket_address ***addrs,
+ char ***names);
#include "libcli/resolve/proto.h"
struct interface;
#include "libcli/resolve/lp_proto.h"
-#endif /* __RESOLVE_H__ */
+#endif /* __LIBCLI_RESOLVE_H__ */
diff --git a/source4/libcli/resolve/testsuite.c b/source4/libcli/resolve/testsuite.c
index 34de1158a5..f1d1fbc85c 100644
--- a/source4/libcli/resolve/testsuite.c
+++ b/source4/libcli/resolve/testsuite.c
@@ -44,9 +44,9 @@ static bool test_async_resolve(struct torture_context *tctx)
host, timelimit);
while (timeval_elapsed(&tv) < timelimit) {
struct socket_address **s;
- struct composite_context *c = resolve_name_host_send(mem_ctx, ev, NULL, &n);
+ struct composite_context *c = resolve_name_host_send(mem_ctx, ev, NULL, 0, 0, &n);
torture_assert(tctx, c != NULL, "resolve_name_host_send");
- torture_assert_ntstatus_ok(tctx, resolve_name_host_recv(c, mem_ctx, &s),
+ torture_assert_ntstatus_ok(tctx, resolve_name_host_recv(c, mem_ctx, &s, NULL),
"async resolve failed");
count++;
}
diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c
index ae142f7054..1940688ecb 100644
--- a/source4/libcli/resolve/wins.c
+++ b/source4/libcli/resolve/wins.c
@@ -40,11 +40,16 @@ struct composite_context *resolve_name_wins_send(
TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
void *userdata,
+ uint32_t flags,
+ uint16_t port,
struct nbt_name *name)
{
struct resolve_wins_data *wins_data = talloc_get_type(userdata, struct resolve_wins_data);
if (wins_data->address_list == NULL) return NULL;
- return resolve_name_nbtlist_send(mem_ctx, event_ctx, name, wins_data->address_list, wins_data->ifaces, wins_data->nbt_port, wins_data->nbt_timeout, false, true);
+ return resolve_name_nbtlist_send(mem_ctx, event_ctx, flags, port, name,
+ wins_data->address_list, wins_data->ifaces,
+ wins_data->nbt_port, wins_data->nbt_timeout,
+ false, true);
}
/*
@@ -52,30 +57,10 @@ struct composite_context *resolve_name_wins_send(
*/
NTSTATUS resolve_name_wins_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
- return resolve_name_nbtlist_recv(c, mem_ctx, addrs);
-}
-
-/*
- wins name resolution method - sync call
- */
-NTSTATUS resolve_name_wins(struct nbt_name *name,
- TALLOC_CTX *mem_ctx,
- const char **address_list,
- struct interface *ifaces,
- uint16_t nbt_port,
- int nbt_timeout,
- struct socket_address ***addrs)
-{
- struct composite_context *c;
- struct resolve_wins_data *wins_data = talloc(mem_ctx, struct resolve_wins_data);
- wins_data->address_list = address_list;
- wins_data->ifaces = ifaces;
- wins_data->nbt_port = nbt_port;
- wins_data->nbt_timeout = nbt_timeout;
- c = resolve_name_wins_send(mem_ctx, NULL, wins_data, name);
- return resolve_name_wins_recv(c, mem_ctx, addrs);
+ return resolve_name_nbtlist_recv(c, mem_ctx, addrs, names);
}
bool resolve_context_add_wins_method(struct resolve_context *ctx, const char **address_list, struct interface *ifaces, uint16_t nbt_port, int nbt_timeout)
diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c
index 84bda8c858..930616d211 100644
--- a/source4/libcli/wrepl/winsrepl.c
+++ b/source4/libcli/wrepl/winsrepl.c
@@ -30,7 +30,6 @@
#include "system/network.h"
#include "lib/socket/netif.h"
#include "param/param.h"
-#include "libcli/resolve/resolve.h"
static struct wrepl_request *wrepl_request_finished(struct wrepl_request *req, NTSTATUS status);
@@ -319,7 +318,6 @@ const char *wrepl_best_ip(struct loadparm_context *lp_ctx, const char *peer_ip)
connect a wrepl_socket to a WINS server
*/
struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket,
- struct resolve_context *resolve_ctx,
const char *our_ip, const char *peer_ip)
{
struct composite_context *result;
@@ -347,8 +345,7 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket,
if (composite_nomem(peer, result)) return result;
state->creq = socket_connect_send(wrepl_socket->sock, us, peer,
- 0, resolve_ctx,
- wrepl_socket->event.ctx);
+ 0, wrepl_socket->event.ctx);
composite_continue(result, state->creq, wrepl_connect_handler, state);
return result;
}
@@ -374,10 +371,10 @@ NTSTATUS wrepl_connect_recv(struct composite_context *result)
/*
connect a wrepl_socket to a WINS server - sync API
*/
-NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, struct resolve_context *resolve_ctx,
+NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket,
const char *our_ip, const char *peer_ip)
{
- struct composite_context *c_req = wrepl_connect_send(wrepl_socket, resolve_ctx, our_ip, peer_ip);
+ struct composite_context *c_req = wrepl_connect_send(wrepl_socket, our_ip, peer_ip);
return wrepl_connect_recv(c_req);
}