summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2008-12-13 20:50:36 +0100
committerStefan Metzmacher <metze@samba.org>2008-12-17 20:26:38 +0100
commit7d0e78a52cfed797100696725611655227cf01ac (patch)
tree27a53cf8c534b559290720533e8984b278a2c988
parent937fdb8a7e348103708adbdafcff28b05cc1fda3 (diff)
downloadsamba-7d0e78a52cfed797100696725611655227cf01ac.tar.gz
samba-7d0e78a52cfed797100696725611655227cf01ac.tar.bz2
samba-7d0e78a52cfed797100696725611655227cf01ac.zip
s4:libcli/resolve: optionally return the name that belongs to the returned address
E.g. this helps for DNS CNAME and SRV results. metze
-rw-r--r--source4/libcli/resolve/bcast.c5
-rw-r--r--source4/libcli/resolve/dns_ex.c55
-rw-r--r--source4/libcli/resolve/host.c5
-rw-r--r--source4/libcli/resolve/nbtlist.c14
-rw-r--r--source4/libcli/resolve/resolve.c16
-rw-r--r--source4/libcli/resolve/resolve.h3
-rw-r--r--source4/libcli/resolve/testsuite.c2
-rw-r--r--source4/libcli/resolve/wins.c5
8 files changed, 82 insertions, 23 deletions
diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c
index 285a612fb1..23c8e0ca56 100644
--- a/source4/libcli/resolve/bcast.c
+++ b/source4/libcli/resolve/bcast.c
@@ -76,9 +76,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 */
diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c
index 36d7269be4..cfe4531654 100644
--- a/source4/libcli/resolve/dns_ex.c
+++ b/source4/libcli/resolve/dns_ex.c
@@ -46,6 +46,7 @@ struct dns_ex_state {
uint32_t flags;
struct nbt_name name;
struct socket_address **addrs;
+ char **names;
pid_t child;
int child_fd;
struct fd_event *fde;
@@ -231,10 +232,11 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
if (!addrs_rr[i]) {
continue;
}
- addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u",
+ addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
first?"":",",
inet_ntoa(*addrs_rr[i]->u.a),
- srv_rr[i]?srv_rr[i]->u.srv->port:0);
+ srv_rr[i]?srv_rr[i]->u.srv->port:0,
+ addrs_rr[i]->domain);
if (!addrs) {
goto done;
}
@@ -289,10 +291,10 @@ static void run_child_getaddrinfo(struct dns_ex_state *state, int fd)
}
in = (struct sockaddr_in *)res->ai_addr;
- addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u",
+ addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
first?"":",",
inet_ntoa(in->sin_addr),
- 0);
+ 0, state->name.name);
if (!addrs) {
goto done;
}
@@ -318,21 +320,31 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
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[2048];
+ 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);
- /* 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);
+ 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);
@@ -356,9 +368,13 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
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);
@@ -368,6 +384,15 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
*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);
@@ -382,8 +407,12 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
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);
}
@@ -470,7 +499,8 @@ struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx,
*/
NTSTATUS resolve_name_dns_ex_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
NTSTATUS status;
@@ -480,6 +510,9 @@ NTSTATUS resolve_name_dns_ex_recv(struct composite_context *c,
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);
diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c
index 1ad1473e92..d85c63b5d3 100644
--- a/source4/libcli/resolve/host.c
+++ b/source4/libcli/resolve/host.c
@@ -46,9 +46,10 @@ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx,
*/
NTSTATUS resolve_name_host_recv(struct composite_context *c,
TALLOC_CTX *mem_ctx,
- struct socket_address ***addrs)
+ struct socket_address ***addrs,
+ char ***names)
{
- return resolve_name_dns_ex_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 962dd420ab..8d6a5a7a7e 100644
--- a/source4/libcli/resolve/nbtlist.c
+++ b/source4/libcli/resolve/nbtlist.c
@@ -41,6 +41,7 @@ struct nbtlist_state {
struct nbt_name_request **queries;
struct nbt_name_query *io_queries;
struct socket_address **addrs;
+ char **names;
struct interface *ifaces;
};
@@ -82,14 +83,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);
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);
}
@@ -184,7 +192,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;
@@ -193,6 +202,9 @@ 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);
diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c
index 072eeabb7a..b688dc7a76 100644
--- a/source4/libcli/resolve/resolve.c
+++ b/source4/libcli/resolve/resolve.c
@@ -35,6 +35,7 @@ struct resolve_state {
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 +85,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;
@@ -171,6 +172,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;
}
@@ -191,7 +197,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;
@@ -200,6 +207,9 @@ 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);
@@ -220,7 +230,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 9808b81393..344307febb 100644
--- a/source4/libcli/resolve/resolve.h
+++ b/source4/libcli/resolve/resolve.h
@@ -33,7 +33,8 @@ typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx,
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"
diff --git a/source4/libcli/resolve/testsuite.c b/source4/libcli/resolve/testsuite.c
index 7e002bd310..ded1d1c9c1 100644
--- a/source4/libcli/resolve/testsuite.c
+++ b/source4/libcli/resolve/testsuite.c
@@ -46,7 +46,7 @@ static bool test_async_resolve(struct torture_context *tctx)
struct socket_address **s;
struct composite_context *c = resolve_name_host_send(mem_ctx, ev, NULL, 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 31e6b9e75c..c560d94a8d 100644
--- a/source4/libcli/resolve/wins.c
+++ b/source4/libcli/resolve/wins.c
@@ -56,9 +56,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);
+ 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)