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:
parent
937fdb8a7e
commit
7d0e78a52c
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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++;
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user