diff options
-rw-r--r-- | source3/Makefile.in | 1 | ||||
-rw-r--r-- | source3/winbindd/winbindd.c | 6 | ||||
-rw-r--r-- | source3/winbindd/winbindd_proto.h | 6 | ||||
-rw-r--r-- | source3/winbindd/winbindd_wins_byname.c | 149 | ||||
-rwxr-xr-x | source3/wscript_build | 1 |
5 files changed, 159 insertions, 4 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 31d170d34d..7e1ebfacb2 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -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 \ diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 8cd68e5219..469d64e41d 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -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 } }; diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index e0a582e44e..ce66964ace 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -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 index 0000000000..ad642d479d --- /dev/null +++ b/source3/winbindd/winbindd_wins_byname.c @@ -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; +} diff --git a/source3/wscript_build b/source3/wscript_build index 7c914b876e..52134ea6a2 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -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 |