ctdb-recoverd: Call an election when the recovery lock is lost
[samba.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 it's 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);
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, lpcfg_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, lpcfg_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         if (!iface->nbtsock) {
217                 talloc_free(iface);
218                 return NT_STATUS_NO_MEMORY;
219         }
220
221         unicast_address = socket_address_from_strings(iface->nbtsock, 
222                                                       iface->nbtsock->sock->backend_name, 
223                                                       bind_address, lpcfg_nbt_port(lp_ctx));
224
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, lpcfg_nbt_port(lp_ctx), nt_errstr(status)));
229                 talloc_free(iface);
230                 return status;
231         }
232         talloc_free(unicast_address);
233
234         nbt_set_incoming_handler(iface->nbtsock, nbtd_request_handler, iface);
235         nbt_set_unexpected_handler(iface->nbtsock, nbtd_unexpected_handler, iface);
236
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)));
242                 talloc_free(iface);
243                 return status;
244         }
245         
246         if (strcmp(netmask, "0.0.0.0") == 0) {
247                 DLIST_ADD(nbtsrv->bcast_interface, iface);
248         } else {
249                 DLIST_ADD(nbtsrv->interfaces, iface);
250         }
251
252         return NT_STATUS_OK;
253 }
254
255 /*
256   setup a socket for talking to our WINS servers
257 */
258 static NTSTATUS nbtd_add_wins_socket(struct nbtd_server *nbtsrv)
259 {
260         struct nbtd_interface *iface;
261
262         iface = talloc_zero(nbtsrv, struct nbtd_interface);
263         NT_STATUS_HAVE_NO_MEMORY(iface);
264
265         iface->nbtsrv        = nbtsrv;
266
267         DLIST_ADD(nbtsrv->wins_interface, iface);
268
269         return NT_STATUS_OK;
270 }
271
272
273 /*
274   setup our listening sockets on the configured network interfaces
275 */
276 NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx,
277                                  struct interface *ifaces)
278 {
279         int num_interfaces = iface_list_count(ifaces);
280         int i;
281         TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv);
282         NTSTATUS status;
283
284         /* if we are allowing incoming packets from any address, then
285            we also need to bind to the wildcard address */
286         if (!lpcfg_bind_interfaces_only(lp_ctx)) {
287                 const char *primary_address;
288
289                 primary_address = iface_list_first_v4(ifaces);
290
291                 /* the primary address is the address we will return
292                    for non-WINS queries not made on a specific
293                    interface */
294                 if (primary_address == NULL) {
295                         primary_address = inet_ntoa(interpret_addr2(
296                                                             lpcfg_netbios_name(lp_ctx)));
297                 }
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;
313                 const char *address, *netmask;
314
315                 if (!iface_list_n_is_v4(ifaces, i)) {
316                         /* v4 only for NBT protocol */
317                         continue;
318                 }
319
320                 bcast = iface_list_n_bcast(ifaces, i);
321                 /* we can't assume every interface is broadcast capable */
322                 if (bcast == NULL) continue;
323
324                 address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i));
325                 bcast   = talloc_strdup(tmp_ctx, bcast);
326                 netmask = talloc_strdup(tmp_ctx, iface_list_n_netmask(ifaces, i));
327
328                 status = nbtd_add_socket(nbtsrv, lp_ctx,
329                                          address, address, bcast, netmask);
330                 NT_STATUS_NOT_OK_RETURN(status);
331         }
332
333         if (lpcfg_wins_server_list(lp_ctx)) {
334                 status = nbtd_add_wins_socket(nbtsrv);
335                 NT_STATUS_NOT_OK_RETURN(status);
336         }
337
338         talloc_free(tmp_ctx);
339
340         return NT_STATUS_OK;
341 }
342
343
344 /*
345   form a list of addresses that we should use in name query replies
346   we always place the IP in the given interface first
347 */
348 const char **nbtd_address_list(struct nbtd_interface *iface, TALLOC_CTX *mem_ctx)
349 {
350         struct nbtd_server *nbtsrv = iface->nbtsrv;
351         const char **ret = NULL;
352         struct nbtd_interface *iface2;
353         bool is_loopback = false;
354
355         if (iface->ip_address) {
356                 is_loopback = iface_list_same_net(iface->ip_address, "127.0.0.1", "255.0.0.0");
357                 ret = str_list_add(ret, iface->ip_address);
358         }
359
360         for (iface2=nbtsrv->interfaces;iface2;iface2=iface2->next) {
361                 if (iface2 == iface) continue;
362
363                 if (!iface2->ip_address) continue;
364
365                 if (!is_loopback) {
366                         if (iface_list_same_net(iface2->ip_address, "127.0.0.1", "255.0.0.0")) {
367                                 continue;
368                         }
369                 }
370
371                 ret = str_list_add(ret, iface2->ip_address);
372         }
373
374         talloc_steal(mem_ctx, ret);
375
376         return ret;
377 }
378
379
380 /*
381   find the interface to use for sending a outgoing request
382 */
383 struct nbtd_interface *nbtd_find_request_iface(struct nbtd_server *nbtd_server,
384                                                const char *address, bool allow_bcast_iface)
385 {
386         struct nbtd_interface *cur;
387
388         /* try to find a exact match */
389         for (cur=nbtd_server->interfaces;cur;cur=cur->next) {
390                 if (iface_list_same_net(address, cur->ip_address, cur->netmask)) {
391                         DEBUG(10,("find interface for dst[%s] ip: %s/%s (iface[%p])\n",
392                                   address, cur->ip_address, cur->netmask, cur));
393                         return cur;
394                 }
395         }
396
397         /* no exact match, if we have the broadcast interface, use that */
398         if (allow_bcast_iface && nbtd_server->bcast_interface) {
399                 cur = nbtd_server->bcast_interface;
400                 DEBUG(10,("find interface for dst[%s] ip: %s/%s (bcast iface[%p])\n",
401                         address, cur->ip_address, cur->netmask, cur));
402                 return cur;
403         }
404
405         /* fallback to first interface */
406         cur = nbtd_server->interfaces;
407         DEBUG(10,("find interface for dst[%s] ip: %s/%s (default iface[%p])\n",
408                 address, cur->ip_address, cur->netmask, cur));
409         return cur;
410 }
411
412 /*
413  * find the interface to use for sending a outgoing reply
414  */
415 struct nbtd_interface *nbtd_find_reply_iface(struct nbtd_interface *iface,
416                                              const char *address, bool allow_bcast_iface)
417 {
418         struct nbtd_server *nbtd_server = iface->nbtsrv;
419
420         /* first try to use the given interfacel when it's not the broadcast one */
421         if (iface != nbtd_server->bcast_interface) {
422                 return iface;
423         }
424
425         return nbtd_find_request_iface(nbtd_server, address, allow_bcast_iface);
426 }