r23779: Change from v2 or later to v3 or later.
[sfrench/samba-autobuild/.git] / source3 / nsswitch / winbindd_wins.c
index 8ddd5dc10df1522558e020cb0761c5ff47bf1f0d..80d27e90fc2185498ef6687d80e6c101068787cc 100644 (file)
@@ -8,7 +8,7 @@
    
    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 2 of the License, or
+   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,
@@ -21,6 +21,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "includes.h"
 #include "winbindd.h"
 
 #undef DBGC_CLASS
@@ -64,12 +65,12 @@ static int wins_lookup_open_socket_in(void)
 }
 
 
-static struct node_status *lookup_byaddr_backend(char *addr, int *count)
+static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
 {
        int fd;
        struct in_addr  ip;
        struct nmb_name nname;
-       struct node_status *status;
+       NODE_STATUS_STRUCT *status;
 
        fd = wins_lookup_open_socket_in();
        if (fd == -1)
@@ -77,7 +78,7 @@ static struct node_status *lookup_byaddr_backend(char *addr, int *count)
 
        make_nmb_name(&nname, "*", 0);
        ip = *interpret_addr2(addr);
-       status = node_status_query(fd,&nname,ip, count);
+       status = node_status_query(fd,&nname,ip, count, NULL);
 
        close(fd);
        return status;
@@ -86,14 +87,27 @@ static struct node_status *lookup_byaddr_backend(char *addr, int *count)
 static struct in_addr *lookup_byname_backend(const char *name, int *count)
 {
        int fd;
-       struct in_addr *ret = NULL;
-       int j, flags = 0;
+       struct ip_service *ret = NULL;
+       struct in_addr *return_ip = NULL;
+       int j, i, flags = 0;
 
        *count = 0;
 
        /* always try with wins first */
        if (resolve_wins(name,0x20,&ret,count)) {
-               return ret;
+               if ( *count == 0 )
+                       return NULL;
+               if ( (return_ip = SMB_MALLOC_ARRAY(struct in_addr, *count)) == NULL ) {
+                       free( ret );
+                       return NULL;
+               }
+
+               /* copy the IP addresses */
+               for ( i=0; i<(*count); i++ ) 
+                       return_ip[i] = ret[i].ip;
+               
+               free( ret );
+               return return_ip;
        }
 
        fd = wins_lookup_open_socket_in();
@@ -106,26 +120,28 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
             j >= 0;
             j--) {
                struct in_addr *bcast = iface_n_bcast(j);
-               ret = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
-               if (ret) break;
+               return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
+               if (return_ip) {
+                       break;
+               }
        }
 
        close(fd);
-       return ret;
+       return return_ip;
 }
 
 /* Get hostname from IP  */
 
-enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
+void winbindd_wins_byip(struct winbindd_cli_state *state)
 {
        fstring response;
        int i, count, maxlen, size;
-       struct node_status *status;
+       NODE_STATUS_STRUCT *status;
 
        /* Ensure null termination */
        state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
 
-       DEBUG(3, ("[%5d]: wins_byip %s\n", state->pid,
+       DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)state->pid,
                state->request.data.winsreq));
 
        *response = '\0';
@@ -135,10 +151,11 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
            size = strlen(state->request.data.winsreq);
            if (size > maxlen) {
                SAFE_FREE(status);
-               return WINBINDD_ERROR;
+               request_error(state);
+               return;
            }
-           safe_strcat(response,state->request.data.winsreq,maxlen);
-           safe_strcat(response,"\t",maxlen);
+           fstrcat(response,state->request.data.winsreq);
+           fstrcat(response,"\t");
            for (i = 0; i < count; i++) {
                /* ignore group names */
                if (status[i].flags & 0x80) continue;
@@ -146,10 +163,11 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
                        size = sizeof(status[i].name) + strlen(response);
                        if (size > maxlen) {
                            SAFE_FREE(status);
-                           return WINBINDD_ERROR;
+                           request_error(state);
+                           return;
                        }
-                       safe_strcat(response, status[i].name, maxlen);
-                       safe_strcat(response, " ", maxlen);
+                       fstrcat(response, status[i].name);
+                       fstrcat(response, " ");
                }
            }
            /* make last character a newline */
@@ -157,12 +175,12 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
            SAFE_FREE(status);
        }
        fstrcpy(state->response.data.winsresp,response);
-       return WINBINDD_OK;
+       request_ok(state);
 }
 
 /* Get IP from hostname */
 
-enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
+void winbindd_wins_byname(struct winbindd_cli_state *state)
 {
        struct in_addr *ip_list;
        int i, count, maxlen, size;
@@ -172,7 +190,7 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
        /* Ensure null termination */
        state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
 
-       DEBUG(3, ("[%5d]: wins_byname %s\n", state->pid,
+       DEBUG(3, ("[%5lu]: wins_byname %s\n", (unsigned long)state->pid,
                state->request.data.winsreq));
 
        *response = '\0';
@@ -184,27 +202,34 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
                    size = strlen(addr);
                    if (size > maxlen) {
                        SAFE_FREE(ip_list);
-                       return WINBINDD_ERROR;
+                       request_error(state);
+                       return;
                    }
                    if (i != 0) {
                        /* Clear out the newline character */
-                       response[strlen(response)-1] = ' '; 
+                       /* But only if there is something in there, 
+                          otherwise we clobber something in the stack */
+                       if (strlen(response))
+                               response[strlen(response)-1] = ' '; 
                    }
-                   safe_strcat(response,addr,maxlen);
-                   safe_strcat(response,"\t",maxlen);
+                   fstrcat(response,addr);
+                   fstrcat(response,"\t");
                }
                size = strlen(state->request.data.winsreq) + strlen(response);
                if (size > maxlen) {
                    SAFE_FREE(ip_list);
-                   return WINBINDD_ERROR;
+                   request_error(state);
+                   return;
                }   
-               safe_strcat(response,state->request.data.winsreq,maxlen);
-               safe_strcat(response,"\n",maxlen);
+               fstrcat(response,state->request.data.winsreq);
+               fstrcat(response,"\n");
                SAFE_FREE(ip_list);
-       } else
-               return WINBINDD_ERROR;
+       } else {
+               request_error(state);
+               return;
+       }
 
        fstrcpy(state->response.data.winsresp,response);
 
-       return WINBINDD_OK;
+       request_ok(state);
 }