Fix bug 7307 - man net usershare mistake
[nivanova/samba-autobuild/.git] / source4 / nbt_server / interfaces.c
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 "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"
32 #include "lib/util/util_net.h"
33
34
35 /*
36   receive an incoming request and dispatch it to the right place
37 */
38 static void nbtd_request_handler(struct nbt_name_socket *nbtsock, 
39                                  struct nbt_name_packet *packet, 
40                                  struct socket_address *src)
41 {
42         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
43                                                        struct nbtd_interface);
44         struct nbtd_server *nbtsrv = iface->nbtsrv;
45
46         nbtsrv->stats.total_received++;
47
48         /* see if its from one of our own interfaces - if so, then ignore it */
49         if (nbtd_self_packet_and_bcast(nbtsock, packet, src)) {
50                 DEBUG(10,("Ignoring bcast self packet from %s:%d\n", src->addr, src->port));
51                 return;
52         }
53
54         switch (packet->operation & NBT_OPCODE) {
55         case NBT_OPCODE_QUERY:
56                 nbtsrv->stats.query_count++;
57                 nbtd_request_query(nbtsock, packet, src);
58                 break;
59
60         case NBT_OPCODE_REGISTER:
61         case NBT_OPCODE_REFRESH:
62         case NBT_OPCODE_REFRESH2:
63                 nbtsrv->stats.register_count++;
64                 nbtd_request_defense(nbtsock, packet, src);
65                 break;
66
67         case NBT_OPCODE_RELEASE:
68         case NBT_OPCODE_MULTI_HOME_REG:
69                 nbtsrv->stats.release_count++;
70                 nbtd_winsserver_request(nbtsock, packet, src);
71                 break;
72
73         default:
74                 nbtd_bad_packet(packet, src, "Unexpected opcode");
75                 break;
76         }
77 }
78
79 static void nbtd_unexpected_handler(struct nbt_name_socket *nbtsock,
80                                     struct nbt_name_packet *packet,
81                                     struct socket_address *src)
82 {
83         struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
84                                                        struct nbtd_interface);
85         struct nbtd_server *nbtsrv = iface->nbtsrv;
86         struct nbtd_interface *i;
87         struct nbt_name_request *req = NULL;
88
89         nbtsrv->stats.total_received++;
90
91         DEBUG(10,("unexpected from src[%s] on interface[%p] %s/%s\n",
92                 src->addr, iface, iface->ip_address, iface->netmask));
93
94         /* try the broadcast interface */
95         if (nbtsrv->bcast_interface) {
96                 i = nbtsrv->bcast_interface;
97                 req = idr_find(i->nbtsock->idr, packet->name_trn_id);
98         }
99
100         /* try the wins server client interface */
101         if (!req && nbtsrv->wins_interface && nbtsrv->wins_interface->nbtsock) {
102                 i = nbtsrv->wins_interface;
103                 req = idr_find(i->nbtsock->idr, packet->name_trn_id);
104         }
105
106         /* try all other interfaces... */
107         if (!req) {
108                 for (i = nbtsrv->interfaces; i; i = i->next) {
109                         if (i == iface) {
110                                 continue;
111                         }
112                         req = idr_find(i->nbtsock->idr, packet->name_trn_id);
113                         if (req) break;
114                 }
115         }
116
117         if (!req) {
118                 DEBUG(10,("unexpected from src[%s] unable to redirected\n", src->addr));
119                 return;
120         }
121
122         DEBUG(10,("unexpected from src[%s] redirected to interface[%p] %s/%s\n",
123                 src->addr, i, i->ip_address, i->netmask));
124
125         /*
126          * redirect the incoming response to the socket
127          * we sent the matching request
128          */
129         nbt_name_socket_handle_response_packet(req, packet, src);
130 }
131
132 /*
133   find a registered name on an interface
134 */
135 struct nbtd_iface_name *nbtd_find_iname(struct nbtd_interface *iface, 
136                                         struct nbt_name *name, 
137                                         uint16_t nb_flags)
138 {
139         struct nbtd_iface_name *iname;
140         for (iname=iface->names;iname;iname=iname->next) {
141                 if (iname->name.type == name->type &&
142                     strcmp(name->name, iname->name.name) == 0 &&
143                     ((iname->nb_flags & nb_flags) == nb_flags)) {
144                         return iname;
145                 }
146         }
147         return NULL;
148 }
149
150 /*
151   start listening on the given address
152 */
153 static NTSTATUS nbtd_add_socket(struct nbtd_server *nbtsrv, 
154                                 struct loadparm_context *lp_ctx,
155                                 const char *bind_address, 
156                                 const char *address, 
157                                 const char *bcast, 
158                                 const char *netmask)
159 {
160         struct nbtd_interface *iface;
161         NTSTATUS status;
162         struct socket_address *bcast_address;
163         struct socket_address *unicast_address;
164
165         DEBUG(6,("nbtd_add_socket(%s, %s, %s, %s)\n", bind_address, address, bcast, netmask));
166
167         /*
168           we actually create two sockets. One listens on the broadcast address
169           for the interface, and the other listens on our specific address. This
170           allows us to run with "bind interfaces only" while still receiving 
171           broadcast addresses, and also simplifies matching incoming requests 
172           to interfaces
173         */
174
175         iface = talloc(nbtsrv, struct nbtd_interface);
176         NT_STATUS_HAVE_NO_MEMORY(iface);
177
178         iface->nbtsrv        = nbtsrv;
179         iface->bcast_address = talloc_steal(iface, bcast);
180         iface->ip_address    = talloc_steal(iface, address);
181         iface->netmask       = talloc_steal(iface, netmask);
182         iface->names         = NULL;
183         iface->wack_queue    = NULL;
184
185         if (strcmp(netmask, "0.0.0.0") != 0) {
186                 struct nbt_name_socket *bcast_nbtsock;
187
188                 /* listen for broadcasts on port 137 */
189                 bcast_nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx, lp_iconv_convenience(nbtsrv->task->lp_ctx));
190                 if (!bcast_nbtsock) {
191                         talloc_free(iface);
192                         return NT_STATUS_NO_MEMORY;
193                 }
194
195                 bcast_address = socket_address_from_strings(bcast_nbtsock, bcast_nbtsock->sock->backend_name, 
196                                                             bcast, lp_nbt_port(lp_ctx));
197                 if (!bcast_address) {
198                         talloc_free(iface);
199                         return NT_STATUS_NO_MEMORY;
200                 }
201
202                 status = socket_listen(bcast_nbtsock->sock, bcast_address, 0, 0);
203                 if (!NT_STATUS_IS_OK(status)) {
204                         DEBUG(0,("Failed to bind to %s:%d - %s\n", 
205                                  bcast, lp_nbt_port(lp_ctx), nt_errstr(status)));
206                         talloc_free(iface);
207                         return status;
208                 }
209                 talloc_free(bcast_address);
210
211                 nbt_set_incoming_handler(bcast_nbtsock, nbtd_request_handler, iface);
212         }
213
214         /* listen for unicasts on port 137 */
215         iface->nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx, 
216                                               lp_iconv_convenience(nbtsrv->task->lp_ctx));
217         if (!iface->nbtsock) {
218                 talloc_free(iface);
219                 return NT_STATUS_NO_MEMORY;
220         }
221
222         unicast_address = socket_address_from_strings(iface->nbtsock, 
223                                                       iface->nbtsock->sock->backend_name, 
224                                                       bind_address, lp_nbt_port(lp_ctx));
225
226         status = socket_listen(iface->nbtsock->sock, unicast_address, 0, 0);
227         if (!NT_STATUS_IS_OK(status)) {
228                 DEBUG(0,("Failed to bind to %s:%d - %s\n", 
229                          bind_address, lp_nbt_port(lp_ctx), nt_errstr(status)));
230                 talloc_free(iface);
231                 return status;
232         }
233         talloc_free(unicast_address);
234
235         nbt_set_incoming_handler(iface->nbtsock, nbtd_request_handler, iface);
236         nbt_set_unexpected_handler(iface->nbtsock, nbtd_unexpected_handler, iface);
237
238         /* also setup the datagram listeners */
239         status = nbtd_dgram_setup(iface, bind_address);
240         if (!NT_STATUS_IS_OK(status)) {
241                 DEBUG(0,("Failed to setup dgram listen on %s - %s\n", 
242                          bind_address, nt_errstr(status)));
243                 talloc_free(iface);
244                 return status;
245         }
246         
247         if (strcmp(netmask, "0.0.0.0") == 0) {
248                 DLIST_ADD(nbtsrv->bcast_interface, iface);
249         } else {
250                 DLIST_ADD(nbtsrv->interfaces, iface);
251         }
252
253         return NT_STATUS_OK;
254 }
255
256 /*
257   setup a socket for talking to our WINS servers
258 */
259 static NTSTATUS nbtd_add_wins_socket(struct nbtd_server *nbtsrv)
260 {
261         struct nbtd_interface *iface;
262
263         iface = talloc_zero(nbtsrv, struct nbtd_interface);
264         NT_STATUS_HAVE_NO_MEMORY(iface);
265
266         iface->nbtsrv        = nbtsrv;
267
268         DLIST_ADD(nbtsrv->wins_interface, iface);
269
270         return NT_STATUS_OK;
271 }
272
273
274 /*
275   setup our listening sockets on the configured network interfaces
276 */
277 NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx,
278                                  struct interface *ifaces)
279 {
280         int num_interfaces = iface_count(ifaces);
281         int i;
282         TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv);
283         NTSTATUS status;
284
285         /* if we are allowing incoming packets from any address, then
286            we also need to bind to the wildcard address */
287         if (!lp_bind_interfaces_only(lp_ctx)) {
288                 const char *primary_address;
289
290                 /* the primary address is the address we will return
291                    for non-WINS queries not made on a specific
292                    interface */
293                 if (num_interfaces > 0) {
294                         primary_address = iface_n_ip(ifaces, 0);
295                 } else {
296                         primary_address = inet_ntoa(interpret_addr2(
297                                                         lp_netbios_name(lp_ctx)));
298                 }
299                 primary_address = talloc_strdup(tmp_ctx, primary_address);
300                 NT_STATUS_HAVE_NO_MEMORY(primary_address);
301
302                 status = nbtd_add_socket(nbtsrv, 
303                                          lp_ctx,
304                                          "0.0.0.0",
305                                          primary_address,
306                                          talloc_strdup(tmp_ctx, "255.255.255.255"),
307                                          talloc_strdup(tmp_ctx, "0.0.0.0"));
308                 NT_STATUS_NOT_OK_RETURN(status);
309         }
310
311         for (i=0; i<num_interfaces; i++) {
312                 const char *bcast = iface_n_bcast(ifaces, i);
313                 const char *address, *netmask;
314
315                 /* we can't assume every interface is broadcast capable */
316                 if (bcast == NULL) continue;
317
318                 address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
319                 bcast   = talloc_strdup(tmp_ctx, bcast);
320                 netmask = talloc_strdup(tmp_ctx, iface_n_netmask(ifaces, i));
321
322                 status = nbtd_add_socket(nbtsrv, lp_ctx, 
323                                          address, address, bcast, netmask);
324                 NT_STATUS_NOT_OK_RETURN(status);
325         }
326
327         if (lp_wins_server_list(lp_ctx)) {
328                 status = nbtd_add_wins_socket(nbtsrv);
329                 NT_STATUS_NOT_OK_RETURN(status);
330         }
331
332         talloc_free(tmp_ctx);
333
334         return NT_STATUS_OK;
335 }
336
337
338 /*
339   form a list of addresses that we should use in name query replies
340   we always place the IP in the given interface first
341 */
342 const char **nbtd_address_list(struct nbtd_interface *iface, TALLOC_CTX *mem_ctx)
343 {
344         struct nbtd_server *nbtsrv = iface->nbtsrv;
345         const char **ret = NULL;
346         struct nbtd_interface *iface2;
347         bool is_loopback = false;
348
349         if (iface->ip_address) {
350                 is_loopback = iface_same_net(iface->ip_address, "127.0.0.1", "255.0.0.0");
351                 ret = str_list_add(ret, iface->ip_address);
352         }
353
354         for (iface2=nbtsrv->interfaces;iface2;iface2=iface2->next) {
355                 if (iface2 == iface) continue;
356
357                 if (!iface2->ip_address) continue;
358
359                 if (!is_loopback) {
360                         if (iface_same_net(iface2->ip_address, "127.0.0.1", "255.0.0.0")) {
361                                 continue;
362                         }
363                 }
364
365                 ret = str_list_add(ret, iface2->ip_address);
366         }
367
368         talloc_steal(mem_ctx, ret);
369
370         return ret;
371 }
372
373
374 /*
375   find the interface to use for sending a outgoing request
376 */
377 struct nbtd_interface *nbtd_find_request_iface(struct nbtd_server *nbtd_server,
378                                                const char *address, bool allow_bcast_iface)
379 {
380         struct nbtd_interface *cur;
381
382         /* try to find a exact match */
383         for (cur=nbtd_server->interfaces;cur;cur=cur->next) {
384                 if (iface_same_net(address, cur->ip_address, cur->netmask)) {
385                         DEBUG(10,("find interface for dst[%s] ip: %s/%s (iface[%p])\n",
386                                   address, cur->ip_address, cur->netmask, cur));
387                         return cur;
388                 }
389         }
390
391         /* no exact match, if we have the broadcast interface, use that */
392         if (allow_bcast_iface && nbtd_server->bcast_interface) {
393                 cur = nbtd_server->bcast_interface;
394                 DEBUG(10,("find interface for dst[%s] ip: %s/%s (bcast iface[%p])\n",
395                         address, cur->ip_address, cur->netmask, cur));
396                 return cur;
397         }
398
399         /* fallback to first interface */
400         cur = nbtd_server->interfaces;
401         DEBUG(10,("find interface for dst[%s] ip: %s/%s (default iface[%p])\n",
402                 address, cur->ip_address, cur->netmask, cur));
403         return cur;
404 }
405
406 /*
407  * find the interface to use for sending a outgoing reply
408  */
409 struct nbtd_interface *nbtd_find_reply_iface(struct nbtd_interface *iface,
410                                              const char *address, bool allow_bcast_iface)
411 {
412         struct nbtd_server *nbtd_server = iface->nbtsrv;
413
414         /* first try to use the given interfacel when it's not the broadcast one */
415         if (iface != nbtd_server->bcast_interface) {
416                 return iface;
417         }
418
419         return nbtd_find_request_iface(nbtd_server, address, allow_bcast_iface);
420 }