s3: Convert WINBINDD_WINS_BYNAME to the async API
authorVolker Lendecke <vl@samba.org>
Tue, 14 Jun 2011 21:51:10 +0000 (23:51 +0200)
committerVolker Lendecke <vl@samba.org>
Tue, 21 Jun 2011 12:25:12 +0000 (14:25 +0200)
source3/Makefile.in
source3/winbindd/winbindd.c
source3/winbindd/winbindd_proto.h
source3/winbindd/winbindd_wins_byname.c [new file with mode: 0644]
source3/wscript_build

index 31d170d34d541db9602af53f8f1e2254fc5f7b78..7e1ebfacb24930c28087956e1ed13935afa30934 100644 (file)
@@ -1355,6 +1355,7 @@ WINBINDD_OBJ1 = \
                winbindd/winbindd_cm.o    \
                winbindd/winbindd_wins.o  \
                winbindd/winbindd_wins_byip.o  \
+               winbindd/winbindd_wins_byname.o  \
                winbindd/winbindd_msrpc.o \
                winbindd/winbindd_rpc.o   \
                winbindd/winbindd_reconnect.o \
index 8cd68e5219608d0cd182b0410948a5a5635c5004..469d64e41d597b4476765476ead0c2128ffe6da1 100644 (file)
@@ -450,10 +450,6 @@ static struct winbindd_dispatch_table {
        { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
        { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
 
-       /* WINS functions */
-
-       { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
-
        /* End of list */
 
        { WINBINDD_NUM_CMDS, NULL, "NONE" }
@@ -546,6 +542,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
          winbindd_pam_chng_pswd_auth_crap_recv },
        { WINBINDD_WINS_BYIP, "WINS_BYIP",
          winbindd_wins_byip_send, winbindd_wins_byip_recv },
+       { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
+         winbindd_wins_byname_send, winbindd_wins_byname_recv },
 
        { 0, NULL, NULL, NULL }
 };
index e0a582e44e0a62db633f4d7ff01688ad53194e37..ce66964ace4865ae65073019678d9a02d706fc01 100644 (file)
@@ -866,6 +866,12 @@ struct tevent_req *winbindd_wins_byip_send(TALLOC_CTX *mem_ctx,
                                           struct winbindd_request *request);
 NTSTATUS winbindd_wins_byip_recv(struct tevent_req *req,
                                 struct winbindd_response *presp);
+struct tevent_req *winbindd_wins_byname_send(TALLOC_CTX *mem_ctx,
+                                            struct tevent_context *ev,
+                                            struct winbindd_cli_state *cli,
+                                            struct winbindd_request *request);
+NTSTATUS winbindd_wins_byname_recv(struct tevent_req *req,
+                                  struct winbindd_response *presp);
 
 
 /* The following definitions come from winbindd/winbindd_samr.c  */
diff --git a/source3/winbindd/winbindd_wins_byname.c b/source3/winbindd/winbindd_wins_byname.c
new file mode 100644 (file)
index 0000000..ad642d4
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+   Unix SMB/CIFS implementation.
+   async implementation of WINBINDD_WINS_BYNAME
+   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"
+#include "lib/util/string_wrappers.h"
+
+struct winbindd_wins_byname_state {
+       struct tevent_context *ev;
+       struct winbindd_request *request;
+       struct sockaddr_storage *addrs;
+       int num_addrs;
+};
+
+static void winbindd_wins_byname_wins_done(struct tevent_req *subreq);
+static void winbindd_wins_byname_bcast_done(struct tevent_req *subreq);
+
+struct tevent_req *winbindd_wins_byname_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_byname_state *state;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct winbindd_wins_byname_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->ev = ev;
+       state->request = request;
+
+       /* Ensure null termination */
+       request->data.winsreq[sizeof(request->data.winsreq)-1]='\0';
+
+       DEBUG(3, ("[%5lu]: wins_byname %s\n", (unsigned long)cli->pid,
+                 request->data.winsreq));
+
+       subreq = resolve_wins_send(state, ev, state->request->data.winsreq,
+                                  0x20);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, winbindd_wins_byname_wins_done, req);
+       return req;
+}
+
+static void winbindd_wins_byname_wins_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_wins_byname_state *state = tevent_req_data(
+               req, struct winbindd_wins_byname_state);
+       NTSTATUS status;
+
+       status = resolve_wins_recv(subreq, talloc_tos(), &state->addrs,
+                                  &state->num_addrs, NULL);
+       TALLOC_FREE(subreq);
+       if (NT_STATUS_IS_OK(status)) {
+               tevent_req_done(req);
+               return;
+       }
+       subreq = name_resolve_bcast_send(state, state->ev,
+                                        state->request->data.winsreq, 0x20);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, winbindd_wins_byname_bcast_done, req);
+}
+
+static void winbindd_wins_byname_bcast_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct winbindd_wins_byname_state *state = tevent_req_data(
+               req, struct winbindd_wins_byname_state);
+       NTSTATUS status;
+
+       status = name_resolve_bcast_recv(subreq, talloc_tos(), &state->addrs,
+                                        &state->num_addrs);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+NTSTATUS winbindd_wins_byname_recv(struct tevent_req *req,
+                                  struct winbindd_response *presp)
+{
+       struct winbindd_wins_byname_state *state = tevent_req_data(
+               req, struct winbindd_wins_byname_state);
+       char *response;
+       NTSTATUS status;
+       int i;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+
+       response = talloc_strdup(talloc_tos(), "");
+       if (response == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i=0; i<state->num_addrs; i++) {
+               char addr[INET6_ADDRSTRLEN];
+               print_sockaddr(addr, sizeof(addr), &state->addrs[i]);
+
+               response = talloc_asprintf_append_buffer(
+                       response, "%s\t", addr);
+               if (response == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       response = talloc_asprintf_append_buffer(
+               response, "%s\n", state->request->data.winsreq);
+       if (response == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (talloc_get_size(response) > sizeof(presp->data.winsresp)) {
+               TALLOC_FREE(response);
+               return NT_STATUS_MARSHALL_OVERFLOW;
+       }
+       fstrcpy(presp->data.winsresp, response);
+       TALLOC_FREE(response);
+       return NT_STATUS_OK;
+}
index 7c914b876e851a5d8544782ed601094ad33bd06c..52134ea6a2b7121db2616fa087f8d45ee5b3c7a2 100755 (executable)
@@ -252,6 +252,7 @@ WINBINDD_SRC1 = '''winbindd/winbindd.c
                    winbindd/winbindd_cm.c
                    winbindd/winbindd_wins.c
                    winbindd/winbindd_wins_byip.c
+                   winbindd/winbindd_wins_byname.c
                    winbindd/winbindd_msrpc.c
                    winbindd/winbindd_rpc.c
                    winbindd/winbindd_reconnect.c