s3: Make node_status_query return NTSTATUS
authorVolker Lendecke <vl@samba.org>
Tue, 28 Dec 2010 11:53:12 +0000 (12:53 +0100)
committerVolker Lendecke <vlendec@samba.org>
Tue, 28 Dec 2010 12:46:59 +0000 (13:46 +0100)
Also make the result talloc'ed

Autobuild-User: Volker Lendecke <vlendec@samba.org>
Autobuild-Date: Tue Dec 28 13:46:59 CET 2010 on sn-devel-104

source3/include/proto.h
source3/libsmb/namequery.c
source3/utils/nmblookup.c
source3/winbindd/winbindd_wins.c

index af2b35953116800d4ce1adb83ee4eb2e748cd46a..8278ffbcd5f5560c56568575f33675f4f4daa27a 100644 (file)
@@ -2699,11 +2699,13 @@ bool saf_store( const char *domain, const char *servername );
 bool saf_join_store( const char *domain, const char *servername );
 bool saf_delete( const char *domain );
 char *saf_fetch( const char *domain );
-struct node_status *node_status_query(int fd,
-                                       struct nmb_name *name,
-                                       const struct sockaddr_storage *to_ss,
-                                       int *num_names,
-                                       struct node_status_extra *extra);
+NTSTATUS node_status_query(int fd,
+                          struct nmb_name *name,
+                          const struct sockaddr_storage *to_ss,
+                          TALLOC_CTX *mem_ctx,
+                          struct node_status **names,
+                          int *num_names,
+                          struct node_status_extra *extra);
 bool name_status_find(const char *q_name,
                        int q_type,
                        int type,
index e20945177e5af96d88d7896b212e25569323e852..a283038c32f32d06ce1a531b3a8c60146ddedc09 100644 (file)
@@ -212,7 +212,7 @@ static int generate_trn_id(void)
  Parse a node status response into an array of structures.
 ****************************************************************************/
 
-static struct node_status *parse_node_status(char *p,
+static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p,
                                int *num_names,
                                struct node_status_extra *extra)
 {
@@ -224,7 +224,7 @@ static struct node_status *parse_node_status(char *p,
        if (*num_names == 0)
                return NULL;
 
-       ret = SMB_MALLOC_ARRAY(struct node_status,*num_names);
+       ret = TALLOC_ARRAY(mem_ctx, struct node_status,*num_names);
        if (!ret)
                return NULL;
 
@@ -278,11 +278,13 @@ static bool send_packet_request(struct packet_struct *p)
  structures holding the returned names or NULL if the query failed.
 **************************************************************************/
 
-struct node_status *node_status_query(int fd,
-                                       struct nmb_name *name,
-                                       const struct sockaddr_storage *to_ss,
-                                       int *num_names,
-                                       struct node_status_extra *extra)
+NTSTATUS node_status_query(int fd,
+                          struct nmb_name *name,
+                          const struct sockaddr_storage *to_ss,
+                          TALLOC_CTX *mem_ctx,
+                          struct node_status **names,
+                          int *num_names,
+                          struct node_status_extra *extra)
 {
        bool found=False;
        int retries = 2;
@@ -297,7 +299,7 @@ struct node_status *node_status_query(int fd,
 
        if (to_ss->ss_family != AF_INET) {
                /* Can't do node status to IPv6 */
-               return NULL;
+               return NT_STATUS_INVALID_ADDRESS;
        }
        nmb->header.name_trn_id = generate_trn_id();
        nmb->header.opcode = 0;
@@ -326,7 +328,7 @@ struct node_status *node_status_query(int fd,
        clock_gettime_mono(&tp);
 
        if (!send_packet_request(&p))
-               return NULL;
+               return NT_STATUS_NOT_FOUND;
 
        retries--;
 
@@ -337,7 +339,7 @@ struct node_status *node_status_query(int fd,
                        if (!retries)
                                break;
                        if (!found && !send_packet_request(&p))
-                               return NULL;
+                               return NT_STATUS_NOT_FOUND;
                        clock_gettime_mono(&tp);
                        retries--;
                }
@@ -358,14 +360,20 @@ struct node_status *node_status_query(int fd,
                                continue;
                        }
 
-                       ret = parse_node_status(&nmb2->answers->rdata[0],
-                                       num_names, extra);
+                       ret = parse_node_status(
+                               mem_ctx, &nmb2->answers->rdata[0], num_names,
+                               extra);
                        free_packet(p2);
-                       return ret;
+
+                       if (ret == NULL) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
+                       *names = ret;
+                       return NT_STATUS_OK;
                }
        }
 
-       return NULL;
+       return NT_STATUS_IO_TIMEOUT;
 }
 
 /****************************************************************************
@@ -381,11 +389,12 @@ bool name_status_find(const char *q_name,
 {
        char addr[INET6_ADDRSTRLEN];
        struct sockaddr_storage ss;
-       struct node_status *status = NULL;
+       struct node_status *addrs = NULL;
        struct nmb_name nname;
        int count, i;
        int sock;
        bool result = false;
+       NTSTATUS status;
 
        if (lp_disable_netbios()) {
                DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
@@ -420,20 +429,22 @@ bool name_status_find(const char *q_name,
 
        /* W2K PDC's seem not to respond to '*'#0. JRA */
        make_nmb_name(&nname, q_name, q_type);
-       status = node_status_query(sock, &nname, to_ss, &count, NULL);
+       status = node_status_query(sock, &nname, to_ss, talloc_tos(),
+                                  &addrs, &count, NULL);
        close(sock);
-       if (!status)
+       if (!NT_STATUS_IS_OK(status)) {
                goto done;
+       }
 
        for (i=0;i<count;i++) {
                 /* Find first one of the requested type that's not a GROUP. */
-               if (status[i].type == type && ! (status[i].flags & 0x80))
+               if (addrs[i].type == type && ! (addrs[i].flags & 0x80))
                        break;
        }
        if (i == count)
                goto done;
 
-       pull_ascii_nstring(name, sizeof(fstring), status[i].name);
+       pull_ascii_nstring(name, sizeof(fstring), addrs[i].name);
 
        /* Store the result in the cache. */
        /* but don't store an entry for 0x1c names here.  Here we have
@@ -446,7 +457,7 @@ bool name_status_find(const char *q_name,
        result = true;
 
  done:
-       SAFE_FREE(status);
+       TALLOC_FREE(addrs);
 
        DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
 
index e5cfe218060c53eadb7f1788a8645c9719c8c5fd..5bbd06c99408c65e87312f110c7b813b607f11e6 100644 (file)
@@ -113,33 +113,35 @@ static void do_node_status(int fd,
 {
        struct nmb_name nname;
        int count, i, j;
-       struct node_status *status;
+       struct node_status *addrs;
        struct node_status_extra extra;
        fstring cleanname;
        char addr[INET6_ADDRSTRLEN];
+       NTSTATUS status;
 
        print_sockaddr(addr, sizeof(addr), pss);
        d_printf("Looking up status of %s\n",addr);
        make_nmb_name(&nname, name, type);
-       status = node_status_query(fd, &nname, pss, &count, &extra);
-       if (status) {
+       status = node_status_query(fd, &nname, pss, talloc_tos(),
+                                  &addrs, &count, &extra);
+       if (NT_STATUS_IS_OK(status)) {
                for (i=0;i<count;i++) {
-                       pull_ascii_fstring(cleanname, status[i].name);
+                       pull_ascii_fstring(cleanname, addrs[i].name);
                        for (j=0;cleanname[j];j++) {
                                if (!isprint((int)cleanname[j])) {
                                        cleanname[j] = '.';
                                }
                        }
                        d_printf("\t%-15s <%02x> - %s\n",
-                              cleanname,status[i].type,
-                              node_status_flags(status[i].flags));
+                              cleanname,addrs[i].type,
+                              node_status_flags(addrs[i].flags));
                }
                d_printf("\n\tMAC Address = %02X-%02X-%02X-%02X-%02X-%02X\n",
                                extra.mac_addr[0], extra.mac_addr[1],
                                extra.mac_addr[2], extra.mac_addr[3],
                                extra.mac_addr[4], extra.mac_addr[5]);
                d_printf("\n");
-               SAFE_FREE(status);
+               TALLOC_FREE(addrs);
        } else {
                d_printf("No reply from %s\n\n",addr);
        }
index 1326fbc0a329ece05c4a974b81666f4023a38605..484b39342a629c8faf1ebcc7fdd3a1f4457ca147 100644 (file)
@@ -70,12 +70,14 @@ static int wins_lookup_open_socket_in(void)
 }
 
 
-static struct node_status *lookup_byaddr_backend(const char *addr, int *count)
+static struct node_status *lookup_byaddr_backend(TALLOC_CTX *mem_ctx,
+                                                const char *addr, int *count)
 {
        int fd;
        struct sockaddr_storage ss;
        struct nmb_name nname;
-       struct node_status *status;
+       struct node_status *result;
+       NTSTATUS status;
 
        fd = wins_lookup_open_socket_in();
        if (fd == -1)
@@ -85,10 +87,13 @@ static struct node_status *lookup_byaddr_backend(const char *addr, int *count)
        if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) {
                return NULL;
        }
-       status = node_status_query(fd, &nname, &ss, count, NULL);
-
+       status = node_status_query(fd, &nname, &ss, mem_ctx,
+                                  &result, count, NULL);
        close(fd);
-       return status;
+       if (!NT_STATUS_IS_OK(status)) {
+               return NULL;
+       }
+       return result;
 }
 
 static struct sockaddr_storage *lookup_byname_backend(const char *name,
@@ -158,10 +163,11 @@ void winbindd_wins_byip(struct winbindd_cli_state *state)
        *response = '\0';
        maxlen = sizeof(response) - 1;
 
-       if ((status = lookup_byaddr_backend(state->request->data.winsreq, &count))){
+       if ((status = lookup_byaddr_backend(
+                    state->mem_ctx, state->request->data.winsreq, &count))) {
            size = strlen(state->request->data.winsreq);
            if (size > maxlen) {
-               SAFE_FREE(status);
+               TALLOC_FREE(status);
                request_error(state);
                return;
            }
@@ -173,7 +179,7 @@ void winbindd_wins_byip(struct winbindd_cli_state *state)
                if (status[i].type == 0x20) {
                        size = sizeof(status[i].name) + strlen(response);
                        if (size > maxlen) {
-                           SAFE_FREE(status);
+                           TALLOC_FREE(status);
                            request_error(state);
                            return;
                        }
@@ -183,7 +189,7 @@ void winbindd_wins_byip(struct winbindd_cli_state *state)
            }
            /* make last character a newline */
            response[strlen(response)-1] = '\n';
-           SAFE_FREE(status);
+           TALLOC_FREE(status);
        }
        fstrcpy(state->response->data.winsresp,response);
        request_ok(state);