Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : NBT interface handling
5 :
6 : Copyright (C) Andrew Tridgell 2005
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "../lib/util/dlinklist.h"
24 : #include "nbt_server/nbt_server.h"
25 : #include "samba/service_task.h"
26 : #include "lib/socket/socket.h"
27 : #include "nbt_server/wins/winsserver.h"
28 : #include "nbt_server/dgram/proto.h"
29 : #include "system/network.h"
30 : #include "lib/socket/netif.h"
31 : #include "param/param.h"
32 : #include "lib/util/util_net.h"
33 : #include "lib/util/idtree.h"
34 : #include "../source3/include/fstring.h"
35 : #include "../source3/libsmb/nmblib.h"
36 : #include "../source3/libsmb/unexpected.h"
37 :
38 : /*
39 : receive an incoming request and dispatch it to the right place
40 : */
41 12432 : static void nbtd_request_handler(struct nbt_name_socket *nbtsock,
42 : struct nbt_name_packet *packet,
43 : struct socket_address *src)
44 : {
45 12432 : struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
46 : struct nbtd_interface);
47 12432 : struct nbtd_server *nbtsrv = iface->nbtsrv;
48 :
49 12432 : nbtsrv->stats.total_received++;
50 :
51 : /* see if it's from one of our own interfaces - if so, then ignore it */
52 12432 : if (nbtd_self_packet_and_bcast(nbtsock, packet, src)) {
53 0 : DEBUG(10,("Ignoring bcast self packet from %s:%d\n", src->addr, src->port));
54 0 : return;
55 : }
56 :
57 12432 : switch (packet->operation & NBT_OPCODE) {
58 6645 : case NBT_OPCODE_QUERY:
59 6645 : nbtsrv->stats.query_count++;
60 6645 : nbtd_request_query(nbtsock, packet, src);
61 6645 : break;
62 :
63 5489 : case NBT_OPCODE_REGISTER:
64 : case NBT_OPCODE_REFRESH:
65 : case NBT_OPCODE_REFRESH2:
66 5489 : nbtsrv->stats.register_count++;
67 5489 : nbtd_request_defense(nbtsock, packet, src);
68 5489 : break;
69 :
70 298 : case NBT_OPCODE_RELEASE:
71 : case NBT_OPCODE_MULTI_HOME_REG:
72 298 : nbtsrv->stats.release_count++;
73 298 : nbtd_winsserver_request(nbtsock, packet, src);
74 298 : break;
75 :
76 0 : default:
77 0 : nbtd_bad_packet(packet, src, "Unexpected opcode");
78 0 : break;
79 : }
80 : }
81 :
82 0 : static void nbtd_unexpected_handler(struct nbt_name_socket *nbtsock,
83 : struct nbt_name_packet *packet,
84 : struct socket_address *src)
85 : {
86 0 : struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
87 : struct nbtd_interface);
88 0 : struct nbtd_server *nbtsrv = iface->nbtsrv;
89 0 : struct nbtd_interface *i;
90 0 : struct nbt_name_request *req = NULL;
91 :
92 0 : nbtsrv->stats.total_received++;
93 :
94 0 : DEBUG(10,("unexpected from src[%s] on interface[%p] %s/%s\n",
95 : src->addr, iface, iface->ip_address, iface->netmask));
96 :
97 : /* try the broadcast interface */
98 0 : if (nbtsrv->bcast_interface) {
99 0 : i = nbtsrv->bcast_interface;
100 0 : req = idr_find(i->nbtsock->idr, packet->name_trn_id);
101 : }
102 :
103 : /* try the wins server client interface */
104 0 : if (!req && nbtsrv->wins_interface && nbtsrv->wins_interface->nbtsock) {
105 0 : i = nbtsrv->wins_interface;
106 0 : req = idr_find(i->nbtsock->idr, packet->name_trn_id);
107 : }
108 :
109 : /* try all other interfaces... */
110 0 : if (!req) {
111 0 : for (i = nbtsrv->interfaces; i; i = i->next) {
112 0 : if (i == iface) {
113 0 : continue;
114 : }
115 0 : req = idr_find(i->nbtsock->idr, packet->name_trn_id);
116 0 : if (req) break;
117 : }
118 : }
119 :
120 0 : if (!req) {
121 0 : struct packet_struct *pstruct = NULL;
122 0 : DATA_BLOB blob = { .length = 0, };
123 0 : enum ndr_err_code ndr_err;
124 :
125 : /*
126 : * Here we have NBT_FLAG_REPLY
127 : */
128 0 : DEBUG(10,("unexpected from src[%s] unable to redirected\n", src->addr));
129 :
130 0 : ndr_err = ndr_push_struct_blob(&blob, packet, packet,
131 : (ndr_push_flags_fn_t)ndr_push_nbt_name_packet);
132 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
133 0 : DBG_ERR("ndr_push_nbt_name_packet - %s\n",
134 : ndr_errstr(ndr_err));
135 0 : return;
136 : }
137 :
138 0 : pstruct = parse_packet((char *)blob.data,
139 0 : blob.length,
140 : NMB_PACKET,
141 0 : interpret_addr2(src->addr),
142 : src->port);
143 0 : if (pstruct != NULL) {
144 0 : nb_packet_dispatch(nbtsrv->unexpected_server, pstruct);
145 0 : free_packet(pstruct);
146 : }
147 :
148 0 : return;
149 : }
150 :
151 0 : DEBUG(10,("unexpected from src[%s] redirected to interface[%p] %s/%s\n",
152 : src->addr, i, i->ip_address, i->netmask));
153 :
154 : /*
155 : * redirect the incoming response to the socket
156 : * we sent the matching request
157 : */
158 0 : nbt_name_socket_handle_response_packet(req, packet, src);
159 : }
160 :
161 : /*
162 : find a registered name on an interface
163 : */
164 10678 : struct nbtd_iface_name *nbtd_find_iname(struct nbtd_interface *iface,
165 : struct nbt_name *name,
166 : uint16_t nb_flags)
167 : {
168 61 : struct nbtd_iface_name *iname;
169 95685 : for (iname=iface->names;iname;iname=iname->next) {
170 86575 : if (iname->name.type == name->type &&
171 18776 : strcmp(name->name, iname->name.name) == 0 &&
172 1568 : ((iname->nb_flags & nb_flags) == nb_flags)) {
173 1568 : return iname;
174 : }
175 : }
176 9088 : return NULL;
177 : }
178 :
179 : /*
180 : start listening on the given address
181 : */
182 130 : static NTSTATUS nbtd_add_socket(struct nbtd_server *nbtsrv,
183 : struct loadparm_context *lp_ctx,
184 : const char *bind_address,
185 : const char *address,
186 : const char *bcast,
187 : const char *netmask)
188 : {
189 4 : struct nbtd_interface *iface;
190 4 : NTSTATUS status;
191 4 : struct socket_address *bcast_address;
192 4 : struct socket_address *unicast_address;
193 :
194 130 : DEBUG(6,("nbtd_add_socket(%s, %s, %s, %s)\n", bind_address, address, bcast, netmask));
195 :
196 : /*
197 : we actually create two sockets. One listens on the broadcast address
198 : for the interface, and the other listens on our specific address. This
199 : allows us to run with "bind interfaces only" while still receiving
200 : broadcast addresses, and also simplifies matching incoming requests
201 : to interfaces
202 : */
203 :
204 130 : iface = talloc(nbtsrv, struct nbtd_interface);
205 130 : NT_STATUS_HAVE_NO_MEMORY(iface);
206 :
207 130 : iface->nbtsrv = nbtsrv;
208 130 : iface->bcast_address = talloc_steal(iface, bcast);
209 130 : iface->ip_address = talloc_steal(iface, address);
210 130 : iface->netmask = talloc_steal(iface, netmask);
211 130 : iface->names = NULL;
212 130 : iface->wack_queue = NULL;
213 :
214 130 : if (strcmp(netmask, "0.0.0.0") != 0) {
215 2 : struct nbt_name_socket *bcast_nbtsock;
216 :
217 : /* listen for broadcasts on port 137 */
218 65 : bcast_nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx);
219 65 : if (!bcast_nbtsock) {
220 0 : talloc_free(iface);
221 0 : return NT_STATUS_NO_MEMORY;
222 : }
223 :
224 65 : bcast_address = socket_address_from_strings(bcast_nbtsock, bcast_nbtsock->sock->backend_name,
225 : bcast, lpcfg_nbt_port(lp_ctx));
226 65 : if (!bcast_address) {
227 0 : talloc_free(iface);
228 0 : return NT_STATUS_NO_MEMORY;
229 : }
230 :
231 65 : status = socket_listen(bcast_nbtsock->sock, bcast_address, 0, 0);
232 65 : if (!NT_STATUS_IS_OK(status)) {
233 0 : DEBUG(0,("Failed to bind to %s:%d - %s\n",
234 : bcast, lpcfg_nbt_port(lp_ctx), nt_errstr(status)));
235 0 : talloc_free(iface);
236 0 : return status;
237 : }
238 65 : talloc_free(bcast_address);
239 :
240 65 : nbt_set_incoming_handler(bcast_nbtsock, nbtd_request_handler, iface);
241 : }
242 :
243 : /* listen for unicasts on port 137 */
244 130 : iface->nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx);
245 130 : if (!iface->nbtsock) {
246 0 : talloc_free(iface);
247 0 : return NT_STATUS_NO_MEMORY;
248 : }
249 :
250 130 : unicast_address = socket_address_from_strings(iface->nbtsock,
251 130 : iface->nbtsock->sock->backend_name,
252 : bind_address, lpcfg_nbt_port(lp_ctx));
253 :
254 130 : status = socket_listen(iface->nbtsock->sock, unicast_address, 0, 0);
255 130 : if (!NT_STATUS_IS_OK(status)) {
256 0 : DEBUG(0,("Failed to bind to %s:%d - %s\n",
257 : bind_address, lpcfg_nbt_port(lp_ctx), nt_errstr(status)));
258 0 : talloc_free(iface);
259 0 : return status;
260 : }
261 130 : talloc_free(unicast_address);
262 :
263 130 : nbt_set_incoming_handler(iface->nbtsock, nbtd_request_handler, iface);
264 130 : nbt_set_unexpected_handler(iface->nbtsock, nbtd_unexpected_handler, iface);
265 :
266 : /* also setup the datagram listeners */
267 130 : status = nbtd_dgram_setup(iface, bind_address);
268 130 : if (!NT_STATUS_IS_OK(status)) {
269 0 : DEBUG(0,("Failed to setup dgram listen on %s - %s\n",
270 : bind_address, nt_errstr(status)));
271 0 : talloc_free(iface);
272 0 : return status;
273 : }
274 :
275 130 : if (strcmp(netmask, "0.0.0.0") == 0) {
276 65 : DLIST_ADD(nbtsrv->bcast_interface, iface);
277 : } else {
278 65 : DLIST_ADD(nbtsrv->interfaces, iface);
279 : }
280 :
281 130 : return NT_STATUS_OK;
282 : }
283 :
284 : /*
285 : setup a socket for talking to our WINS servers
286 : */
287 65 : static NTSTATUS nbtd_add_wins_socket(struct nbtd_server *nbtsrv)
288 : {
289 2 : struct nbtd_interface *iface;
290 :
291 65 : iface = talloc_zero(nbtsrv, struct nbtd_interface);
292 65 : NT_STATUS_HAVE_NO_MEMORY(iface);
293 :
294 65 : iface->nbtsrv = nbtsrv;
295 :
296 65 : DLIST_ADD(nbtsrv->wins_interface, iface);
297 :
298 65 : return NT_STATUS_OK;
299 : }
300 :
301 :
302 : /*
303 : setup our listening sockets on the configured network interfaces
304 : */
305 65 : NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx,
306 : struct interface *ifaces)
307 : {
308 65 : int num_interfaces = iface_list_count(ifaces);
309 2 : int i;
310 65 : TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv);
311 2 : NTSTATUS status;
312 :
313 : /* if we are allowing incoming packets from any address, then
314 : we also need to bind to the wildcard address */
315 65 : if (!lpcfg_bind_interfaces_only(lp_ctx)) {
316 2 : const char *primary_address;
317 :
318 65 : primary_address = iface_list_first_v4(ifaces);
319 :
320 : /* the primary address is the address we will return
321 : for non-WINS queries not made on a specific
322 : interface */
323 65 : if (primary_address == NULL) {
324 0 : primary_address = inet_ntoa(interpret_addr2(
325 : lpcfg_netbios_name(lp_ctx)));
326 : }
327 :
328 65 : primary_address = talloc_strdup(tmp_ctx, primary_address);
329 65 : NT_STATUS_HAVE_NO_MEMORY(primary_address);
330 :
331 65 : status = nbtd_add_socket(nbtsrv,
332 : lp_ctx,
333 : "0.0.0.0",
334 : primary_address,
335 65 : talloc_strdup(tmp_ctx, "255.255.255.255"),
336 65 : talloc_strdup(tmp_ctx, "0.0.0.0"));
337 65 : NT_STATUS_NOT_OK_RETURN(status);
338 : }
339 :
340 195 : for (i=0; i<num_interfaces; i++) {
341 4 : const char *bcast;
342 4 : const char *address, *netmask;
343 :
344 130 : if (!iface_list_n_is_v4(ifaces, i)) {
345 : /* v4 only for NBT protocol */
346 65 : continue;
347 : }
348 :
349 65 : bcast = iface_list_n_bcast(ifaces, i);
350 : /* we can't assume every interface is broadcast capable */
351 65 : if (bcast == NULL) continue;
352 :
353 65 : address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i));
354 65 : bcast = talloc_strdup(tmp_ctx, bcast);
355 65 : netmask = talloc_strdup(tmp_ctx, iface_list_n_netmask(ifaces, i));
356 :
357 65 : status = nbtd_add_socket(nbtsrv, lp_ctx,
358 : address, address, bcast, netmask);
359 67 : NT_STATUS_NOT_OK_RETURN(status);
360 : }
361 :
362 65 : if (lpcfg_wins_server_list(lp_ctx)) {
363 65 : status = nbtd_add_wins_socket(nbtsrv);
364 65 : NT_STATUS_NOT_OK_RETURN(status);
365 : }
366 :
367 65 : talloc_free(tmp_ctx);
368 :
369 65 : return NT_STATUS_OK;
370 : }
371 :
372 :
373 : /*
374 : form a list of addresses that we should use in name query replies
375 : we always place the IP in the given interface first
376 : */
377 1447 : const char **nbtd_address_list(struct nbtd_interface *iface, TALLOC_CTX *mem_ctx)
378 : {
379 1447 : struct nbtd_server *nbtsrv = iface->nbtsrv;
380 1447 : const char **ret = NULL;
381 36 : struct nbtd_interface *iface2;
382 1447 : bool is_loopback = false;
383 :
384 1447 : if (iface->ip_address) {
385 1058 : is_loopback = iface_list_same_net(iface->ip_address, "127.0.0.1", "255.0.0.0");
386 1058 : ret = str_list_add(ret, iface->ip_address);
387 : }
388 :
389 2894 : for (iface2=nbtsrv->interfaces;iface2;iface2=iface2->next) {
390 1447 : if (iface2 == iface) continue;
391 :
392 389 : if (!iface2->ip_address) continue;
393 :
394 389 : if (!is_loopback) {
395 389 : if (iface_list_same_net(iface2->ip_address, "127.0.0.1", "255.0.0.0")) {
396 0 : continue;
397 : }
398 : }
399 :
400 389 : ret = str_list_add(ret, iface2->ip_address);
401 : }
402 :
403 1447 : talloc_steal(mem_ctx, ret);
404 :
405 1447 : return ret;
406 : }
407 :
408 :
409 : /*
410 : find the interface to use for sending a outgoing request
411 : */
412 64 : struct nbtd_interface *nbtd_find_request_iface(struct nbtd_server *nbtd_server,
413 : const char *address, bool allow_bcast_iface)
414 : {
415 0 : struct nbtd_interface *cur;
416 :
417 : /* try to find a exact match */
418 74 : for (cur=nbtd_server->interfaces;cur;cur=cur->next) {
419 64 : if (iface_list_same_net(address, cur->ip_address, cur->netmask)) {
420 54 : DEBUG(10,("find interface for dst[%s] ip: %s/%s (iface[%p])\n",
421 : address, cur->ip_address, cur->netmask, cur));
422 54 : return cur;
423 : }
424 : }
425 :
426 : /* no exact match, if we have the broadcast interface, use that */
427 10 : if (allow_bcast_iface && nbtd_server->bcast_interface) {
428 10 : cur = nbtd_server->bcast_interface;
429 10 : DEBUG(10,("find interface for dst[%s] ip: %s/%s (bcast iface[%p])\n",
430 : address, cur->ip_address, cur->netmask, cur));
431 10 : return cur;
432 : }
433 :
434 : /* fallback to first interface */
435 0 : cur = nbtd_server->interfaces;
436 0 : DEBUG(10,("find interface for dst[%s] ip: %s/%s (default iface[%p])\n",
437 : address, cur->ip_address, cur->netmask, cur));
438 0 : return cur;
439 : }
440 :
441 : /*
442 : * find the interface to use for sending a outgoing reply
443 : */
444 45 : struct nbtd_interface *nbtd_find_reply_iface(struct nbtd_interface *iface,
445 : const char *address, bool allow_bcast_iface)
446 : {
447 45 : struct nbtd_server *nbtd_server = iface->nbtsrv;
448 :
449 : /* first try to use the given interfacel when it's not the broadcast one */
450 45 : if (iface != nbtd_server->bcast_interface) {
451 45 : return iface;
452 : }
453 :
454 0 : return nbtd_find_request_iface(nbtd_server, address, allow_bcast_iface);
455 : }
|