s4:libcli/resolve: optionally return the name that belongs to the returned address
authorStefan Metzmacher <metze@samba.org>
Sat, 13 Dec 2008 19:50:36 +0000 (20:50 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 17 Dec 2008 19:26:38 +0000 (20:26 +0100)
E.g. this helps for DNS CNAME and SRV results.

metze

source4/libcli/resolve/bcast.c
source4/libcli/resolve/dns_ex.c
source4/libcli/resolve/host.c
source4/libcli/resolve/nbtlist.c
source4/libcli/resolve/resolve.c
source4/libcli/resolve/resolve.h
source4/libcli/resolve/testsuite.c
source4/libcli/resolve/wins.c

index 285a612fb19bfc1f1202cbf302bb988879a4980e..23c8e0ca56d07ac0a9113ef6805db191e6fffd39 100644 (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 */
index 36d7269be4956e2819623469cf7c5149491c4061..cfe453165471297730b6bb06a6a498fc2c992d59 100644 (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);
index 1ad1473e92e9942d1a971d9d2edf039fea871a0b..d85c63b5d364dec4d0a967935f67b69396ce28e2 100644 (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)
index 962dd420abfc582dfca9c49e98203eb91e960d04..8d6a5a7a7e0d340f375a7346c9e6efbed5197adc 100644 (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);
index 072eeabb7a3be3f76f1484edb973b95d2c1fda3d..b688dc7a765c8431a6f18c5bef2be5086de5811a 100644 (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);
index 9808b81393342bdeb7a792f1007ac22937d347a9..344307febbc0b00cc8bd7e2c67f0c8c50eca1db8 100644 (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"
index 7e002bd31060a39accbd2f3543dbcc179b33b0ee..ded1d1c9c1e384875cc779a45d6c575ca8a24c09 100644 (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++;
        }
index 31e6b9e75c9e69c94863b0d90fb31382b19e0a73..c560d94a8d6269abdd22c2193b7c2b14803ef340 100644 (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)