2
Unix SMB/CIFS implementation.
6
Copyright (C) Andrew Tridgell 2005
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.
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.
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/>.
23
#include "../lib/util/dlinklist.h"
24
#include "nbt_server/nbt_server.h"
25
#include "smbd/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"
35
receive an incoming request and dispatch it to the right place
37
static void nbtd_request_handler(struct nbt_name_socket *nbtsock,
38
struct nbt_name_packet *packet,
39
struct socket_address *src)
41
struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
42
struct nbtd_interface);
43
struct nbtd_server *nbtsrv = iface->nbtsrv;
45
nbtsrv->stats.total_received++;
47
/* see if its from one of our own interfaces - if so, then ignore it */
48
if (nbtd_self_packet_and_bcast(nbtsock, packet, src)) {
49
DEBUG(10,("Ignoring bcast self packet from %s:%d\n", src->addr, src->port));
53
switch (packet->operation & NBT_OPCODE) {
54
case NBT_OPCODE_QUERY:
55
nbtsrv->stats.query_count++;
56
nbtd_request_query(nbtsock, packet, src);
59
case NBT_OPCODE_REGISTER:
60
case NBT_OPCODE_REFRESH:
61
case NBT_OPCODE_REFRESH2:
62
nbtsrv->stats.register_count++;
63
nbtd_request_defense(nbtsock, packet, src);
66
case NBT_OPCODE_RELEASE:
67
case NBT_OPCODE_MULTI_HOME_REG:
68
nbtsrv->stats.release_count++;
69
nbtd_winsserver_request(nbtsock, packet, src);
73
nbtd_bad_packet(packet, src, "Unexpected opcode");
78
static void nbtd_unexpected_handler(struct nbt_name_socket *nbtsock,
79
struct nbt_name_packet *packet,
80
struct socket_address *src)
82
struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
83
struct nbtd_interface);
84
struct nbtd_server *nbtsrv = iface->nbtsrv;
85
struct nbtd_interface *i;
86
struct nbt_name_request *req = NULL;
88
nbtsrv->stats.total_received++;
90
DEBUG(10,("unexpected from src[%s] on interface[%p] %s/%s\n",
91
src->addr, iface, iface->ip_address, iface->netmask));
93
/* try the broadcast interface */
94
if (nbtsrv->bcast_interface) {
95
i = nbtsrv->bcast_interface;
96
req = idr_find(i->nbtsock->idr, packet->name_trn_id);
99
/* try the wins server client interface */
100
if (!req && nbtsrv->wins_interface && nbtsrv->wins_interface->nbtsock) {
101
i = nbtsrv->wins_interface;
102
req = idr_find(i->nbtsock->idr, packet->name_trn_id);
105
/* try all other interfaces... */
107
for (i = nbtsrv->interfaces; i; i = i->next) {
111
req = idr_find(i->nbtsock->idr, packet->name_trn_id);
117
DEBUG(10,("unexpected from src[%s] unable to redirected\n", src->addr));
121
DEBUG(10,("unexpected from src[%s] redirected to interface[%p] %s/%s\n",
122
src->addr, i, i->ip_address, i->netmask));
125
* redirect the incoming response to the socket
126
* we sent the matching request
128
nbt_name_socket_handle_response_packet(req, packet, src);
132
find a registered name on an interface
134
struct nbtd_iface_name *nbtd_find_iname(struct nbtd_interface *iface,
135
struct nbt_name *name,
138
struct nbtd_iface_name *iname;
139
for (iname=iface->names;iname;iname=iname->next) {
140
if (iname->name.type == name->type &&
141
strcmp(name->name, iname->name.name) == 0 &&
142
((iname->nb_flags & nb_flags) == nb_flags)) {
150
start listening on the given address
152
static NTSTATUS nbtd_add_socket(struct nbtd_server *nbtsrv,
153
struct loadparm_context *lp_ctx,
154
const char *bind_address,
159
struct nbtd_interface *iface;
161
struct socket_address *bcast_address;
162
struct socket_address *unicast_address;
164
DEBUG(6,("nbtd_add_socket(%s, %s, %s, %s)\n", bind_address, address, bcast, netmask));
167
we actually create two sockets. One listens on the broadcast address
168
for the interface, and the other listens on our specific address. This
169
allows us to run with "bind interfaces only" while still receiving
170
broadcast addresses, and also simplifies matching incoming requests
174
iface = talloc(nbtsrv, struct nbtd_interface);
175
NT_STATUS_HAVE_NO_MEMORY(iface);
177
iface->nbtsrv = nbtsrv;
178
iface->bcast_address = talloc_steal(iface, bcast);
179
iface->ip_address = talloc_steal(iface, address);
180
iface->netmask = talloc_steal(iface, netmask);
182
iface->wack_queue = NULL;
184
if (strcmp(netmask, "0.0.0.0") != 0) {
185
struct nbt_name_socket *bcast_nbtsock;
187
/* listen for broadcasts on port 137 */
188
bcast_nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx, lp_iconv_convenience(nbtsrv->task->lp_ctx));
189
if (!bcast_nbtsock) {
191
return NT_STATUS_NO_MEMORY;
194
bcast_address = socket_address_from_strings(bcast_nbtsock, bcast_nbtsock->sock->backend_name,
195
bcast, lp_nbt_port(lp_ctx));
196
if (!bcast_address) {
198
return NT_STATUS_NO_MEMORY;
201
status = socket_listen(bcast_nbtsock->sock, bcast_address, 0, 0);
202
if (!NT_STATUS_IS_OK(status)) {
203
DEBUG(0,("Failed to bind to %s:%d - %s\n",
204
bcast, lp_nbt_port(lp_ctx), nt_errstr(status)));
208
talloc_free(bcast_address);
210
nbt_set_incoming_handler(bcast_nbtsock, nbtd_request_handler, iface);
213
/* listen for unicasts on port 137 */
214
iface->nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx,
215
lp_iconv_convenience(nbtsrv->task->lp_ctx));
216
if (!iface->nbtsock) {
218
return NT_STATUS_NO_MEMORY;
221
unicast_address = socket_address_from_strings(iface->nbtsock,
222
iface->nbtsock->sock->backend_name,
223
bind_address, lp_nbt_port(lp_ctx));
225
status = socket_listen(iface->nbtsock->sock, unicast_address, 0, 0);
226
if (!NT_STATUS_IS_OK(status)) {
227
DEBUG(0,("Failed to bind to %s:%d - %s\n",
228
bind_address, lp_nbt_port(lp_ctx), nt_errstr(status)));
232
talloc_free(unicast_address);
234
nbt_set_incoming_handler(iface->nbtsock, nbtd_request_handler, iface);
235
nbt_set_unexpected_handler(iface->nbtsock, nbtd_unexpected_handler, iface);
237
/* also setup the datagram listeners */
238
status = nbtd_dgram_setup(iface, bind_address);
239
if (!NT_STATUS_IS_OK(status)) {
240
DEBUG(0,("Failed to setup dgram listen on %s - %s\n",
241
bind_address, nt_errstr(status)));
246
if (strcmp(netmask, "0.0.0.0") == 0) {
247
DLIST_ADD(nbtsrv->bcast_interface, iface);
249
DLIST_ADD(nbtsrv->interfaces, iface);
256
setup a socket for talking to our WINS servers
258
static NTSTATUS nbtd_add_wins_socket(struct nbtd_server *nbtsrv)
260
struct nbtd_interface *iface;
262
iface = talloc_zero(nbtsrv, struct nbtd_interface);
263
NT_STATUS_HAVE_NO_MEMORY(iface);
265
iface->nbtsrv = nbtsrv;
267
DLIST_ADD(nbtsrv->wins_interface, iface);
274
setup our listening sockets on the configured network interfaces
276
NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx,
277
struct interface *ifaces)
279
int num_interfaces = iface_count(ifaces);
281
TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv);
284
/* if we are allowing incoming packets from any address, then
285
we also need to bind to the wildcard address */
286
if (!lp_bind_interfaces_only(lp_ctx)) {
287
const char *primary_address;
289
/* the primary address is the address we will return
290
for non-WINS queries not made on a specific
292
if (num_interfaces > 0) {
293
primary_address = iface_n_ip(ifaces, 0);
295
primary_address = inet_ntoa(interpret_addr2(
296
lp_netbios_name(lp_ctx)));
298
primary_address = talloc_strdup(tmp_ctx, primary_address);
299
NT_STATUS_HAVE_NO_MEMORY(primary_address);
301
status = nbtd_add_socket(nbtsrv,
305
talloc_strdup(tmp_ctx, "255.255.255.255"),
306
talloc_strdup(tmp_ctx, "0.0.0.0"));
307
NT_STATUS_NOT_OK_RETURN(status);
310
for (i=0; i<num_interfaces; i++) {
311
const char *bcast = iface_n_bcast(ifaces, i);
312
const char *address, *netmask;
314
/* we can't assume every interface is broadcast capable */
315
if (bcast == NULL) continue;
317
address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
318
bcast = talloc_strdup(tmp_ctx, bcast);
319
netmask = talloc_strdup(tmp_ctx, iface_n_netmask(ifaces, i));
321
status = nbtd_add_socket(nbtsrv, lp_ctx,
322
address, address, bcast, netmask);
323
NT_STATUS_NOT_OK_RETURN(status);
326
if (lp_wins_server_list(lp_ctx)) {
327
status = nbtd_add_wins_socket(nbtsrv);
328
NT_STATUS_NOT_OK_RETURN(status);
331
talloc_free(tmp_ctx);
338
form a list of addresses that we should use in name query replies
339
we always place the IP in the given interface first
341
const char **nbtd_address_list(struct nbtd_interface *iface, TALLOC_CTX *mem_ctx)
343
struct nbtd_server *nbtsrv = iface->nbtsrv;
344
const char **ret = NULL;
345
struct nbtd_interface *iface2;
346
bool is_loopback = false;
348
if (iface->ip_address) {
349
is_loopback = iface_same_net(iface->ip_address, "127.0.0.1", "255.0.0.0");
350
ret = str_list_add(ret, iface->ip_address);
353
for (iface2=nbtsrv->interfaces;iface2;iface2=iface2->next) {
354
if (iface2 == iface) continue;
356
if (!iface2->ip_address) continue;
359
if (iface_same_net(iface2->ip_address, "127.0.0.1", "255.0.0.0")) {
364
ret = str_list_add(ret, iface2->ip_address);
367
talloc_steal(mem_ctx, ret);
374
find the interface to use for sending a outgoing request
376
struct nbtd_interface *nbtd_find_request_iface(struct nbtd_server *nbtd_server,
377
const char *address, bool allow_bcast_iface)
379
struct nbtd_interface *cur;
381
/* try to find a exact match */
382
for (cur=nbtd_server->interfaces;cur;cur=cur->next) {
383
if (iface_same_net(address, cur->ip_address, cur->netmask)) {
384
DEBUG(10,("find interface for dst[%s] ip: %s/%s (iface[%p])\n",
385
address, cur->ip_address, cur->netmask, cur));
390
/* no exact match, if we have the broadcast interface, use that */
391
if (allow_bcast_iface && nbtd_server->bcast_interface) {
392
cur = nbtd_server->bcast_interface;
393
DEBUG(10,("find interface for dst[%s] ip: %s/%s (bcast iface[%p])\n",
394
address, cur->ip_address, cur->netmask, cur));
398
/* fallback to first interface */
399
cur = nbtd_server->interfaces;
400
DEBUG(10,("find interface for dst[%s] ip: %s/%s (default iface[%p])\n",
401
address, cur->ip_address, cur->netmask, cur));
406
* find the interface to use for sending a outgoing reply
408
struct nbtd_interface *nbtd_find_reply_iface(struct nbtd_interface *iface,
409
const char *address, bool allow_bcast_iface)
411
struct nbtd_server *nbtd_server = iface->nbtsrv;
413
/* first try to use the given interfacel when it's not the broadcast one */
414
if (iface != nbtd_server->bcast_interface) {
418
return nbtd_find_request_iface(nbtd_server, address, allow_bcast_iface);