Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : async implementation of WINBINDD_WINS_BYIP
4 : Copyright (C) Volker Lendecke 2011
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "winbindd.h"
22 : #include "libsmb/namequery.h"
23 : #include "librpc/gen_ndr/ndr_winbind_c.h"
24 : #include "libsmb/nmblib.h"
25 : #include "lib/util/string_wrappers.h"
26 :
27 : struct winbindd_wins_byip_state {
28 : struct nmb_name star;
29 : struct sockaddr_storage addr;
30 : fstring response;
31 : };
32 :
33 : static void winbindd_wins_byip_done(struct tevent_req *subreq);
34 :
35 4 : struct tevent_req *winbindd_wins_byip_send(TALLOC_CTX *mem_ctx,
36 : struct tevent_context *ev,
37 : struct winbindd_cli_state *cli,
38 : struct winbindd_request *request)
39 : {
40 0 : struct tevent_req *req, *subreq;
41 0 : struct winbindd_wins_byip_state *state;
42 :
43 4 : req = tevent_req_create(mem_ctx, &state,
44 : struct winbindd_wins_byip_state);
45 4 : if (req == NULL) {
46 0 : return NULL;
47 : }
48 : /* Ensure null termination */
49 4 : request->data.winsreq[sizeof(request->data.winsreq)-1]='\0';
50 :
51 4 : fstr_sprintf(state->response, "%s\t", request->data.winsreq);
52 :
53 4 : D_NOTICE("[%s (%u)] Winbind external command WINS_BYIP start.\n"
54 : "Resolving wins byip for %s.\n",
55 : cli->client_name,
56 : (unsigned int)cli->pid,
57 : request->data.winsreq);
58 :
59 4 : make_nmb_name(&state->star, "*", 0);
60 :
61 4 : if (!interpret_string_addr(&state->addr, request->data.winsreq,
62 : AI_NUMERICHOST)) {
63 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
64 0 : return tevent_req_post(req, ev);
65 : }
66 :
67 4 : subreq = node_status_query_send(state, ev, &state->star,
68 4 : &state->addr);
69 4 : if (tevent_req_nomem(subreq, req)) {
70 0 : return tevent_req_post(req, ev);
71 : }
72 4 : tevent_req_set_callback(subreq, winbindd_wins_byip_done, req);
73 4 : return req;
74 : }
75 :
76 4 : static void winbindd_wins_byip_done(struct tevent_req *subreq)
77 : {
78 4 : struct tevent_req *req = tevent_req_callback_data(
79 : subreq, struct tevent_req);
80 4 : struct winbindd_wins_byip_state *state = tevent_req_data(
81 : req, struct winbindd_wins_byip_state);
82 0 : struct node_status *names;
83 0 : size_t i;
84 4 : size_t num_names = 0;
85 0 : NTSTATUS status;
86 :
87 4 : status = node_status_query_recv(subreq, talloc_tos(), &names,
88 : &num_names, NULL);
89 4 : TALLOC_FREE(subreq);
90 4 : if (tevent_req_nterror(req, status)) {
91 0 : return;
92 : }
93 :
94 48 : for (i=0; i<num_names; i++) {
95 0 : size_t size;
96 : /*
97 : * ignore group names
98 : */
99 44 : if (names[i].flags & 0x80) {
100 12 : continue;
101 : }
102 : /*
103 : * Only report 0x20
104 : */
105 32 : if (names[i].type != 0x20) {
106 24 : continue;
107 : }
108 :
109 8 : D_DEBUG("Got name '%s'.\n", names[i].name);
110 :
111 8 : size = strlen(names[i].name + strlen(state->response));
112 8 : if (size > sizeof(state->response) - 1) {
113 0 : D_WARNING("Too much data!\n");
114 0 : tevent_req_nterror(req, STATUS_BUFFER_OVERFLOW);
115 0 : return;
116 : }
117 8 : fstrcat(state->response, names[i].name);
118 8 : fstrcat(state->response, " ");
119 : }
120 4 : state->response[strlen(state->response)-1] = '\n';
121 :
122 :
123 4 : TALLOC_FREE(names);
124 4 : tevent_req_done(req);
125 : }
126 :
127 4 : NTSTATUS winbindd_wins_byip_recv(struct tevent_req *req,
128 : struct winbindd_response *presp)
129 : {
130 4 : struct winbindd_wins_byip_state *state = tevent_req_data(
131 : req, struct winbindd_wins_byip_state);
132 0 : NTSTATUS status;
133 :
134 4 : if (tevent_req_is_nterror(req, &status)) {
135 0 : return status;
136 : }
137 4 : D_NOTICE("Winbind external command WINS_BYIP end.\n"
138 : "Response: %s",
139 : state->response);
140 4 : fstrcpy(presp->data.winsresp, state->response);
141 4 : return NT_STATUS_OK;
142 : }
|