E.g. this helps for DNS CNAME and SRV results.
metze
*/
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 */
uint32_t flags;
struct nbt_name name;
struct socket_address **addrs;
+ char **names;
pid_t child;
int child_fd;
struct fd_event *fde;
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;
}
}
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;
}
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);
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);
*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);
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);
}
*/
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;
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);
*/
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)
struct nbt_name_request **queries;
struct nbt_name_query *io_queries;
struct socket_address **addrs;
+ char **names;
struct interface *ifaces;
};
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);
}
*/
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;
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);
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);
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;
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;
}
*/
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;
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);
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);
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"
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++;
}
*/
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)