From 081f8883bafc11ca7c08f868ec19f1ea32071837 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Dec 2008 00:06:34 +0100 Subject: s4: fix LIBEVENTS dependencies and use more forward declarations We should only include events.h where we really need it and prefer forward declarations of 'struct event_context' metze --- source4/libcli/resolve/resolve.c | 1 - source4/libcli/resolve/resolve.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/libcli/resolve') diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 7d1c48cbee..12764e1084 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" diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index 01fc930fce..942a0a0bd2 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -23,6 +23,7 @@ #define __RESOLVE_H__ struct socket_address; +struct event_context; #include "../libcli/nbt/libnbt.h" typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx, -- cgit From 8df2140c18996e616e6fe1fcc8fd3e52ca5dcd74 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 13 Dec 2008 11:24:10 +0100 Subject: s4:libcli/resolve: don't use __RESOLVE_H__ it might be used by system headers too metze --- source4/libcli/resolve/resolve.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/libcli/resolve') diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index 942a0a0bd2..f83db3f71d 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -19,8 +19,8 @@ along with this program. If not, see . */ -#ifndef __RESOLVE_H__ -#define __RESOLVE_H__ +#ifndef __LIBCLI_RESOLVE_H__ +#define __LIBCLI_RESOLVE_H__ struct socket_address; struct event_context; @@ -37,4 +37,4 @@ typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *creq, struct interface; #include "libcli/resolve/lp_proto.h" -#endif /* __RESOLVE_H__ */ +#endif /* __LIBCLI_RESOLVE_H__ */ -- cgit From 9492f0f00fd7c1815959f19988f83accce108ce4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 12 Dec 2008 15:15:21 +0100 Subject: s4:libcli/resolve: add getaddrinfo()/dns_looup() resolving This "dns_ex" module provides flexible lookup methods for dns lookups. The getaddrinfo() part looks at /etc/hosts and dns. As it handles CNAME replies badly we fallback to use dns_lookup(name, "A"). The dns_lookup() makes DNS SRV lookups possible. This module is not a real resolve module, it's just a generic helper as the nbtlist.c code is. The next step will be that the "host" module will use the dns_ex.c code. metze --- source4/libcli/resolve/dns_ex.c | 484 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 484 insertions(+) create mode 100644 source4/libcli/resolve/dns_ex.c (limited to 'source4/libcli/resolve') diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c new file mode 100644 index 0000000000..4bcf50a014 --- /dev/null +++ b/source4/libcli/resolve/dns_ex.c @@ -0,0 +1,484 @@ +/* + 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 . +*/ + +/* + 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_getaddrinfo; + bool do_fallback; + bool do_srv; + 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 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; + + /* this is the blocking call we are going to lots of trouble + to avoid in the parent */ + reply = dns_lookup(state->name.name, state->do_srv?"SRV":"A"); + if (!reply) { + goto done; + } + + if (state->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 (state->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 (state->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++) { + if (!addrs_rr[i]) { + continue; + } + addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u", + first?"":",", + inet_ntoa(*addrs_rr[i]->u.a), + srv_rr[i]?srv_rr[i]->u.srv->port:0); + 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", + first?"":",", + inet_ntoa(in->sin_addr), + 0); + 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[2048]; + uint32_t num_addrs, i; + char **addrs; + 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; + + 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; + + for (i=0; i < num_addrs; i++) { + uint32_t port = 0; + char *p = strrchr(addrs[i], ':'); + + if (!p) { + composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); + return; + } + + *p = '\0'; + p++; + + 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) { + port = 0; + } + state->addrs[i] = socket_address_from_strings(state->addrs, + "ipv4", + addrs[i], + port); + if (composite_nomem(state->addrs[i], c)) return; + } + state->addrs[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, + struct nbt_name *name, + bool do_getaddrinfo, + bool do_fallback, + bool do_srv) +{ + 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 (composite_nomem(c->event_ctx, c)) 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_getaddrinfo = do_getaddrinfo; + state->do_fallback = do_fallback; + state->do_srv = do_srv; + + 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->do_getaddrinfo) { + run_child_getaddrinfo(state, fd[1]); + } else { + run_child_dns_lookup(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) +{ + 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); + } + + talloc_free(c); + return status; +} -- cgit From f6b3c70b9728484106eb09a5f53425227bb1b288 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 12 Dec 2008 19:40:47 +0100 Subject: s4:libcli/resolve: let the "host" module use the dns_ex.c code That means we now return all ip addresses instead of just the first one. metze --- source4/libcli/resolve/host.c | 194 +++--------------------------------------- 1 file changed, 11 insertions(+), 183 deletions(-) (limited to 'source4/libcli/resolve') diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 7b1aef803e..1fbee7e22c 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 . */ -/* - 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,194 +29,30 @@ #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, 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, + name, true, true, false); } /* - 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; + return resolve_name_dns_ex_recv(c, mem_ctx, addrs); } /* - gethostbyname name resolution method - sync call + getaddrinfo() name resolution method - sync call */ NTSTATUS resolve_name_host(struct nbt_name *name, TALLOC_CTX *mem_ctx, -- cgit From c8565c0e7acc6febf1b4015bde6baa1c5b7adddc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 13 Dec 2008 10:57:44 +0100 Subject: s4:libcli/resolve: remove all backend specific sync functions metze --- source4/libcli/resolve/bcast.c | 20 -------------------- source4/libcli/resolve/host.c | 11 ----------- source4/libcli/resolve/nbtlist.c | 20 -------------------- source4/libcli/resolve/resolve.c | 13 ------------- source4/libcli/resolve/wins.c | 21 --------------------- 5 files changed, 85 deletions(-) (limited to 'source4/libcli/resolve') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 0a71ebed99..a572e873fc 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -85,26 +85,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/host.c b/source4/libcli/resolve/host.c index 1fbee7e22c..2facb54362 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -51,17 +51,6 @@ NTSTATUS resolve_name_host_recv(struct composite_context *c, return resolve_name_dns_ex_recv(c, mem_ctx, addrs); } -/* - getaddrinfo() name resolution method - sync call - */ -NTSTATUS resolve_name_host(struct nbt_name *name, - TALLOC_CTX *mem_ctx, - struct socket_address ***addrs) -{ - struct composite_context *c = resolve_name_host_send(mem_ctx, NULL, NULL, name); - return resolve_name_host_recv(c, mem_ctx, addrs); -} - bool resolve_context_add_host_method(struct resolve_context *ctx) { return resolve_context_add_method(ctx, resolve_name_host_send, resolve_name_host_recv, diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 9c53fcb7ec..76721e2af5 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -195,23 +195,3 @@ NTSTATUS resolve_name_nbtlist_recv(struct composite_context *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 12764e1084..68b806506d 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -199,19 +199,6 @@ NTSTATUS resolve_name_all_recv(struct composite_context *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) diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index ae142f7054..ba25b6c5c9 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -57,27 +57,6 @@ NTSTATUS resolve_name_wins_recv(struct composite_context *c, 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); -} - bool resolve_context_add_wins_method(struct resolve_context *ctx, const char **address_list, struct interface *ifaces, uint16_t nbt_port, int nbt_timeout) { struct resolve_wins_data *wins_data = talloc(ctx, struct resolve_wins_data); -- cgit From 937fdb8a7e348103708adbdafcff28b05cc1fda3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 13 Dec 2008 11:03:52 +0100 Subject: s4:libcli/resolve: pass down flags to the resolver backends metze --- source4/libcli/resolve/bcast.c | 6 ++++-- source4/libcli/resolve/dns_ex.c | 3 +++ source4/libcli/resolve/host.c | 4 ++-- source4/libcli/resolve/nbtlist.c | 4 ++++ source4/libcli/resolve/resolve.c | 11 +++++++++-- source4/libcli/resolve/resolve.h | 1 + source4/libcli/resolve/testsuite.c | 2 +- source4/libcli/resolve/wins.c | 6 +++++- 8 files changed, 29 insertions(+), 8 deletions(-) (limited to 'source4/libcli/resolve') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index a572e873fc..285a612fb1 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -37,7 +37,7 @@ 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, struct nbt_name *name) { int num_interfaces; @@ -63,7 +63,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, name, + address_list, data->ifaces, data->nbt_port, + data->nbt_timeout, true, false); talloc_free(address_list); return c; diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c index 4bcf50a014..36d7269be4 100644 --- a/source4/libcli/resolve/dns_ex.c +++ b/source4/libcli/resolve/dns_ex.c @@ -43,6 +43,7 @@ struct dns_ex_state { bool do_getaddrinfo; bool do_fallback; bool do_srv; + uint32_t flags; struct nbt_name name; struct socket_address **addrs; pid_t child; @@ -393,6 +394,7 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, void *privdata, + uint32_t flags, struct nbt_name *name, bool do_getaddrinfo, bool do_fallback, @@ -425,6 +427,7 @@ struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx, state->do_getaddrinfo = do_getaddrinfo; state->do_fallback = do_fallback; state->do_srv = do_srv; + state->flags = flags; state->child_fd = fd[0]; state->event_ctx = c->event_ctx; diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 2facb54362..1ad1473e92 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -34,10 +34,10 @@ */ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, - void *privdata, + void *privdata, uint32_t flags, struct nbt_name *name) { - return resolve_name_dns_ex_send(mem_ctx, event_ctx, NULL, + return resolve_name_dns_ex_send(mem_ctx, event_ctx, NULL, flags, name, true, true, false); } diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 76721e2af5..962dd420ab 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -34,6 +34,7 @@ #include "libcli/resolve/resolve.h" struct nbtlist_state { + uint16_t flags; struct nbt_name name; struct nbt_name_socket *nbtsock; int num_queries; @@ -98,6 +99,7 @@ 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, struct nbt_name *name, const char **address_list, struct interface *ifaces, @@ -119,6 +121,8 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, if (composite_nomem(state, c)) return c; c->private_data = state; + state->flags = flags; + c->status = nbt_name_dup(state, name, &state->name); if (!composite_is_ok(c)) return c; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index 68b806506d..072eeabb7a 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -31,6 +31,7 @@ struct resolve_state { struct resolve_context *ctx; struct resolve_method *method; + uint32_t flags; struct nbt_name name; struct composite_context *creq; struct socket_address **addrs; @@ -111,7 +112,10 @@ 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->name); } if (creq == NULL && state->method) state->method = state->method->next; @@ -129,6 +133,7 @@ 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, struct nbt_name *name, struct event_context *event_ctx) { @@ -148,6 +153,8 @@ 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; + c->status = nbt_name_dup(state, name, &state->name); if (!composite_is_ok(c)) return c; @@ -203,7 +210,7 @@ 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, name, event_ctx); } NTSTATUS resolve_name_recv(struct composite_context *c, diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index f83db3f71d..9808b81393 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -29,6 +29,7 @@ struct event_context; typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx, struct event_context *, void *privdata, + uint32_t flags, struct nbt_name *); typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *creq, TALLOC_CTX *mem_ctx, diff --git a/source4/libcli/resolve/testsuite.c b/source4/libcli/resolve/testsuite.c index 34de1158a5..7e002bd310 100644 --- a/source4/libcli/resolve/testsuite.c +++ b/source4/libcli/resolve/testsuite.c @@ -44,7 +44,7 @@ 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, &n); torture_assert(tctx, c != NULL, "resolve_name_host_send"); torture_assert_ntstatus_ok(tctx, resolve_name_host_recv(c, mem_ctx, &s), "async resolve failed"); diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index ba25b6c5c9..31e6b9e75c 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -40,11 +40,15 @@ struct composite_context *resolve_name_wins_send( TALLOC_CTX *mem_ctx, struct event_context *event_ctx, void *userdata, + uint32_t flags, 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, name, + wins_data->address_list, wins_data->ifaces, + wins_data->nbt_port, wins_data->nbt_timeout, + false, true); } /* -- cgit From 7d0e78a52cfed797100696725611655227cf01ac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 13 Dec 2008 20:50:36 +0100 Subject: s4:libcli/resolve: optionally return the name that belongs to the returned address E.g. this helps for DNS CNAME and SRV results. metze --- source4/libcli/resolve/bcast.c | 5 ++-- source4/libcli/resolve/dns_ex.c | 55 ++++++++++++++++++++++++++++++-------- source4/libcli/resolve/host.c | 5 ++-- source4/libcli/resolve/nbtlist.c | 14 +++++++++- source4/libcli/resolve/resolve.c | 16 ++++++++--- source4/libcli/resolve/resolve.h | 3 ++- source4/libcli/resolve/testsuite.c | 2 +- source4/libcli/resolve/wins.c | 5 ++-- 8 files changed, 82 insertions(+), 23 deletions(-) (limited to 'source4/libcli/resolve') 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;iout.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) -- cgit From 116fbd6b5a82a2e9f2440aae4ad56cf8a457c85b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Dec 2008 17:25:40 +0100 Subject: s4:libcli/resolve: specify the port for the resulting socket_addresses metze --- source4/libcli/resolve/bcast.c | 3 ++- source4/libcli/resolve/dns_ex.c | 11 ++++++++--- source4/libcli/resolve/host.c | 3 ++- source4/libcli/resolve/nbtlist.c | 5 ++++- source4/libcli/resolve/resolve.c | 6 +++++- source4/libcli/resolve/resolve.h | 1 + source4/libcli/resolve/testsuite.c | 2 +- source4/libcli/resolve/wins.c | 3 ++- 8 files changed, 25 insertions(+), 9 deletions(-) (limited to 'source4/libcli/resolve') diff --git a/source4/libcli/resolve/bcast.c b/source4/libcli/resolve/bcast.c index 23c8e0ca56..866ce7a152 100644 --- a/source4/libcli/resolve/bcast.c +++ b/source4/libcli/resolve/bcast.c @@ -38,6 +38,7 @@ struct resolve_bcast_data { struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, void *userdata, uint32_t flags, + uint16_t port, struct nbt_name *name) { int num_interfaces; @@ -63,7 +64,7 @@ struct composite_context *resolve_name_bcast_send(TALLOC_CTX *mem_ctx, } address_list[count] = NULL; - c = resolve_name_nbtlist_send(mem_ctx, event_ctx, flags, name, + 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); diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c index cfe4531654..5f08201978 100644 --- a/source4/libcli/resolve/dns_ex.c +++ b/source4/libcli/resolve/dns_ex.c @@ -44,6 +44,7 @@ struct dns_ex_state { bool do_fallback; bool do_srv; uint32_t flags; + uint16_t port; struct nbt_name name; struct socket_address **addrs; char **names; @@ -235,7 +236,7 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) 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, + state->port, addrs_rr[i]->domain); if (!addrs) { goto done; @@ -294,7 +295,8 @@ static void run_child_getaddrinfo(struct dns_ex_state *state, int fd) addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s", first?"":",", inet_ntoa(in->sin_addr), - 0, state->name.name); + state->port, + state->name.name); if (!addrs) { goto done; } @@ -400,7 +402,8 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, } port = strtoul(p, NULL, 10); if (port > UINT16_MAX) { - port = 0; + composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); + return; } state->addrs[i] = socket_address_from_strings(state->addrs, "ipv4", @@ -424,6 +427,7 @@ 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_getaddrinfo, bool do_fallback, @@ -457,6 +461,7 @@ struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx, state->do_fallback = do_fallback; state->do_srv = do_srv; state->flags = flags; + state->port = port; state->child_fd = fd[0]; state->event_ctx = c->event_ctx; diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index d85c63b5d3..908d173d86 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -35,10 +35,11 @@ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, void *privdata, uint32_t flags, + uint16_t port, struct nbt_name *name) { return resolve_name_dns_ex_send(mem_ctx, event_ctx, NULL, flags, - name, true, true, false); + port, name, true, true, false); } /* diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 8d6a5a7a7e..2c128e2560 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -35,6 +35,7 @@ struct nbtlist_state { uint16_t flags; + uint16_t port; struct nbt_name name; struct nbt_name_socket *nbtsock; int num_queries; @@ -90,7 +91,7 @@ static void nbtlist_handler(struct nbt_name_request *req) 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); @@ -108,6 +109,7 @@ 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, @@ -130,6 +132,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, 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; diff --git a/source4/libcli/resolve/resolve.c b/source4/libcli/resolve/resolve.c index b688dc7a76..752678abb8 100644 --- a/source4/libcli/resolve/resolve.c +++ b/source4/libcli/resolve/resolve.c @@ -32,6 +32,7 @@ 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; @@ -116,6 +117,7 @@ static struct composite_context *setup_next_method(struct composite_context *c) 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; @@ -135,6 +137,7 @@ static struct composite_context *setup_next_method(struct composite_context *c) */ 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) { @@ -155,6 +158,7 @@ struct composite_context *resolve_name_all_send(struct resolve_context *ctx, 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; @@ -220,7 +224,7 @@ 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, 0, name, event_ctx); + return resolve_name_all_send(ctx, 0, 0, name, event_ctx); } NTSTATUS resolve_name_recv(struct composite_context *c, diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index 344307febb..072a8a112d 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -30,6 +30,7 @@ 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, diff --git a/source4/libcli/resolve/testsuite.c b/source4/libcli/resolve/testsuite.c index ded1d1c9c1..f1d1fbc85c 100644 --- a/source4/libcli/resolve/testsuite.c +++ b/source4/libcli/resolve/testsuite.c @@ -44,7 +44,7 @@ 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, 0, &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, NULL), "async resolve failed"); diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c index c560d94a8d..1940688ecb 100644 --- a/source4/libcli/resolve/wins.c +++ b/source4/libcli/resolve/wins.c @@ -41,11 +41,12 @@ struct composite_context *resolve_name_wins_send( 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, flags, name, + 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); -- cgit From a60159c8734210d199b2b76705b4f70641395a2d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Dec 2008 16:55:44 +0100 Subject: s4:libcli/replace: add some RESOLVE_NAME_FLAG* flags metze --- source4/libcli/resolve/dns_ex.c | 39 +++++++++++++++++++++++---------------- source4/libcli/resolve/host.c | 2 +- source4/libcli/resolve/nbtlist.c | 10 +++++++++- source4/libcli/resolve/resolve.h | 10 ++++++++++ 4 files changed, 43 insertions(+), 18 deletions(-) (limited to 'source4/libcli/resolve') diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c index 5f08201978..948ad9f134 100644 --- a/source4/libcli/resolve/dns_ex.c +++ b/source4/libcli/resolve/dns_ex.c @@ -40,9 +40,7 @@ #include "heimdal/lib/roken/resolve.h" struct dns_ex_state { - bool do_getaddrinfo; bool do_fallback; - bool do_srv; uint32_t flags; uint16_t port; struct nbt_name name; @@ -88,15 +86,16 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) 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, state->do_srv?"SRV":"A"); + reply = dns_lookup(state->name.name, do_srv?"SRV":"A"); if (!reply) { goto done; } - if (state->do_srv) { + if (do_srv) { dns_srv_order(reply); } @@ -107,7 +106,7 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) continue; } - if (state->do_srv) { + if (do_srv) { /* we are only interested in SRV records */ if (rr->type != T_SRV) { continue; @@ -162,7 +161,7 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) continue; } - if (state->do_srv) { + if (do_srv) { /* we are only interested in SRV records */ if (rr->type != T_SRV) { continue; @@ -230,13 +229,22 @@ static void run_child_dns_lookup(struct dns_ex_state *state, int fd) } 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), - state->port, + port, addrs_rr[i]->domain); if (!addrs) { goto done; @@ -429,9 +437,7 @@ struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx, uint32_t flags, uint16_t port, struct nbt_name *name, - bool do_getaddrinfo, - bool do_fallback, - bool do_srv) + bool do_fallback) { struct composite_context *c; struct dns_ex_state *state; @@ -441,7 +447,10 @@ struct composite_context *resolve_name_dns_ex_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_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; @@ -457,9 +466,7 @@ struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx, return c; } - state->do_getaddrinfo = do_getaddrinfo; state->do_fallback = do_fallback; - state->do_srv = do_srv; state->flags = flags; state->port = port; @@ -484,10 +491,10 @@ struct composite_context *resolve_name_dns_ex_send(TALLOC_CTX *mem_ctx, if (state->child == 0) { close(fd[0]); - if (state->do_getaddrinfo) { - run_child_getaddrinfo(state, fd[1]); - } else { + if (state->flags & RESOLVE_NAME_FLAG_FORCE_DNS) { run_child_dns_lookup(state, fd[1]); + } else { + run_child_getaddrinfo(state, fd[1]); } _exit(0); } diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 908d173d86..b7eaf4bef5 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -39,7 +39,7 @@ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx, struct nbt_name *name) { return resolve_name_dns_ex_send(mem_ctx, event_ctx, NULL, flags, - port, name, true, true, false); + port, name, true); } /* diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 2c128e2560..734fd5a5bc 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -125,7 +125,15 @@ 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; diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h index 072a8a112d..b55ab83f2a 100644 --- a/source4/libcli/resolve/resolve.h +++ b/source4/libcli/resolve/resolve.h @@ -26,6 +26,16 @@ 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, -- cgit