s3:winbind: Convert WINBINDD_WINS_BYIP to the async API
authorVolker Lendecke <vl@samba.org>
Sun, 5 Jun 2011 09:30:43 +0000 (11:30 +0200)
committerVolker Lendecke <vl@samba.org>
Sun, 5 Jun 2011 10:10:15 +0000 (12:10 +0200)
source3/Makefile.in
source3/winbindd/winbindd.c
source3/winbindd/winbindd_proto.h
source3/winbindd/winbindd_wins.c
source3/winbindd/winbindd_wins_byip.c [new file with mode: 0644]
source3/wscript_build

index f95fbeb4617370c7d8999ae4bab5549c97e95715..f7458d353a015b376d38ee9f9338766dfee42692 100644 (file)
@@ -1349,6 +1349,7 @@ WINBINDD_OBJ1 = \
                winbindd/winbindd_misc.o  \
                winbindd/winbindd_cm.o    \
                winbindd/winbindd_wins.o  \
+               winbindd/winbindd_wins_byip.o  \
                winbindd/winbindd_msrpc.o \
                winbindd/winbindd_rpc.o   \
                winbindd/winbindd_reconnect.o \
index 677f7661828c3ffbc1c247566b2eb6b08c68a5ee..8c6d91e6282fa86d94e0bfddbe7ca95a13b20ce8 100644 (file)
@@ -453,7 +453,6 @@ static struct winbindd_dispatch_table {
        /* WINS functions */
 
        { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
-       { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
 
        /* End of list */
 
@@ -545,6 +544,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
        { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
          winbindd_pam_chng_pswd_auth_crap_send,
          winbindd_pam_chng_pswd_auth_crap_recv },
+       { WINBINDD_WINS_BYIP, "PING",
+         winbindd_wins_byip_send, winbindd_wins_byip_recv },
 
        { 0, NULL, NULL, NULL }
 };
index ab61223c86d2547eac3ca307af6f73cb240748a3..e0a582e44e0a62db633f4d7ff01688ad53194e37 100644 (file)
@@ -436,7 +436,6 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,
 
 /* The following definitions come from winbindd/winbindd_wins.c  */
 
-void winbindd_wins_byip(struct winbindd_cli_state *state);
 void winbindd_wins_byname(struct winbindd_cli_state *state);
 
 struct tevent_req *wb_ping_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
@@ -861,6 +860,12 @@ struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx,
                                              struct winbindd_request *request);
 NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req,
                                    struct winbindd_response *response);
+struct tevent_req *winbindd_wins_byip_send(TALLOC_CTX *mem_ctx,
+                                          struct tevent_context *ev,
+                                          struct winbindd_cli_state *cli,
+                                          struct winbindd_request *request);
+NTSTATUS winbindd_wins_byip_recv(struct tevent_req *req,
+                                struct winbindd_response *presp);
 
 
 /* The following definitions come from winbindd/winbindd_samr.c  */
index 5ac6109411239e84aea8b7bb1a1ac6a9f7954046..a468b0f8b3dc8cbb41cfb3f5b04d133ed83e0b25 100644 (file)
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
-static struct node_status *lookup_byaddr_backend(TALLOC_CTX *mem_ctx,
-                                                const char *addr, int *count)
-{
-       struct sockaddr_storage ss;
-       struct nmb_name nname;
-       struct node_status *result;
-       NTSTATUS status;
-
-       make_nmb_name(&nname, "*", 0);
-       if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) {
-               return NULL;
-       }
-       status = node_status_query(mem_ctx, &nname, &ss,
-                                  &result, count, NULL);
-       if (!NT_STATUS_IS_OK(status)) {
-               return NULL;
-       }
-       return result;
-}
-
 static struct sockaddr_storage *lookup_byname_backend(TALLOC_CTX *mem_ctx,
                                                      const char *name,
                                                      int *count)
@@ -95,57 +75,6 @@ static struct sockaddr_storage *lookup_byname_backend(TALLOC_CTX *mem_ctx,
        return return_ss;
 }
 
