1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-28 01:58:17 +03:00

s4:libcli/resolve: optionally return the name that belongs to the returned address

E.g. this helps for DNS CNAME and SRV results.

metze
This commit is contained in:
Stefan Metzmacher 2008-12-13 20:50:36 +01:00
parent 937fdb8a7e
commit 7d0e78a52c
8 changed files with 82 additions and 23 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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"

View File

@ -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++;
}

View File

@ -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)