Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : name query routines
4 : Copyright (C) Andrew Tridgell 1994-1998
5 : Copyright (C) Jeremy Allison 2007.
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include "libsmb/namequery.h"
23 : #include "../lib/util/tevent_ntstatus.h"
24 : #include "libads/sitename_cache.h"
25 : #include "../lib/addns/dnsquery.h"
26 : #include "../lib/addns/dnsquery_srv.h"
27 : #include "../libcli/netlogon/netlogon.h"
28 : #include "lib/async_req/async_sock.h"
29 : #include "lib/tsocket/tsocket.h"
30 : #include "libsmb/nmblib.h"
31 : #include "libsmb/unexpected.h"
32 : #include "../libcli/nbt/libnbt.h"
33 : #include "libads/kerberos_proto.h"
34 : #include "lib/gencache.h"
35 : #include "librpc/gen_ndr/dns.h"
36 : #include "lib/util/util_net.h"
37 : #include "lib/util/string_wrappers.h"
38 :
39 : /* nmbd.c sets this to True. */
40 : bool global_in_nmbd = False;
41 :
42 : /*
43 : * Utility function to convert from a sockaddr_storage
44 : * array to a struct samba_sockaddr array.
45 : */
46 :
47 164 : static NTSTATUS sockaddr_array_to_samba_sockaddr_array(
48 : TALLOC_CTX *ctx,
49 : struct samba_sockaddr **sa_out,
50 : size_t *count_out,
51 : const struct sockaddr_storage *ss_in,
52 : size_t count_in)
53 : {
54 164 : struct samba_sockaddr *sa = NULL;
55 : size_t i;
56 164 : size_t count = 0;
57 :
58 164 : if (count_in == 0) {
59 : /*
60 : * Zero length arrays are returned as NULL.
61 : * in the name resolution code.
62 : */
63 0 : *count_out = 0;
64 0 : *sa_out = NULL;
65 0 : return NT_STATUS_OK;
66 : }
67 164 : sa = talloc_zero_array(ctx,
68 : struct samba_sockaddr,
69 : count_in);
70 164 : if (sa == NULL) {
71 0 : return NT_STATUS_NO_MEMORY;
72 : }
73 164 : count = 0;
74 478 : for (i = 0; i < count_in; i++) {
75 : bool ok;
76 :
77 : /* Filter out zero addresses. */
78 314 : if (is_zero_addr(&ss_in[i])) {
79 0 : continue;
80 : }
81 314 : ok = sockaddr_storage_to_samba_sockaddr(&sa[count],
82 314 : &ss_in[i]);
83 314 : if (!ok) {
84 0 : continue;
85 : }
86 314 : count++;
87 : }
88 164 : if (count == 0) {
89 : /*
90 : * Zero length arrays are returned as NULL.
91 : * in the name resolution code.
92 : */
93 0 : TALLOC_FREE(sa);
94 : }
95 164 : *count_out = count;
96 164 : *sa_out = sa;
97 164 : return NT_STATUS_OK;
98 : }
99 :
100 : /****************************
101 : * SERVER AFFINITY ROUTINES *
102 : ****************************/
103 :
104 : /* Server affinity is the concept of preferring the last domain
105 : controller with whom you had a successful conversation */
106 :
107 : /****************************************************************************
108 : ****************************************************************************/
109 : #define SAFKEY_FMT "SAF/DOMAIN/%s"
110 : #define SAF_TTL 900
111 : #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
112 : #define SAFJOIN_TTL 3600
113 :
114 272 : static char *saf_key(TALLOC_CTX *mem_ctx, const char *domain)
115 : {
116 272 : return talloc_asprintf_strupper_m(mem_ctx, SAFKEY_FMT, domain);
117 : }
118 :
119 245 : static char *saf_join_key(TALLOC_CTX *mem_ctx, const char *domain)
120 : {
121 245 : return talloc_asprintf_strupper_m(mem_ctx, SAFJOINKEY_FMT, domain);
122 : }
123 :
124 : /****************************************************************************
125 : ****************************************************************************/
126 :
127 190 : bool saf_store( const char *domain, const char *servername )
128 : {
129 : char *key;
130 : time_t expire;
131 190 : bool ret = False;
132 :
133 190 : if ( !domain || !servername ) {
134 12 : DEBUG(2,("saf_store: "
135 : "Refusing to store empty domain or servername!\n"));
136 12 : return False;
137 : }
138 :
139 178 : if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
140 0 : DEBUG(0,("saf_store: "
141 : "refusing to store 0 length domain or servername!\n"));
142 0 : return False;
143 : }
144 :
145 178 : key = saf_key(talloc_tos(), domain);
146 178 : if (key == NULL) {
147 0 : DEBUG(1, ("saf_key() failed\n"));
148 0 : return false;
149 : }
150 178 : expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
151 :
152 178 : DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
153 : domain, servername, (unsigned int)expire ));
154 :
155 178 : ret = gencache_set( key, servername, expire );
156 :
157 178 : TALLOC_FREE( key );
158 :
159 178 : return ret;
160 : }
161 :
162 53 : bool saf_join_store( const char *domain, const char *servername )
163 : {
164 : char *key;
165 : time_t expire;
166 53 : bool ret = False;
167 :
168 53 : if ( !domain || !servername ) {
169 0 : DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
170 0 : return False;
171 : }
172 :
173 53 : if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
174 0 : DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
175 0 : return False;
176 : }
177 :
178 53 : key = saf_join_key(talloc_tos(), domain);
179 53 : if (key == NULL) {
180 0 : DEBUG(1, ("saf_join_key() failed\n"));
181 0 : return false;
182 : }
183 53 : expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
184 :
185 53 : DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
186 : domain, servername, (unsigned int)expire ));
187 :
188 53 : ret = gencache_set( key, servername, expire );
189 :
190 53 : TALLOC_FREE( key );
191 :
192 53 : return ret;
193 : }
194 :
195 0 : bool saf_delete( const char *domain )
196 : {
197 : char *key;
198 0 : bool ret = False;
199 :
200 0 : if ( !domain ) {
201 0 : DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
202 0 : return False;
203 : }
204 :
205 0 : key = saf_join_key(talloc_tos(), domain);
206 0 : if (key == NULL) {
207 0 : DEBUG(1, ("saf_join_key() failed\n"));
208 0 : return false;
209 : }
210 0 : ret = gencache_del(key);
211 0 : TALLOC_FREE(key);
212 :
213 0 : if (ret) {
214 0 : DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
215 : }
216 :
217 0 : key = saf_key(talloc_tos(), domain);
218 0 : if (key == NULL) {
219 0 : DEBUG(1, ("saf_key() failed\n"));
220 0 : return false;
221 : }
222 0 : ret = gencache_del(key);
223 0 : TALLOC_FREE(key);
224 :
225 0 : if (ret) {
226 0 : DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
227 : }
228 :
229 0 : return ret;
230 : }
231 :
232 : /****************************************************************************
233 : ****************************************************************************/
234 :
235 192 : char *saf_fetch(TALLOC_CTX *mem_ctx, const char *domain )
236 : {
237 192 : char *server = NULL;
238 : time_t timeout;
239 192 : bool ret = False;
240 192 : char *key = NULL;
241 :
242 192 : if ( !domain || strlen(domain) == 0) {
243 0 : DEBUG(2,("saf_fetch: Empty domain name!\n"));
244 0 : return NULL;
245 : }
246 :
247 192 : key = saf_join_key(talloc_tos(), domain);
248 192 : if (key == NULL) {
249 0 : DEBUG(1, ("saf_join_key() failed\n"));
250 0 : return NULL;
251 : }
252 :
253 192 : ret = gencache_get( key, mem_ctx, &server, &timeout );
254 :
255 192 : TALLOC_FREE( key );
256 :
257 192 : if ( ret ) {
258 98 : DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
259 : server, domain ));
260 98 : return server;
261 : }
262 :
263 94 : key = saf_key(talloc_tos(), domain);
264 94 : if (key == NULL) {
265 0 : DEBUG(1, ("saf_key() failed\n"));
266 0 : return NULL;
267 : }
268 :
269 94 : ret = gencache_get( key, mem_ctx, &server, &timeout );
270 :
271 94 : TALLOC_FREE( key );
272 :
273 94 : if ( !ret ) {
274 88 : DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
275 : domain ));
276 : } else {
277 6 : DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
278 : server, domain ));
279 : }
280 :
281 94 : return server;
282 : }
283 :
284 268 : static void set_socket_addr_v4(struct samba_sockaddr *addr)
285 : {
286 268 : if (!interpret_string_addr(&addr->u.ss, lp_nbt_client_socket_address(),
287 : AI_NUMERICHOST|AI_PASSIVE)) {
288 0 : zero_sockaddr(&addr->u.ss);
289 : /* zero_sockaddr sets family to AF_INET. */
290 0 : addr->sa_socklen = sizeof(struct sockaddr_in);
291 : }
292 268 : if (addr->u.ss.ss_family != AF_INET) {
293 0 : zero_sockaddr(&addr->u.ss);
294 : /* zero_sockaddr sets family to AF_INET. */
295 0 : addr->sa_socklen = sizeof(struct sockaddr_in);
296 : }
297 268 : }
298 :
299 0 : static struct in_addr my_socket_addr_v4(void)
300 : {
301 0 : struct samba_sockaddr my_addr = {0};
302 :
303 0 : set_socket_addr_v4(&my_addr);
304 0 : return my_addr.u.in.sin_addr;
305 : }
306 :
307 : /****************************************************************************
308 : Generate a random trn_id.
309 : ****************************************************************************/
310 :
311 268 : static int generate_trn_id(void)
312 : {
313 : uint16_t id;
314 :
315 268 : generate_random_buffer((uint8_t *)&id, sizeof(id));
316 :
317 268 : return id % (unsigned)0x7FFF;
318 : }
319 :
320 : /****************************************************************************
321 : Parse a node status response into an array of structures.
322 : ****************************************************************************/
323 :
324 8 : static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p,
325 : size_t *num_names,
326 : struct node_status_extra *extra)
327 : {
328 : struct node_status *ret;
329 : size_t i;
330 8 : size_t result_count = 0;
331 :
332 8 : result_count = CVAL(p,0);
333 :
334 8 : if (result_count == 0)
335 0 : return NULL;
336 :
337 8 : ret = talloc_array(mem_ctx, struct node_status,result_count);
338 8 : if (!ret)
339 0 : return NULL;
340 :
341 8 : p++;
342 78 : for (i=0;i< result_count;i++) {
343 70 : strlcpy(ret[i].name,p,16);
344 70 : trim_char(ret[i].name,'\0',' ');
345 70 : ret[i].type = CVAL(p,15);
346 70 : ret[i].flags = p[16];
347 70 : p += 18;
348 70 : DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
349 : ret[i].type, ret[i].flags));
350 : }
351 : /*
352 : * Also, pick up the MAC address ...
353 : */
354 8 : if (extra) {
355 0 : memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
356 : }
357 8 : *num_names = result_count;
358 8 : return ret;
359 : }
360 :
361 : struct sock_packet_read_state {
362 : struct tevent_context *ev;
363 : enum packet_type type;
364 : int trn_id;
365 :
366 : struct nb_packet_reader *reader;
367 : struct tevent_req *reader_req;
368 :
369 : struct tdgram_context *sock;
370 : struct tevent_req *socket_req;
371 : uint8_t *buf;
372 : struct tsocket_address *addr;
373 :
374 : bool (*validator)(struct packet_struct *p,
375 : void *private_data);
376 : void *private_data;
377 :
378 : struct packet_struct *packet;
379 : };
380 :
381 : static void sock_packet_read_got_packet(struct tevent_req *subreq);
382 : static void sock_packet_read_got_socket(struct tevent_req *subreq);
383 :
384 268 : static struct tevent_req *sock_packet_read_send(
385 : TALLOC_CTX *mem_ctx,
386 : struct tevent_context *ev,
387 : struct tdgram_context *sock,
388 : struct nb_packet_reader *reader,
389 : enum packet_type type,
390 : int trn_id,
391 : bool (*validator)(struct packet_struct *p, void *private_data),
392 : void *private_data)
393 : {
394 : struct tevent_req *req;
395 : struct sock_packet_read_state *state;
396 :
397 268 : req = tevent_req_create(mem_ctx, &state,
398 : struct sock_packet_read_state);
399 268 : if (req == NULL) {
400 0 : return NULL;
401 : }
402 268 : state->ev = ev;
403 268 : state->reader = reader;
404 268 : state->sock = sock;
405 268 : state->type = type;
406 268 : state->trn_id = trn_id;
407 268 : state->validator = validator;
408 268 : state->private_data = private_data;
409 :
410 268 : if (reader != NULL) {
411 169 : state->reader_req = nb_packet_read_send(state, ev, reader);
412 169 : if (tevent_req_nomem(state->reader_req, req)) {
413 0 : return tevent_req_post(req, ev);
414 : }
415 169 : tevent_req_set_callback(
416 169 : state->reader_req, sock_packet_read_got_packet, req);
417 : }
418 :
419 268 : state->socket_req = tdgram_recvfrom_send(state, ev, state->sock);
420 268 : if (tevent_req_nomem(state->socket_req, req)) {
421 0 : return tevent_req_post(req, ev);
422 : }
423 268 : tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
424 : req);
425 :
426 268 : return req;
427 : }
428 :
429 0 : static void sock_packet_read_got_packet(struct tevent_req *subreq)
430 : {
431 0 : struct tevent_req *req = tevent_req_callback_data(
432 : subreq, struct tevent_req);
433 0 : struct sock_packet_read_state *state = tevent_req_data(
434 : req, struct sock_packet_read_state);
435 : NTSTATUS status;
436 :
437 0 : status = nb_packet_read_recv(subreq, state, &state->packet);
438 :
439 0 : TALLOC_FREE(state->reader_req);
440 :
441 0 : if (!NT_STATUS_IS_OK(status)) {
442 0 : if (state->socket_req != NULL) {
443 : /*
444 : * Still waiting for socket
445 : */
446 0 : return;
447 : }
448 : /*
449 : * Both socket and packet reader failed
450 : */
451 0 : tevent_req_nterror(req, status);
452 0 : return;
453 : }
454 :
455 0 : if ((state->validator != NULL) &&
456 0 : !state->validator(state->packet, state->private_data)) {
457 0 : DEBUG(10, ("validator failed\n"));
458 :
459 0 : TALLOC_FREE(state->packet);
460 :
461 0 : state->reader_req = nb_packet_read_send(state, state->ev,
462 : state->reader);
463 0 : if (tevent_req_nomem(state->reader_req, req)) {
464 0 : return;
465 : }
466 0 : tevent_req_set_callback(
467 : state->reader_req, sock_packet_read_got_packet, req);
468 0 : return;
469 : }
470 :
471 0 : TALLOC_FREE(state->socket_req);
472 0 : tevent_req_done(req);
473 : }
474 :
475 150 : static void sock_packet_read_got_socket(struct tevent_req *subreq)
476 : {
477 150 : struct tevent_req *req = tevent_req_callback_data(
478 : subreq, struct tevent_req);
479 150 : struct sock_packet_read_state *state = tevent_req_data(
480 : req, struct sock_packet_read_state);
481 150 : struct samba_sockaddr addr = {0};
482 : ssize_t ret;
483 : ssize_t received;
484 : int err;
485 : bool ok;
486 :
487 150 : received = tdgram_recvfrom_recv(subreq, &err, state,
488 : &state->buf, &state->addr);
489 :
490 150 : TALLOC_FREE(state->socket_req);
491 :
492 150 : if (received == -1) {
493 0 : if (state->reader_req != NULL) {
494 : /*
495 : * Still waiting for reader
496 : */
497 140 : return;
498 : }
499 : /*
500 : * Both socket and reader failed
501 : */
502 0 : tevent_req_nterror(req, map_nt_error_from_unix(err));
503 0 : return;
504 : }
505 150 : ok = tsocket_address_is_inet(state->addr, "ipv4");
506 150 : if (!ok) {
507 0 : goto retry;
508 : }
509 150 : ret = tsocket_address_bsd_sockaddr(state->addr,
510 : &addr.u.sa,
511 : sizeof(addr.u.in));
512 150 : if (ret == -1) {
513 0 : tevent_req_nterror(req, map_nt_error_from_unix(errno));
514 0 : return;
515 : }
516 :
517 300 : state->packet = parse_packet_talloc(
518 150 : state, (char *)state->buf, received, state->type,
519 150 : addr.u.in.sin_addr, addr.u.in.sin_port);
520 150 : if (state->packet == NULL) {
521 0 : DEBUG(10, ("parse_packet failed\n"));
522 0 : goto retry;
523 : }
524 300 : if ((state->trn_id != -1) &&
525 150 : (state->trn_id != packet_trn_id(state->packet))) {
526 0 : DEBUG(10, ("Expected transaction id %d, got %d\n",
527 : state->trn_id, packet_trn_id(state->packet)));
528 0 : goto retry;
529 : }
530 :
531 245 : if ((state->validator != NULL) &&
532 150 : !state->validator(state->packet, state->private_data)) {
533 10 : DEBUG(10, ("validator failed\n"));
534 10 : goto retry;
535 : }
536 :
537 140 : tevent_req_done(req);
538 140 : return;
539 :
540 10 : retry:
541 10 : TALLOC_FREE(state->packet);
542 10 : TALLOC_FREE(state->buf);
543 10 : TALLOC_FREE(state->addr);
544 :
545 10 : state->socket_req = tdgram_recvfrom_send(state, state->ev, state->sock);
546 10 : if (tevent_req_nomem(state->socket_req, req)) {
547 0 : return;
548 : }
549 10 : tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
550 : req);
551 : }
552 :
553 140 : static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
554 : TALLOC_CTX *mem_ctx,
555 : struct packet_struct **ppacket)
556 : {
557 140 : struct sock_packet_read_state *state = tevent_req_data(
558 : req, struct sock_packet_read_state);
559 : NTSTATUS status;
560 :
561 140 : if (tevent_req_is_nterror(req, &status)) {
562 0 : return status;
563 : }
564 140 : *ppacket = talloc_move(mem_ctx, &state->packet);
565 140 : return NT_STATUS_OK;
566 : }
567 :
568 : struct nb_trans_state {
569 : struct tevent_context *ev;
570 : struct tdgram_context *sock;
571 : struct nb_packet_reader *reader;
572 :
573 : struct tsocket_address *src_addr;
574 : struct tsocket_address *dst_addr;
575 : uint8_t *buf;
576 : size_t buflen;
577 : enum packet_type type;
578 : int trn_id;
579 :
580 : bool (*validator)(struct packet_struct *p,
581 : void *private_data);
582 : void *private_data;
583 :
584 : struct packet_struct *packet;
585 : };
586 :
587 : static void nb_trans_got_reader(struct tevent_req *subreq);
588 : static void nb_trans_done(struct tevent_req *subreq);
589 : static void nb_trans_sent(struct tevent_req *subreq);
590 : static void nb_trans_send_next(struct tevent_req *subreq);
591 :
592 268 : static struct tevent_req *nb_trans_send(
593 : TALLOC_CTX *mem_ctx,
594 : struct tevent_context *ev,
595 : const struct samba_sockaddr *_my_addr,
596 : const struct samba_sockaddr *_dst_addr,
597 : bool bcast,
598 : uint8_t *buf, size_t buflen,
599 : enum packet_type type, int trn_id,
600 : bool (*validator)(struct packet_struct *p,
601 : void *private_data),
602 : void *private_data)
603 : {
604 268 : const struct sockaddr *my_addr = &_my_addr->u.sa;
605 268 : size_t my_addr_len = sizeof(_my_addr->u.in); /*We know it's AF_INET.*/
606 268 : const struct sockaddr *dst_addr = &_dst_addr->u.sa;
607 268 : size_t dst_addr_len = sizeof(_dst_addr->u.in); /*We know it's AF_INET.*/
608 : struct tevent_req *req, *subreq;
609 : struct nb_trans_state *state;
610 : int ret;
611 :
612 268 : req = tevent_req_create(mem_ctx, &state, struct nb_trans_state);
613 268 : if (req == NULL) {
614 0 : return NULL;
615 : }
616 268 : state->ev = ev;
617 268 : state->buf = buf;
618 268 : state->buflen = buflen;
619 268 : state->type = type;
620 268 : state->trn_id = trn_id;
621 268 : state->validator = validator;
622 268 : state->private_data = private_data;
623 :
624 268 : ret = tsocket_address_bsd_from_sockaddr(state,
625 : my_addr, my_addr_len,
626 : &state->src_addr);
627 268 : if (ret == -1) {
628 0 : tevent_req_nterror(req, map_nt_error_from_unix(errno));
629 0 : return tevent_req_post(req, ev);
630 : }
631 :
632 268 : ret = tsocket_address_bsd_from_sockaddr(state,
633 : dst_addr, dst_addr_len,
634 : &state->dst_addr);
635 268 : if (ret == -1) {
636 0 : tevent_req_nterror(req, map_nt_error_from_unix(errno));
637 0 : return tevent_req_post(req, ev);
638 : }
639 :
640 268 : ret = tdgram_inet_udp_broadcast_socket(state->src_addr, state,
641 : &state->sock);
642 268 : if (ret == -1) {
643 0 : tevent_req_nterror(req, map_nt_error_from_unix(errno));
644 0 : return tevent_req_post(req, ev);
645 : }
646 :
647 268 : subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL);
648 268 : if (tevent_req_nomem(subreq, req)) {
649 0 : return tevent_req_post(req, ev);
650 : }
651 268 : tevent_req_set_callback(subreq, nb_trans_got_reader, req);
652 268 : return req;
653 : }
654 :
655 268 : static void nb_trans_got_reader(struct tevent_req *subreq)
656 : {
657 268 : struct tevent_req *req = tevent_req_callback_data(
658 : subreq, struct tevent_req);
659 268 : struct nb_trans_state *state = tevent_req_data(
660 : req, struct nb_trans_state);
661 : NTSTATUS status;
662 :
663 268 : status = nb_packet_reader_recv(subreq, state, &state->reader);
664 268 : TALLOC_FREE(subreq);
665 :
666 268 : if (!NT_STATUS_IS_OK(status)) {
667 99 : DEBUG(10, ("nmbd not around\n"));
668 99 : state->reader = NULL;
669 : }
670 :
671 268 : subreq = sock_packet_read_send(
672 : state, state->ev, state->sock,
673 : state->reader, state->type, state->trn_id,
674 : state->validator, state->private_data);
675 268 : if (tevent_req_nomem(subreq, req)) {
676 0 : return;
677 : }
678 268 : tevent_req_set_callback(subreq, nb_trans_done, req);
679 :
680 442 : subreq = tdgram_sendto_send(state, state->ev,
681 : state->sock,
682 268 : state->buf, state->buflen,
683 268 : state->dst_addr);
684 268 : if (tevent_req_nomem(subreq, req)) {
685 0 : return;
686 : }
687 268 : tevent_req_set_callback(subreq, nb_trans_sent, req);
688 : }
689 :
690 268 : static void nb_trans_sent(struct tevent_req *subreq)
691 : {
692 268 : struct tevent_req *req = tevent_req_callback_data(
693 : subreq, struct tevent_req);
694 268 : struct nb_trans_state *state = tevent_req_data(
695 : req, struct nb_trans_state);
696 : ssize_t sent;
697 : int err;
698 :
699 268 : sent = tdgram_sendto_recv(subreq, &err);
700 268 : TALLOC_FREE(subreq);
701 268 : if (sent == -1) {
702 24 : DEBUG(10, ("sendto failed: %s\n", strerror(err)));
703 24 : tevent_req_nterror(req, map_nt_error_from_unix(err));
704 24 : return;
705 : }
706 244 : subreq = tevent_wakeup_send(state, state->ev,
707 : timeval_current_ofs(1, 0));
708 244 : if (tevent_req_nomem(subreq, req)) {
709 0 : return;
710 : }
711 244 : tevent_req_set_callback(subreq, nb_trans_send_next, req);
712 : }
713 :
714 0 : static void nb_trans_send_next(struct tevent_req *subreq)
715 : {
716 0 : struct tevent_req *req = tevent_req_callback_data(
717 : subreq, struct tevent_req);
718 0 : struct nb_trans_state *state = tevent_req_data(
719 : req, struct nb_trans_state);
720 : bool ret;
721 :
722 0 : ret = tevent_wakeup_recv(subreq);
723 0 : TALLOC_FREE(subreq);
724 0 : if (!ret) {
725 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
726 0 : return;
727 : }
728 0 : subreq = tdgram_sendto_send(state, state->ev,
729 : state->sock,
730 0 : state->buf, state->buflen,
731 0 : state->dst_addr);
732 0 : if (tevent_req_nomem(subreq, req)) {
733 0 : return;
734 : }
735 0 : tevent_req_set_callback(subreq, nb_trans_sent, req);
736 : }
737 :
738 140 : static void nb_trans_done(struct tevent_req *subreq)
739 : {
740 140 : struct tevent_req *req = tevent_req_callback_data(
741 : subreq, struct tevent_req);
742 140 : struct nb_trans_state *state = tevent_req_data(
743 : req, struct nb_trans_state);
744 : NTSTATUS status;
745 :
746 140 : status = sock_packet_read_recv(subreq, state, &state->packet);
747 140 : TALLOC_FREE(subreq);
748 140 : if (tevent_req_nterror(req, status)) {
749 0 : return;
750 : }
751 140 : tevent_req_done(req);
752 : }
753 :
754 164 : static NTSTATUS nb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
755 : struct packet_struct **ppacket)
756 : {
757 164 : struct nb_trans_state *state = tevent_req_data(
758 : req, struct nb_trans_state);
759 : NTSTATUS status;
760 :
761 164 : if (tevent_req_is_nterror(req, &status)) {
762 24 : return status;
763 : }
764 140 : *ppacket = talloc_move(mem_ctx, &state->packet);
765 140 : return NT_STATUS_OK;
766 : }
767 :
768 : /****************************************************************************
769 : Do a NBT node status query on an open socket and return an array of
770 : structures holding the returned names or NULL if the query failed.
771 : **************************************************************************/
772 :
773 : struct node_status_query_state {
774 : struct samba_sockaddr my_addr;
775 : struct samba_sockaddr addr;
776 : uint8_t buf[1024];
777 : ssize_t buflen;
778 : struct packet_struct *packet;
779 : };
780 :
781 : static bool node_status_query_validator(struct packet_struct *p,
782 : void *private_data);
783 : static void node_status_query_done(struct tevent_req *subreq);
784 :
785 8 : struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
786 : struct tevent_context *ev,
787 : struct nmb_name *name,
788 : const struct sockaddr_storage *addr)
789 : {
790 : struct tevent_req *req, *subreq;
791 : struct node_status_query_state *state;
792 : struct packet_struct p;
793 8 : struct nmb_packet *nmb = &p.packet.nmb;
794 : bool ok;
795 :
796 8 : req = tevent_req_create(mem_ctx, &state,
797 : struct node_status_query_state);
798 8 : if (req == NULL) {
799 0 : return NULL;
800 : }
801 :
802 8 : if (addr->ss_family != AF_INET) {
803 : /* Can't do node status to IPv6 */
804 0 : tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
805 0 : return tevent_req_post(req, ev);
806 : }
807 :
808 8 : ok = sockaddr_storage_to_samba_sockaddr(&state->addr, addr);
809 8 : if (!ok) {
810 : /* node status must be IPv4 */
811 0 : tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
812 0 : return tevent_req_post(req, ev);
813 : }
814 8 : state->addr.u.in.sin_port = htons(NMB_PORT);
815 :
816 8 : set_socket_addr_v4(&state->my_addr);
817 :
818 8 : ZERO_STRUCT(p);
819 8 : nmb->header.name_trn_id = generate_trn_id();
820 8 : nmb->header.opcode = 0;
821 8 : nmb->header.response = false;
822 8 : nmb->header.nm_flags.bcast = false;
823 8 : nmb->header.nm_flags.recursion_available = false;
824 8 : nmb->header.nm_flags.recursion_desired = false;
825 8 : nmb->header.nm_flags.trunc = false;
826 8 : nmb->header.nm_flags.authoritative = false;
827 8 : nmb->header.rcode = 0;
828 8 : nmb->header.qdcount = 1;
829 8 : nmb->header.ancount = 0;
830 8 : nmb->header.nscount = 0;
831 8 : nmb->header.arcount = 0;
832 8 : nmb->question.question_name = *name;
833 8 : nmb->question.question_type = 0x21;
834 8 : nmb->question.question_class = 0x1;
835 :
836 8 : state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
837 : &p);
838 8 : if (state->buflen == 0) {
839 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
840 0 : DEBUG(10, ("build_packet failed\n"));
841 0 : return tevent_req_post(req, ev);
842 : }
843 :
844 20 : subreq = nb_trans_send(state,
845 : ev,
846 8 : &state->my_addr,
847 8 : &state->addr,
848 : false,
849 8 : state->buf,
850 8 : state->buflen,
851 : NMB_PACKET,
852 : nmb->header.name_trn_id,
853 : node_status_query_validator,
854 : NULL);
855 8 : if (tevent_req_nomem(subreq, req)) {
856 0 : DEBUG(10, ("nb_trans_send failed\n"));
857 0 : return tevent_req_post(req, ev);
858 : }
859 8 : if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(10, 0))) {
860 0 : return tevent_req_post(req, ev);
861 : }
862 8 : tevent_req_set_callback(subreq, node_status_query_done, req);
863 8 : return req;
864 : }
865 :
866 8 : static bool node_status_query_validator(struct packet_struct *p,
867 : void *private_data)
868 : {
869 8 : struct nmb_packet *nmb = &p->packet.nmb;
870 8 : debug_nmb_packet(p);
871 :
872 14 : if (nmb->header.opcode != 0 ||
873 14 : nmb->header.nm_flags.bcast ||
874 14 : nmb->header.rcode ||
875 14 : !nmb->header.ancount ||
876 8 : nmb->answers->rr_type != 0x21) {
877 : /*
878 : * XXXX what do we do with this? could be a redirect,
879 : * but we'll discard it for the moment
880 : */
881 0 : return false;
882 : }
883 8 : return true;
884 : }
885 :
886 8 : static void node_status_query_done(struct tevent_req *subreq)
887 : {
888 8 : struct tevent_req *req = tevent_req_callback_data(
889 : subreq, struct tevent_req);
890 8 : struct node_status_query_state *state = tevent_req_data(
891 : req, struct node_status_query_state);
892 : NTSTATUS status;
893 :
894 8 : status = nb_trans_recv(subreq, state, &state->packet);
895 8 : TALLOC_FREE(subreq);
896 8 : if (tevent_req_nterror(req, status)) {
897 0 : return;
898 : }
899 8 : tevent_req_done(req);
900 : }
901 :
902 8 : NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
903 : struct node_status **pnode_status,
904 : size_t *pnum_names,
905 : struct node_status_extra *extra)
906 : {
907 8 : struct node_status_query_state *state = tevent_req_data(
908 : req, struct node_status_query_state);
909 : struct node_status *node_status;
910 8 : size_t num_names = 0;
911 : NTSTATUS status;
912 :
913 8 : if (tevent_req_is_nterror(req, &status)) {
914 0 : return status;
915 : }
916 8 : node_status = parse_node_status(
917 8 : mem_ctx, &state->packet->packet.nmb.answers->rdata[0],
918 : &num_names, extra);
919 8 : if (node_status == NULL) {
920 0 : return NT_STATUS_NO_MEMORY;
921 : }
922 8 : *pnode_status = node_status;
923 8 : *pnum_names = num_names;
924 8 : return NT_STATUS_OK;
925 : }
926 :
927 3 : NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name,
928 : const struct sockaddr_storage *addr,
929 : struct node_status **pnode_status,
930 : size_t *pnum_names,
931 : struct node_status_extra *extra)
932 : {
933 3 : TALLOC_CTX *frame = talloc_stackframe();
934 : struct tevent_context *ev;
935 : struct tevent_req *req;
936 3 : NTSTATUS status = NT_STATUS_NO_MEMORY;
937 :
938 3 : ev = samba_tevent_context_init(frame);
939 3 : if (ev == NULL) {
940 0 : goto fail;
941 : }
942 3 : req = node_status_query_send(ev, ev, name, addr);
943 3 : if (req == NULL) {
944 0 : goto fail;
945 : }
946 3 : if (!tevent_req_poll_ntstatus(req, ev, &status)) {
947 0 : goto fail;
948 : }
949 3 : status = node_status_query_recv(req, mem_ctx, pnode_status,
950 : pnum_names, extra);
951 3 : fail:
952 3 : TALLOC_FREE(frame);
953 3 : return status;
954 : }
955 :
956 3 : static bool name_status_lmhosts(const struct sockaddr_storage *paddr,
957 : int qname_type, fstring pname)
958 : {
959 : FILE *f;
960 : char *name;
961 : int name_type;
962 3 : struct samba_sockaddr addr_in = {0};
963 3 : struct samba_sockaddr addr = {0};
964 : bool ok;
965 :
966 3 : ok = sockaddr_storage_to_samba_sockaddr(&addr_in, paddr);
967 3 : if (!ok) {
968 0 : return false;
969 : }
970 3 : if (addr_in.u.ss.ss_family != AF_INET) {
971 0 : return false;
972 : }
973 :
974 3 : f = startlmhosts(get_dyn_LMHOSTSFILE());
975 3 : if (f == NULL) {
976 3 : return false;
977 : }
978 :
979 0 : while (getlmhostsent(talloc_tos(), f, &name, &name_type, &addr.u.ss)) {
980 0 : if (addr.u.ss.ss_family != AF_INET) {
981 0 : continue;
982 : }
983 0 : if (name_type != qname_type) {
984 0 : continue;
985 : }
986 0 : if (sockaddr_equal(&addr_in.u.sa, &addr.u.sa)) {
987 0 : fstrcpy(pname, name);
988 0 : endlmhosts(f);
989 0 : return true;
990 : }
991 : }
992 0 : endlmhosts(f);
993 0 : return false;
994 : }
995 :
996 : /****************************************************************************
997 : Find the first type XX name in a node status reply - used for finding
998 : a servers name given its IP. Return the matched name in *name.
999 : **************************************************************************/
1000 :
1001 3 : bool name_status_find(const char *q_name,
1002 : int q_type,
1003 : int type,
1004 : const struct sockaddr_storage *to_ss,
1005 : fstring name)
1006 : {
1007 : char addr[INET6_ADDRSTRLEN];
1008 3 : struct node_status *addrs = NULL;
1009 : struct nmb_name nname;
1010 3 : size_t count = 0, i;
1011 3 : bool result = false;
1012 : NTSTATUS status;
1013 :
1014 3 : if (lp_disable_netbios()) {
1015 0 : DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
1016 : q_name, q_type));
1017 0 : return False;
1018 : }
1019 :
1020 3 : print_sockaddr(addr, sizeof(addr), to_ss);
1021 :
1022 3 : DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
1023 : q_type, addr));
1024 :
1025 : /* Check the cache first. */
1026 :
1027 3 : if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
1028 0 : return True;
1029 : }
1030 :
1031 3 : if (to_ss->ss_family != AF_INET) {
1032 : /* Can't do node status to IPv6 */
1033 0 : return false;
1034 : }
1035 :
1036 3 : result = name_status_lmhosts(to_ss, type, name);
1037 3 : if (result) {
1038 0 : DBG_DEBUG("Found name %s in lmhosts\n", name);
1039 0 : namecache_status_store(q_name, q_type, type, to_ss, name);
1040 0 : return true;
1041 : }
1042 :
1043 : /* W2K PDC's seem not to respond to '*'#0. JRA */
1044 3 : make_nmb_name(&nname, q_name, q_type);
1045 3 : status = node_status_query(talloc_tos(), &nname, to_ss,
1046 : &addrs, &count, NULL);
1047 3 : if (!NT_STATUS_IS_OK(status)) {
1048 0 : goto done;
1049 : }
1050 :
1051 9 : for (i=0;i<count;i++) {
1052 : /* Find first one of the requested type that's not a GROUP. */
1053 9 : if (addrs[i].type == type && ! (addrs[i].flags & 0x80))
1054 3 : break;
1055 : }
1056 3 : if (i == count)
1057 0 : goto done;
1058 :
1059 3 : pull_ascii_nstring(name, sizeof(fstring), addrs[i].name);
1060 :
1061 : /* Store the result in the cache. */
1062 : /* but don't store an entry for 0x1c names here. Here we have
1063 : a single host and DOMAIN<0x1c> names should be a list of hosts */
1064 :
1065 3 : if ( q_type != 0x1c ) {
1066 0 : namecache_status_store(q_name, q_type, type, to_ss, name);
1067 : }
1068 :
1069 3 : result = true;
1070 :
1071 3 : done:
1072 3 : TALLOC_FREE(addrs);
1073 :
1074 3 : DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
1075 :
1076 3 : if (result)
1077 3 : DEBUGADD(10, (", name %s ip address is %s", name, addr));
1078 :
1079 3 : DEBUG(10, ("\n"));
1080 :
1081 3 : return result;
1082 : }
1083 :
1084 : /*
1085 : comparison function used by sort_addr_list
1086 : */
1087 :
1088 11 : static int addr_compare(const struct sockaddr_storage *ss1,
1089 : const struct sockaddr_storage *ss2)
1090 : {
1091 11 : int max_bits1=0, max_bits2=0;
1092 11 : int num_interfaces = iface_count();
1093 : int i;
1094 : struct samba_sockaddr sa1;
1095 : struct samba_sockaddr sa2;
1096 : bool ok;
1097 :
1098 11 : ok = sockaddr_storage_to_samba_sockaddr(&sa1, ss1);
1099 11 : if (!ok) {
1100 0 : return 0; /* No change. */
1101 : }
1102 :
1103 11 : ok = sockaddr_storage_to_samba_sockaddr(&sa2, ss2);
1104 11 : if (!ok) {
1105 0 : return 0; /* No change. */
1106 : }
1107 :
1108 : /* Sort IPv4 addresses first. */
1109 11 : if (sa1.u.ss.ss_family != sa2.u.ss.ss_family) {
1110 0 : if (sa2.u.ss.ss_family == AF_INET) {
1111 0 : return 1;
1112 : } else {
1113 0 : return -1;
1114 : }
1115 : }
1116 :
1117 : /* Here we know both addresses are of the same
1118 : * family. */
1119 :
1120 33 : for (i=0;i<num_interfaces;i++) {
1121 22 : struct samba_sockaddr sif = {0};
1122 22 : const unsigned char *p_ss1 = NULL;
1123 22 : const unsigned char *p_ss2 = NULL;
1124 22 : const unsigned char *p_if = NULL;
1125 22 : size_t len = 0;
1126 : int bits1, bits2;
1127 :
1128 22 : ok = sockaddr_storage_to_samba_sockaddr(&sif, iface_n_bcast(i));
1129 22 : if (!ok) {
1130 0 : return 0; /* No change. */
1131 : }
1132 22 : if (sif.u.ss.ss_family != sa1.u.ss.ss_family) {
1133 : /* Ignore interfaces of the wrong type. */
1134 14 : continue;
1135 : }
1136 11 : if (sif.u.ss.ss_family == AF_INET) {
1137 11 : p_if = (const unsigned char *)&sif.u.in.sin_addr;
1138 11 : p_ss1 = (const unsigned char *)&sa1.u.in.sin_addr;
1139 11 : p_ss2 = (const unsigned char *)&sa2.u.in.sin_addr;
1140 11 : len = 4;
1141 : }
1142 : #if defined(HAVE_IPV6)
1143 11 : if (sif.u.ss.ss_family == AF_INET6) {
1144 0 : p_if = (const unsigned char *)&sif.u.in6.sin6_addr;
1145 0 : p_ss1 = (const unsigned char *)&sa1.u.in6.sin6_addr;
1146 0 : p_ss2 = (const unsigned char *)&sa2.u.in6.sin6_addr;
1147 0 : len = 16;
1148 : }
1149 : #endif
1150 11 : if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
1151 0 : continue;
1152 : }
1153 11 : bits1 = matching_len_bits(p_ss1, p_if, len);
1154 11 : bits2 = matching_len_bits(p_ss2, p_if, len);
1155 11 : max_bits1 = MAX(bits1, max_bits1);
1156 11 : max_bits2 = MAX(bits2, max_bits2);
1157 : }
1158 :
1159 : /* Bias towards directly reachable IPs */
1160 11 : if (iface_local(&sa1.u.sa)) {
1161 11 : if (sa1.u.ss.ss_family == AF_INET) {
1162 11 : max_bits1 += 32;
1163 : } else {
1164 0 : max_bits1 += 128;
1165 : }
1166 : }
1167 11 : if (iface_local(&sa2.u.sa)) {
1168 11 : if (sa2.u.ss.ss_family == AF_INET) {
1169 11 : max_bits2 += 32;
1170 : } else {
1171 0 : max_bits2 += 128;
1172 : }
1173 : }
1174 11 : return max_bits2 - max_bits1;
1175 : }
1176 :
1177 : /*
1178 : sort an IP list so that names that are close to one of our interfaces
1179 : are at the top. This prevents the problem where a WINS server returns an IP
1180 : that is not reachable from our subnet as the first match
1181 : */
1182 :
1183 135 : static void sort_addr_list(struct sockaddr_storage *sslist, size_t count)
1184 : {
1185 135 : if (count <= 1) {
1186 132 : return;
1187 : }
1188 :
1189 3 : TYPESAFE_QSORT(sslist, count, addr_compare);
1190 : }
1191 :
1192 0 : static int samba_sockaddr_compare(struct samba_sockaddr *sa1,
1193 : struct samba_sockaddr *sa2)
1194 : {
1195 0 : return addr_compare(&sa1->u.ss, &sa2->u.ss);
1196 : }
1197 :
1198 0 : static void sort_sa_list(struct samba_sockaddr *salist, size_t count)
1199 : {
1200 0 : if (count <= 1) {
1201 0 : return;
1202 : }
1203 :
1204 0 : TYPESAFE_QSORT(salist, count, samba_sockaddr_compare);
1205 : }
1206 :
1207 : /**********************************************************************
1208 : Remove any duplicate address/port pairs in the samba_sockaddr array.
1209 : *********************************************************************/
1210 :
1211 1991 : size_t remove_duplicate_addrs2(struct samba_sockaddr *salist, size_t count )
1212 : {
1213 : size_t i, j;
1214 :
1215 1991 : DBG_DEBUG("looking for duplicate address/port pairs\n");
1216 :
1217 : /* One loop to set duplicates to a zero addr. */
1218 5778 : for (i=0; i < count; i++) {
1219 3787 : if (is_zero_addr(&salist[i].u.ss)) {
1220 102 : continue;
1221 : }
1222 :
1223 5481 : for (j=i+1; j<count; j++) {
1224 1796 : if (sockaddr_equal(&salist[i].u.sa, &salist[j].u.sa)) {
1225 102 : zero_sockaddr(&salist[j].u.ss);
1226 : }
1227 : }
1228 : }
1229 :
1230 : /* Now remove any addresses set to zero above. */
1231 5760 : for (i = 0; i < count; i++) {
1232 10335 : while (i < count &&
1233 3787 : is_zero_addr(&salist[i].u.ss)) {
1234 102 : ARRAY_DEL_ELEMENT(salist, i, count);
1235 102 : count--;
1236 : }
1237 : }
1238 :
1239 1991 : return count;
1240 : }
1241 :
1242 188 : static bool prioritize_ipv4_list(struct samba_sockaddr *salist, size_t count)
1243 : {
1244 188 : TALLOC_CTX *frame = talloc_stackframe();
1245 188 : struct samba_sockaddr *salist_new = talloc_array(frame,
1246 : struct samba_sockaddr,
1247 : count);
1248 : size_t i, j;
1249 :
1250 188 : if (salist_new == NULL) {
1251 0 : TALLOC_FREE(frame);
1252 0 : return false;
1253 : }
1254 :
1255 188 : j = 0;
1256 :
1257 : /* Copy IPv4 first. */
1258 413 : for (i = 0; i < count; i++) {
1259 225 : if (salist[i].u.ss.ss_family == AF_INET) {
1260 188 : salist_new[j++] = salist[i];
1261 : }
1262 : }
1263 :
1264 : /* Copy IPv6. */
1265 413 : for (i = 0; i < count; i++) {
1266 225 : if (salist[i].u.ss.ss_family != AF_INET) {
1267 37 : salist_new[j++] = salist[i];
1268 : }
1269 : }
1270 :
1271 188 : memcpy(salist, salist_new, sizeof(struct samba_sockaddr)*count);
1272 188 : TALLOC_FREE(frame);
1273 188 : return true;
1274 : }
1275 :
1276 : /****************************************************************************
1277 : Do a netbios name query to find someones IP.
1278 : Returns an array of IP addresses or NULL if none.
1279 : *count will be set to the number of addresses returned.
1280 : *timed_out is set if we failed by timing out
1281 : ****************************************************************************/
1282 :
1283 : struct name_query_state {
1284 : struct samba_sockaddr my_addr;
1285 : struct samba_sockaddr addr;
1286 : bool bcast;
1287 : bool bcast_star_query;
1288 :
1289 :
1290 : uint8_t buf[1024];
1291 : ssize_t buflen;
1292 :
1293 : NTSTATUS validate_error;
1294 : uint8_t flags;
1295 :
1296 : struct sockaddr_storage *addrs;
1297 : size_t num_addrs;
1298 : };
1299 :
1300 : static bool name_query_validator(struct packet_struct *p, void *private_data);
1301 : static void name_query_done(struct tevent_req *subreq);
1302 :
1303 260 : struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
1304 : struct tevent_context *ev,
1305 : const char *name, int name_type,
1306 : bool bcast, bool recurse,
1307 : const struct sockaddr_storage *addr)
1308 : {
1309 : struct tevent_req *req, *subreq;
1310 : struct name_query_state *state;
1311 : struct packet_struct p;
1312 260 : struct nmb_packet *nmb = &p.packet.nmb;
1313 : bool ok;
1314 :
1315 260 : req = tevent_req_create(mem_ctx, &state, struct name_query_state);
1316 260 : if (req == NULL) {
1317 0 : return NULL;
1318 : }
1319 260 : state->bcast = bcast;
1320 :
1321 260 : if (addr->ss_family != AF_INET) {
1322 : /* Can't do node status to IPv6 */
1323 0 : tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
1324 0 : return tevent_req_post(req, ev);
1325 : }
1326 :
1327 260 : if (lp_disable_netbios()) {
1328 0 : DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
1329 : name, name_type));
1330 0 : tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
1331 0 : return tevent_req_post(req, ev);
1332 : }
1333 :
1334 260 : ok = sockaddr_storage_to_samba_sockaddr(&state->addr, addr);
1335 260 : if (!ok) {
1336 : /* Node status must be IPv4 */
1337 0 : tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
1338 0 : return tevent_req_post(req, ev);
1339 : }
1340 260 : state->addr.u.in.sin_port = htons(NMB_PORT);
1341 :
1342 260 : set_socket_addr_v4(&state->my_addr);
1343 :
1344 260 : ZERO_STRUCT(p);
1345 260 : nmb->header.name_trn_id = generate_trn_id();
1346 260 : nmb->header.opcode = 0;
1347 260 : nmb->header.response = false;
1348 260 : nmb->header.nm_flags.bcast = bcast;
1349 260 : nmb->header.nm_flags.recursion_available = false;
1350 260 : nmb->header.nm_flags.recursion_desired = recurse;
1351 260 : nmb->header.nm_flags.trunc = false;
1352 260 : nmb->header.nm_flags.authoritative = false;
1353 260 : nmb->header.rcode = 0;
1354 260 : nmb->header.qdcount = 1;
1355 260 : nmb->header.ancount = 0;
1356 260 : nmb->header.nscount = 0;
1357 260 : nmb->header.arcount = 0;
1358 :
1359 260 : if (bcast && (strcmp(name, "*")==0)) {
1360 : /*
1361 : * We're doing a broadcast query for all
1362 : * names in the area. Remember this so
1363 : * we will wait for all names within
1364 : * the timeout period.
1365 : */
1366 0 : state->bcast_star_query = true;
1367 : }
1368 :
1369 260 : make_nmb_name(&nmb->question.question_name,name,name_type);
1370 :
1371 260 : nmb->question.question_type = 0x20;
1372 260 : nmb->question.question_class = 0x1;
1373 :
1374 260 : state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
1375 : &p);
1376 260 : if (state->buflen == 0) {
1377 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1378 0 : DEBUG(10, ("build_packet failed\n"));
1379 0 : return tevent_req_post(req, ev);
1380 : }
1381 :
1382 764 : subreq = nb_trans_send(state,
1383 : ev,
1384 260 : &state->my_addr,
1385 260 : &state->addr,
1386 : bcast,
1387 260 : state->buf,
1388 260 : state->buflen,
1389 : NMB_PACKET,
1390 : nmb->header.name_trn_id,
1391 : name_query_validator,
1392 : state);
1393 260 : if (tevent_req_nomem(subreq, req)) {
1394 0 : DEBUG(10, ("nb_trans_send failed\n"));
1395 0 : return tevent_req_post(req, ev);
1396 : }
1397 260 : tevent_req_set_callback(subreq, name_query_done, req);
1398 260 : return req;
1399 : }
1400 :
1401 142 : static bool name_query_validator(struct packet_struct *p, void *private_data)
1402 : {
1403 142 : struct name_query_state *state = talloc_get_type_abort(
1404 : private_data, struct name_query_state);
1405 142 : struct nmb_packet *nmb = &p->packet.nmb;
1406 : struct sockaddr_storage *tmp_addrs;
1407 142 : bool got_unique_netbios_name = false;
1408 : int i;
1409 :
1410 142 : debug_nmb_packet(p);
1411 :
1412 : /*
1413 : * If we get a Negative Name Query Response from a WINS
1414 : * server, we should report it and give up.
1415 : */
1416 142 : if( 0 == nmb->header.opcode /* A query response */
1417 142 : && !state->bcast /* from a WINS server */
1418 69 : && nmb->header.rcode /* Error returned */
1419 : ) {
1420 :
1421 0 : if( DEBUGLVL( 3 ) ) {
1422 : /* Only executed if DEBUGLEVEL >= 3 */
1423 0 : dbgtext( "Negative name query "
1424 : "response, rcode 0x%02x: ",
1425 : nmb->header.rcode );
1426 0 : switch( nmb->header.rcode ) {
1427 0 : case 0x01:
1428 0 : dbgtext("Request was invalidly formatted.\n");
1429 0 : break;
1430 0 : case 0x02:
1431 0 : dbgtext("Problem with NBNS, cannot process "
1432 : "name.\n");
1433 0 : break;
1434 0 : case 0x03:
1435 0 : dbgtext("The name requested does not "
1436 : "exist.\n");
1437 0 : break;
1438 0 : case 0x04:
1439 0 : dbgtext("Unsupported request error.\n");
1440 0 : break;
1441 0 : case 0x05:
1442 0 : dbgtext("Query refused error.\n");
1443 0 : break;
1444 0 : default:
1445 0 : dbgtext("Unrecognized error code.\n" );
1446 0 : break;
1447 : }
1448 0 : }
1449 :
1450 : /*
1451 : * We accept this packet as valid, but tell the upper
1452 : * layers that it's a negative response.
1453 : */
1454 0 : state->validate_error = NT_STATUS_NOT_FOUND;
1455 0 : return true;
1456 : }
1457 :
1458 231 : if (nmb->header.opcode != 0 ||
1459 231 : nmb->header.nm_flags.bcast ||
1460 231 : nmb->header.rcode ||
1461 142 : !nmb->header.ancount) {
1462 : /*
1463 : * XXXX what do we do with this? Could be a redirect,
1464 : * but we'll discard it for the moment.
1465 : */
1466 0 : return false;
1467 : }
1468 :
1469 142 : tmp_addrs = talloc_realloc(
1470 : state, state->addrs, struct sockaddr_storage,
1471 : state->num_addrs + nmb->answers->rdlength/6);
1472 142 : if (tmp_addrs == NULL) {
1473 0 : state->validate_error = NT_STATUS_NO_MEMORY;
1474 0 : return true;
1475 : }
1476 142 : state->addrs = tmp_addrs;
1477 :
1478 142 : DEBUG(2,("Got a positive name query response "
1479 : "from %s ( ", inet_ntoa(p->ip)));
1480 :
1481 284 : for (i=0; i<nmb->answers->rdlength/6; i++) {
1482 : uint16_t flags;
1483 : struct in_addr ip;
1484 : struct sockaddr_storage addr;
1485 142 : struct samba_sockaddr sa = {0};
1486 : bool ok;
1487 : size_t j;
1488 :
1489 142 : flags = RSVAL(&nmb->answers->rdata[i*6], 0);
1490 142 : got_unique_netbios_name |= ((flags & 0x8000) == 0);
1491 :
1492 142 : putip((char *)&ip,&nmb->answers->rdata[2+i*6]);
1493 142 : in_addr_to_sockaddr_storage(&addr, ip);
1494 :
1495 142 : ok = sockaddr_storage_to_samba_sockaddr(&sa, &addr);
1496 142 : if (!ok) {
1497 0 : continue;
1498 : }
1499 :
1500 142 : if (is_zero_addr(&sa.u.ss)) {
1501 0 : continue;
1502 : }
1503 :
1504 154 : for (j=0; j<state->num_addrs; j++) {
1505 12 : struct samba_sockaddr sa_j = {0};
1506 :
1507 12 : ok = sockaddr_storage_to_samba_sockaddr(&sa_j,
1508 12 : &state->addrs[j]);
1509 12 : if (!ok) {
1510 0 : continue;
1511 : }
1512 12 : if (sockaddr_equal(&sa.u.sa, &sa_j.u.sa)) {
1513 0 : break;
1514 : }
1515 : }
1516 142 : if (j < state->num_addrs) {
1517 : /* Already got it */
1518 0 : continue;
1519 : }
1520 :
1521 142 : DEBUGADD(2,("%s ",inet_ntoa(ip)));
1522 :
1523 142 : state->addrs[state->num_addrs] = addr;
1524 : /* wrap check. */
1525 142 : if (state->num_addrs + 1 < state->num_addrs) {
1526 0 : return false;
1527 : }
1528 142 : state->num_addrs += 1;
1529 : }
1530 142 : DEBUGADD(2,(")\n"));
1531 :
1532 : /* We add the flags back ... */
1533 142 : if (nmb->header.response)
1534 142 : state->flags |= NM_FLAGS_RS;
1535 142 : if (nmb->header.nm_flags.authoritative)
1536 142 : state->flags |= NM_FLAGS_AA;
1537 142 : if (nmb->header.nm_flags.trunc)
1538 0 : state->flags |= NM_FLAGS_TC;
1539 142 : if (nmb->header.nm_flags.recursion_desired)
1540 142 : state->flags |= NM_FLAGS_RD;
1541 142 : if (nmb->header.nm_flags.recursion_available)
1542 142 : state->flags |= NM_FLAGS_RA;
1543 142 : if (nmb->header.nm_flags.bcast)
1544 0 : state->flags |= NM_FLAGS_B;
1545 :
1546 142 : if (state->bcast) {
1547 : /*
1548 : * We have to collect all entries coming in from broadcast
1549 : * queries. If we got a unique name and we are not querying
1550 : * all names registered within broadcast area (query
1551 : * for the name '*', so state->bcast_star_query is set),
1552 : * we're done.
1553 : */
1554 73 : return (got_unique_netbios_name && !state->bcast_star_query);
1555 : }
1556 : /*
1557 : * WINS responses are accepted when they are received
1558 : */
1559 69 : return true;
1560 : }
1561 :
1562 156 : static void name_query_done(struct tevent_req *subreq)
1563 : {
1564 156 : struct tevent_req *req = tevent_req_callback_data(
1565 : subreq, struct tevent_req);
1566 156 : struct name_query_state *state = tevent_req_data(
1567 : req, struct name_query_state);
1568 : NTSTATUS status;
1569 156 : struct packet_struct *p = NULL;
1570 :
1571 156 : status = nb_trans_recv(subreq, state, &p);
1572 156 : TALLOC_FREE(subreq);
1573 156 : if (tevent_req_nterror(req, status)) {
1574 45 : return;
1575 : }
1576 132 : if (!NT_STATUS_IS_OK(state->validate_error)) {
1577 0 : tevent_req_nterror(req, state->validate_error);
1578 0 : return;
1579 : }
1580 132 : tevent_req_done(req);
1581 : }
1582 :
1583 220 : NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1584 : struct sockaddr_storage **addrs, size_t *num_addrs,
1585 : uint8_t *flags)
1586 : {
1587 220 : struct name_query_state *state = tevent_req_data(
1588 : req, struct name_query_state);
1589 : NTSTATUS status;
1590 :
1591 220 : if (tevent_req_is_nterror(req, &status)) {
1592 130 : if (state->bcast &&
1593 64 : NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1594 : /*
1595 : * In the broadcast case we collect replies until the
1596 : * timeout.
1597 : */
1598 64 : status = NT_STATUS_OK;
1599 : }
1600 88 : if (!NT_STATUS_IS_OK(status)) {
1601 24 : return status;
1602 : }
1603 : }
1604 196 : if (state->num_addrs == 0) {
1605 61 : return NT_STATUS_NOT_FOUND;
1606 : }
1607 135 : *addrs = talloc_move(mem_ctx, &state->addrs);
1608 135 : sort_addr_list(*addrs, state->num_addrs);
1609 135 : *num_addrs = state->num_addrs;
1610 135 : if (flags != NULL) {
1611 135 : *flags = state->flags;
1612 : }
1613 135 : return NT_STATUS_OK;
1614 : }
1615 :
1616 69 : NTSTATUS name_query(const char *name, int name_type,
1617 : bool bcast, bool recurse,
1618 : const struct sockaddr_storage *to_ss,
1619 : TALLOC_CTX *mem_ctx,
1620 : struct sockaddr_storage **addrs,
1621 : size_t *num_addrs, uint8_t *flags)
1622 : {
1623 69 : TALLOC_CTX *frame = talloc_stackframe();
1624 : struct tevent_context *ev;
1625 : struct tevent_req *req;
1626 : struct timeval timeout;
1627 69 : NTSTATUS status = NT_STATUS_NO_MEMORY;
1628 :
1629 69 : ev = samba_tevent_context_init(frame);
1630 69 : if (ev == NULL) {
1631 0 : goto fail;
1632 : }
1633 69 : req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss);
1634 69 : if (req == NULL) {
1635 0 : goto fail;
1636 : }
1637 69 : if (bcast) {
1638 0 : timeout = timeval_current_ofs(0, 250000);
1639 : } else {
1640 69 : timeout = timeval_current_ofs(2, 0);
1641 : }
1642 69 : if (!tevent_req_set_endtime(req, ev, timeout)) {
1643 0 : goto fail;
1644 : }
1645 69 : if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1646 0 : goto fail;
1647 : }
1648 69 : status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags);
1649 69 : fail:
1650 69 : TALLOC_FREE(frame);
1651 69 : return status;
1652 : }
1653 :
1654 : struct name_queries_state {
1655 : struct tevent_context *ev;
1656 : const char *name;
1657 : int name_type;
1658 : bool bcast;
1659 : bool recurse;
1660 : const struct sockaddr_storage *addrs;
1661 : size_t num_addrs;
1662 : int wait_msec;
1663 : int timeout_msec;
1664 :
1665 : struct tevent_req **subreqs;
1666 : size_t num_received;
1667 : size_t num_sent;
1668 :
1669 : size_t received_index;
1670 : struct sockaddr_storage *result_addrs;
1671 : size_t num_result_addrs;
1672 : uint8_t flags;
1673 : };
1674 :
1675 : static void name_queries_done(struct tevent_req *subreq);
1676 : static void name_queries_next(struct tevent_req *subreq);
1677 :
1678 : /*
1679 : * Send a name query to multiple destinations with a wait time in between
1680 : */
1681 :
1682 127 : static struct tevent_req *name_queries_send(
1683 : TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1684 : const char *name, int name_type,
1685 : bool bcast, bool recurse,
1686 : const struct sockaddr_storage *addrs,
1687 : size_t num_addrs, int wait_msec, int timeout_msec)
1688 : {
1689 : struct tevent_req *req, *subreq;
1690 : struct name_queries_state *state;
1691 :
1692 127 : req = tevent_req_create(mem_ctx, &state,
1693 : struct name_queries_state);
1694 127 : if (req == NULL) {
1695 0 : return NULL;
1696 : }
1697 127 : state->ev = ev;
1698 127 : state->name = name;
1699 127 : state->name_type = name_type;
1700 127 : state->bcast = bcast;
1701 127 : state->recurse = recurse;
1702 127 : state->addrs = addrs;
1703 127 : state->num_addrs = num_addrs;
1704 127 : state->wait_msec = wait_msec;
1705 127 : state->timeout_msec = timeout_msec;
1706 :
1707 127 : state->subreqs = talloc_zero_array(
1708 : state, struct tevent_req *, num_addrs);
1709 127 : if (tevent_req_nomem(state->subreqs, req)) {
1710 0 : return tevent_req_post(req, ev);
1711 : }
1712 127 : state->num_sent = 0;
1713 :
1714 291 : subreq = name_query_send(
1715 209 : state->subreqs, state->ev, name, name_type, bcast, recurse,
1716 127 : &state->addrs[state->num_sent]);
1717 127 : if (tevent_req_nomem(subreq, req)) {
1718 0 : return tevent_req_post(req, ev);
1719 : }
1720 209 : if (!tevent_req_set_endtime(
1721 127 : subreq, state->ev,
1722 127 : timeval_current_ofs(0, state->timeout_msec * 1000))) {
1723 0 : return tevent_req_post(req, ev);
1724 : }
1725 127 : tevent_req_set_callback(subreq, name_queries_done, req);
1726 :
1727 127 : state->subreqs[state->num_sent] = subreq;
1728 127 : state->num_sent += 1;
1729 :
1730 127 : if (state->num_sent < state->num_addrs) {
1731 16 : subreq = tevent_wakeup_send(
1732 8 : state, state->ev,
1733 8 : timeval_current_ofs(0, state->wait_msec * 1000));
1734 8 : if (tevent_req_nomem(subreq, req)) {
1735 0 : return tevent_req_post(req, ev);
1736 : }
1737 8 : tevent_req_set_callback(subreq, name_queries_next, req);
1738 : }
1739 127 : return req;
1740 : }
1741 :
1742 127 : static void name_queries_done(struct tevent_req *subreq)
1743 : {
1744 127 : struct tevent_req *req = tevent_req_callback_data(
1745 : subreq, struct tevent_req);
1746 127 : struct name_queries_state *state = tevent_req_data(
1747 : req, struct name_queries_state);
1748 : size_t i;
1749 : NTSTATUS status;
1750 :
1751 127 : status = name_query_recv(subreq, state, &state->result_addrs,
1752 : &state->num_result_addrs, &state->flags);
1753 :
1754 127 : for (i=0; i<state->num_sent; i++) {
1755 127 : if (state->subreqs[i] == subreq) {
1756 127 : break;
1757 : }
1758 : }
1759 127 : if (i == state->num_sent) {
1760 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1761 0 : return;
1762 : }
1763 127 : TALLOC_FREE(state->subreqs[i]);
1764 :
1765 : /* wrap check. */
1766 127 : if (state->num_received + 1 < state->num_received) {
1767 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1768 0 : return;
1769 : }
1770 127 : state->num_received += 1;
1771 :
1772 127 : if (!NT_STATUS_IS_OK(status)) {
1773 :
1774 61 : if (state->num_received >= state->num_addrs) {
1775 61 : tevent_req_nterror(req, status);
1776 61 : return;
1777 : }
1778 : /*
1779 : * Still outstanding requests, just wait
1780 : */
1781 0 : return;
1782 : }
1783 66 : state->received_index = i;
1784 66 : tevent_req_done(req);
1785 : }
1786 :
1787 40 : static void name_queries_next(struct tevent_req *subreq)
1788 : {
1789 40 : struct tevent_req *req = tevent_req_callback_data(
1790 : subreq, struct tevent_req);
1791 40 : struct name_queries_state *state = tevent_req_data(
1792 : req, struct name_queries_state);
1793 :
1794 40 : if (!tevent_wakeup_recv(subreq)) {
1795 0 : tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1796 0 : return;
1797 : }
1798 :
1799 100 : subreq = name_query_send(
1800 40 : state->subreqs, state->ev,
1801 60 : state->name, state->name_type, state->bcast, state->recurse,
1802 40 : &state->addrs[state->num_sent]);
1803 40 : if (tevent_req_nomem(subreq, req)) {
1804 0 : return;
1805 : }
1806 40 : tevent_req_set_callback(subreq, name_queries_done, req);
1807 40 : if (!tevent_req_set_endtime(
1808 : subreq, state->ev,
1809 40 : timeval_current_ofs(0, state->timeout_msec * 1000))) {
1810 0 : return;
1811 : }
1812 40 : state->subreqs[state->num_sent] = subreq;
1813 40 : state->num_sent += 1;
1814 :
1815 40 : if (state->num_sent < state->num_addrs) {
1816 32 : subreq = tevent_wakeup_send(
1817 : state, state->ev,
1818 32 : timeval_current_ofs(0, state->wait_msec * 1000));
1819 32 : if (tevent_req_nomem(subreq, req)) {
1820 0 : return;
1821 : }
1822 32 : tevent_req_set_callback(subreq, name_queries_next, req);
1823 : }
1824 : }
1825 :
1826 127 : static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1827 : struct sockaddr_storage **result_addrs,
1828 : size_t *num_result_addrs, uint8_t *flags,
1829 : size_t *received_index)
1830 : {
1831 127 : struct name_queries_state *state = tevent_req_data(
1832 : req, struct name_queries_state);
1833 : NTSTATUS status;
1834 :
1835 127 : if (tevent_req_is_nterror(req, &status)) {
1836 61 : return status;
1837 : }
1838 :
1839 66 : if (result_addrs != NULL) {
1840 66 : *result_addrs = talloc_move(mem_ctx, &state->result_addrs);
1841 : }
1842 66 : if (num_result_addrs != NULL) {
1843 66 : *num_result_addrs = state->num_result_addrs;
1844 : }
1845 66 : if (flags != NULL) {
1846 0 : *flags = state->flags;
1847 : }
1848 66 : if (received_index != NULL) {
1849 0 : *received_index = state->received_index;
1850 : }
1851 66 : return NT_STATUS_OK;
1852 : }
1853 :
1854 : /********************************************************
1855 : Resolve via "bcast" method.
1856 : *********************************************************/
1857 :
1858 : struct name_resolve_bcast_state {
1859 : struct sockaddr_storage *addrs;
1860 : size_t num_addrs;
1861 : };
1862 :
1863 : static void name_resolve_bcast_done(struct tevent_req *subreq);
1864 :
1865 127 : struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx,
1866 : struct tevent_context *ev,
1867 : const char *name,
1868 : int name_type)
1869 : {
1870 : struct tevent_req *req, *subreq;
1871 : struct name_resolve_bcast_state *state;
1872 : struct sockaddr_storage *bcast_addrs;
1873 : size_t i, num_addrs, num_bcast_addrs;
1874 :
1875 127 : req = tevent_req_create(mem_ctx, &state,
1876 : struct name_resolve_bcast_state);
1877 127 : if (req == NULL) {
1878 0 : return NULL;
1879 : }
1880 :
1881 127 : if (lp_disable_netbios()) {
1882 0 : DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n",
1883 : name, name_type));
1884 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1885 0 : return tevent_req_post(req, ev);
1886 : }
1887 :
1888 : /*
1889 : * "bcast" means do a broadcast lookup on all the local interfaces.
1890 : */
1891 :
1892 127 : DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup "
1893 : "for name %s<0x%x>\n", name, name_type));
1894 :
1895 127 : num_addrs = iface_count();
1896 127 : bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs);
1897 127 : if (tevent_req_nomem(bcast_addrs, req)) {
1898 0 : return tevent_req_post(req, ev);
1899 : }
1900 :
1901 : /*
1902 : * Lookup the name on all the interfaces, return on
1903 : * the first successful match.
1904 : */
1905 127 : num_bcast_addrs = 0;
1906 :
1907 421 : for (i=0; i<num_addrs; i++) {
1908 294 : const struct sockaddr_storage *pss = iface_n_bcast(i);
1909 :
1910 294 : if (pss->ss_family != AF_INET) {
1911 127 : continue;
1912 : }
1913 167 : bcast_addrs[num_bcast_addrs] = *pss;
1914 167 : num_bcast_addrs += 1;
1915 : }
1916 :
1917 127 : subreq = name_queries_send(state, ev, name, name_type, true, true,
1918 : bcast_addrs, num_bcast_addrs, 0, 250);
1919 127 : if (tevent_req_nomem(subreq, req)) {
1920 0 : return tevent_req_post(req, ev);
1921 : }
1922 127 : tevent_req_set_callback(subreq, name_resolve_bcast_done, req);
1923 127 : return req;
1924 : }
1925 :
1926 127 : static void name_resolve_bcast_done(struct tevent_req *subreq)
1927 : {
1928 127 : struct tevent_req *req = tevent_req_callback_data(
1929 : subreq, struct tevent_req);
1930 127 : struct name_resolve_bcast_state *state = tevent_req_data(
1931 : req, struct name_resolve_bcast_state);
1932 : NTSTATUS status;
1933 :
1934 127 : status = name_queries_recv(subreq, state,
1935 : &state->addrs, &state->num_addrs,
1936 : NULL, NULL);
1937 127 : TALLOC_FREE(subreq);
1938 127 : if (tevent_req_nterror(req, status)) {
1939 61 : return;
1940 : }
1941 66 : tevent_req_done(req);
1942 : }
1943 :
1944 127 : NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1945 : struct sockaddr_storage **addrs,
1946 : size_t *num_addrs)
1947 : {
1948 127 : struct name_resolve_bcast_state *state = tevent_req_data(
1949 : req, struct name_resolve_bcast_state);
1950 : NTSTATUS status;
1951 :
1952 127 : if (tevent_req_is_nterror(req, &status)) {
1953 61 : return status;
1954 : }
1955 66 : *addrs = talloc_move(mem_ctx, &state->addrs);
1956 66 : *num_addrs = state->num_addrs;
1957 66 : return NT_STATUS_OK;
1958 : }
1959 :
1960 122 : NTSTATUS name_resolve_bcast(TALLOC_CTX *mem_ctx,
1961 : const char *name,
1962 : int name_type,
1963 : struct sockaddr_storage **return_iplist,
1964 : size_t *return_count)
1965 : {
1966 122 : TALLOC_CTX *frame = talloc_stackframe();
1967 : struct tevent_context *ev;
1968 : struct tevent_req *req;
1969 122 : NTSTATUS status = NT_STATUS_NO_MEMORY;
1970 :
1971 122 : ev = samba_tevent_context_init(frame);
1972 122 : if (ev == NULL) {
1973 0 : goto fail;
1974 : }
1975 122 : req = name_resolve_bcast_send(frame, ev, name, name_type);
1976 122 : if (req == NULL) {
1977 0 : goto fail;
1978 : }
1979 122 : if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1980 0 : goto fail;
1981 : }
1982 122 : status = name_resolve_bcast_recv(req, mem_ctx, return_iplist,
1983 : return_count);
1984 122 : fail:
1985 122 : TALLOC_FREE(frame);
1986 122 : return status;
1987 : }
1988 :
1989 : struct query_wins_list_state {
1990 : struct tevent_context *ev;
1991 : const char *name;
1992 : uint8_t name_type;
1993 : struct in_addr *servers;
1994 : size_t num_servers;
1995 : struct sockaddr_storage server;
1996 : size_t num_sent;
1997 :
1998 : struct sockaddr_storage *addrs;
1999 : size_t num_addrs;
2000 : uint8_t flags;
2001 : };
2002 :
2003 : static void query_wins_list_done(struct tevent_req *subreq);
2004 :
2005 : /*
2006 : * Query a list of (replicating) wins servers in sequence, call them
2007 : * dead if they don't reply
2008 : */
2009 :
2010 24 : static struct tevent_req *query_wins_list_send(
2011 : TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2012 : struct in_addr src_ip, const char *name, uint8_t name_type,
2013 : struct in_addr *servers, size_t num_servers)
2014 : {
2015 : struct tevent_req *req, *subreq;
2016 : struct query_wins_list_state *state;
2017 :
2018 24 : req = tevent_req_create(mem_ctx, &state,
2019 : struct query_wins_list_state);
2020 24 : if (req == NULL) {
2021 0 : return NULL;
2022 : }
2023 24 : state->ev = ev;
2024 24 : state->name = name;
2025 24 : state->name_type = name_type;
2026 24 : state->servers = servers;
2027 24 : state->num_servers = num_servers;
2028 :
2029 24 : if (state->num_servers == 0) {
2030 0 : tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2031 0 : return tevent_req_post(req, ev);
2032 : }
2033 :
2034 24 : in_addr_to_sockaddr_storage(
2035 24 : &state->server, state->servers[state->num_sent]);
2036 :
2037 45 : subreq = name_query_send(state, state->ev,
2038 45 : state->name, state->name_type,
2039 24 : false, true, &state->server);
2040 :
2041 24 : if (tevent_req_nomem(subreq, req)) {
2042 0 : return tevent_req_post(req, ev);
2043 : }
2044 :
2045 : /* wrap check */
2046 24 : if (state->num_sent + 1 < state->num_sent) {
2047 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2048 0 : return tevent_req_post(req, ev);
2049 : }
2050 :
2051 24 : state->num_sent += 1;
2052 24 : if (!tevent_req_set_endtime(subreq, state->ev,
2053 : timeval_current_ofs(2, 0))) {
2054 0 : return tevent_req_post(req, ev);
2055 : }
2056 24 : tevent_req_set_callback(subreq, query_wins_list_done, req);
2057 24 : return req;
2058 : }
2059 :
2060 24 : static void query_wins_list_done(struct tevent_req *subreq)
2061 : {
2062 24 : struct tevent_req *req = tevent_req_callback_data(
2063 : subreq, struct tevent_req);
2064 24 : struct query_wins_list_state *state = tevent_req_data(
2065 : req, struct query_wins_list_state);
2066 : NTSTATUS status;
2067 :
2068 24 : status = name_query_recv(subreq, state,
2069 : &state->addrs, &state->num_addrs,
2070 : &state->flags);
2071 24 : TALLOC_FREE(subreq);
2072 24 : if (NT_STATUS_IS_OK(status)) {
2073 0 : tevent_req_done(req);
2074 3 : return;
2075 : }
2076 24 : if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
2077 24 : tevent_req_nterror(req, status);
2078 24 : return;
2079 : }
2080 0 : wins_srv_died(state->servers[state->num_sent-1],
2081 : my_socket_addr_v4());
2082 :
2083 0 : if (state->num_sent == state->num_servers) {
2084 0 : tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2085 0 : return;
2086 : }
2087 :
2088 0 : in_addr_to_sockaddr_storage(
2089 0 : &state->server, state->servers[state->num_sent]);
2090 :
2091 0 : subreq = name_query_send(state, state->ev,
2092 0 : state->name, state->name_type,
2093 0 : false, true, &state->server);
2094 0 : state->num_sent += 1;
2095 0 : if (tevent_req_nomem(subreq, req)) {
2096 0 : return;
2097 : }
2098 0 : if (!tevent_req_set_endtime(subreq, state->ev,
2099 : timeval_current_ofs(2, 0))) {
2100 0 : return;
2101 : }
2102 0 : tevent_req_set_callback(subreq, query_wins_list_done, req);
2103 : }
2104 :
2105 24 : static NTSTATUS query_wins_list_recv(struct tevent_req *req,
2106 : TALLOC_CTX *mem_ctx,
2107 : struct sockaddr_storage **addrs,
2108 : size_t *num_addrs,
2109 : uint8_t *flags)
2110 : {
2111 24 : struct query_wins_list_state *state = tevent_req_data(
2112 : req, struct query_wins_list_state);
2113 : NTSTATUS status;
2114 :
2115 24 : if (tevent_req_is_nterror(req, &status)) {
2116 24 : return status;
2117 : }
2118 0 : if (addrs != NULL) {
2119 0 : *addrs = talloc_move(mem_ctx, &state->addrs);
2120 : }
2121 0 : if (num_addrs != NULL) {
2122 0 : *num_addrs = state->num_addrs;
2123 : }
2124 0 : if (flags != NULL) {
2125 0 : *flags = state->flags;
2126 : }
2127 0 : return NT_STATUS_OK;
2128 : }
2129 :
2130 : struct resolve_wins_state {
2131 : size_t num_sent;
2132 : size_t num_received;
2133 :
2134 : struct sockaddr_storage *addrs;
2135 : size_t num_addrs;
2136 : uint8_t flags;
2137 : };
2138 :
2139 : static void resolve_wins_done(struct tevent_req *subreq);
2140 :
2141 112 : struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
2142 : struct tevent_context *ev,
2143 : const char *name,
2144 : int name_type)
2145 : {
2146 : struct tevent_req *req, *subreq;
2147 : struct resolve_wins_state *state;
2148 112 : char **wins_tags = NULL;
2149 : struct sockaddr_storage src_ss;
2150 112 : struct samba_sockaddr src_sa = {0};
2151 : struct in_addr src_ip;
2152 : size_t i, num_wins_tags;
2153 : bool ok;
2154 :
2155 112 : req = tevent_req_create(mem_ctx, &state,
2156 : struct resolve_wins_state);
2157 112 : if (req == NULL) {
2158 0 : return NULL;
2159 : }
2160 :
2161 112 : if (wins_srv_count() < 1) {
2162 84 : DEBUG(3,("resolve_wins: WINS server resolution selected "
2163 : "and no WINS servers listed.\n"));
2164 84 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2165 84 : goto fail;
2166 : }
2167 :
2168 : /* the address we will be sending from */
2169 28 : if (!interpret_string_addr(&src_ss, lp_nbt_client_socket_address(),
2170 : AI_NUMERICHOST|AI_PASSIVE)) {
2171 0 : zero_sockaddr(&src_ss);
2172 : }
2173 :
2174 28 : ok = sockaddr_storage_to_samba_sockaddr(&src_sa, &src_ss);
2175 28 : if (!ok) {
2176 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2177 0 : goto fail;
2178 : }
2179 :
2180 28 : if (src_sa.u.ss.ss_family != AF_INET) {
2181 : char addr[INET6_ADDRSTRLEN];
2182 0 : print_sockaddr(addr, sizeof(addr), &src_sa.u.ss);
2183 0 : DEBUG(3,("resolve_wins: cannot receive WINS replies "
2184 : "on IPv6 address %s\n",
2185 : addr));
2186 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2187 0 : goto fail;
2188 : }
2189 :
2190 28 : src_ip = src_sa.u.in.sin_addr;
2191 :
2192 28 : wins_tags = wins_srv_tags();
2193 28 : if (wins_tags == NULL) {
2194 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2195 0 : goto fail;
2196 : }
2197 :
2198 28 : num_wins_tags = 0;
2199 81 : while (wins_tags[num_wins_tags] != NULL) {
2200 : /* wrap check. */
2201 28 : if (num_wins_tags + 1 < num_wins_tags) {
2202 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2203 0 : goto fail;
2204 : }
2205 28 : num_wins_tags += 1;
2206 : }
2207 :
2208 56 : for (i=0; i<num_wins_tags; i++) {
2209 : size_t num_servers, num_alive;
2210 : struct in_addr *servers, *alive;
2211 : size_t j;
2212 :
2213 28 : if (!wins_server_tag_ips(wins_tags[i], talloc_tos(),
2214 : &servers, &num_servers)) {
2215 4 : DEBUG(10, ("wins_server_tag_ips failed for tag %s\n",
2216 : wins_tags[i]));
2217 8 : continue;
2218 : }
2219 :
2220 24 : alive = talloc_array(state, struct in_addr, num_servers);
2221 24 : if (tevent_req_nomem(alive, req)) {
2222 0 : goto fail;
2223 : }
2224 :
2225 24 : num_alive = 0;
2226 48 : for (j=0; j<num_servers; j++) {
2227 24 : struct in_addr wins_ip = servers[j];
2228 :
2229 24 : if (global_in_nmbd && ismyip_v4(wins_ip)) {
2230 : /* yikes! we'll loop forever */
2231 0 : continue;
2232 : }
2233 : /* skip any that have been unresponsive lately */
2234 24 : if (wins_srv_is_dead(wins_ip, src_ip)) {
2235 0 : continue;
2236 : }
2237 24 : DEBUG(3, ("resolve_wins: using WINS server %s "
2238 : "and tag '%s'\n",
2239 : inet_ntoa(wins_ip), wins_tags[i]));
2240 24 : alive[num_alive] = wins_ip;
2241 24 : num_alive += 1;
2242 : }
2243 24 : TALLOC_FREE(servers);
2244 :
2245 24 : if (num_alive == 0) {
2246 0 : continue;
2247 : }
2248 :
2249 24 : subreq = query_wins_list_send(
2250 : state, ev, src_ip, name, name_type,
2251 : alive, num_alive);
2252 24 : if (tevent_req_nomem(subreq, req)) {
2253 0 : goto fail;
2254 : }
2255 24 : tevent_req_set_callback(subreq, resolve_wins_done, req);
2256 24 : state->num_sent += 1;
2257 : }
2258 :
2259 28 : if (state->num_sent == 0) {
2260 4 : tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2261 4 : goto fail;
2262 : }
2263 :
2264 24 : wins_srv_tags_free(wins_tags);
2265 24 : return req;
2266 88 : fail:
2267 88 : wins_srv_tags_free(wins_tags);
2268 88 : return tevent_req_post(req, ev);
2269 : }
2270 :
2271 24 : static void resolve_wins_done(struct tevent_req *subreq)
2272 : {
2273 24 : struct tevent_req *req = tevent_req_callback_data(
2274 : subreq, struct tevent_req);
2275 24 : struct resolve_wins_state *state = tevent_req_data(
2276 : req, struct resolve_wins_state);
2277 : NTSTATUS status;
2278 :
2279 24 : status = query_wins_list_recv(subreq, state, &state->addrs,
2280 : &state->num_addrs, &state->flags);
2281 24 : if (NT_STATUS_IS_OK(status)) {
2282 0 : tevent_req_done(req);
2283 0 : return;
2284 : }
2285 :
2286 : /* wrap check. */
2287 24 : if (state->num_received + 1 < state->num_received) {
2288 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2289 0 : return;
2290 : }
2291 :
2292 24 : state->num_received += 1;
2293 :
2294 24 : if (state->num_received < state->num_sent) {
2295 : /*
2296 : * Wait for the others
2297 : */
2298 0 : return;
2299 : }
2300 24 : tevent_req_nterror(req, status);
2301 : }
2302 :
2303 112 : NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2304 : struct sockaddr_storage **addrs,
2305 : size_t *num_addrs, uint8_t *flags)
2306 : {
2307 112 : struct resolve_wins_state *state = tevent_req_data(
2308 : req, struct resolve_wins_state);
2309 : NTSTATUS status;
2310 :
2311 112 : if (tevent_req_is_nterror(req, &status)) {
2312 112 : return status;
2313 : }
2314 0 : if (addrs != NULL) {
2315 0 : *addrs = talloc_move(mem_ctx, &state->addrs);
2316 : }
2317 0 : if (num_addrs != NULL) {
2318 0 : *num_addrs = state->num_addrs;
2319 : }
2320 0 : if (flags != NULL) {
2321 0 : *flags = state->flags;
2322 : }
2323 0 : return NT_STATUS_OK;
2324 : }
2325 :
2326 : /********************************************************
2327 : Resolve via "wins" method.
2328 : *********************************************************/
2329 :
2330 107 : NTSTATUS resolve_wins(TALLOC_CTX *mem_ctx,
2331 : const char *name,
2332 : int name_type,
2333 : struct sockaddr_storage **return_iplist,
2334 : size_t *return_count)
2335 : {
2336 : struct tevent_context *ev;
2337 : struct tevent_req *req;
2338 107 : NTSTATUS status = NT_STATUS_NO_MEMORY;
2339 :
2340 107 : ev = samba_tevent_context_init(talloc_tos());
2341 107 : if (ev == NULL) {
2342 0 : goto fail;
2343 : }
2344 107 : req = resolve_wins_send(ev, ev, name, name_type);
2345 107 : if (req == NULL) {
2346 0 : goto fail;
2347 : }
2348 107 : if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2349 0 : goto fail;
2350 : }
2351 107 : status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count,
2352 : NULL);
2353 107 : fail:
2354 107 : TALLOC_FREE(ev);
2355 107 : return status;
2356 : }
2357 :
2358 :
2359 : /********************************************************
2360 : Resolve via "hosts" method.
2361 : *********************************************************/
2362 :
2363 135 : static NTSTATUS resolve_hosts(TALLOC_CTX *mem_ctx,
2364 : const char *name,
2365 : int name_type,
2366 : struct sockaddr_storage **return_iplist,
2367 : size_t *return_count)
2368 : {
2369 : /*
2370 : * "host" means do a localhost, or dns lookup.
2371 : */
2372 : struct addrinfo hints;
2373 135 : struct addrinfo *ailist = NULL;
2374 135 : struct addrinfo *res = NULL;
2375 135 : int ret = -1;
2376 135 : size_t i = 0;
2377 135 : size_t ret_count = 0;
2378 135 : struct sockaddr_storage *iplist = NULL;
2379 :
2380 135 : if ( name_type != 0x20 && name_type != 0x0) {
2381 8 : DEBUG(5, ("resolve_hosts: not appropriate "
2382 : "for name type <0x%x>\n",
2383 : name_type));
2384 8 : return NT_STATUS_INVALID_PARAMETER;
2385 : }
2386 :
2387 127 : DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
2388 : name, name_type));
2389 :
2390 127 : ZERO_STRUCT(hints);
2391 : /* By default make sure it supports TCP. */
2392 127 : hints.ai_socktype = SOCK_STREAM;
2393 127 : hints.ai_flags = AI_ADDRCONFIG;
2394 :
2395 : #if !defined(HAVE_IPV6)
2396 : /* Unless we have IPv6, we really only want IPv4 addresses back. */
2397 : hints.ai_family = AF_INET;
2398 : #endif
2399 :
2400 127 : ret = getaddrinfo(name,
2401 : NULL,
2402 : &hints,
2403 : &ailist);
2404 127 : if (ret) {
2405 4 : DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
2406 : name,
2407 : gai_strerror(ret) ));
2408 : }
2409 :
2410 373 : for (res = ailist; res; res = res->ai_next) {
2411 246 : struct sockaddr_storage ss = {0};
2412 246 : struct sockaddr_storage *tmp = NULL;
2413 :
2414 402 : if ((res->ai_addr == NULL) ||
2415 402 : (res->ai_addrlen == 0) ||
2416 246 : (res->ai_addrlen > sizeof(ss))) {
2417 0 : continue;
2418 : }
2419 :
2420 246 : memcpy(&ss, res->ai_addr, res->ai_addrlen);
2421 :
2422 246 : if (is_zero_addr(&ss)) {
2423 0 : continue;
2424 : }
2425 :
2426 : /* wrap check. */
2427 246 : if (ret_count + 1 < ret_count) {
2428 0 : freeaddrinfo(ailist);
2429 0 : TALLOC_FREE(iplist);
2430 0 : return NT_STATUS_INVALID_PARAMETER;
2431 : }
2432 246 : ret_count += 1;
2433 :
2434 246 : tmp = talloc_realloc(
2435 : mem_ctx, iplist, struct sockaddr_storage,
2436 : ret_count);
2437 246 : if (tmp == NULL) {
2438 0 : DEBUG(3,("resolve_hosts: malloc fail !\n"));
2439 0 : freeaddrinfo(ailist);
2440 0 : TALLOC_FREE(iplist);
2441 0 : return NT_STATUS_NO_MEMORY;
2442 : }
2443 246 : iplist = tmp;
2444 246 : iplist[i] = ss;
2445 246 : i++;
2446 : }
2447 127 : if (ailist) {
2448 123 : freeaddrinfo(ailist);
2449 : }
2450 127 : if (ret_count == 0) {
2451 4 : return NT_STATUS_UNSUCCESSFUL;
2452 : }
2453 123 : *return_count = ret_count;
2454 123 : *return_iplist = iplist;
2455 123 : return NT_STATUS_OK;
2456 : }
2457 :
2458 : /********************************************************
2459 : Resolve via "ADS" method.
2460 : *********************************************************/
2461 :
2462 : /* Special name type used to cause a _kerberos DNS lookup. */
2463 : #define KDC_NAME_TYPE 0xDCDC
2464 :
2465 27 : static NTSTATUS resolve_ads(TALLOC_CTX *ctx,
2466 : const char *name,
2467 : int name_type,
2468 : const char *sitename,
2469 : struct sockaddr_storage **return_addrs,
2470 : size_t *return_count)
2471 : {
2472 : size_t i;
2473 : NTSTATUS status;
2474 27 : struct dns_rr_srv *dcs = NULL;
2475 27 : size_t numdcs = 0;
2476 27 : size_t num_srv_addrs = 0;
2477 27 : struct sockaddr_storage *srv_addrs = NULL;
2478 27 : char *query = NULL;
2479 :
2480 27 : if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
2481 : (name_type != 0x1b)) {
2482 0 : return NT_STATUS_INVALID_PARAMETER;
2483 : }
2484 :
2485 27 : status = NT_STATUS_OK;
2486 :
2487 27 : switch (name_type) {
2488 0 : case 0x1b:
2489 0 : DEBUG(5,("resolve_ads: Attempting to resolve "
2490 : "PDC for %s using DNS\n", name));
2491 0 : query = ads_dns_query_string_pdc(ctx, name);
2492 0 : break;
2493 :
2494 11 : case 0x1c:
2495 11 : DEBUG(5,("resolve_ads: Attempting to resolve "
2496 : "DCs for %s using DNS\n", name));
2497 11 : query = ads_dns_query_string_dcs(ctx, name);
2498 11 : break;
2499 16 : case KDC_NAME_TYPE:
2500 16 : DEBUG(5,("resolve_ads: Attempting to resolve "
2501 : "KDCs for %s using DNS\n", name));
2502 16 : query = ads_dns_query_string_kdcs(ctx, name);
2503 16 : break;
2504 0 : default:
2505 0 : status = NT_STATUS_INVALID_PARAMETER;
2506 0 : break;
2507 : }
2508 :
2509 27 : if (!NT_STATUS_IS_OK(status)) {
2510 0 : return status;
2511 : }
2512 27 : if (query == NULL) {
2513 0 : return NT_STATUS_NO_MEMORY;
2514 : }
2515 :
2516 27 : DBG_DEBUG("SRV query for %s\n", query);
2517 :
2518 27 : status = ads_dns_query_srv(
2519 : ctx,
2520 : lp_get_async_dns_timeout(),
2521 : sitename,
2522 : query,
2523 : &dcs,
2524 : &numdcs);
2525 27 : if (!NT_STATUS_IS_OK(status)) {
2526 0 : return status;
2527 : }
2528 :
2529 27 : if (numdcs == 0) {
2530 0 : *return_addrs = NULL;
2531 0 : *return_count = 0;
2532 0 : TALLOC_FREE(dcs);
2533 0 : return NT_STATUS_OK;
2534 : }
2535 :
2536 : /* First count the sizes of each array. */
2537 54 : for(i = 0; i < numdcs; i++) {
2538 27 : if (dcs[i].ss_s == NULL) {
2539 : /*
2540 : * Nothing received or timeout in A/AAAA reqs
2541 : */
2542 0 : continue;
2543 : }
2544 :
2545 27 : if (num_srv_addrs + dcs[i].num_ips < num_srv_addrs) {
2546 : /* Wrap check. */
2547 0 : TALLOC_FREE(dcs);
2548 0 : return NT_STATUS_INVALID_PARAMETER;
2549 : }
2550 : /* Add in the number of addresses we got. */
2551 27 : num_srv_addrs += dcs[i].num_ips;
2552 : }
2553 :
2554 : /* Allocate the list of IP addresses we already have. */
2555 27 : srv_addrs = talloc_zero_array(ctx,
2556 : struct sockaddr_storage,
2557 : num_srv_addrs);
2558 27 : if (srv_addrs == NULL) {
2559 0 : TALLOC_FREE(dcs);
2560 0 : return NT_STATUS_NO_MEMORY;
2561 : }
2562 :
2563 27 : num_srv_addrs = 0;
2564 54 : for(i = 0; i < numdcs; i++) {
2565 : /* Copy all the IP addresses from the SRV response */
2566 : size_t j;
2567 81 : for (j = 0; j < dcs[i].num_ips; j++) {
2568 : char addr[INET6_ADDRSTRLEN];
2569 :
2570 54 : srv_addrs[num_srv_addrs] = dcs[i].ss_s[j];
2571 54 : if (is_zero_addr(&srv_addrs[num_srv_addrs])) {
2572 0 : continue;
2573 : }
2574 :
2575 54 : DBG_DEBUG("SRV lookup %s got IP[%zu] %s\n",
2576 : name,
2577 : j,
2578 : print_sockaddr(addr,
2579 : sizeof(addr),
2580 : &srv_addrs[num_srv_addrs]));
2581 :
2582 54 : num_srv_addrs++;
2583 : }
2584 : }
2585 :
2586 27 : TALLOC_FREE(dcs);
2587 :
2588 27 : *return_addrs = srv_addrs;
2589 27 : *return_count = num_srv_addrs;
2590 27 : return NT_STATUS_OK;
2591 : }
2592 :
2593 57 : static const char **filter_out_nbt_lookup(TALLOC_CTX *mem_ctx,
2594 : const char **resolve_order)
2595 : {
2596 : size_t i, len, result_idx;
2597 : const char **result;
2598 :
2599 57 : len = 0;
2600 244 : while (resolve_order[len] != NULL) {
2601 147 : len += 1;
2602 : }
2603 :
2604 57 : result = talloc_array(mem_ctx, const char *, len+1);
2605 57 : if (result == NULL) {
2606 0 : return NULL;
2607 : }
2608 :
2609 57 : result_idx = 0;
2610 :
2611 204 : for (i=0; i<len; i++) {
2612 147 : const char *tok = resolve_order[i];
2613 :
2614 234 : if (strequal(tok, "lmhosts") || strequal(tok, "wins") ||
2615 87 : strequal(tok, "bcast")) {
2616 90 : continue;
2617 : }
2618 57 : result[result_idx++] = tok;
2619 : }
2620 57 : result[result_idx] = NULL;
2621 :
2622 57 : return result;
2623 : }
2624 :
2625 : /*******************************************************************
2626 : Samba interface to resolve a name into an IP address.
2627 : Use this function if the string is either an IP address, DNS
2628 : or host name or NetBIOS name. This uses the name switch in the
2629 : smb.conf to determine the order of name resolution.
2630 :
2631 : Added support for ip addr/port to support ADS ldap servers.
2632 : the only place we currently care about the port is in the
2633 : resolve_hosts() when looking up DC's via SRV RR entries in DNS
2634 : **********************************************************************/
2635 :
2636 1803 : NTSTATUS internal_resolve_name(TALLOC_CTX *ctx,
2637 : const char *name,
2638 : int name_type,
2639 : const char *sitename,
2640 : struct samba_sockaddr **return_salist,
2641 : size_t *return_count,
2642 : const char **resolve_order)
2643 : {
2644 1803 : NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2645 : size_t i;
2646 1803 : size_t nc_count = 0;
2647 1803 : size_t ret_count = 0;
2648 : bool ok;
2649 1803 : struct sockaddr_storage *ss_list = NULL;
2650 1803 : struct samba_sockaddr *sa_list = NULL;
2651 1803 : TALLOC_CTX *frame = talloc_stackframe();
2652 :
2653 1803 : DBG_DEBUG("looking up %s#%x (sitename %s)\n",
2654 : name, name_type, sitename ? sitename : "(null)");
2655 :
2656 1803 : if (is_ipaddress(name)) {
2657 : struct sockaddr_storage ss;
2658 :
2659 : /* if it's in the form of an IP address then get the lib to interpret it */
2660 0 : ok = interpret_string_addr(&ss, name, AI_NUMERICHOST);
2661 0 : if (!ok) {
2662 0 : DBG_WARNING("interpret_string_addr failed on %s\n",
2663 : name);
2664 0 : TALLOC_FREE(frame);
2665 0 : return NT_STATUS_INVALID_PARAMETER;
2666 : }
2667 0 : if (is_zero_addr(&ss)) {
2668 0 : TALLOC_FREE(frame);
2669 0 : return NT_STATUS_UNSUCCESSFUL;
2670 : }
2671 :
2672 0 : status = sockaddr_array_to_samba_sockaddr_array(frame,
2673 : &sa_list,
2674 : &ret_count,
2675 : &ss,
2676 : 1);
2677 0 : if (!NT_STATUS_IS_OK(status)) {
2678 0 : TALLOC_FREE(frame);
2679 0 : return status;
2680 : }
2681 :
2682 0 : *return_salist = talloc_move(ctx, &sa_list);
2683 0 : *return_count = 1;
2684 0 : TALLOC_FREE(frame);
2685 0 : return NT_STATUS_OK;
2686 : }
2687 :
2688 : /* Check name cache */
2689 :
2690 1803 : ok = namecache_fetch(frame,
2691 : name,
2692 : name_type,
2693 : &sa_list,
2694 : &nc_count);
2695 1803 : if (ok) {
2696 : /*
2697 : * remove_duplicate_addrs2() has the
2698 : * side effect of removing zero addresses,
2699 : * so use it here.
2700 : */
2701 1639 : nc_count = remove_duplicate_addrs2(sa_list, nc_count);
2702 1639 : if (nc_count == 0) {
2703 0 : TALLOC_FREE(sa_list);
2704 0 : TALLOC_FREE(frame);
2705 0 : return NT_STATUS_UNSUCCESSFUL;
2706 : }
2707 1639 : *return_count = nc_count;
2708 1639 : *return_salist = talloc_move(ctx, &sa_list);
2709 1639 : TALLOC_FREE(frame);
2710 1639 : return NT_STATUS_OK;
2711 : }
2712 :
2713 : /* set the name resolution order */
2714 :
2715 164 : if (resolve_order && strcmp(resolve_order[0], "NULL") == 0) {
2716 0 : DBG_DEBUG("all lookups disabled\n");
2717 0 : TALLOC_FREE(frame);
2718 0 : return NT_STATUS_INVALID_PARAMETER;
2719 : }
2720 :
2721 164 : if (!resolve_order || !resolve_order[0]) {
2722 : static const char *host_order[] = { "host", NULL };
2723 0 : resolve_order = host_order;
2724 : }
2725 :
2726 232 : if ((strlen(name) > MAX_NETBIOSNAME_LEN - 1) ||
2727 107 : (strchr(name, '.') != NULL)) {
2728 : /*
2729 : * Don't do NBT lookup, the name would not fit anyway
2730 : */
2731 57 : resolve_order = filter_out_nbt_lookup(frame, resolve_order);
2732 57 : if (resolve_order == NULL) {
2733 0 : TALLOC_FREE(frame);
2734 0 : return NT_STATUS_NO_MEMORY;
2735 : }
2736 : }
2737 :
2738 : /* iterate through the name resolution backends */
2739 :
2740 390 : for (i=0; resolve_order[i]; i++) {
2741 390 : const char *tok = resolve_order[i];
2742 :
2743 390 : if ((strequal(tok, "host") || strequal(tok, "hosts"))) {
2744 135 : status = resolve_hosts(talloc_tos(),
2745 : name,
2746 : name_type,
2747 : &ss_list,
2748 : &ret_count);
2749 135 : if (!NT_STATUS_IS_OK(status)) {
2750 12 : continue;
2751 : }
2752 123 : goto done;
2753 : }
2754 :
2755 255 : if (strequal(tok, "kdc")) {
2756 : /* deal with KDC_NAME_TYPE names here.
2757 : * This will result in a SRV record lookup */
2758 16 : status = resolve_ads(talloc_tos(),
2759 : name,
2760 : KDC_NAME_TYPE,
2761 : sitename,
2762 : &ss_list,
2763 : &ret_count);
2764 16 : if (!NT_STATUS_IS_OK(status)) {
2765 0 : continue;
2766 : }
2767 : /* Ensure we don't namecache
2768 : * this with the KDC port. */
2769 16 : name_type = KDC_NAME_TYPE;
2770 16 : goto done;
2771 : }
2772 :
2773 239 : if (strequal(tok, "ads")) {
2774 : /* deal with 0x1c and 0x1b names here.
2775 : * This will result in a SRV record lookup */
2776 11 : status = resolve_ads(talloc_tos(),
2777 : name,
2778 : name_type,
2779 : sitename,
2780 : &ss_list,
2781 : &ret_count);
2782 11 : if (!NT_STATUS_IS_OK(status)) {
2783 0 : continue;
2784 : }
2785 11 : goto done;
2786 : }
2787 :
2788 228 : if (strequal(tok, "lmhosts")) {
2789 107 : status = resolve_lmhosts_file_as_sockaddr(
2790 : talloc_tos(),
2791 : get_dyn_LMHOSTSFILE(),
2792 : name,
2793 : name_type,
2794 : &ss_list,
2795 : &ret_count);
2796 107 : if (!NT_STATUS_IS_OK(status)) {
2797 107 : continue;
2798 : }
2799 0 : goto done;
2800 : }
2801 :
2802 121 : if (strequal(tok, "wins")) {
2803 : /* don't resolve 1D via WINS */
2804 107 : if (name_type == 0x1D) {
2805 0 : continue;
2806 : }
2807 107 : status = resolve_wins(talloc_tos(),
2808 : name,
2809 : name_type,
2810 : &ss_list,
2811 : &ret_count);
2812 107 : if (!NT_STATUS_IS_OK(status)) {
2813 107 : continue;
2814 : }
2815 0 : goto done;
2816 : }
2817 :
2818 14 : if (strequal(tok, "bcast")) {
2819 14 : status = name_resolve_bcast(
2820 : talloc_tos(),
2821 : name,
2822 : name_type,
2823 : &ss_list,
2824 : &ret_count);
2825 14 : if (!NT_STATUS_IS_OK(status)) {
2826 0 : continue;
2827 : }
2828 14 : goto done;
2829 : }
2830 :
2831 0 : DBG_ERR("unknown name switch type %s\n", tok);
2832 : }
2833 :
2834 : /* All of the resolve_* functions above have returned false. */
2835 :
2836 0 : TALLOC_FREE(frame);
2837 0 : *return_count = 0;
2838 :
2839 0 : return status;
2840 :
2841 164 : done:
2842 :
2843 164 : status = sockaddr_array_to_samba_sockaddr_array(frame,
2844 : &sa_list,
2845 : &ret_count,
2846 : ss_list,
2847 : ret_count);
2848 164 : if (!NT_STATUS_IS_OK(status)) {
2849 0 : TALLOC_FREE(frame);
2850 0 : return NT_STATUS_NO_MEMORY;
2851 : }
2852 :
2853 : /* Remove duplicate entries. Some queries, notably #1c (domain
2854 : controllers) return the PDC in iplist[0] and then all domain
2855 : controllers including the PDC in iplist[1..n]. Iterating over
2856 : the iplist when the PDC is down will cause two sets of timeouts. */
2857 :
2858 164 : ret_count = remove_duplicate_addrs2(sa_list, ret_count);
2859 :
2860 : /* Save in name cache */
2861 164 : if ( DEBUGLEVEL >= 100 ) {
2862 0 : for (i = 0; i < ret_count && DEBUGLEVEL == 100; i++) {
2863 : char addr[INET6_ADDRSTRLEN];
2864 0 : print_sockaddr(addr, sizeof(addr),
2865 0 : &sa_list[i].u.ss);
2866 0 : DEBUG(100, ("Storing name %s of type %d (%s:0)\n",
2867 : name,
2868 : name_type,
2869 : addr));
2870 : }
2871 : }
2872 :
2873 164 : if (ret_count) {
2874 164 : namecache_store(name,
2875 : name_type,
2876 : ret_count,
2877 : sa_list);
2878 : }
2879 :
2880 : /* Display some debugging info */
2881 :
2882 164 : if ( DEBUGLEVEL >= 10 ) {
2883 0 : DBG_DEBUG("returning %zu addresses: ",
2884 : ret_count);
2885 :
2886 0 : for (i = 0; i < ret_count; i++) {
2887 : char addr[INET6_ADDRSTRLEN];
2888 0 : print_sockaddr(addr, sizeof(addr),
2889 0 : &sa_list[i].u.ss);
2890 0 : DEBUGADD(10, ("%s ", addr));
2891 : }
2892 0 : DEBUG(10, ("\n"));
2893 : }
2894 :
2895 164 : *return_count = ret_count;
2896 164 : *return_salist = talloc_move(ctx, &sa_list);
2897 :
2898 164 : TALLOC_FREE(frame);
2899 164 : return status;
2900 : }
2901 :
2902 : /********************************************************
2903 : Internal interface to resolve a name into one IP address.
2904 : Use this function if the string is either an IP address, DNS
2905 : or host name or NetBIOS name. This uses the name switch in the
2906 : smb.conf to determine the order of name resolution.
2907 : *********************************************************/
2908 :
2909 461 : bool resolve_name(const char *name,
2910 : struct sockaddr_storage *return_ss,
2911 : int name_type,
2912 : bool prefer_ipv4)
2913 : {
2914 461 : struct samba_sockaddr *sa_list = NULL;
2915 461 : char *sitename = NULL;
2916 461 : size_t count = 0;
2917 : NTSTATUS status;
2918 461 : TALLOC_CTX *frame = NULL;
2919 :
2920 461 : if (is_ipaddress(name)) {
2921 4 : return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
2922 : }
2923 :
2924 457 : frame = talloc_stackframe();
2925 :
2926 457 : sitename = sitename_fetch(frame, lp_realm()); /* wild guess */
2927 :
2928 457 : status = internal_resolve_name(frame,
2929 : name,
2930 : name_type,
2931 : sitename,
2932 : &sa_list,
2933 : &count,
2934 : lp_name_resolve_order());
2935 457 : if (NT_STATUS_IS_OK(status)) {
2936 : size_t i;
2937 :
2938 457 : if (prefer_ipv4) {
2939 317 : for (i=0; i<count; i++) {
2940 483 : if (!is_broadcast_addr(&sa_list[i].u.sa) &&
2941 317 : (sa_list[i].u.ss.ss_family == AF_INET)) {
2942 317 : *return_ss = sa_list[i].u.ss;
2943 317 : TALLOC_FREE(sa_list);
2944 317 : TALLOC_FREE(frame);
2945 317 : return True;
2946 : }
2947 : }
2948 : }
2949 :
2950 : /* only return valid addresses for TCP connections */
2951 140 : for (i=0; i<count; i++) {
2952 140 : if (!is_broadcast_addr(&sa_list[i].u.sa)) {
2953 140 : *return_ss = sa_list[i].u.ss;
2954 140 : TALLOC_FREE(sa_list);
2955 140 : TALLOC_FREE(frame);
2956 140 : return True;
2957 : }
2958 : }
2959 : }
2960 :
2961 0 : TALLOC_FREE(sa_list);
2962 0 : TALLOC_FREE(frame);
2963 0 : return False;
2964 : }
2965 :
2966 : /********************************************************
2967 : Internal interface to resolve a name into a list of IP addresses.
2968 : Use this function if the string is either an IP address, DNS
2969 : or host name or NetBIOS name. This uses the name switch in the
2970 : smb.conf to determine the order of name resolution.
2971 : *********************************************************/
2972 :
2973 1704 : NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
2974 : const char *name,
2975 : int name_type,
2976 : struct sockaddr_storage **return_ss_arr,
2977 : unsigned int *p_num_entries)
2978 : {
2979 1704 : struct samba_sockaddr *sa_list = NULL;
2980 1704 : char *sitename = NULL;
2981 1704 : size_t count = 0;
2982 : size_t i;
2983 1704 : unsigned int num_entries = 0;
2984 1704 : struct sockaddr_storage *result_arr = NULL;
2985 : NTSTATUS status;
2986 :
2987 1704 : if (is_ipaddress(name)) {
2988 399 : result_arr = talloc(ctx, struct sockaddr_storage);
2989 399 : if (result_arr == NULL) {
2990 0 : return NT_STATUS_NO_MEMORY;
2991 : }
2992 399 : if (!interpret_string_addr(result_arr, name, AI_NUMERICHOST)) {
2993 0 : TALLOC_FREE(result_arr);
2994 0 : return NT_STATUS_BAD_NETWORK_NAME;
2995 : }
2996 399 : *p_num_entries = 1;
2997 399 : *return_ss_arr = result_arr;
2998 399 : return NT_STATUS_OK;
2999 : }
3000 :
3001 1305 : sitename = sitename_fetch(ctx, lp_realm()); /* wild guess */
3002 :
3003 1305 : status = internal_resolve_name(ctx,
3004 : name,
3005 : name_type,
3006 : sitename,
3007 : &sa_list,
3008 : &count,
3009 : lp_name_resolve_order());
3010 1305 : TALLOC_FREE(sitename);
3011 :
3012 1305 : if (!NT_STATUS_IS_OK(status)) {
3013 0 : return status;
3014 : }
3015 :
3016 : /* only return valid addresses for TCP connections */
3017 3876 : for (i=0, num_entries = 0; i<count; i++) {
3018 4584 : if (!is_zero_addr(&sa_list[i].u.ss) &&
3019 2571 : !is_broadcast_addr(&sa_list[i].u.sa)) {
3020 2571 : num_entries++;
3021 : }
3022 : }
3023 1305 : if (num_entries == 0) {
3024 0 : status = NT_STATUS_BAD_NETWORK_NAME;
3025 0 : goto done;
3026 : }
3027 :
3028 1305 : result_arr = talloc_array(ctx,
3029 : struct sockaddr_storage,
3030 : num_entries);
3031 1305 : if (result_arr == NULL) {
3032 0 : status = NT_STATUS_NO_MEMORY;
3033 0 : goto done;
3034 : }
3035 :
3036 3876 : for (i=0, num_entries = 0; i<count; i++) {
3037 4584 : if (!is_zero_addr(&sa_list[i].u.ss) &&
3038 2571 : !is_broadcast_addr(&sa_list[i].u.sa)) {
3039 2571 : result_arr[num_entries++] = sa_list[i].u.ss;
3040 : }
3041 : }
3042 :
3043 1305 : if (num_entries == 0) {
3044 0 : TALLOC_FREE(result_arr);
3045 0 : status = NT_STATUS_BAD_NETWORK_NAME;
3046 0 : goto done;
3047 : }
3048 :
3049 1305 : status = NT_STATUS_OK;
3050 1305 : *p_num_entries = num_entries;
3051 1305 : *return_ss_arr = result_arr;
3052 1305 : done:
3053 1305 : TALLOC_FREE(sa_list);
3054 1305 : return status;
3055 : }
3056 :
3057 : /********************************************************
3058 : Find the IP address of the master browser or DMB for a workgroup.
3059 : *********************************************************/
3060 :
3061 0 : bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
3062 : {
3063 0 : struct samba_sockaddr *sa_list = NULL;
3064 0 : size_t count = 0;
3065 : NTSTATUS status;
3066 :
3067 0 : if (lp_disable_netbios()) {
3068 0 : DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
3069 0 : return false;
3070 : }
3071 :
3072 0 : status = internal_resolve_name(talloc_tos(),
3073 : group,
3074 : 0x1D,
3075 : NULL,
3076 : &sa_list,
3077 : &count,
3078 : lp_name_resolve_order());
3079 0 : if (NT_STATUS_IS_OK(status)) {
3080 0 : *master_ss = sa_list[0].u.ss;
3081 0 : TALLOC_FREE(sa_list);
3082 0 : return true;
3083 : }
3084 :
3085 0 : TALLOC_FREE(sa_list);
3086 :
3087 0 : status = internal_resolve_name(talloc_tos(),
3088 : group,
3089 : 0x1B,
3090 : NULL,
3091 : &sa_list,
3092 : &count,
3093 : lp_name_resolve_order());
3094 0 : if (NT_STATUS_IS_OK(status)) {
3095 0 : *master_ss = sa_list[0].u.ss;
3096 0 : TALLOC_FREE(sa_list);
3097 0 : return true;
3098 : }
3099 :
3100 0 : TALLOC_FREE(sa_list);
3101 0 : return false;
3102 : }
3103 :
3104 : /********************************************************
3105 : Get the IP address list of the primary domain controller
3106 : for a domain.
3107 : *********************************************************/
3108 :
3109 0 : bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
3110 : {
3111 0 : struct samba_sockaddr *sa_list = NULL;
3112 0 : size_t count = 0;
3113 0 : NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
3114 : static const char *ads_order[] = { "ads", NULL };
3115 : /* Look up #1B name */
3116 :
3117 0 : if (lp_security() == SEC_ADS) {
3118 0 : status = internal_resolve_name(talloc_tos(),
3119 : domain,
3120 : 0x1b,
3121 : NULL,
3122 : &sa_list,
3123 : &count,
3124 : ads_order);
3125 : }
3126 :
3127 0 : if (!NT_STATUS_IS_OK(status) || count == 0) {
3128 0 : TALLOC_FREE(sa_list);
3129 0 : status = internal_resolve_name(talloc_tos(),
3130 : domain,
3131 : 0x1b,
3132 : NULL,
3133 : &sa_list,
3134 : &count,
3135 : lp_name_resolve_order());
3136 0 : if (!NT_STATUS_IS_OK(status)) {
3137 0 : TALLOC_FREE(sa_list);
3138 0 : return false;
3139 : }
3140 : }
3141 :
3142 : /* if we get more than 1 IP back we have to assume it is a
3143 : multi-homed PDC and not a mess up */
3144 :
3145 0 : if ( count > 1 ) {
3146 0 : DBG_INFO("PDC has %zu IP addresses!\n", count);
3147 0 : sort_sa_list(sa_list, count);
3148 : }
3149 :
3150 0 : *pss = sa_list[0].u.ss;
3151 0 : TALLOC_FREE(sa_list);
3152 0 : return true;
3153 : }
3154 :
3155 : /* Private enum type for lookups. */
3156 :
3157 : enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
3158 :
3159 : /********************************************************
3160 : Get the IP address list of the domain controllers for
3161 : a domain.
3162 : *********************************************************/
3163 :
3164 188 : static NTSTATUS get_dc_list(TALLOC_CTX *ctx,
3165 : const char *domain,
3166 : const char *sitename,
3167 : struct samba_sockaddr **sa_list_ret,
3168 : size_t *ret_count,
3169 : enum dc_lookup_type lookup_type,
3170 : bool *ordered)
3171 : {
3172 188 : const char **resolve_order = NULL;
3173 188 : char *saf_servername = NULL;
3174 188 : char *pserver = NULL;
3175 : const char *p;
3176 : char *name;
3177 188 : size_t num_addresses = 0;
3178 188 : size_t local_count = 0;
3179 : size_t i;
3180 188 : struct samba_sockaddr *auto_sa_list = NULL;
3181 188 : struct samba_sockaddr *return_salist = NULL;
3182 188 : bool done_auto_lookup = false;
3183 188 : size_t auto_count = 0;
3184 : NTSTATUS status;
3185 188 : TALLOC_CTX *frame = talloc_stackframe();
3186 188 : int auto_name_type = 0x1C;
3187 :
3188 188 : *ordered = False;
3189 :
3190 : /* if we are restricted to solely using DNS for looking
3191 : up a domain controller, make sure that host lookups
3192 : are enabled for the 'name resolve order'. If host lookups
3193 : are disabled and ads_only is True, then set the string to
3194 : NULL. */
3195 :
3196 188 : resolve_order = lp_name_resolve_order();
3197 188 : if (!resolve_order) {
3198 0 : status = NT_STATUS_NO_MEMORY;
3199 0 : goto out;
3200 : }
3201 188 : if (lookup_type == DC_ADS_ONLY) {
3202 59 : if (str_list_check_ci(resolve_order, "host")) {
3203 : static const char *ads_order[] = { "ads", NULL };
3204 59 : resolve_order = ads_order;
3205 :
3206 : /* DNS SRV lookups used by the ads resolver
3207 : are already sorted by priority and weight */
3208 59 : *ordered = true;
3209 : } else {
3210 : /* this is quite bizarre! */
3211 : static const char *null_order[] = { "NULL", NULL };
3212 0 : resolve_order = null_order;
3213 : }
3214 129 : } else if (lookup_type == DC_KDC_ONLY) {
3215 : static const char *kdc_order[] = { "kdc", NULL };
3216 : /* DNS SRV lookups used by the ads/kdc resolver
3217 : are already sorted by priority and weight */
3218 123 : *ordered = true;
3219 123 : resolve_order = kdc_order;
3220 123 : auto_name_type = KDC_NAME_TYPE;
3221 : }
3222 :
3223 : /* fetch the server we have affinity for. Add the
3224 : 'password server' list to a search for our domain controllers */
3225 :
3226 188 : saf_servername = saf_fetch(frame, domain);
3227 :
3228 188 : if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
3229 180 : pserver = talloc_asprintf(frame, "%s, %s",
3230 : saf_servername ? saf_servername : "",
3231 : lp_password_server());
3232 : } else {
3233 8 : pserver = talloc_asprintf(frame, "%s, *",
3234 : saf_servername ? saf_servername : "");
3235 : }
3236 :
3237 188 : TALLOC_FREE(saf_servername);
3238 188 : if (!pserver) {
3239 0 : status = NT_STATUS_NO_MEMORY;
3240 0 : goto out;
3241 : }
3242 :
3243 188 : DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
3244 :
3245 : /*
3246 : * if '*' appears in the "password server" list then add
3247 : * an auto lookup to the list of manually configured
3248 : * DC's. If any DC is listed by name, then the list should be
3249 : * considered to be ordered
3250 : */
3251 :
3252 188 : p = pserver;
3253 582 : while (next_token_talloc(frame, &p, &name, LIST_SEP)) {
3254 290 : if (!done_auto_lookup && strequal(name, "*")) {
3255 37 : done_auto_lookup = true;
3256 :
3257 37 : status = internal_resolve_name(frame,
3258 : domain,
3259 : auto_name_type,
3260 : sitename,
3261 : &auto_sa_list,
3262 : &auto_count,
3263 : resolve_order);
3264 37 : if (!NT_STATUS_IS_OK(status)) {
3265 0 : continue;
3266 : }
3267 : /* Wrap check. */
3268 37 : if (num_addresses + auto_count < num_addresses) {
3269 0 : TALLOC_FREE(auto_sa_list);
3270 0 : status = NT_STATUS_INVALID_PARAMETER;
3271 0 : goto out;
3272 : }
3273 37 : num_addresses += auto_count;
3274 37 : DBG_DEBUG("Adding %zu DC's from auto lookup\n",
3275 : auto_count);
3276 : } else {
3277 : /* Wrap check. */
3278 253 : if (num_addresses + 1 < num_addresses) {
3279 0 : TALLOC_FREE(auto_sa_list);
3280 0 : status = NT_STATUS_INVALID_PARAMETER;
3281 0 : goto out;
3282 : }
3283 253 : num_addresses++;
3284 : }
3285 : }
3286 :
3287 : /* if we have no addresses and haven't done the auto lookup, then
3288 : just return the list of DC's. Or maybe we just failed. */
3289 :
3290 188 : if (num_addresses == 0) {
3291 0 : struct samba_sockaddr *dc_salist = NULL;
3292 0 : size_t dc_count = 0;
3293 :
3294 0 : if (done_auto_lookup) {
3295 0 : DEBUG(4,("get_dc_list: no servers found\n"));
3296 0 : status = NT_STATUS_NO_LOGON_SERVERS;
3297 0 : goto out;
3298 : }
3299 : /* talloc off frame, only move to ctx on success. */
3300 0 : status = internal_resolve_name(frame,
3301 : domain,
3302 : auto_name_type,
3303 : sitename,
3304 : &dc_salist,
3305 : &dc_count,
3306 : resolve_order);
3307 0 : if (!NT_STATUS_IS_OK(status)) {
3308 0 : goto out;
3309 : }
3310 0 : return_salist = dc_salist;
3311 0 : local_count = dc_count;
3312 0 : goto out;
3313 : }
3314 :
3315 188 : return_salist = talloc_zero_array(frame,
3316 : struct samba_sockaddr,
3317 : num_addresses);
3318 188 : if (return_salist == NULL) {
3319 0 : DEBUG(3,("get_dc_list: malloc fail !\n"));
3320 0 : status = NT_STATUS_NO_MEMORY;
3321 0 : goto out;
3322 : }
3323 :
3324 188 : p = pserver;
3325 188 : local_count = 0;
3326 :
3327 : /* fill in the return list now with real IP's */
3328 :
3329 872 : while ((local_count<num_addresses) &&
3330 290 : next_token_talloc(frame, &p, &name, LIST_SEP)) {
3331 290 : struct samba_sockaddr name_sa = {0};
3332 :
3333 : /* copy any addresses from the auto lookup */
3334 :
3335 290 : if (strequal(name, "*")) {
3336 : size_t j;
3337 111 : for (j=0; j<auto_count; j++) {
3338 : char addr[INET6_ADDRSTRLEN];
3339 74 : print_sockaddr(addr,
3340 : sizeof(addr),
3341 74 : &auto_sa_list[j].u.ss);
3342 : /* Check for and don't copy any
3343 : * known bad DC IP's. */
3344 74 : if(!NT_STATUS_IS_OK(check_negative_conn_cache(
3345 : domain,
3346 : addr))) {
3347 0 : DEBUG(5,("get_dc_list: "
3348 : "negative entry %s removed "
3349 : "from DC list\n",
3350 : addr));
3351 0 : continue;
3352 : }
3353 74 : return_salist[local_count] = auto_sa_list[j];
3354 74 : local_count++;
3355 : }
3356 68 : continue;
3357 : }
3358 :
3359 : /* explicit lookup; resolve_name() will
3360 : * handle names & IP addresses */
3361 253 : if (resolve_name(name, &name_sa.u.ss, 0x20, true)) {
3362 : char addr[INET6_ADDRSTRLEN];
3363 : bool ok;
3364 :
3365 : /*
3366 : * Ensure we set sa_socklen correctly.
3367 : * Doesn't matter now, but eventually we
3368 : * will remove ip_service and return samba_sockaddr
3369 : * arrays directly.
3370 : */
3371 253 : ok = sockaddr_storage_to_samba_sockaddr(
3372 : &name_sa,
3373 : &name_sa.u.ss);
3374 253 : if (!ok) {
3375 0 : status = NT_STATUS_INVALID_ADDRESS;
3376 0 : goto out;
3377 : }
3378 :
3379 253 : print_sockaddr(addr,
3380 : sizeof(addr),
3381 : &name_sa.u.ss);
3382 :
3383 : /* Check for and don't copy any known bad DC IP's. */
3384 253 : if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
3385 : addr)) ) {
3386 0 : DEBUG(5,("get_dc_list: negative entry %s "
3387 : "removed from DC list\n",
3388 : name ));
3389 0 : continue;
3390 : }
3391 :
3392 253 : return_salist[local_count] = name_sa;
3393 253 : local_count++;
3394 253 : *ordered = true;
3395 : }
3396 : }
3397 :
3398 : /* need to remove duplicates in the list if we have any
3399 : explicit password servers */
3400 :
3401 188 : local_count = remove_duplicate_addrs2(return_salist, local_count );
3402 :
3403 : /* For DC's we always prioritize IPv4 due to W2K3 not
3404 : * supporting LDAP, KRB5 or CLDAP over IPv6. */
3405 :
3406 188 : if (local_count && return_salist != NULL) {
3407 188 : prioritize_ipv4_list(return_salist, local_count);
3408 : }
3409 :
3410 188 : if ( DEBUGLEVEL >= 4 ) {
3411 3 : DEBUG(4,("get_dc_list: returning %zu ip addresses "
3412 : "in an %sordered list\n",
3413 : local_count,
3414 : *ordered ? "":"un"));
3415 3 : DEBUG(4,("get_dc_list: "));
3416 6 : for ( i=0; i<local_count; i++ ) {
3417 : char addr[INET6_ADDRSTRLEN];
3418 3 : print_sockaddr(addr,
3419 : sizeof(addr),
3420 3 : &return_salist[i].u.ss);
3421 3 : DEBUGADD(4,("%s ", addr));
3422 : }
3423 3 : DEBUGADD(4,("\n"));
3424 : }
3425 :
3426 188 : status = (local_count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS);
3427 :
3428 188 : out:
3429 :
3430 188 : if (NT_STATUS_IS_OK(status)) {
3431 188 : *sa_list_ret = talloc_move(ctx, &return_salist);
3432 188 : *ret_count = local_count;
3433 : }
3434 188 : TALLOC_FREE(return_salist);
3435 188 : TALLOC_FREE(auto_sa_list);
3436 188 : TALLOC_FREE(frame);
3437 188 : return status;
3438 : }
3439 :
3440 : /*********************************************************************
3441 : Small wrapper function to get the DC list and sort it if neccessary.
3442 : Returns a samba_sockaddr array.
3443 : *********************************************************************/
3444 :
3445 65 : NTSTATUS get_sorted_dc_list(TALLOC_CTX *ctx,
3446 : const char *domain,
3447 : const char *sitename,
3448 : struct samba_sockaddr **sa_list_ret,
3449 : size_t *ret_count,
3450 : bool ads_only)
3451 : {
3452 65 : bool ordered = false;
3453 : NTSTATUS status;
3454 65 : enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
3455 65 : struct samba_sockaddr *sa_list = NULL;
3456 65 : size_t count = 0;
3457 :
3458 65 : DBG_INFO("attempting lookup for name %s (sitename %s)\n",
3459 : domain,
3460 : sitename ? sitename : "NULL");
3461 :
3462 65 : if (ads_only) {
3463 59 : lookup_type = DC_ADS_ONLY;
3464 : }
3465 :
3466 65 : status = get_dc_list(ctx,
3467 : domain,
3468 : sitename,
3469 : &sa_list,
3470 : &count,
3471 : lookup_type,
3472 : &ordered);
3473 65 : if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
3474 0 : && sitename) {
3475 0 : DBG_NOTICE("no server for name %s available"
3476 : " in site %s, fallback to all servers\n",
3477 : domain,
3478 : sitename);
3479 0 : status = get_dc_list(ctx,
3480 : domain,
3481 : NULL,
3482 : &sa_list,
3483 : &count,
3484 : lookup_type,
3485 : &ordered);
3486 : }
3487 :
3488 65 : if (!NT_STATUS_IS_OK(status)) {
3489 0 : return status;
3490 : }
3491 :
3492 : /* only sort if we don't already have an ordered list */
3493 65 : if (!ordered) {
3494 0 : sort_sa_list(sa_list, count);
3495 : }
3496 :
3497 65 : *ret_count = count;
3498 65 : *sa_list_ret = sa_list;
3499 65 : return status;
3500 : }
3501 :
3502 : /*********************************************************************
3503 : Get the KDC list - re-use all the logic in get_dc_list.
3504 : Returns a samba_sockaddr array.
3505 : *********************************************************************/
3506 :
3507 123 : NTSTATUS get_kdc_list(TALLOC_CTX *ctx,
3508 : const char *realm,
3509 : const char *sitename,
3510 : struct samba_sockaddr **sa_list_ret,
3511 : size_t *ret_count)
3512 : {
3513 123 : size_t count = 0;
3514 123 : struct samba_sockaddr *sa_list = NULL;
3515 123 : bool ordered = false;
3516 : NTSTATUS status;
3517 :
3518 123 : status = get_dc_list(ctx,
3519 : realm,
3520 : sitename,
3521 : &sa_list,
3522 : &count,
3523 : DC_KDC_ONLY,
3524 : &ordered);
3525 :
3526 123 : if (!NT_STATUS_IS_OK(status)) {
3527 0 : return status;
3528 : }
3529 :
3530 : /* only sort if we don't already have an ordered list */
3531 123 : if (!ordered ) {
3532 0 : sort_sa_list(sa_list, count);
3533 : }
3534 :
3535 123 : *ret_count = count;
3536 123 : *sa_list_ret = sa_list;
3537 123 : return status;
3538 : }
|