-/* Get hostname from IP  */
-
-void winbindd_wins_byip(struct winbindd_cli_state *state)
-{
-       fstring response;
-       int i, count, maxlen, size;
-       struct node_status *status;
-
-       /* Ensure null termination */
-       state->request->data.winsreq[sizeof(state->request->data.winsreq)-1]='\0';
-
-       DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)state->pid,
-               state->request->data.winsreq));
-
-       *response = '\0';
-       maxlen = sizeof(response) - 1;
-
-       if ((status = lookup_byaddr_backend(
-                    state->mem_ctx, state->request->data.winsreq, &count))) {
-           size = strlen(state->request->data.winsreq);
-           if (size > maxlen) {
-               TALLOC_FREE(status);
-               request_error(state);
-               return;
-           }
-           fstrcat(response,state->request->data.winsreq);
-           fstrcat(response,"\t");
-           for (i = 0; i < count; i++) {
-               /* ignore group names */
-               if (status[i].flags & 0x80) continue;
-               if (status[i].type == 0x20) {
-                       size = sizeof(status[i].name) + strlen(response);
-                       if (size > maxlen) {
-                           TALLOC_FREE(status);
-                           request_error(state);
-                           return;
-                       }
-                       fstrcat(response, status[i].name);
-                       fstrcat(response, " ");
-               }
-           }
-           /* make last character a newline */
-           response[strlen(response)-1] = '\n';
-           TALLOC_FREE(status);
-       }
-       strlcpy(state->response->data.winsresp,
-                       response,
-                       sizeof(state->response->data.winsresp));
-       request_ok(state);
-}
-
 /* Get IP from hostname */
 
 void winbindd_wins_byname(struct winbindd_cli_state *state)
diff --git a/source3/winbindd/winbindd_wins_byip.c b/source3/winbindd/winbindd_wins_byip.c
new file mode 100644 (file)
index 0000000..4ae1b82
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+   Unix SMB/CIFS implementation.
+   async implementation of WINBINDD_WINS_BYIP
+   Copyright (C) Volker Lendecke 2011
+
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+#include "librpc/gen_ndr/ndr_wbint_c.h"
+#include "libsmb/nmblib.h"
+
+struct winbindd_wins_byip_state {
+       struct nmb_name star;
+       struct sockaddr_storage addr;
+       fstring response;
+};
+
+static void winbindd_wins_byip_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_wins_byip_send(TALLOC_CTX *mem_ctx,
+                                          struct tevent_context *ev,
+                                          struct winbindd_cli_state *cli,
+                                          struct winbindd_request *request)
+{
+       struct tevent_req *req, *subreq;
+       struct winbindd_wins_byip_state *state;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct winbindd_wins_byip_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       /* Ensure null termination */
+       request->data.winsreq[sizeof(request->data.winsreq)-1]='\0';
+
+       fstr_sprintf(state->response, "%s\t", request->data.winsreq);
+
+       DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)cli->pid,
+                 request->data.winsreq));
+
+       make_nmb_name(&state->star, "*", 0);
+
+       if (!interpret_string_addr(&state->addr, request->data.winsreq,
+                                  AI_NUMERICHOST)) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
+       }
+
+       subreq = node_status_query_send(state, ev, &state->star,
+                                       &state->addr);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, winbindd_wins_byip_done, req);
+       return req;
+}
+
+static void winbindd_wins_byip_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_wins_byip_state *state = tevent_req_data(
+               req, struct winbindd_wins_byip_state);
+       struct node_status *names;
+       int i, num_names;
+       NTSTATUS status;
+
+       status = node_status_query_recv(subreq, talloc_tos(), &names,
+                                       &num_names, NULL);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+
+       for (i=0; i<num_names; i++) {
+               size_t size;
+               /*
+                * ignore group names
+                */
+               if (names[i].flags & 0x80) {
+                       continue;
+               }
+               /*
+                * Only report 0x20
+                */
+               if (names[i].type != 0x20) {
+                       continue;
+               }
+
+               DEBUG(10, ("got name %s\n", names[i].name));
+
+               size = strlen(names[i].name + strlen(state->response));
+               if (size > sizeof(state->response) - 1) {
+                       DEBUG(10, ("To much data\n"));
+                       tevent_req_nterror(req, STATUS_BUFFER_OVERFLOW);
+                       return;
+               }
+               fstrcat(state->response, names[i].name);
+               fstrcat(state->response, " ");
+       }
+       state->response[strlen(state->response)-1] = '\n';
+
+       DEBUG(10, ("response: %s", state->response));
+
+       TALLOC_FREE(names);
+       tevent_req_done(req);
+}
+
+NTSTATUS winbindd_wins_byip_recv(struct tevent_req *req,
+                                struct winbindd_response *presp)
+{
+       struct winbindd_wins_byip_state *state = tevent_req_data(
+               req, struct winbindd_wins_byip_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+       fstrcpy(presp->data.winsresp, state->response);
+       return NT_STATUS_OK;
+}
index 834c7f56c2f3d021b924847dfa57e121c89955f5..4fd7a7b5568cf8c093d99e9fa816ce6955710293 100755 (executable)
@@ -255,6 +255,7 @@ WINBINDD_SRC1 = '''winbindd/winbindd.c
                    winbindd/winbindd_misc.c
                    winbindd/winbindd_cm.c
                    winbindd/winbindd_wins.c
+                   winbindd/winbindd_wins_byip.c
                    winbindd/winbindd_msrpc.c
                    winbindd/winbindd_rpc.c
                    winbindd/winbindd_reconnect.c