lib: talloc: Fix memlimit on pool realloc.
[Samba.git] / source3 / libsmb / namequery.c
blob1e109ecc37174e8e89a2dc510fc7c47f34df6f1e
1 /*
2 Unix SMB/CIFS implementation.
3 name query routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2007.
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.
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.
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/>.
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 "../libcli/netlogon/netlogon.h"
27 #include "lib/async_req/async_sock.h"
28 #include "lib/tsocket/tsocket.h"
29 #include "libsmb/nmblib.h"
30 #include "libsmb/unexpected.h"
31 #include "../libcli/nbt/libnbt.h"
32 #include "libads/kerberos_proto.h"
33 #include "lib/gencache.h"
34 #include "librpc/gen_ndr/dns.h"
35 #include "lib/util/util_net.h"
36 #include "lib/util/string_wrappers.h"
38 /* nmbd.c sets this to True. */
39 bool global_in_nmbd = False;
42 * Utility function that copes only with AF_INET and AF_INET6
43 * as that's all we're going to get out of DNS / NetBIOS / WINS
44 * name resolution functions.
47 bool sockaddr_storage_to_samba_sockaddr(struct samba_sockaddr *sa,
48 const struct sockaddr_storage *ss)
50 sa->u.ss = *ss;
52 switch (ss->ss_family) {
53 case AF_INET:
54 sa->sa_socklen = sizeof(struct sockaddr_in);
55 break;
56 #ifdef HAVE_IPV6
57 case AF_INET6:
58 sa->sa_socklen = sizeof(struct sockaddr_in6);
59 break;
60 #endif
61 default:
62 return false;
64 return true;
68 * Utility function to convert from a sockaddr_storage
69 * array to a struct samba_sockaddr array.
72 static NTSTATUS sockaddr_array_to_samba_sockaddr_array(
73 TALLOC_CTX *ctx,
74 struct samba_sockaddr **sa_out,
75 size_t *count_out,
76 const struct sockaddr_storage *ss_in,
77 size_t count_in)
79 struct samba_sockaddr *sa = NULL;
80 size_t i;
81 size_t count = 0;
83 if (count_in == 0) {
85 * Zero length arrays are returned as NULL.
86 * in the name resolution code.
88 *count_out = 0;
89 *sa_out = NULL;
90 return NT_STATUS_OK;
92 sa = talloc_zero_array(ctx,
93 struct samba_sockaddr,
94 count_in);
95 if (sa == NULL) {
96 return NT_STATUS_NO_MEMORY;
98 count = 0;
99 for (i = 0; i < count_in; i++) {
100 bool ok;
102 /* Filter out zero addresses. */
103 if (is_zero_addr(&ss_in[i])) {
104 continue;
106 ok = sockaddr_storage_to_samba_sockaddr(&sa[count],
107 &ss_in[i]);
108 if (!ok) {
109 continue;
111 count++;
113 if (count == 0) {
115 * Zero length arrays are returned as NULL.
116 * in the name resolution code.
118 TALLOC_FREE(sa);
120 *count_out = count;
121 *sa_out = sa;
122 return NT_STATUS_OK;
125 /****************************
126 * SERVER AFFINITY ROUTINES *
127 ****************************/
129 /* Server affinity is the concept of preferring the last domain
130 controller with whom you had a successful conversation */
132 /****************************************************************************
133 ****************************************************************************/
134 #define SAFKEY_FMT "SAF/DOMAIN/%s"
135 #define SAF_TTL 900
136 #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
137 #define SAFJOIN_TTL 3600
139 static char *saf_key(TALLOC_CTX *mem_ctx, const char *domain)
141 return talloc_asprintf_strupper_m(mem_ctx, SAFKEY_FMT, domain);
144 static char *saf_join_key(TALLOC_CTX *mem_ctx, const char *domain)
146 return talloc_asprintf_strupper_m(mem_ctx, SAFJOINKEY_FMT, domain);
149 /****************************************************************************
150 ****************************************************************************/
152 bool saf_store( const char *domain, const char *servername )
154 char *key;
155 time_t expire;
156 bool ret = False;
158 if ( !domain || !servername ) {
159 DEBUG(2,("saf_store: "
160 "Refusing to store empty domain or servername!\n"));
161 return False;
164 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
165 DEBUG(0,("saf_store: "
166 "refusing to store 0 length domain or servername!\n"));
167 return False;
170 key = saf_key(talloc_tos(), domain);
171 if (key == NULL) {
172 DEBUG(1, ("saf_key() failed\n"));
173 return false;
175 expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
177 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
178 domain, servername, (unsigned int)expire ));
180 ret = gencache_set( key, servername, expire );
182 TALLOC_FREE( key );
184 return ret;
187 bool saf_join_store( const char *domain, const char *servername )
189 char *key;
190 time_t expire;
191 bool ret = False;
193 if ( !domain || !servername ) {
194 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
195 return False;
198 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
199 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
200 return False;
203 key = saf_join_key(talloc_tos(), domain);
204 if (key == NULL) {
205 DEBUG(1, ("saf_join_key() failed\n"));
206 return false;
208 expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
210 DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
211 domain, servername, (unsigned int)expire ));
213 ret = gencache_set( key, servername, expire );
215 TALLOC_FREE( key );
217 return ret;
220 bool saf_delete( const char *domain )
222 char *key;
223 bool ret = False;
225 if ( !domain ) {
226 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
227 return False;
230 key = saf_join_key(talloc_tos(), domain);
231 if (key == NULL) {
232 DEBUG(1, ("saf_join_key() failed\n"));
233 return false;
235 ret = gencache_del(key);
236 TALLOC_FREE(key);
238 if (ret) {
239 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
242 key = saf_key(talloc_tos(), domain);
243 if (key == NULL) {
244 DEBUG(1, ("saf_key() failed\n"));
245 return false;
247 ret = gencache_del(key);
248 TALLOC_FREE(key);
250 if (ret) {
251 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
254 return ret;
257 /****************************************************************************
258 ****************************************************************************/
260 char *saf_fetch(TALLOC_CTX *mem_ctx, const char *domain )
262 char *server = NULL;
263 time_t timeout;
264 bool ret = False;
265 char *key = NULL;
267 if ( !domain || strlen(domain) == 0) {
268 DEBUG(2,("saf_fetch: Empty domain name!\n"));
269 return NULL;
272 key = saf_join_key(talloc_tos(), domain);
273 if (key == NULL) {
274 DEBUG(1, ("saf_join_key() failed\n"));
275 return NULL;
278 ret = gencache_get( key, mem_ctx, &server, &timeout );
280 TALLOC_FREE( key );
282 if ( ret ) {
283 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
284 server, domain ));
285 return server;
288 key = saf_key(talloc_tos(), domain);
289 if (key == NULL) {
290 DEBUG(1, ("saf_key() failed\n"));
291 return NULL;
294 ret = gencache_get( key, mem_ctx, &server, &timeout );
296 TALLOC_FREE( key );
298 if ( !ret ) {
299 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
300 domain ));
301 } else {
302 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
303 server, domain ));
306 return server;
309 static void set_socket_addr_v4(struct samba_sockaddr *addr)
311 if (!interpret_string_addr(&addr->u.ss, lp_nbt_client_socket_address(),
312 AI_NUMERICHOST|AI_PASSIVE)) {
313 zero_sockaddr(&addr->u.ss);
314 /* zero_sockaddr sets family to AF_INET. */
315 addr->sa_socklen = sizeof(struct sockaddr_in);
317 if (addr->u.ss.ss_family != AF_INET) {
318 zero_sockaddr(&addr->u.ss);
319 /* zero_sockaddr sets family to AF_INET. */
320 addr->sa_socklen = sizeof(struct sockaddr_in);
324 static struct in_addr my_socket_addr_v4(void)
326 struct samba_sockaddr my_addr = {0};
328 set_socket_addr_v4(&my_addr);
329 return my_addr.u.in.sin_addr;
332 /****************************************************************************
333 Generate a random trn_id.
334 ****************************************************************************/
336 static int generate_trn_id(void)
338 uint16_t id;
340 generate_random_buffer((uint8_t *)&id, sizeof(id));
342 return id % (unsigned)0x7FFF;
345 /****************************************************************************
346 Parse a node status response into an array of structures.
347 ****************************************************************************/
349 static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p,
350 size_t *num_names,
351 struct node_status_extra *extra)
353 struct node_status *ret;
354 size_t i;
355 size_t result_count = 0;
357 result_count = CVAL(p,0);
359 if (result_count == 0)
360 return NULL;
362 ret = talloc_array(mem_ctx, struct node_status,result_count);
363 if (!ret)
364 return NULL;
366 p++;
367 for (i=0;i< result_count;i++) {
368 strlcpy(ret[i].name,p,16);
369 trim_char(ret[i].name,'\0',' ');
370 ret[i].type = CVAL(p,15);
371 ret[i].flags = p[16];
372 p += 18;
373 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
374 ret[i].type, ret[i].flags));
377 * Also, pick up the MAC address ...
379 if (extra) {
380 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
382 *num_names = result_count;
383 return ret;
386 struct sock_packet_read_state {
387 struct tevent_context *ev;
388 enum packet_type type;
389 int trn_id;
391 struct nb_packet_reader *reader;
392 struct tevent_req *reader_req;
394 struct tdgram_context *sock;
395 struct tevent_req *socket_req;
396 uint8_t *buf;
397 struct tsocket_address *addr;
399 bool (*validator)(struct packet_struct *p,
400 void *private_data);
401 void *private_data;
403 struct packet_struct *packet;
406 static void sock_packet_read_got_packet(struct tevent_req *subreq);
407 static void sock_packet_read_got_socket(struct tevent_req *subreq);
409 static struct tevent_req *sock_packet_read_send(
410 TALLOC_CTX *mem_ctx,
411 struct tevent_context *ev,
412 struct tdgram_context *sock,
413 struct nb_packet_reader *reader,
414 enum packet_type type,
415 int trn_id,
416 bool (*validator)(struct packet_struct *p, void *private_data),
417 void *private_data)
419 struct tevent_req *req;
420 struct sock_packet_read_state *state;
422 req = tevent_req_create(mem_ctx, &state,
423 struct sock_packet_read_state);
424 if (req == NULL) {
425 return NULL;
427 state->ev = ev;
428 state->reader = reader;
429 state->sock = sock;
430 state->type = type;
431 state->trn_id = trn_id;
432 state->validator = validator;
433 state->private_data = private_data;
435 if (reader != NULL) {
436 state->reader_req = nb_packet_read_send(state, ev, reader);
437 if (tevent_req_nomem(state->reader_req, req)) {
438 return tevent_req_post(req, ev);
440 tevent_req_set_callback(
441 state->reader_req, sock_packet_read_got_packet, req);
444 state->socket_req = tdgram_recvfrom_send(state, ev, state->sock);
445 if (tevent_req_nomem(state->socket_req, req)) {
446 return tevent_req_post(req, ev);
448 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
449 req);
451 return req;
454 static void sock_packet_read_got_packet(struct tevent_req *subreq)
456 struct tevent_req *req = tevent_req_callback_data(
457 subreq, struct tevent_req);
458 struct sock_packet_read_state *state = tevent_req_data(
459 req, struct sock_packet_read_state);
460 NTSTATUS status;
462 status = nb_packet_read_recv(subreq, state, &state->packet);
464 TALLOC_FREE(state->reader_req);
466 if (!NT_STATUS_IS_OK(status)) {
467 if (state->socket_req != NULL) {
469 * Still waiting for socket
471 return;
474 * Both socket and packet reader failed
476 tevent_req_nterror(req, status);
477 return;
480 if ((state->validator != NULL) &&
481 !state->validator(state->packet, state->private_data)) {
482 DEBUG(10, ("validator failed\n"));
484 TALLOC_FREE(state->packet);
486 state->reader_req = nb_packet_read_send(state, state->ev,
487 state->reader);
488 if (tevent_req_nomem(state->reader_req, req)) {
489 return;
491 tevent_req_set_callback(
492 state->reader_req, sock_packet_read_got_packet, req);
493 return;
496 TALLOC_FREE(state->socket_req);
497 tevent_req_done(req);
500 static void sock_packet_read_got_socket(struct tevent_req *subreq)
502 struct tevent_req *req = tevent_req_callback_data(
503 subreq, struct tevent_req);
504 struct sock_packet_read_state *state = tevent_req_data(
505 req, struct sock_packet_read_state);
506 struct samba_sockaddr addr = {0};
507 ssize_t ret;
508 ssize_t received;
509 int err;
510 bool ok;
512 received = tdgram_recvfrom_recv(subreq, &err, state,
513 &state->buf, &state->addr);
515 TALLOC_FREE(state->socket_req);
517 if (received == -1) {
518 if (state->reader_req != NULL) {
520 * Still waiting for reader
522 return;
525 * Both socket and reader failed
527 tevent_req_nterror(req, map_nt_error_from_unix(err));
528 return;
530 ok = tsocket_address_is_inet(state->addr, "ipv4");
531 if (!ok) {
532 goto retry;
534 ret = tsocket_address_bsd_sockaddr(state->addr,
535 &addr.u.sa,
536 sizeof(addr.u.in));
537 if (ret == -1) {
538 tevent_req_nterror(req, map_nt_error_from_unix(errno));
539 return;
542 state->packet = parse_packet_talloc(
543 state, (char *)state->buf, received, state->type,
544 addr.u.in.sin_addr, addr.u.in.sin_port);
545 if (state->packet == NULL) {
546 DEBUG(10, ("parse_packet failed\n"));
547 goto retry;
549 if ((state->trn_id != -1) &&
550 (state->trn_id != packet_trn_id(state->packet))) {
551 DEBUG(10, ("Expected transaction id %d, got %d\n",
552 state->trn_id, packet_trn_id(state->packet)));
553 goto retry;
556 if ((state->validator != NULL) &&
557 !state->validator(state->packet, state->private_data)) {
558 DEBUG(10, ("validator failed\n"));
559 goto retry;
562 tevent_req_done(req);
563 return;
565 retry:
566 TALLOC_FREE(state->packet);
567 TALLOC_FREE(state->buf);
568 TALLOC_FREE(state->addr);
570 state->socket_req = tdgram_recvfrom_send(state, state->ev, state->sock);
571 if (tevent_req_nomem(state->socket_req, req)) {
572 return;
574 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
575 req);
578 static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
579 TALLOC_CTX *mem_ctx,
580 struct packet_struct **ppacket)
582 struct sock_packet_read_state *state = tevent_req_data(
583 req, struct sock_packet_read_state);
584 NTSTATUS status;
586 if (tevent_req_is_nterror(req, &status)) {
587 return status;
589 *ppacket = talloc_move(mem_ctx, &state->packet);
590 return NT_STATUS_OK;
593 struct nb_trans_state {
594 struct tevent_context *ev;
595 struct tdgram_context *sock;
596 struct nb_packet_reader *reader;
598 struct tsocket_address *src_addr;
599 struct tsocket_address *dst_addr;
600 uint8_t *buf;
601 size_t buflen;
602 enum packet_type type;
603 int trn_id;
605 bool (*validator)(struct packet_struct *p,
606 void *private_data);
607 void *private_data;
609 struct packet_struct *packet;
612 static void nb_trans_got_reader(struct tevent_req *subreq);
613 static void nb_trans_done(struct tevent_req *subreq);
614 static void nb_trans_sent(struct tevent_req *subreq);
615 static void nb_trans_send_next(struct tevent_req *subreq);
617 static struct tevent_req *nb_trans_send(
618 TALLOC_CTX *mem_ctx,
619 struct tevent_context *ev,
620 const struct samba_sockaddr *_my_addr,
621 const struct samba_sockaddr *_dst_addr,
622 bool bcast,
623 uint8_t *buf, size_t buflen,
624 enum packet_type type, int trn_id,
625 bool (*validator)(struct packet_struct *p,
626 void *private_data),
627 void *private_data)
629 const struct sockaddr *my_addr = &_my_addr->u.sa;
630 size_t my_addr_len = sizeof(_my_addr->u.in); /*We know it's AF_INET.*/
631 const struct sockaddr *dst_addr = &_dst_addr->u.sa;
632 size_t dst_addr_len = sizeof(_dst_addr->u.in); /*We know it's AF_INET.*/
633 struct tevent_req *req, *subreq;
634 struct nb_trans_state *state;
635 int ret;
637 req = tevent_req_create(mem_ctx, &state, struct nb_trans_state);
638 if (req == NULL) {
639 return NULL;
641 state->ev = ev;
642 state->buf = buf;
643 state->buflen = buflen;
644 state->type = type;
645 state->trn_id = trn_id;
646 state->validator = validator;
647 state->private_data = private_data;
649 ret = tsocket_address_bsd_from_sockaddr(state,
650 my_addr, my_addr_len,
651 &state->src_addr);
652 if (ret == -1) {
653 tevent_req_nterror(req, map_nt_error_from_unix(errno));
654 return tevent_req_post(req, ev);
657 ret = tsocket_address_bsd_from_sockaddr(state,
658 dst_addr, dst_addr_len,
659 &state->dst_addr);
660 if (ret == -1) {
661 tevent_req_nterror(req, map_nt_error_from_unix(errno));
662 return tevent_req_post(req, ev);
665 ret = tdgram_inet_udp_broadcast_socket(state->src_addr, state,
666 &state->sock);
667 if (ret == -1) {
668 tevent_req_nterror(req, map_nt_error_from_unix(errno));
669 return tevent_req_post(req, ev);
672 subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL);
673 if (tevent_req_nomem(subreq, req)) {
674 return tevent_req_post(req, ev);
676 tevent_req_set_callback(subreq, nb_trans_got_reader, req);
677 return req;
680 static void nb_trans_got_reader(struct tevent_req *subreq)
682 struct tevent_req *req = tevent_req_callback_data(
683 subreq, struct tevent_req);
684 struct nb_trans_state *state = tevent_req_data(
685 req, struct nb_trans_state);
686 NTSTATUS status;
688 status = nb_packet_reader_recv(subreq, state, &state->reader);
689 TALLOC_FREE(subreq);
691 if (!NT_STATUS_IS_OK(status)) {
692 DEBUG(10, ("nmbd not around\n"));
693 state->reader = NULL;
696 subreq = sock_packet_read_send(
697 state, state->ev, state->sock,
698 state->reader, state->type, state->trn_id,
699 state->validator, state->private_data);
700 if (tevent_req_nomem(subreq, req)) {
701 return;
703 tevent_req_set_callback(subreq, nb_trans_done, req);
705 subreq = tdgram_sendto_send(state, state->ev,
706 state->sock,
707 state->buf, state->buflen,
708 state->dst_addr);
709 if (tevent_req_nomem(subreq, req)) {
710 return;
712 tevent_req_set_callback(subreq, nb_trans_sent, req);
715 static void nb_trans_sent(struct tevent_req *subreq)
717 struct tevent_req *req = tevent_req_callback_data(
718 subreq, struct tevent_req);
719 struct nb_trans_state *state = tevent_req_data(
720 req, struct nb_trans_state);
721 ssize_t sent;
722 int err;
724 sent = tdgram_sendto_recv(subreq, &err);
725 TALLOC_FREE(subreq);
726 if (sent == -1) {
727 DEBUG(10, ("sendto failed: %s\n", strerror(err)));
728 tevent_req_nterror(req, map_nt_error_from_unix(err));
729 return;
731 subreq = tevent_wakeup_send(state, state->ev,
732 timeval_current_ofs(1, 0));
733 if (tevent_req_nomem(subreq, req)) {
734 return;
736 tevent_req_set_callback(subreq, nb_trans_send_next, req);
739 static void nb_trans_send_next(struct tevent_req *subreq)
741 struct tevent_req *req = tevent_req_callback_data(
742 subreq, struct tevent_req);
743 struct nb_trans_state *state = tevent_req_data(
744 req, struct nb_trans_state);
745 bool ret;
747 ret = tevent_wakeup_recv(subreq);
748 TALLOC_FREE(subreq);
749 if (!ret) {
750 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
751 return;
753 subreq = tdgram_sendto_send(state, state->ev,
754 state->sock,
755 state->buf, state->buflen,
756 state->dst_addr);
757 if (tevent_req_nomem(subreq, req)) {
758 return;
760 tevent_req_set_callback(subreq, nb_trans_sent, req);
763 static void nb_trans_done(struct tevent_req *subreq)
765 struct tevent_req *req = tevent_req_callback_data(
766 subreq, struct tevent_req);
767 struct nb_trans_state *state = tevent_req_data(
768 req, struct nb_trans_state);
769 NTSTATUS status;
771 status = sock_packet_read_recv(subreq, state, &state->packet);
772 TALLOC_FREE(subreq);
773 if (tevent_req_nterror(req, status)) {
774 return;
776 tevent_req_done(req);
779 static NTSTATUS nb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
780 struct packet_struct **ppacket)
782 struct nb_trans_state *state = tevent_req_data(
783 req, struct nb_trans_state);
784 NTSTATUS status;
786 if (tevent_req_is_nterror(req, &status)) {
787 return status;
789 *ppacket = talloc_move(mem_ctx, &state->packet);
790 return NT_STATUS_OK;
793 /****************************************************************************
794 Do a NBT node status query on an open socket and return an array of
795 structures holding the returned names or NULL if the query failed.
796 **************************************************************************/
798 struct node_status_query_state {
799 struct samba_sockaddr my_addr;
800 struct samba_sockaddr addr;
801 uint8_t buf[1024];
802 ssize_t buflen;
803 struct packet_struct *packet;
806 static bool node_status_query_validator(struct packet_struct *p,
807 void *private_data);
808 static void node_status_query_done(struct tevent_req *subreq);
810 struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
811 struct tevent_context *ev,
812 struct nmb_name *name,
813 const struct sockaddr_storage *addr)
815 struct tevent_req *req, *subreq;
816 struct node_status_query_state *state;
817 struct packet_struct p;
818 struct nmb_packet *nmb = &p.packet.nmb;
819 bool ok;
821 req = tevent_req_create(mem_ctx, &state,
822 struct node_status_query_state);
823 if (req == NULL) {
824 return NULL;
827 if (addr->ss_family != AF_INET) {
828 /* Can't do node status to IPv6 */
829 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
830 return tevent_req_post(req, ev);
833 ok = sockaddr_storage_to_samba_sockaddr(&state->addr, addr);
834 if (!ok) {
835 /* node status must be IPv4 */
836 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
837 return tevent_req_post(req, ev);
839 state->addr.u.in.sin_port = htons(NMB_PORT);
841 set_socket_addr_v4(&state->my_addr);
843 ZERO_STRUCT(p);
844 nmb->header.name_trn_id = generate_trn_id();
845 nmb->header.opcode = 0;
846 nmb->header.response = false;
847 nmb->header.nm_flags.bcast = false;
848 nmb->header.nm_flags.recursion_available = false;
849 nmb->header.nm_flags.recursion_desired = false;
850 nmb->header.nm_flags.trunc = false;
851 nmb->header.nm_flags.authoritative = false;
852 nmb->header.rcode = 0;
853 nmb->header.qdcount = 1;
854 nmb->header.ancount = 0;
855 nmb->header.nscount = 0;
856 nmb->header.arcount = 0;
857 nmb->question.question_name = *name;
858 nmb->question.question_type = 0x21;
859 nmb->question.question_class = 0x1;
861 state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
862 &p);
863 if (state->buflen == 0) {
864 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
865 DEBUG(10, ("build_packet failed\n"));
866 return tevent_req_post(req, ev);
869 subreq = nb_trans_send(state,
871 &state->my_addr,
872 &state->addr,
873 false,
874 state->buf,
875 state->buflen,
876 NMB_PACKET,
877 nmb->header.name_trn_id,
878 node_status_query_validator,
879 NULL);
880 if (tevent_req_nomem(subreq, req)) {
881 DEBUG(10, ("nb_trans_send failed\n"));
882 return tevent_req_post(req, ev);
884 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(10, 0))) {
885 return tevent_req_post(req, ev);
887 tevent_req_set_callback(subreq, node_status_query_done, req);
888 return req;
891 static bool node_status_query_validator(struct packet_struct *p,
892 void *private_data)
894 struct nmb_packet *nmb = &p->packet.nmb;
895 debug_nmb_packet(p);
897 if (nmb->header.opcode != 0 ||
898 nmb->header.nm_flags.bcast ||
899 nmb->header.rcode ||
900 !nmb->header.ancount ||
901 nmb->answers->rr_type != 0x21) {
903 * XXXX what do we do with this? could be a redirect,
904 * but we'll discard it for the moment
906 return false;
908 return true;
911 static void node_status_query_done(struct tevent_req *subreq)
913 struct tevent_req *req = tevent_req_callback_data(
914 subreq, struct tevent_req);
915 struct node_status_query_state *state = tevent_req_data(
916 req, struct node_status_query_state);
917 NTSTATUS status;
919 status = nb_trans_recv(subreq, state, &state->packet);
920 TALLOC_FREE(subreq);
921 if (tevent_req_nterror(req, status)) {
922 return;
924 tevent_req_done(req);
927 NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
928 struct node_status **pnode_status,
929 size_t *pnum_names,
930 struct node_status_extra *extra)
932 struct node_status_query_state *state = tevent_req_data(
933 req, struct node_status_query_state);
934 struct node_status *node_status;
935 size_t num_names = 0;
936 NTSTATUS status;
938 if (tevent_req_is_nterror(req, &status)) {
939 return status;
941 node_status = parse_node_status(
942 mem_ctx, &state->packet->packet.nmb.answers->rdata[0],
943 &num_names, extra);
944 if (node_status == NULL) {
945 return NT_STATUS_NO_MEMORY;
947 *pnode_status = node_status;
948 *pnum_names = num_names;
949 return NT_STATUS_OK;
952 NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name,
953 const struct sockaddr_storage *addr,
954 struct node_status **pnode_status,
955 size_t *pnum_names,
956 struct node_status_extra *extra)
958 TALLOC_CTX *frame = talloc_stackframe();
959 struct tevent_context *ev;
960 struct tevent_req *req;
961 NTSTATUS status = NT_STATUS_NO_MEMORY;
963 ev = samba_tevent_context_init(frame);
964 if (ev == NULL) {
965 goto fail;
967 req = node_status_query_send(ev, ev, name, addr);
968 if (req == NULL) {
969 goto fail;
971 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
972 goto fail;
974 status = node_status_query_recv(req, mem_ctx, pnode_status,
975 pnum_names, extra);
976 fail:
977 TALLOC_FREE(frame);
978 return status;
981 static bool name_status_lmhosts(const struct sockaddr_storage *paddr,
982 int qname_type, fstring pname)
984 FILE *f;
985 char *name;
986 int name_type;
987 struct samba_sockaddr addr_in = {0};
988 struct samba_sockaddr addr = {0};
989 bool ok;
991 ok = sockaddr_storage_to_samba_sockaddr(&addr_in, paddr);
992 if (!ok) {
993 return false;
995 if (addr_in.u.ss.ss_family != AF_INET) {
996 return false;
999 f = startlmhosts(get_dyn_LMHOSTSFILE());
1000 if (f == NULL) {
1001 return false;
1004 while (getlmhostsent(talloc_tos(), f, &name, &name_type, &addr.u.ss)) {
1005 if (addr.u.ss.ss_family != AF_INET) {
1006 continue;
1008 if (name_type != qname_type) {
1009 continue;
1011 if (sockaddr_equal(&addr_in.u.sa, &addr.u.sa)) {
1012 fstrcpy(pname, name);
1013 endlmhosts(f);
1014 return true;
1017 endlmhosts(f);
1018 return false;
1021 /****************************************************************************
1022 Find the first type XX name in a node status reply - used for finding
1023 a servers name given its IP. Return the matched name in *name.
1024 **************************************************************************/
1026 bool name_status_find(const char *q_name,
1027 int q_type,
1028 int type,
1029 const struct sockaddr_storage *to_ss,
1030 fstring name)
1032 char addr[INET6_ADDRSTRLEN];
1033 struct node_status *addrs = NULL;
1034 struct nmb_name nname;
1035 size_t count = 0, i;
1036 bool result = false;
1037 NTSTATUS status;
1039 if (lp_disable_netbios()) {
1040 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
1041 q_name, q_type));
1042 return False;
1045 print_sockaddr(addr, sizeof(addr), to_ss);
1047 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
1048 q_type, addr));
1050 /* Check the cache first. */
1052 if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
1053 return True;
1056 if (to_ss->ss_family != AF_INET) {
1057 /* Can't do node status to IPv6 */
1058 return false;
1061 result = name_status_lmhosts(to_ss, type, name);
1062 if (result) {
1063 DBG_DEBUG("Found name %s in lmhosts\n", name);
1064 namecache_status_store(q_name, q_type, type, to_ss, name);
1065 return true;
1068 /* W2K PDC's seem not to respond to '*'#0. JRA */
1069 make_nmb_name(&nname, q_name, q_type);
1070 status = node_status_query(talloc_tos(), &nname, to_ss,
1071 &addrs, &count, NULL);
1072 if (!NT_STATUS_IS_OK(status)) {
1073 goto done;
1076 for (i=0;i<count;i++) {
1077 /* Find first one of the requested type that's not a GROUP. */
1078 if (addrs[i].type == type && ! (addrs[i].flags & 0x80))
1079 break;
1081 if (i == count)
1082 goto done;
1084 pull_ascii_nstring(name, sizeof(fstring), addrs[i].name);
1086 /* Store the result in the cache. */
1087 /* but don't store an entry for 0x1c names here. Here we have
1088 a single host and DOMAIN<0x1c> names should be a list of hosts */
1090 if ( q_type != 0x1c ) {
1091 namecache_status_store(q_name, q_type, type, to_ss, name);
1094 result = true;
1096 done:
1097 TALLOC_FREE(addrs);
1099 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
1101 if (result)
1102 DEBUGADD(10, (", name %s ip address is %s", name, addr));
1104 DEBUG(10, ("\n"));
1106 return result;
1110 comparison function used by sort_addr_list
1113 static int addr_compare(const struct sockaddr_storage *ss1,
1114 const struct sockaddr_storage *ss2)
1116 int max_bits1=0, max_bits2=0;
1117 int num_interfaces = iface_count();
1118 int i;
1119 struct samba_sockaddr sa1;
1120 struct samba_sockaddr sa2;
1121 bool ok;
1123 ok = sockaddr_storage_to_samba_sockaddr(&sa1, ss1);
1124 if (!ok) {
1125 return 0; /* No change. */
1128 ok = sockaddr_storage_to_samba_sockaddr(&sa2, ss2);
1129 if (!ok) {
1130 return 0; /* No change. */
1133 /* Sort IPv4 addresses first. */
1134 if (sa1.u.ss.ss_family != sa2.u.ss.ss_family) {
1135 if (sa2.u.ss.ss_family == AF_INET) {
1136 return 1;
1137 } else {
1138 return -1;
1142 /* Here we know both addresses are of the same
1143 * family. */
1145 for (i=0;i<num_interfaces;i++) {
1146 struct samba_sockaddr sif = {0};
1147 const unsigned char *p_ss1 = NULL;
1148 const unsigned char *p_ss2 = NULL;
1149 const unsigned char *p_if = NULL;
1150 size_t len = 0;
1151 int bits1, bits2;
1153 ok = sockaddr_storage_to_samba_sockaddr(&sif, iface_n_bcast(i));
1154 if (!ok) {
1155 return 0; /* No change. */
1157 if (sif.u.ss.ss_family != sa1.u.ss.ss_family) {
1158 /* Ignore interfaces of the wrong type. */
1159 continue;
1161 if (sif.u.ss.ss_family == AF_INET) {
1162 p_if = (const unsigned char *)&sif.u.in.sin_addr;
1163 p_ss1 = (const unsigned char *)&sa1.u.in.sin_addr;
1164 p_ss2 = (const unsigned char *)&sa2.u.in.sin_addr;
1165 len = 4;
1167 #if defined(HAVE_IPV6)
1168 if (sif.u.ss.ss_family == AF_INET6) {
1169 p_if = (const unsigned char *)&sif.u.in6.sin6_addr;
1170 p_ss1 = (const unsigned char *)&sa1.u.in6.sin6_addr;
1171 p_ss2 = (const unsigned char *)&sa2.u.in6.sin6_addr;
1172 len = 16;
1174 #endif
1175 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
1176 continue;
1178 bits1 = matching_len_bits(p_ss1, p_if, len);
1179 bits2 = matching_len_bits(p_ss2, p_if, len);
1180 max_bits1 = MAX(bits1, max_bits1);
1181 max_bits2 = MAX(bits2, max_bits2);
1184 /* Bias towards directly reachable IPs */
1185 if (iface_local(&sa1.u.sa)) {
1186 if (sa1.u.ss.ss_family == AF_INET) {
1187 max_bits1 += 32;
1188 } else {
1189 max_bits1 += 128;
1192 if (iface_local(&sa2.u.sa)) {
1193 if (sa2.u.ss.ss_family == AF_INET) {
1194 max_bits2 += 32;
1195 } else {
1196 max_bits2 += 128;
1199 return max_bits2 - max_bits1;
1203 sort an IP list so that names that are close to one of our interfaces
1204 are at the top. This prevents the problem where a WINS server returns an IP
1205 that is not reachable from our subnet as the first match
1208 static void sort_addr_list(struct sockaddr_storage *sslist, size_t count)
1210 if (count <= 1) {
1211 return;
1214 TYPESAFE_QSORT(sslist, count, addr_compare);
1217 static int samba_sockaddr_compare(struct samba_sockaddr *sa1,
1218 struct samba_sockaddr *sa2)
1220 return addr_compare(&sa1->u.ss, &sa2->u.ss);
1223 static void sort_sa_list(struct samba_sockaddr *salist, size_t count)
1225 if (count <= 1) {
1226 return;
1229 TYPESAFE_QSORT(salist, count, samba_sockaddr_compare);
1232 /**********************************************************************
1233 Remove any duplicate address/port pairs in the samba_sockaddr array.
1234 *********************************************************************/
1236 size_t remove_duplicate_addrs2(struct samba_sockaddr *salist, size_t count )
1238 size_t i, j;
1240 DBG_DEBUG("looking for duplicate address/port pairs\n");
1242 /* One loop to set duplicates to a zero addr. */
1243 for (i=0; i < count; i++) {
1244 if (is_zero_addr(&salist[i].u.ss)) {
1245 continue;
1248 for (j=i+1; j<count; j++) {
1249 if (sockaddr_equal(&salist[i].u.sa, &salist[j].u.sa)) {
1250 zero_sockaddr(&salist[j].u.ss);
1255 /* Now remove any addresses set to zero above. */
1256 for (i = 0; i < count; i++) {
1257 while (i < count &&
1258 is_zero_addr(&salist[i].u.ss)) {
1259 ARRAY_DEL_ELEMENT(salist, i, count);
1260 count--;
1264 return count;
1267 static bool prioritize_ipv4_list(struct samba_sockaddr *salist, size_t count)
1269 TALLOC_CTX *frame = talloc_stackframe();
1270 struct samba_sockaddr *salist_new = talloc_array(frame,
1271 struct samba_sockaddr,
1272 count);
1273 size_t i, j;
1275 if (salist_new == NULL) {
1276 TALLOC_FREE(frame);
1277 return false;
1280 j = 0;
1282 /* Copy IPv4 first. */
1283 for (i = 0; i < count; i++) {
1284 if (salist[i].u.ss.ss_family == AF_INET) {
1285 salist_new[j++] = salist[i];
1289 /* Copy IPv6. */
1290 for (i = 0; i < count; i++) {
1291 if (salist[i].u.ss.ss_family != AF_INET) {
1292 salist_new[j++] = salist[i];
1296 memcpy(salist, salist_new, sizeof(struct samba_sockaddr)*count);
1297 TALLOC_FREE(frame);
1298 return true;
1301 /****************************************************************************
1302 Do a netbios name query to find someones IP.
1303 Returns an array of IP addresses or NULL if none.
1304 *count will be set to the number of addresses returned.
1305 *timed_out is set if we failed by timing out
1306 ****************************************************************************/
1308 struct name_query_state {
1309 struct samba_sockaddr my_addr;
1310 struct samba_sockaddr addr;
1311 bool bcast;
1312 bool bcast_star_query;
1315 uint8_t buf[1024];
1316 ssize_t buflen;
1318 NTSTATUS validate_error;
1319 uint8_t flags;
1321 struct sockaddr_storage *addrs;
1322 size_t num_addrs;
1325 static bool name_query_validator(struct packet_struct *p, void *private_data);
1326 static void name_query_done(struct tevent_req *subreq);
1328 struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
1329 struct tevent_context *ev,
1330 const char *name, int name_type,
1331 bool bcast, bool recurse,
1332 const struct sockaddr_storage *addr)
1334 struct tevent_req *req, *subreq;
1335 struct name_query_state *state;
1336 struct packet_struct p;
1337 struct nmb_packet *nmb = &p.packet.nmb;
1338 bool ok;
1340 req = tevent_req_create(mem_ctx, &state, struct name_query_state);
1341 if (req == NULL) {
1342 return NULL;
1344 state->bcast = bcast;
1346 if (addr->ss_family != AF_INET) {
1347 /* Can't do node status to IPv6 */
1348 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
1349 return tevent_req_post(req, ev);
1352 if (lp_disable_netbios()) {
1353 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
1354 name, name_type));
1355 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
1356 return tevent_req_post(req, ev);
1359 ok = sockaddr_storage_to_samba_sockaddr(&state->addr, addr);
1360 if (!ok) {
1361 /* Node status must be IPv4 */
1362 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
1363 return tevent_req_post(req, ev);
1365 state->addr.u.in.sin_port = htons(NMB_PORT);
1367 set_socket_addr_v4(&state->my_addr);
1369 ZERO_STRUCT(p);
1370 nmb->header.name_trn_id = generate_trn_id();
1371 nmb->header.opcode = 0;
1372 nmb->header.response = false;
1373 nmb->header.nm_flags.bcast = bcast;
1374 nmb->header.nm_flags.recursion_available = false;
1375 nmb->header.nm_flags.recursion_desired = recurse;
1376 nmb->header.nm_flags.trunc = false;
1377 nmb->header.nm_flags.authoritative = false;
1378 nmb->header.rcode = 0;
1379 nmb->header.qdcount = 1;
1380 nmb->header.ancount = 0;
1381 nmb->header.nscount = 0;
1382 nmb->header.arcount = 0;
1384 if (bcast && (strcmp(name, "*")==0)) {
1386 * We're doing a broadcast query for all
1387 * names in the area. Remember this so
1388 * we will wait for all names within
1389 * the timeout period.
1391 state->bcast_star_query = true;
1394 make_nmb_name(&nmb->question.question_name,name,name_type);
1396 nmb->question.question_type = 0x20;
1397 nmb->question.question_class = 0x1;
1399 state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
1400 &p);
1401 if (state->buflen == 0) {
1402 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1403 DEBUG(10, ("build_packet failed\n"));
1404 return tevent_req_post(req, ev);
1407 subreq = nb_trans_send(state,
1409 &state->my_addr,
1410 &state->addr,
1411 bcast,
1412 state->buf,
1413 state->buflen,
1414 NMB_PACKET,
1415 nmb->header.name_trn_id,
1416 name_query_validator,
1417 state);
1418 if (tevent_req_nomem(subreq, req)) {
1419 DEBUG(10, ("nb_trans_send failed\n"));
1420 return tevent_req_post(req, ev);
1422 tevent_req_set_callback(subreq, name_query_done, req);
1423 return req;
1426 static bool name_query_validator(struct packet_struct *p, void *private_data)
1428 struct name_query_state *state = talloc_get_type_abort(
1429 private_data, struct name_query_state);
1430 struct nmb_packet *nmb = &p->packet.nmb;
1431 struct sockaddr_storage *tmp_addrs;
1432 bool got_unique_netbios_name = false;
1433 int i;
1435 debug_nmb_packet(p);
1438 * If we get a Negative Name Query Response from a WINS
1439 * server, we should report it and give up.
1441 if( 0 == nmb->header.opcode /* A query response */
1442 && !state->bcast /* from a WINS server */
1443 && nmb->header.rcode /* Error returned */
1446 if( DEBUGLVL( 3 ) ) {
1447 /* Only executed if DEBUGLEVEL >= 3 */
1448 dbgtext( "Negative name query "
1449 "response, rcode 0x%02x: ",
1450 nmb->header.rcode );
1451 switch( nmb->header.rcode ) {
1452 case 0x01:
1453 dbgtext("Request was invalidly formatted.\n");
1454 break;
1455 case 0x02:
1456 dbgtext("Problem with NBNS, cannot process "
1457 "name.\n");
1458 break;
1459 case 0x03:
1460 dbgtext("The name requested does not "
1461 "exist.\n");
1462 break;
1463 case 0x04:
1464 dbgtext("Unsupported request error.\n");
1465 break;
1466 case 0x05:
1467 dbgtext("Query refused error.\n");
1468 break;
1469 default:
1470 dbgtext("Unrecognized error code.\n" );
1471 break;
1476 * We accept this packet as valid, but tell the upper
1477 * layers that it's a negative response.
1479 state->validate_error = NT_STATUS_NOT_FOUND;
1480 return true;
1483 if (nmb->header.opcode != 0 ||
1484 nmb->header.nm_flags.bcast ||
1485 nmb->header.rcode ||
1486 !nmb->header.ancount) {
1488 * XXXX what do we do with this? Could be a redirect,
1489 * but we'll discard it for the moment.
1491 return false;
1494 tmp_addrs = talloc_realloc(
1495 state, state->addrs, struct sockaddr_storage,
1496 state->num_addrs + nmb->answers->rdlength/6);
1497 if (tmp_addrs == NULL) {
1498 state->validate_error = NT_STATUS_NO_MEMORY;
1499 return true;
1501 state->addrs = tmp_addrs;
1503 DEBUG(2,("Got a positive name query response "
1504 "from %s ( ", inet_ntoa(p->ip)));
1506 for (i=0; i<nmb->answers->rdlength/6; i++) {
1507 uint16_t flags;
1508 struct in_addr ip;
1509 struct sockaddr_storage addr;
1510 struct samba_sockaddr sa = {0};
1511 bool ok;
1512 int j;
1514 flags = RSVAL(&nmb->answers->rdata[i*6], 0);
1515 got_unique_netbios_name |= ((flags & 0x8000) == 0);
1517 putip((char *)&ip,&nmb->answers->rdata[2+i*6]);
1518 in_addr_to_sockaddr_storage(&addr, ip);
1520 ok = sockaddr_storage_to_samba_sockaddr(&sa, &addr);
1521 if (!ok) {
1522 continue;
1525 if (is_zero_addr(&sa.u.ss)) {
1526 continue;
1529 for (j=0; j<state->num_addrs; j++) {
1530 struct samba_sockaddr sa_j = {0};
1532 ok = sockaddr_storage_to_samba_sockaddr(&sa_j,
1533 &state->addrs[j]);
1534 if (!ok) {
1535 continue;
1537 if (sockaddr_equal(&sa.u.sa, &sa_j.u.sa)) {
1538 break;
1541 if (j < state->num_addrs) {
1542 /* Already got it */
1543 continue;
1546 DEBUGADD(2,("%s ",inet_ntoa(ip)));
1548 state->addrs[state->num_addrs] = addr;
1549 /* wrap check. */
1550 if (state->num_addrs + 1 < state->num_addrs) {
1551 return false;
1553 state->num_addrs += 1;
1555 DEBUGADD(2,(")\n"));
1557 /* We add the flags back ... */
1558 if (nmb->header.response)
1559 state->flags |= NM_FLAGS_RS;
1560 if (nmb->header.nm_flags.authoritative)
1561 state->flags |= NM_FLAGS_AA;
1562 if (nmb->header.nm_flags.trunc)
1563 state->flags |= NM_FLAGS_TC;
1564 if (nmb->header.nm_flags.recursion_desired)
1565 state->flags |= NM_FLAGS_RD;
1566 if (nmb->header.nm_flags.recursion_available)
1567 state->flags |= NM_FLAGS_RA;
1568 if (nmb->header.nm_flags.bcast)
1569 state->flags |= NM_FLAGS_B;
1571 if (state->bcast) {
1573 * We have to collect all entries coming in from broadcast
1574 * queries. If we got a unique name and we are not querying
1575 * all names registered within broadcast area (query
1576 * for the name '*', so state->bcast_star_query is set),
1577 * we're done.
1579 return (got_unique_netbios_name && !state->bcast_star_query);
1582 * WINS responses are accepted when they are received
1584 return true;
1587 static void name_query_done(struct tevent_req *subreq)
1589 struct tevent_req *req = tevent_req_callback_data(
1590 subreq, struct tevent_req);
1591 struct name_query_state *state = tevent_req_data(
1592 req, struct name_query_state);
1593 NTSTATUS status;
1594 struct packet_struct *p = NULL;
1596 status = nb_trans_recv(subreq, state, &p);
1597 TALLOC_FREE(subreq);
1598 if (tevent_req_nterror(req, status)) {
1599 return;
1601 if (!NT_STATUS_IS_OK(state->validate_error)) {
1602 tevent_req_nterror(req, state->validate_error);
1603 return;
1605 tevent_req_done(req);
1608 NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1609 struct sockaddr_storage **addrs, size_t *num_addrs,
1610 uint8_t *flags)
1612 struct name_query_state *state = tevent_req_data(
1613 req, struct name_query_state);
1614 NTSTATUS status;
1616 if (tevent_req_is_nterror(req, &status)) {
1617 if (state->bcast &&
1618 NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1620 * In the broadcast case we collect replies until the
1621 * timeout.
1623 status = NT_STATUS_OK;
1625 if (!NT_STATUS_IS_OK(status)) {
1626 return status;
1629 if (state->num_addrs == 0) {
1630 return NT_STATUS_NOT_FOUND;
1632 *addrs = talloc_move(mem_ctx, &state->addrs);
1633 sort_addr_list(*addrs, state->num_addrs);
1634 *num_addrs = state->num_addrs;
1635 if (flags != NULL) {
1636 *flags = state->flags;
1638 return NT_STATUS_OK;
1641 NTSTATUS name_query(const char *name, int name_type,
1642 bool bcast, bool recurse,
1643 const struct sockaddr_storage *to_ss,
1644 TALLOC_CTX *mem_ctx,
1645 struct sockaddr_storage **addrs,
1646 size_t *num_addrs, uint8_t *flags)
1648 TALLOC_CTX *frame = talloc_stackframe();
1649 struct tevent_context *ev;
1650 struct tevent_req *req;
1651 struct timeval timeout;
1652 NTSTATUS status = NT_STATUS_NO_MEMORY;
1654 ev = samba_tevent_context_init(frame);
1655 if (ev == NULL) {
1656 goto fail;
1658 req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss);
1659 if (req == NULL) {
1660 goto fail;
1662 if (bcast) {
1663 timeout = timeval_current_ofs(0, 250000);
1664 } else {
1665 timeout = timeval_current_ofs(2, 0);
1667 if (!tevent_req_set_endtime(req, ev, timeout)) {
1668 goto fail;
1670 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1671 goto fail;
1673 status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags);
1674 fail:
1675 TALLOC_FREE(frame);
1676 return status;
1679 struct name_queries_state {
1680 struct tevent_context *ev;
1681 const char *name;
1682 int name_type;
1683 bool bcast;
1684 bool recurse;
1685 const struct sockaddr_storage *addrs;
1686 size_t num_addrs;
1687 int wait_msec;
1688 int timeout_msec;
1690 struct tevent_req **subreqs;
1691 size_t num_received;
1692 size_t num_sent;
1694 size_t received_index;
1695 struct sockaddr_storage *result_addrs;
1696 size_t num_result_addrs;
1697 uint8_t flags;
1700 static void name_queries_done(struct tevent_req *subreq);
1701 static void name_queries_next(struct tevent_req *subreq);
1704 * Send a name query to multiple destinations with a wait time in between
1707 static struct tevent_req *name_queries_send(
1708 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1709 const char *name, int name_type,
1710 bool bcast, bool recurse,
1711 const struct sockaddr_storage *addrs,
1712 size_t num_addrs, int wait_msec, int timeout_msec)
1714 struct tevent_req *req, *subreq;
1715 struct name_queries_state *state;
1717 req = tevent_req_create(mem_ctx, &state,
1718 struct name_queries_state);
1719 if (req == NULL) {
1720 return NULL;
1722 state->ev = ev;
1723 state->name = name;
1724 state->name_type = name_type;
1725 state->bcast = bcast;
1726 state->recurse = recurse;
1727 state->addrs = addrs;
1728 state->num_addrs = num_addrs;
1729 state->wait_msec = wait_msec;
1730 state->timeout_msec = timeout_msec;
1732 state->subreqs = talloc_zero_array(
1733 state, struct tevent_req *, num_addrs);
1734 if (tevent_req_nomem(state->subreqs, req)) {
1735 return tevent_req_post(req, ev);
1737 state->num_sent = 0;
1739 subreq = name_query_send(
1740 state->subreqs, state->ev, name, name_type, bcast, recurse,
1741 &state->addrs[state->num_sent]);
1742 if (tevent_req_nomem(subreq, req)) {
1743 return tevent_req_post(req, ev);
1745 if (!tevent_req_set_endtime(
1746 subreq, state->ev,
1747 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1748 return tevent_req_post(req, ev);
1750 tevent_req_set_callback(subreq, name_queries_done, req);
1752 state->subreqs[state->num_sent] = subreq;
1753 state->num_sent += 1;
1755 if (state->num_sent < state->num_addrs) {
1756 subreq = tevent_wakeup_send(
1757 state, state->ev,
1758 timeval_current_ofs(0, state->wait_msec * 1000));
1759 if (tevent_req_nomem(subreq, req)) {
1760 return tevent_req_post(req, ev);
1762 tevent_req_set_callback(subreq, name_queries_next, req);
1764 return req;
1767 static void name_queries_done(struct tevent_req *subreq)
1769 struct tevent_req *req = tevent_req_callback_data(
1770 subreq, struct tevent_req);
1771 struct name_queries_state *state = tevent_req_data(
1772 req, struct name_queries_state);
1773 size_t i;
1774 NTSTATUS status;
1776 status = name_query_recv(subreq, state, &state->result_addrs,
1777 &state->num_result_addrs, &state->flags);
1779 for (i=0; i<state->num_sent; i++) {
1780 if (state->subreqs[i] == subreq) {
1781 break;
1784 if (i == state->num_sent) {
1785 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1786 return;
1788 TALLOC_FREE(state->subreqs[i]);
1790 /* wrap check. */
1791 if (state->num_received + 1 < state->num_received) {
1792 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1793 return;
1795 state->num_received += 1;
1797 if (!NT_STATUS_IS_OK(status)) {
1799 if (state->num_received >= state->num_addrs) {
1800 tevent_req_nterror(req, status);
1801 return;
1804 * Still outstanding requests, just wait
1806 return;
1808 state->received_index = i;
1809 tevent_req_done(req);
1812 static void name_queries_next(struct tevent_req *subreq)
1814 struct tevent_req *req = tevent_req_callback_data(
1815 subreq, struct tevent_req);
1816 struct name_queries_state *state = tevent_req_data(
1817 req, struct name_queries_state);
1819 if (!tevent_wakeup_recv(subreq)) {
1820 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1821 return;
1824 subreq = name_query_send(
1825 state->subreqs, state->ev,
1826 state->name, state->name_type, state->bcast, state->recurse,
1827 &state->addrs[state->num_sent]);
1828 if (tevent_req_nomem(subreq, req)) {
1829 return;
1831 tevent_req_set_callback(subreq, name_queries_done, req);
1832 if (!tevent_req_set_endtime(
1833 subreq, state->ev,
1834 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1835 return;
1837 state->subreqs[state->num_sent] = subreq;
1838 state->num_sent += 1;
1840 if (state->num_sent < state->num_addrs) {
1841 subreq = tevent_wakeup_send(
1842 state, state->ev,
1843 timeval_current_ofs(0, state->wait_msec * 1000));
1844 if (tevent_req_nomem(subreq, req)) {
1845 return;
1847 tevent_req_set_callback(subreq, name_queries_next, req);
1851 static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1852 struct sockaddr_storage **result_addrs,
1853 size_t *num_result_addrs, uint8_t *flags,
1854 size_t *received_index)
1856 struct name_queries_state *state = tevent_req_data(
1857 req, struct name_queries_state);
1858 NTSTATUS status;
1860 if (tevent_req_is_nterror(req, &status)) {
1861 return status;
1864 if (result_addrs != NULL) {
1865 *result_addrs = talloc_move(mem_ctx, &state->result_addrs);
1867 if (num_result_addrs != NULL) {
1868 *num_result_addrs = state->num_result_addrs;
1870 if (flags != NULL) {
1871 *flags = state->flags;
1873 if (received_index != NULL) {
1874 *received_index = state->received_index;
1876 return NT_STATUS_OK;
1879 /********************************************************
1880 Resolve via "bcast" method.
1881 *********************************************************/
1883 struct name_resolve_bcast_state {
1884 struct sockaddr_storage *addrs;
1885 size_t num_addrs;
1888 static void name_resolve_bcast_done(struct tevent_req *subreq);
1890 struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx,
1891 struct tevent_context *ev,
1892 const char *name,
1893 int name_type)
1895 struct tevent_req *req, *subreq;
1896 struct name_resolve_bcast_state *state;
1897 struct sockaddr_storage *bcast_addrs;
1898 size_t i, num_addrs, num_bcast_addrs;
1900 req = tevent_req_create(mem_ctx, &state,
1901 struct name_resolve_bcast_state);
1902 if (req == NULL) {
1903 return NULL;
1906 if (lp_disable_netbios()) {
1907 DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n",
1908 name, name_type));
1909 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1910 return tevent_req_post(req, ev);
1914 * "bcast" means do a broadcast lookup on all the local interfaces.
1917 DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup "
1918 "for name %s<0x%x>\n", name, name_type));
1920 num_addrs = iface_count();
1921 bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs);
1922 if (tevent_req_nomem(bcast_addrs, req)) {
1923 return tevent_req_post(req, ev);
1927 * Lookup the name on all the interfaces, return on
1928 * the first successful match.
1930 num_bcast_addrs = 0;
1932 for (i=0; i<num_addrs; i++) {
1933 const struct sockaddr_storage *pss = iface_n_bcast(i);
1935 if (pss->ss_family != AF_INET) {
1936 continue;
1938 bcast_addrs[num_bcast_addrs] = *pss;
1939 num_bcast_addrs += 1;
1942 subreq = name_queries_send(state, ev, name, name_type, true, true,
1943 bcast_addrs, num_bcast_addrs, 0, 250);
1944 if (tevent_req_nomem(subreq, req)) {
1945 return tevent_req_post(req, ev);
1947 tevent_req_set_callback(subreq, name_resolve_bcast_done, req);
1948 return req;
1951 static void name_resolve_bcast_done(struct tevent_req *subreq)
1953 struct tevent_req *req = tevent_req_callback_data(
1954 subreq, struct tevent_req);
1955 struct name_resolve_bcast_state *state = tevent_req_data(
1956 req, struct name_resolve_bcast_state);
1957 NTSTATUS status;
1959 status = name_queries_recv(subreq, state,
1960 &state->addrs, &state->num_addrs,
1961 NULL, NULL);
1962 TALLOC_FREE(subreq);
1963 if (tevent_req_nterror(req, status)) {
1964 return;
1966 tevent_req_done(req);
1969 NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1970 struct sockaddr_storage **addrs,
1971 size_t *num_addrs)
1973 struct name_resolve_bcast_state *state = tevent_req_data(
1974 req, struct name_resolve_bcast_state);
1975 NTSTATUS status;
1977 if (tevent_req_is_nterror(req, &status)) {
1978 return status;
1980 *addrs = talloc_move(mem_ctx, &state->addrs);
1981 *num_addrs = state->num_addrs;
1982 return NT_STATUS_OK;
1985 NTSTATUS name_resolve_bcast(TALLOC_CTX *mem_ctx,
1986 const char *name,
1987 int name_type,
1988 struct sockaddr_storage **return_iplist,
1989 size_t *return_count)
1991 TALLOC_CTX *frame = talloc_stackframe();
1992 struct tevent_context *ev;
1993 struct tevent_req *req;
1994 NTSTATUS status = NT_STATUS_NO_MEMORY;
1996 ev = samba_tevent_context_init(frame);
1997 if (ev == NULL) {
1998 goto fail;
2000 req = name_resolve_bcast_send(frame, ev, name, name_type);
2001 if (req == NULL) {
2002 goto fail;
2004 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2005 goto fail;
2007 status = name_resolve_bcast_recv(req, mem_ctx, return_iplist,
2008 return_count);
2009 fail:
2010 TALLOC_FREE(frame);
2011 return status;
2014 struct query_wins_list_state {
2015 struct tevent_context *ev;
2016 const char *name;
2017 uint8_t name_type;
2018 struct in_addr *servers;
2019 size_t num_servers;
2020 struct sockaddr_storage server;
2021 size_t num_sent;
2023 struct sockaddr_storage *addrs;
2024 size_t num_addrs;
2025 uint8_t flags;
2028 static void query_wins_list_done(struct tevent_req *subreq);
2031 * Query a list of (replicating) wins servers in sequence, call them
2032 * dead if they don't reply
2035 static struct tevent_req *query_wins_list_send(
2036 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
2037 struct in_addr src_ip, const char *name, uint8_t name_type,
2038 struct in_addr *servers, size_t num_servers)
2040 struct tevent_req *req, *subreq;
2041 struct query_wins_list_state *state;
2043 req = tevent_req_create(mem_ctx, &state,
2044 struct query_wins_list_state);
2045 if (req == NULL) {
2046 return NULL;
2048 state->ev = ev;
2049 state->name = name;
2050 state->name_type = name_type;
2051 state->servers = servers;
2052 state->num_servers = num_servers;
2054 if (state->num_servers == 0) {
2055 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2056 return tevent_req_post(req, ev);
2059 in_addr_to_sockaddr_storage(
2060 &state->server, state->servers[state->num_sent]);
2062 subreq = name_query_send(state, state->ev,
2063 state->name, state->name_type,
2064 false, true, &state->server);
2066 if (tevent_req_nomem(subreq, req)) {
2067 return tevent_req_post(req, ev);
2070 /* wrap check */
2071 if (state->num_sent + 1 < state->num_sent) {
2072 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2073 return tevent_req_post(req, ev);
2076 state->num_sent += 1;
2077 if (!tevent_req_set_endtime(subreq, state->ev,
2078 timeval_current_ofs(2, 0))) {
2079 return tevent_req_post(req, ev);
2081 tevent_req_set_callback(subreq, query_wins_list_done, req);
2082 return req;
2085 static void query_wins_list_done(struct tevent_req *subreq)
2087 struct tevent_req *req = tevent_req_callback_data(
2088 subreq, struct tevent_req);
2089 struct query_wins_list_state *state = tevent_req_data(
2090 req, struct query_wins_list_state);
2091 NTSTATUS status;
2093 status = name_query_recv(subreq, state,
2094 &state->addrs, &state->num_addrs,
2095 &state->flags);
2096 TALLOC_FREE(subreq);
2097 if (NT_STATUS_IS_OK(status)) {
2098 tevent_req_done(req);
2099 return;
2101 if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
2102 tevent_req_nterror(req, status);
2103 return;
2105 wins_srv_died(state->servers[state->num_sent-1],
2106 my_socket_addr_v4());
2108 if (state->num_sent == state->num_servers) {
2109 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2110 return;
2113 in_addr_to_sockaddr_storage(
2114 &state->server, state->servers[state->num_sent]);
2116 subreq = name_query_send(state, state->ev,
2117 state->name, state->name_type,
2118 false, true, &state->server);
2119 state->num_sent += 1;
2120 if (tevent_req_nomem(subreq, req)) {
2121 return;
2123 if (!tevent_req_set_endtime(subreq, state->ev,
2124 timeval_current_ofs(2, 0))) {
2125 return;
2127 tevent_req_set_callback(subreq, query_wins_list_done, req);
2130 static NTSTATUS query_wins_list_recv(struct tevent_req *req,
2131 TALLOC_CTX *mem_ctx,
2132 struct sockaddr_storage **addrs,
2133 size_t *num_addrs,
2134 uint8_t *flags)
2136 struct query_wins_list_state *state = tevent_req_data(
2137 req, struct query_wins_list_state);
2138 NTSTATUS status;
2140 if (tevent_req_is_nterror(req, &status)) {
2141 return status;
2143 if (addrs != NULL) {
2144 *addrs = talloc_move(mem_ctx, &state->addrs);
2146 if (num_addrs != NULL) {
2147 *num_addrs = state->num_addrs;
2149 if (flags != NULL) {
2150 *flags = state->flags;
2152 return NT_STATUS_OK;
2155 struct resolve_wins_state {
2156 size_t num_sent;
2157 size_t num_received;
2159 struct sockaddr_storage *addrs;
2160 size_t num_addrs;
2161 uint8_t flags;
2164 static void resolve_wins_done(struct tevent_req *subreq);
2166 struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
2167 struct tevent_context *ev,
2168 const char *name,
2169 int name_type)
2171 struct tevent_req *req, *subreq;
2172 struct resolve_wins_state *state;
2173 char **wins_tags = NULL;
2174 struct sockaddr_storage src_ss;
2175 struct samba_sockaddr src_sa = {0};
2176 struct in_addr src_ip;
2177 size_t i, num_wins_tags;
2178 bool ok;
2180 req = tevent_req_create(mem_ctx, &state,
2181 struct resolve_wins_state);
2182 if (req == NULL) {
2183 return NULL;
2186 if (wins_srv_count() < 1) {
2187 DEBUG(3,("resolve_wins: WINS server resolution selected "
2188 "and no WINS servers listed.\n"));
2189 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2190 goto fail;
2193 /* the address we will be sending from */
2194 if (!interpret_string_addr(&src_ss, lp_nbt_client_socket_address(),
2195 AI_NUMERICHOST|AI_PASSIVE)) {
2196 zero_sockaddr(&src_ss);
2199 ok = sockaddr_storage_to_samba_sockaddr(&src_sa, &src_ss);
2200 if (!ok) {
2201 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2202 goto fail;
2205 if (src_sa.u.ss.ss_family != AF_INET) {
2206 char addr[INET6_ADDRSTRLEN];
2207 print_sockaddr(addr, sizeof(addr), &src_sa.u.ss);
2208 DEBUG(3,("resolve_wins: cannot receive WINS replies "
2209 "on IPv6 address %s\n",
2210 addr));
2211 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2212 goto fail;
2215 src_ip = src_sa.u.in.sin_addr;
2217 wins_tags = wins_srv_tags();
2218 if (wins_tags == NULL) {
2219 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2220 goto fail;
2223 num_wins_tags = 0;
2224 while (wins_tags[num_wins_tags] != NULL) {
2225 /* wrap check. */
2226 if (num_wins_tags + 1 < num_wins_tags) {
2227 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2228 goto fail;
2230 num_wins_tags += 1;
2233 for (i=0; i<num_wins_tags; i++) {
2234 size_t num_servers, num_alive;
2235 struct in_addr *servers, *alive;
2236 size_t j;
2238 if (!wins_server_tag_ips(wins_tags[i], talloc_tos(),
2239 &servers, &num_servers)) {
2240 DEBUG(10, ("wins_server_tag_ips failed for tag %s\n",
2241 wins_tags[i]));
2242 continue;
2245 alive = talloc_array(state, struct in_addr, num_servers);
2246 if (tevent_req_nomem(alive, req)) {
2247 goto fail;
2250 num_alive = 0;
2251 for (j=0; j<num_servers; j++) {
2252 struct in_addr wins_ip = servers[j];
2254 if (global_in_nmbd && ismyip_v4(wins_ip)) {
2255 /* yikes! we'll loop forever */
2256 continue;
2258 /* skip any that have been unresponsive lately */
2259 if (wins_srv_is_dead(wins_ip, src_ip)) {
2260 continue;
2262 DEBUG(3, ("resolve_wins: using WINS server %s "
2263 "and tag '%s'\n",
2264 inet_ntoa(wins_ip), wins_tags[i]));
2265 alive[num_alive] = wins_ip;
2266 num_alive += 1;
2268 TALLOC_FREE(servers);
2270 if (num_alive == 0) {
2271 continue;
2274 subreq = query_wins_list_send(
2275 state, ev, src_ip, name, name_type,
2276 alive, num_alive);
2277 if (tevent_req_nomem(subreq, req)) {
2278 goto fail;
2280 tevent_req_set_callback(subreq, resolve_wins_done, req);
2281 state->num_sent += 1;
2284 if (state->num_sent == 0) {
2285 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2286 goto fail;
2289 wins_srv_tags_free(wins_tags);
2290 return req;
2291 fail:
2292 wins_srv_tags_free(wins_tags);
2293 return tevent_req_post(req, ev);
2296 static void resolve_wins_done(struct tevent_req *subreq)
2298 struct tevent_req *req = tevent_req_callback_data(
2299 subreq, struct tevent_req);
2300 struct resolve_wins_state *state = tevent_req_data(
2301 req, struct resolve_wins_state);
2302 NTSTATUS status;
2304 status = query_wins_list_recv(subreq, state, &state->addrs,
2305 &state->num_addrs, &state->flags);
2306 if (NT_STATUS_IS_OK(status)) {
2307 tevent_req_done(req);
2308 return;
2311 /* wrap check. */
2312 if (state->num_received + 1 < state->num_received) {
2313 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2314 return;
2317 state->num_received += 1;
2319 if (state->num_received < state->num_sent) {
2321 * Wait for the others
2323 return;
2325 tevent_req_nterror(req, status);
2328 NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2329 struct sockaddr_storage **addrs,
2330 size_t *num_addrs, uint8_t *flags)
2332 struct resolve_wins_state *state = tevent_req_data(
2333 req, struct resolve_wins_state);
2334 NTSTATUS status;
2336 if (tevent_req_is_nterror(req, &status)) {
2337 return status;
2339 if (addrs != NULL) {
2340 *addrs = talloc_move(mem_ctx, &state->addrs);
2342 if (num_addrs != NULL) {
2343 *num_addrs = state->num_addrs;
2345 if (flags != NULL) {
2346 *flags = state->flags;
2348 return NT_STATUS_OK;
2351 /********************************************************
2352 Resolve via "wins" method.
2353 *********************************************************/
2355 NTSTATUS resolve_wins(TALLOC_CTX *mem_ctx,
2356 const char *name,
2357 int name_type,
2358 struct sockaddr_storage **return_iplist,
2359 size_t *return_count)
2361 struct tevent_context *ev;
2362 struct tevent_req *req;
2363 NTSTATUS status = NT_STATUS_NO_MEMORY;
2365 ev = samba_tevent_context_init(talloc_tos());
2366 if (ev == NULL) {
2367 goto fail;
2369 req = resolve_wins_send(ev, ev, name, name_type);
2370 if (req == NULL) {
2371 goto fail;
2373 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2374 goto fail;
2376 status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count,
2377 NULL);
2378 fail:
2379 TALLOC_FREE(ev);
2380 return status;
2383 /********************************************************
2384 Use ads_dns_lookup_[a|aaaa]_send() calls to look up a
2385 list of names asynchronously.
2386 *********************************************************/
2388 struct dns_query_state {
2389 /* Used to tell our parent we've completed. */
2390 struct dns_lookup_list_async_state *p_async_state;
2391 const char *query_name; /* For debugging only. */
2392 size_t num_addrs;
2393 struct samba_sockaddr *addrs;
2396 struct dns_lookup_list_async_state {
2397 bool timed_out;
2398 size_t num_query_returns;
2399 struct dns_query_state *queries;
2402 /* Called on query timeout. */
2403 static void dns_lookup_send_timeout_handler(struct tevent_context *ev,
2404 struct tevent_timer *te,
2405 struct timeval t,
2406 void *private_data)
2408 bool *timed_out = (bool *)private_data;
2409 *timed_out = true;
2412 static void dns_lookup_list_a_done(struct tevent_req *req);
2413 #if defined(HAVE_IPV6)
2414 static void dns_lookup_list_aaaa_done(struct tevent_req *req);
2415 #endif
2417 NTSTATUS dns_lookup_list_async(TALLOC_CTX *ctx,
2418 size_t num_dns_names,
2419 const char **dns_lookup_names,
2420 size_t *p_num_addrs,
2421 struct samba_sockaddr **pp_addrs,
2422 char ***pp_dns_names)
2424 struct dns_lookup_list_async_state *state = NULL;
2425 struct tevent_context *ev = NULL;
2426 struct tevent_req *req = NULL;
2427 struct tevent_timer *timer = NULL;
2428 size_t num_queries_sent = 0;
2429 size_t queries_size = num_dns_names;
2430 size_t i;
2431 size_t num_addrs = 0;
2432 struct samba_sockaddr *addr_out = NULL;
2433 char **dns_names_ret = NULL;
2434 NTSTATUS status = NT_STATUS_NO_MEMORY;
2436 /* Nothing to do. */
2437 if (num_dns_names == 0) {
2438 *p_num_addrs = 0;
2439 *pp_addrs = NULL;
2440 if (pp_dns_names != NULL) {
2441 *pp_dns_names = NULL;
2443 return NT_STATUS_OK;
2446 state = talloc_zero(ctx, struct dns_lookup_list_async_state);
2447 if (state == NULL) {
2448 goto fail;
2450 ev = samba_tevent_context_init(ctx);
2451 if (ev == NULL) {
2452 goto fail;
2455 #if defined(HAVE_IPV6)
2456 queries_size = 2 * num_dns_names;
2457 /* Wrap protection. */
2458 if (queries_size < num_dns_names) {
2459 goto fail;
2461 #else
2462 queries_size = num_dns_names;
2463 #endif
2465 state->queries = talloc_zero_array(state,
2466 struct dns_query_state,
2467 queries_size);
2468 if (state->queries == NULL) {
2469 goto fail;
2472 /* Hit all the DNS servers with async lookups for all the names. */
2473 for (i = 0; i < num_dns_names; i++) {
2474 DBG_INFO("async DNS lookup A record for %s\n",
2475 dns_lookup_names[i]);
2477 /* Setup the query state. */
2478 state->queries[num_queries_sent].query_name =
2479 dns_lookup_names[i];
2480 state->queries[num_queries_sent].p_async_state = state;
2482 req = ads_dns_lookup_a_send(ev, ev, dns_lookup_names[i]);
2483 if (req == NULL) {
2484 goto fail;
2486 tevent_req_set_callback(req,
2487 dns_lookup_list_a_done,
2488 &state->queries[num_queries_sent]);
2489 num_queries_sent++;
2491 #if defined(HAVE_IPV6)
2492 /* If we're IPv6 capable ask for that too. */
2493 state->queries[num_queries_sent].query_name =
2494 dns_lookup_names[i];
2495 state->queries[num_queries_sent].p_async_state = state;
2497 DBG_INFO("async DNS lookup AAAA record for %s\n",
2498 dns_lookup_names[i]);
2500 req = ads_dns_lookup_aaaa_send(ev, ev, dns_lookup_names[i]);
2501 if (req == NULL) {
2502 goto fail;
2504 tevent_req_set_callback(req,
2505 dns_lookup_list_aaaa_done,
2506 &state->queries[num_queries_sent]);
2507 num_queries_sent++;
2508 #endif
2511 /* We must always have a timeout. */
2512 timer = tevent_add_timer(ev,
2514 timeval_current_ofs(lp_get_async_dns_timeout(),
2516 dns_lookup_send_timeout_handler,
2517 &state->timed_out);
2518 if (timer == NULL) {
2519 goto fail;
2522 /* Loop until timed out or got all replies. */
2523 for(;;) {
2524 int ret;
2526 if (state->timed_out) {
2527 break;
2529 if (state->num_query_returns == num_queries_sent) {
2530 break;
2532 ret = tevent_loop_once(ev);
2533 if (ret != 0) {
2534 goto fail;
2538 /* Count what we got back. */
2539 for (i = 0; i < num_queries_sent; i++) {
2540 struct dns_query_state *query = &state->queries[i];
2542 /* Wrap check. */
2543 if (num_addrs + query->num_addrs < num_addrs) {
2544 goto fail;
2546 num_addrs += query->num_addrs;
2549 if (state->timed_out) {
2550 DBG_INFO("async DNS lookup timed out after %zu entries "
2551 "(not an error)\n",
2552 num_addrs);
2555 addr_out = talloc_zero_array(ctx,
2556 struct samba_sockaddr,
2557 num_addrs);
2558 if (addr_out == NULL) {
2559 goto fail;
2563 * Did the caller want an array of names back
2564 * that match the IP addresses ? If we provide
2565 * this, dsgetdcname() internals can now use this
2566 * async lookup code also.
2568 if (pp_dns_names != NULL) {
2569 dns_names_ret = talloc_zero_array(ctx,
2570 char *,
2571 num_addrs);
2572 if (dns_names_ret == NULL) {
2573 goto fail;
2577 /* Copy what we got back. */
2578 num_addrs = 0;
2579 for (i = 0; i < num_queries_sent; i++) {
2580 size_t j;
2581 struct dns_query_state *query = &state->queries[i];
2583 if (query->num_addrs == 0) {
2584 continue;
2587 if (dns_names_ret != NULL) {
2589 * If caller wants a name array matched with
2590 * the addrs array, copy the same queried name for
2591 * each IP address returned.
2593 for (j = 0; j < query->num_addrs; j++) {
2594 dns_names_ret[num_addrs + j] = talloc_strdup(
2595 ctx,
2596 query->query_name);
2597 if (dns_names_ret[num_addrs + j] == NULL) {
2598 goto fail;
2603 for (j = 0; j < query->num_addrs; j++) {
2604 addr_out[num_addrs] = query->addrs[j];
2606 num_addrs += query->num_addrs;
2609 *p_num_addrs = num_addrs;
2610 *pp_addrs = addr_out;
2611 if (pp_dns_names != NULL) {
2612 *pp_dns_names = dns_names_ret;
2615 status = NT_STATUS_OK;
2617 fail:
2619 TALLOC_FREE(state);
2620 TALLOC_FREE(ev);
2621 return status;
2625 Called when an A record lookup completes.
2628 static void dns_lookup_list_a_done(struct tevent_req *req)
2631 * Callback data is an element of a talloc'ed array,
2632 * not a talloc object in its own right. So use the
2633 * tevent_req_callback_data_void() void * cast function.
2635 struct dns_query_state *state = (struct dns_query_state *)
2636 tevent_req_callback_data_void(req);
2637 uint8_t rcode = 0;
2638 size_t i;
2639 char **hostnames_out = NULL;
2640 struct samba_sockaddr *addrs = NULL;
2641 size_t num_addrs = 0;
2642 NTSTATUS status;
2644 /* For good or ill, tell the parent we're finished. */
2645 state->p_async_state->num_query_returns++;
2647 status = ads_dns_lookup_a_recv(req,
2648 state->p_async_state,
2649 &rcode,
2650 &num_addrs,
2651 &hostnames_out,
2652 &addrs);
2653 if (!NT_STATUS_IS_OK(status)) {
2654 DBG_INFO("async DNS A lookup for %s returned %s\n",
2655 state->query_name,
2656 nt_errstr(status));
2657 return;
2660 if (rcode != DNS_RCODE_OK) {
2661 DBG_INFO("async DNS A lookup for %s returned DNS code %u\n",
2662 state->query_name,
2663 (unsigned int)rcode);
2664 return;
2667 if (num_addrs == 0) {
2668 DBG_INFO("async DNS A lookup for %s returned 0 addresses.\n",
2669 state->query_name);
2670 return;
2673 /* Copy data out. */
2674 state->addrs = talloc_zero_array(state->p_async_state,
2675 struct samba_sockaddr,
2676 num_addrs);
2677 if (state->addrs == NULL) {
2678 return;
2681 for (i = 0; i < num_addrs; i++) {
2682 char addr[INET6_ADDRSTRLEN];
2683 DBG_INFO("async DNS A lookup for %s [%zu] got %s -> %s\n",
2684 state->query_name,
2686 hostnames_out[i],
2687 print_sockaddr(addr,
2688 sizeof(addr),
2689 &addrs[i].u.ss));
2691 state->addrs[i] = addrs[i];
2693 state->num_addrs = num_addrs;
2696 #if defined(HAVE_IPV6)
2698 Called when an AAAA record lookup completes.
2701 static void dns_lookup_list_aaaa_done(struct tevent_req *req)
2704 * Callback data is an element of a talloc'ed array,
2705 * not a talloc object in its own right. So use the
2706 * tevent_req_callback_data_void() void * cast function.
2708 struct dns_query_state *state = (struct dns_query_state *)
2709 tevent_req_callback_data_void(req);
2710 uint8_t rcode = 0;
2711 size_t i;
2712 char **hostnames_out = NULL;
2713 struct samba_sockaddr *addrs = NULL;
2714 size_t num_addrs = 0;
2715 NTSTATUS status;
2717 /* For good or ill, tell the parent we're finished. */
2718 state->p_async_state->num_query_returns++;
2720 status = ads_dns_lookup_aaaa_recv(req,
2721 state->p_async_state,
2722 &rcode,
2723 &num_addrs,
2724 &hostnames_out,
2725 &addrs);
2726 if (!NT_STATUS_IS_OK(status)) {
2727 DBG_INFO("async DNS AAAA lookup for %s returned %s\n",
2728 state->query_name,
2729 nt_errstr(status));
2730 return;
2733 if (rcode != DNS_RCODE_OK) {
2734 DBG_INFO("async DNS AAAA lookup for %s returned DNS code %u\n",
2735 state->query_name,
2736 (unsigned int)rcode);
2737 return;
2740 if (num_addrs == 0) {
2741 DBG_INFO("async DNS AAAA lookup for %s returned 0 addresses.\n",
2742 state->query_name);
2743 return;
2746 /* Copy data out. */
2747 state->addrs = talloc_zero_array(state->p_async_state,
2748 struct samba_sockaddr,
2749 num_addrs);
2750 if (state->addrs == NULL) {
2751 return;
2754 for (i = 0; i < num_addrs; i++) {
2755 char addr[INET6_ADDRSTRLEN];
2756 DBG_INFO("async DNS AAAA lookup for %s [%zu] got %s -> %s\n",
2757 state->query_name,
2759 hostnames_out[i],
2760 print_sockaddr(addr,
2761 sizeof(addr),
2762 &addrs[i].u.ss));
2763 state->addrs[i] = addrs[i];
2765 state->num_addrs = num_addrs;
2767 #endif
2769 /********************************************************
2770 Resolve via "hosts" method.
2771 *********************************************************/
2773 static NTSTATUS resolve_hosts(TALLOC_CTX *mem_ctx,
2774 const char *name,
2775 int name_type,
2776 struct sockaddr_storage **return_iplist,
2777 size_t *return_count)
2780 * "host" means do a localhost, or dns lookup.
2782 struct addrinfo hints;
2783 struct addrinfo *ailist = NULL;
2784 struct addrinfo *res = NULL;
2785 int ret = -1;
2786 size_t i = 0;
2787 size_t ret_count = 0;
2788 struct sockaddr_storage *iplist = NULL;
2790 if ( name_type != 0x20 && name_type != 0x0) {
2791 DEBUG(5, ("resolve_hosts: not appropriate "
2792 "for name type <0x%x>\n",
2793 name_type));
2794 return NT_STATUS_INVALID_PARAMETER;
2797 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
2798 name, name_type));
2800 ZERO_STRUCT(hints);
2801 /* By default make sure it supports TCP. */
2802 hints.ai_socktype = SOCK_STREAM;
2803 hints.ai_flags = AI_ADDRCONFIG;
2805 #if !defined(HAVE_IPV6)
2806 /* Unless we have IPv6, we really only want IPv4 addresses back. */
2807 hints.ai_family = AF_INET;
2808 #endif
2810 ret = getaddrinfo(name,
2811 NULL,
2812 &hints,
2813 &ailist);
2814 if (ret) {
2815 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
2816 name,
2817 gai_strerror(ret) ));
2820 for (res = ailist; res; res = res->ai_next) {
2821 struct sockaddr_storage ss = {0};
2822 struct sockaddr_storage *tmp = NULL;
2824 if ((res->ai_addr == NULL) ||
2825 (res->ai_addrlen == 0) ||
2826 (res->ai_addrlen > sizeof(ss))) {
2827 continue;
2830 memcpy(&ss, res->ai_addr, res->ai_addrlen);
2832 if (is_zero_addr(&ss)) {
2833 continue;
2836 /* wrap check. */
2837 if (ret_count + 1 < ret_count) {
2838 freeaddrinfo(ailist);
2839 TALLOC_FREE(iplist);
2840 return NT_STATUS_INVALID_PARAMETER;
2842 ret_count += 1;
2844 tmp = talloc_realloc(
2845 mem_ctx, iplist, struct sockaddr_storage,
2846 ret_count);
2847 if (tmp == NULL) {
2848 DEBUG(3,("resolve_hosts: malloc fail !\n"));
2849 freeaddrinfo(ailist);
2850 TALLOC_FREE(iplist);
2851 return NT_STATUS_NO_MEMORY;
2853 iplist = tmp;
2854 iplist[i] = ss;
2855 i++;
2857 if (ailist) {
2858 freeaddrinfo(ailist);
2860 if (ret_count == 0) {
2861 return NT_STATUS_UNSUCCESSFUL;
2863 *return_count = ret_count;
2864 *return_iplist = iplist;
2865 return NT_STATUS_OK;
2868 /********************************************************
2869 Resolve via "ADS" method.
2870 *********************************************************/
2872 /* Special name type used to cause a _kerberos DNS lookup. */
2873 #define KDC_NAME_TYPE 0xDCDC
2875 static NTSTATUS resolve_ads(TALLOC_CTX *ctx,
2876 const char *name,
2877 int name_type,
2878 const char *sitename,
2879 struct sockaddr_storage **return_addrs,
2880 size_t *return_count)
2882 size_t i;
2883 NTSTATUS status;
2884 struct dns_rr_srv *dcs = NULL;
2885 size_t numdcs = 0;
2886 size_t numaddrs = 0;
2887 size_t num_srv_addrs = 0;
2888 struct sockaddr_storage *srv_addrs = NULL;
2889 size_t num_dns_addrs = 0;
2890 struct samba_sockaddr *dns_addrs = NULL;
2891 size_t num_dns_names = 0;
2892 const char **dns_lookup_names = NULL;
2893 struct sockaddr_storage *ret_addrs = NULL;
2895 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
2896 (name_type != 0x1b)) {
2897 return NT_STATUS_INVALID_PARAMETER;
2900 switch (name_type) {
2901 case 0x1b:
2902 DEBUG(5,("resolve_ads: Attempting to resolve "
2903 "PDC for %s using DNS\n", name));
2904 status = ads_dns_query_pdc(ctx,
2905 name,
2906 &dcs,
2907 &numdcs);
2908 break;
2910 case 0x1c:
2911 DEBUG(5,("resolve_ads: Attempting to resolve "
2912 "DCs for %s using DNS\n", name));
2913 status = ads_dns_query_dcs(ctx,
2914 name,
2915 sitename,
2916 &dcs,
2917 &numdcs);
2918 break;
2919 case KDC_NAME_TYPE:
2920 DEBUG(5,("resolve_ads: Attempting to resolve "
2921 "KDCs for %s using DNS\n", name));
2922 status = ads_dns_query_kdcs(ctx,
2923 name,
2924 sitename,
2925 &dcs,
2926 &numdcs);
2927 break;
2928 default:
2929 status = NT_STATUS_INVALID_PARAMETER;
2930 break;
2933 if (!NT_STATUS_IS_OK(status)) {
2934 TALLOC_FREE(dcs);
2935 return status;
2938 if (numdcs == 0) {
2939 *return_addrs = NULL;
2940 *return_count = 0;
2941 TALLOC_FREE(dcs);
2942 return NT_STATUS_OK;
2946 * Split the returned values into 2 arrays. First one
2947 * is a struct sockaddr_storage array that contains results
2948 * from the SRV record lookup that contain both hostnames
2949 * and IP addresses. We only need to copy out the IP
2950 * addresses. This is srv_addrs.
2952 * Second array contains the results from the SRV record
2953 * lookup that only contain hostnames - no IP addresses.
2954 * We must then call dns_lookup_list() to lookup
2955 * hostnames -> IP address. This is dns_addrs.
2957 * Finally we will merge these two arrays to create the
2958 * return sockaddr_storage array.
2961 /* First count the sizes of each array. */
2962 for(i = 0; i < numdcs; i++) {
2963 if (dcs[i].ss_s != NULL) {
2964 /* IP address returned in SRV record. */
2965 if (num_srv_addrs + dcs[i].num_ips < num_srv_addrs) {
2966 /* Wrap check. */
2967 TALLOC_FREE(dcs);
2968 return NT_STATUS_INVALID_PARAMETER;
2970 /* Add in the number of addresses we got. */
2971 num_srv_addrs += dcs[i].num_ips;
2973 * If we got any IP addresses zero out
2974 * the hostname so we know we've already
2975 * processed this entry and won't add it
2976 * to the dns_lookup_names array we use
2977 * to do DNS queries below.
2979 dcs[i].hostname = NULL;
2980 } else {
2981 /* Ensure we have a hostname to lookup. */
2982 if (dcs[i].hostname == NULL) {
2983 continue;
2985 /* No IP address returned in SRV record. */
2986 if (num_dns_names + 1 < num_dns_names) {
2987 /* Wrap check. */
2988 TALLOC_FREE(dcs);
2989 return NT_STATUS_INVALID_PARAMETER;
2991 /* One more name to lookup. */
2992 num_dns_names += 1;
2996 /* Allocate the list of IP addresses we already have. */
2997 srv_addrs = talloc_zero_array(ctx,
2998 struct sockaddr_storage,
2999 num_srv_addrs);
3000 if (srv_addrs == NULL) {
3001 TALLOC_FREE(dcs);
3002 return NT_STATUS_NO_MEMORY;
3005 /* Copy the addresses we already have. */
3006 num_srv_addrs = 0;
3007 for(i = 0; i < numdcs; i++) {
3008 /* Copy all the IP addresses from the SRV response */
3009 size_t j;
3010 for (j = 0; j < dcs[i].num_ips; j++) {
3011 char addr[INET6_ADDRSTRLEN];
3013 srv_addrs[num_srv_addrs] = dcs[i].ss_s[j];
3014 if (is_zero_addr(&srv_addrs[num_srv_addrs])) {
3015 continue;
3018 DBG_DEBUG("SRV lookup %s got IP[%zu] %s\n",
3019 name,
3021 print_sockaddr(addr,
3022 sizeof(addr),
3023 &srv_addrs[num_srv_addrs]));
3025 num_srv_addrs++;
3029 /* Allocate the array of hostnames we must look up. */
3030 dns_lookup_names = talloc_zero_array(ctx,
3031 const char *,
3032 num_dns_names);
3033 if (dns_lookup_names == NULL) {
3034 TALLOC_FREE(dcs);
3035 TALLOC_FREE(srv_addrs);
3036 return NT_STATUS_NO_MEMORY;
3039 num_dns_names = 0;
3040 for(i = 0; i < numdcs; i++) {
3041 if (dcs[i].hostname == NULL) {
3043 * Must have been a SRV return with an IP address.
3044 * We don't need to look up this hostname.
3046 continue;
3048 dns_lookup_names[num_dns_names] = dcs[i].hostname;
3049 num_dns_names++;
3052 /* Lookup the addresses on the dns_lookup_list. */
3053 status = dns_lookup_list_async(ctx,
3054 num_dns_names,
3055 dns_lookup_names,
3056 &num_dns_addrs,
3057 &dns_addrs,
3058 NULL);
3060 if (!NT_STATUS_IS_OK(status)) {
3061 TALLOC_FREE(dcs);
3062 TALLOC_FREE(srv_addrs);
3063 TALLOC_FREE(dns_lookup_names);
3064 TALLOC_FREE(dns_addrs);
3065 return status;
3069 * Combine the two sockaddr_storage arrays into a talloc'ed
3070 * struct sockaddr_storage array return.
3073 numaddrs = num_srv_addrs + num_dns_addrs;
3074 /* Wrap check */
3075 if (numaddrs < num_srv_addrs) {
3076 TALLOC_FREE(dcs);
3077 TALLOC_FREE(srv_addrs);
3078 TALLOC_FREE(dns_addrs);
3079 TALLOC_FREE(dns_lookup_names);
3080 return NT_STATUS_INVALID_PARAMETER;
3083 if (numaddrs == 0) {
3084 /* Keep the same semantics for zero names. */
3085 TALLOC_FREE(dcs);
3086 TALLOC_FREE(srv_addrs);
3087 TALLOC_FREE(dns_addrs);
3088 TALLOC_FREE(dns_lookup_names);
3089 *return_addrs = NULL;
3090 *return_count = 0;
3091 return NT_STATUS_OK;
3094 ret_addrs = talloc_zero_array(ctx,
3095 struct sockaddr_storage,
3096 numaddrs);
3097 if (ret_addrs == NULL) {
3098 TALLOC_FREE(dcs);
3099 TALLOC_FREE(srv_addrs);
3100 TALLOC_FREE(dns_addrs);
3101 TALLOC_FREE(dns_lookup_names);
3102 return NT_STATUS_NO_MEMORY;
3105 for (i = 0; i < num_srv_addrs; i++) {
3106 ret_addrs[i] = srv_addrs[i];
3108 for (i = 0; i < num_dns_addrs; i++) {
3109 ret_addrs[num_srv_addrs+i] = dns_addrs[i].u.ss;
3112 TALLOC_FREE(dcs);
3113 TALLOC_FREE(srv_addrs);
3114 TALLOC_FREE(dns_addrs);
3115 TALLOC_FREE(dns_lookup_names);
3117 *return_addrs = ret_addrs;
3118 *return_count = numaddrs;
3119 return NT_STATUS_OK;
3122 static const char **filter_out_nbt_lookup(TALLOC_CTX *mem_ctx,
3123 const char **resolve_order)
3125 size_t i, len, result_idx;
3126 const char **result;
3128 len = 0;
3129 while (resolve_order[len] != NULL) {
3130 len += 1;
3133 result = talloc_array(mem_ctx, const char *, len+1);
3134 if (result == NULL) {
3135 return NULL;
3138 result_idx = 0;
3140 for (i=0; i<len; i++) {
3141 const char *tok = resolve_order[i];
3143 if (strequal(tok, "lmhosts") || strequal(tok, "wins") ||
3144 strequal(tok, "bcast")) {
3145 continue;
3147 result[result_idx++] = tok;
3149 result[result_idx] = NULL;
3151 return result;
3154 /*******************************************************************
3155 Samba interface to resolve a name into an IP address.
3156 Use this function if the string is either an IP address, DNS
3157 or host name or NetBIOS name. This uses the name switch in the
3158 smb.conf to determine the order of name resolution.
3160 Added support for ip addr/port to support ADS ldap servers.
3161 the only place we currently care about the port is in the
3162 resolve_hosts() when looking up DC's via SRV RR entries in DNS
3163 **********************************************************************/
3165 NTSTATUS internal_resolve_name(TALLOC_CTX *ctx,
3166 const char *name,
3167 int name_type,
3168 const char *sitename,
3169 struct samba_sockaddr **return_salist,
3170 size_t *return_count,
3171 const char **resolve_order)
3173 const char *tok;
3174 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
3175 size_t i;
3176 size_t nc_count = 0;
3177 size_t ret_count = 0;
3178 bool ok;
3179 struct sockaddr_storage *ss_list = NULL;
3180 struct samba_sockaddr *sa_list = NULL;
3181 TALLOC_CTX *frame = talloc_stackframe();
3183 DBG_DEBUG("looking up %s#%x (sitename %s)\n",
3184 name, name_type, sitename ? sitename : "(null)");
3186 if (is_ipaddress(name)) {
3187 struct sockaddr_storage ss;
3189 /* if it's in the form of an IP address then get the lib to interpret it */
3190 ok = interpret_string_addr(&ss, name, AI_NUMERICHOST);
3191 if (!ok) {
3192 DBG_WARNING("interpret_string_addr failed on %s\n",
3193 name);
3194 TALLOC_FREE(frame);
3195 return NT_STATUS_INVALID_PARAMETER;
3197 if (is_zero_addr(&ss)) {
3198 TALLOC_FREE(frame);
3199 return NT_STATUS_UNSUCCESSFUL;
3202 status = sockaddr_array_to_samba_sockaddr_array(frame,
3203 &sa_list,
3204 &ret_count,
3205 &ss,
3207 if (!NT_STATUS_IS_OK(status)) {
3208 TALLOC_FREE(frame);
3209 return status;
3212 *return_salist = talloc_move(ctx, &sa_list);
3213 *return_count = 1;
3214 TALLOC_FREE(frame);
3215 return NT_STATUS_OK;
3218 /* Check name cache */
3220 ok = namecache_fetch(frame,
3221 name,
3222 name_type,
3223 &sa_list,
3224 &nc_count);
3225 if (ok) {
3227 * remove_duplicate_addrs2() has the
3228 * side effect of removing zero addresses,
3229 * so use it here.
3231 nc_count = remove_duplicate_addrs2(sa_list, nc_count);
3232 if (nc_count == 0) {
3233 TALLOC_FREE(sa_list);
3234 TALLOC_FREE(frame);
3235 return NT_STATUS_UNSUCCESSFUL;
3237 *return_count = nc_count;
3238 *return_salist = talloc_move(ctx, &sa_list);
3239 TALLOC_FREE(frame);
3240 return NT_STATUS_OK;
3243 /* set the name resolution order */
3245 if (resolve_order && strcmp(resolve_order[0], "NULL") == 0) {
3246 DBG_DEBUG("all lookups disabled\n");
3247 TALLOC_FREE(frame);
3248 return NT_STATUS_INVALID_PARAMETER;
3251 if (!resolve_order || !resolve_order[0]) {
3252 static const char *host_order[] = { "host", NULL };
3253 resolve_order = host_order;
3256 if ((strlen(name) > MAX_NETBIOSNAME_LEN - 1) ||
3257 (strchr(name, '.') != NULL)) {
3259 * Don't do NBT lookup, the name would not fit anyway
3261 resolve_order = filter_out_nbt_lookup(frame, resolve_order);
3262 if (resolve_order == NULL) {
3263 TALLOC_FREE(frame);
3264 return NT_STATUS_NO_MEMORY;
3268 /* iterate through the name resolution backends */
3270 for (i=0; resolve_order[i]; i++) {
3271 tok = resolve_order[i];
3273 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
3274 status = resolve_hosts(talloc_tos(),
3275 name,
3276 name_type,
3277 &ss_list,
3278 &ret_count);
3279 if (!NT_STATUS_IS_OK(status)) {
3280 continue;
3282 goto done;
3283 } else if(strequal( tok, "kdc")) {
3284 /* deal with KDC_NAME_TYPE names here.
3285 * This will result in a SRV record lookup */
3286 status = resolve_ads(talloc_tos(),
3287 name,
3288 KDC_NAME_TYPE,
3289 sitename,
3290 &ss_list,
3291 &ret_count);
3292 if (!NT_STATUS_IS_OK(status)) {
3293 continue;
3295 /* Ensure we don't namecache
3296 * this with the KDC port. */
3297 name_type = KDC_NAME_TYPE;
3298 goto done;
3299 } else if(strequal( tok, "ads")) {
3300 /* deal with 0x1c and 0x1b names here.
3301 * This will result in a SRV record lookup */
3302 status = resolve_ads(talloc_tos(),
3303 name,
3304 name_type,
3305 sitename,
3306 &ss_list,
3307 &ret_count);
3308 if (!NT_STATUS_IS_OK(status)) {
3309 continue;
3311 goto done;
3312 } else if (strequal(tok, "lmhosts")) {
3313 status = resolve_lmhosts_file_as_sockaddr(
3314 talloc_tos(),
3315 get_dyn_LMHOSTSFILE(),
3316 name,
3317 name_type,
3318 &ss_list,
3319 &ret_count);
3320 if (!NT_STATUS_IS_OK(status)) {
3321 continue;
3323 goto done;
3324 } else if (strequal(tok, "wins")) {
3325 /* don't resolve 1D via WINS */
3326 if (name_type == 0x1D) {
3327 continue;
3329 status = resolve_wins(talloc_tos(),
3330 name,
3331 name_type,
3332 &ss_list,
3333 &ret_count);
3334 if (!NT_STATUS_IS_OK(status)) {
3335 continue;
3337 goto done;
3338 } else if (strequal(tok, "bcast")) {
3339 status = name_resolve_bcast(
3340 talloc_tos(),
3341 name,
3342 name_type,
3343 &ss_list,
3344 &ret_count);
3345 if (!NT_STATUS_IS_OK(status)) {
3346 continue;
3348 goto done;
3349 } else {
3350 DBG_ERR("unknown name switch type %s\n",
3351 tok);
3355 /* All of the resolve_* functions above have returned false. */
3357 TALLOC_FREE(frame);
3358 *return_count = 0;
3360 return status;
3362 done:
3364 status = sockaddr_array_to_samba_sockaddr_array(frame,
3365 &sa_list,
3366 &ret_count,
3367 ss_list,
3368 ret_count);
3369 if (!NT_STATUS_IS_OK(status)) {
3370 TALLOC_FREE(frame);
3371 return NT_STATUS_NO_MEMORY;
3374 /* Remove duplicate entries. Some queries, notably #1c (domain
3375 controllers) return the PDC in iplist[0] and then all domain
3376 controllers including the PDC in iplist[1..n]. Iterating over
3377 the iplist when the PDC is down will cause two sets of timeouts. */
3379 ret_count = remove_duplicate_addrs2(sa_list, ret_count);
3381 /* Save in name cache */
3382 if ( DEBUGLEVEL >= 100 ) {
3383 for (i = 0; i < ret_count && DEBUGLEVEL == 100; i++) {
3384 char addr[INET6_ADDRSTRLEN];
3385 print_sockaddr(addr, sizeof(addr),
3386 &sa_list[i].u.ss);
3387 DEBUG(100, ("Storing name %s of type %d (%s:0)\n",
3388 name,
3389 name_type,
3390 addr));
3394 if (ret_count) {
3395 namecache_store(name,
3396 name_type,
3397 ret_count,
3398 sa_list);
3401 /* Display some debugging info */
3403 if ( DEBUGLEVEL >= 10 ) {
3404 DBG_DEBUG("returning %zu addresses: ",
3405 ret_count);
3407 for (i = 0; i < ret_count; i++) {
3408 char addr[INET6_ADDRSTRLEN];
3409 print_sockaddr(addr, sizeof(addr),
3410 &sa_list[i].u.ss);
3411 DEBUGADD(10, ("%s ", addr));
3413 DEBUG(10, ("\n"));
3416 *return_count = ret_count;
3417 *return_salist = talloc_move(ctx, &sa_list);
3419 TALLOC_FREE(frame);
3420 return status;
3423 /********************************************************
3424 Internal interface to resolve a name into one IP address.
3425 Use this function if the string is either an IP address, DNS
3426 or host name or NetBIOS name. This uses the name switch in the
3427 smb.conf to determine the order of name resolution.
3428 *********************************************************/
3430 bool resolve_name(const char *name,
3431 struct sockaddr_storage *return_ss,
3432 int name_type,
3433 bool prefer_ipv4)
3435 struct samba_sockaddr *sa_list = NULL;
3436 char *sitename = NULL;
3437 size_t count = 0;
3438 NTSTATUS status;
3439 TALLOC_CTX *frame = NULL;
3441 if (is_ipaddress(name)) {
3442 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
3445 frame = talloc_stackframe();
3447 sitename = sitename_fetch(frame, lp_realm()); /* wild guess */
3449 status = internal_resolve_name(frame,
3450 name,
3451 name_type,
3452 sitename,
3453 &sa_list,
3454 &count,
3455 lp_name_resolve_order());
3456 if (NT_STATUS_IS_OK(status)) {
3457 size_t i;
3459 if (prefer_ipv4) {
3460 for (i=0; i<count; i++) {
3461 if (!is_broadcast_addr(&sa_list[i].u.sa) &&
3462 (sa_list[i].u.ss.ss_family == AF_INET)) {
3463 *return_ss = sa_list[i].u.ss;
3464 TALLOC_FREE(sa_list);
3465 TALLOC_FREE(frame);
3466 return True;
3471 /* only return valid addresses for TCP connections */
3472 for (i=0; i<count; i++) {
3473 if (!is_broadcast_addr(&sa_list[i].u.sa)) {
3474 *return_ss = sa_list[i].u.ss;
3475 TALLOC_FREE(sa_list);
3476 TALLOC_FREE(frame);
3477 return True;
3482 TALLOC_FREE(sa_list);
3483 TALLOC_FREE(frame);
3484 return False;
3487 /********************************************************
3488 Internal interface to resolve a name into a list of IP addresses.
3489 Use this function if the string is either an IP address, DNS
3490 or host name or NetBIOS name. This uses the name switch in the
3491 smb.conf to determine the order of name resolution.
3492 *********************************************************/
3494 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
3495 const char *name,
3496 int name_type,
3497 struct sockaddr_storage **return_ss_arr,
3498 unsigned int *p_num_entries)
3500 struct samba_sockaddr *sa_list = NULL;
3501 char *sitename = NULL;
3502 size_t count = 0;
3503 size_t i;
3504 unsigned int num_entries = 0;
3505 struct sockaddr_storage *result_arr = NULL;
3506 NTSTATUS status;
3508 if (is_ipaddress(name)) {
3509 result_arr = talloc(ctx, struct sockaddr_storage);
3510 if (result_arr == NULL) {
3511 return NT_STATUS_NO_MEMORY;
3513 if (!interpret_string_addr(result_arr, name, AI_NUMERICHOST)) {
3514 TALLOC_FREE(result_arr);
3515 return NT_STATUS_BAD_NETWORK_NAME;
3517 *p_num_entries = 1;
3518 *return_ss_arr = result_arr;
3519 return NT_STATUS_OK;
3522 sitename = sitename_fetch(ctx, lp_realm()); /* wild guess */
3524 status = internal_resolve_name(ctx,
3525 name,
3526 name_type,
3527 sitename,
3528 &sa_list,
3529 &count,
3530 lp_name_resolve_order());
3531 TALLOC_FREE(sitename);
3533 if (!NT_STATUS_IS_OK(status)) {
3534 return status;
3537 /* only return valid addresses for TCP connections */
3538 for (i=0, num_entries = 0; i<count; i++) {
3539 if (!is_zero_addr(&sa_list[i].u.ss) &&
3540 !is_broadcast_addr(&sa_list[i].u.sa)) {
3541 num_entries++;
3544 if (num_entries == 0) {
3545 status = NT_STATUS_BAD_NETWORK_NAME;
3546 goto done;
3549 result_arr = talloc_array(ctx,
3550 struct sockaddr_storage,
3551 num_entries);
3552 if (result_arr == NULL) {
3553 status = NT_STATUS_NO_MEMORY;
3554 goto done;
3557 for (i=0, num_entries = 0; i<count; i++) {
3558 if (!is_zero_addr(&sa_list[i].u.ss) &&
3559 !is_broadcast_addr(&sa_list[i].u.sa)) {
3560 result_arr[num_entries++] = sa_list[i].u.ss;
3564 if (num_entries == 0) {
3565 TALLOC_FREE(result_arr);
3566 status = NT_STATUS_BAD_NETWORK_NAME;
3567 goto done;
3570 status = NT_STATUS_OK;
3571 *p_num_entries = num_entries;
3572 *return_ss_arr = result_arr;
3573 done:
3574 TALLOC_FREE(sa_list);
3575 return status;
3578 /********************************************************
3579 Find the IP address of the master browser or DMB for a workgroup.
3580 *********************************************************/
3582 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
3584 struct samba_sockaddr *sa_list = NULL;
3585 size_t count = 0;
3586 NTSTATUS status;
3588 if (lp_disable_netbios()) {
3589 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
3590 return false;
3593 status = internal_resolve_name(talloc_tos(),
3594 group,
3595 0x1D,
3596 NULL,
3597 &sa_list,
3598 &count,
3599 lp_name_resolve_order());
3600 if (NT_STATUS_IS_OK(status)) {
3601 *master_ss = sa_list[0].u.ss;
3602 TALLOC_FREE(sa_list);
3603 return true;
3606 TALLOC_FREE(sa_list);
3608 status = internal_resolve_name(talloc_tos(),
3609 group,
3610 0x1B,
3611 NULL,
3612 &sa_list,
3613 &count,
3614 lp_name_resolve_order());
3615 if (NT_STATUS_IS_OK(status)) {
3616 *master_ss = sa_list[0].u.ss;
3617 TALLOC_FREE(sa_list);
3618 return true;
3621 TALLOC_FREE(sa_list);
3622 return false;
3625 /********************************************************
3626 Get the IP address list of the primary domain controller
3627 for a domain.
3628 *********************************************************/
3630 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
3632 struct samba_sockaddr *sa_list = NULL;
3633 size_t count = 0;
3634 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
3635 static const char *ads_order[] = { "ads", NULL };
3636 /* Look up #1B name */
3638 if (lp_security() == SEC_ADS) {
3639 status = internal_resolve_name(talloc_tos(),
3640 domain,
3641 0x1b,
3642 NULL,
3643 &sa_list,
3644 &count,
3645 ads_order);
3648 if (!NT_STATUS_IS_OK(status) || count == 0) {
3649 TALLOC_FREE(sa_list);
3650 status = internal_resolve_name(talloc_tos(),
3651 domain,
3652 0x1b,
3653 NULL,
3654 &sa_list,
3655 &count,
3656 lp_name_resolve_order());
3657 if (!NT_STATUS_IS_OK(status)) {
3658 TALLOC_FREE(sa_list);
3659 return false;
3663 /* if we get more than 1 IP back we have to assume it is a
3664 multi-homed PDC and not a mess up */
3666 if ( count > 1 ) {
3667 DBG_INFO("PDC has %zu IP addresses!\n", count);
3668 sort_sa_list(sa_list, count);
3671 *pss = sa_list[0].u.ss;
3672 TALLOC_FREE(sa_list);
3673 return true;
3676 /* Private enum type for lookups. */
3678 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
3680 /********************************************************
3681 Get the IP address list of the domain controllers for
3682 a domain.
3683 *********************************************************/
3685 static NTSTATUS get_dc_list(TALLOC_CTX *ctx,
3686 const char *domain,
3687 const char *sitename,
3688 struct samba_sockaddr **sa_list_ret,
3689 size_t *ret_count,
3690 enum dc_lookup_type lookup_type,
3691 bool *ordered)
3693 const char **resolve_order = NULL;
3694 char *saf_servername = NULL;
3695 char *pserver = NULL;
3696 const char *p;
3697 char *name;
3698 size_t num_addresses = 0;
3699 size_t local_count = 0;
3700 size_t i;
3701 struct samba_sockaddr *auto_sa_list = NULL;
3702 struct samba_sockaddr *return_salist = NULL;
3703 bool done_auto_lookup = false;
3704 size_t auto_count = 0;
3705 NTSTATUS status;
3706 TALLOC_CTX *frame = talloc_stackframe();
3707 int auto_name_type = 0x1C;
3709 *ordered = False;
3711 /* if we are restricted to solely using DNS for looking
3712 up a domain controller, make sure that host lookups
3713 are enabled for the 'name resolve order'. If host lookups
3714 are disabled and ads_only is True, then set the string to
3715 NULL. */
3717 resolve_order = lp_name_resolve_order();
3718 if (!resolve_order) {
3719 status = NT_STATUS_NO_MEMORY;
3720 goto out;
3722 if (lookup_type == DC_ADS_ONLY) {
3723 if (str_list_check_ci(resolve_order, "host")) {
3724 static const char *ads_order[] = { "ads", NULL };
3725 resolve_order = ads_order;
3727 /* DNS SRV lookups used by the ads resolver
3728 are already sorted by priority and weight */
3729 *ordered = true;
3730 } else {
3731 /* this is quite bizarre! */
3732 static const char *null_order[] = { "NULL", NULL };
3733 resolve_order = null_order;
3735 } else if (lookup_type == DC_KDC_ONLY) {
3736 static const char *kdc_order[] = { "kdc", NULL };
3737 /* DNS SRV lookups used by the ads/kdc resolver
3738 are already sorted by priority and weight */
3739 *ordered = true;
3740 resolve_order = kdc_order;
3741 auto_name_type = KDC_NAME_TYPE;
3744 /* fetch the server we have affinity for. Add the
3745 'password server' list to a search for our domain controllers */
3747 saf_servername = saf_fetch(frame, domain);
3749 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
3750 pserver = talloc_asprintf(frame, "%s, %s",
3751 saf_servername ? saf_servername : "",
3752 lp_password_server());
3753 } else {
3754 pserver = talloc_asprintf(frame, "%s, *",
3755 saf_servername ? saf_servername : "");
3758 TALLOC_FREE(saf_servername);
3759 if (!pserver) {
3760 status = NT_STATUS_NO_MEMORY;
3761 goto out;
3764 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
3767 * if '*' appears in the "password server" list then add
3768 * an auto lookup to the list of manually configured
3769 * DC's. If any DC is listed by name, then the list should be
3770 * considered to be ordered
3773 p = pserver;
3774 while (next_token_talloc(frame, &p, &name, LIST_SEP)) {
3775 if (!done_auto_lookup && strequal(name, "*")) {
3776 done_auto_lookup = true;
3778 status = internal_resolve_name(frame,
3779 domain,
3780 auto_name_type,
3781 sitename,
3782 &auto_sa_list,
3783 &auto_count,
3784 resolve_order);
3785 if (!NT_STATUS_IS_OK(status)) {
3786 continue;
3788 /* Wrap check. */
3789 if (num_addresses + auto_count < num_addresses) {
3790 TALLOC_FREE(auto_sa_list);
3791 status = NT_STATUS_INVALID_PARAMETER;
3792 goto out;
3794 num_addresses += auto_count;
3795 DBG_DEBUG("Adding %zu DC's from auto lookup\n",
3796 auto_count);
3797 } else {
3798 /* Wrap check. */
3799 if (num_addresses + 1 < num_addresses) {
3800 TALLOC_FREE(auto_sa_list);
3801 status = NT_STATUS_INVALID_PARAMETER;
3802 goto out;
3804 num_addresses++;
3808 /* if we have no addresses and haven't done the auto lookup, then
3809 just return the list of DC's. Or maybe we just failed. */
3811 if (num_addresses == 0) {
3812 struct samba_sockaddr *dc_salist = NULL;
3813 size_t dc_count = 0;
3815 if (done_auto_lookup) {
3816 DEBUG(4,("get_dc_list: no servers found\n"));
3817 status = NT_STATUS_NO_LOGON_SERVERS;
3818 goto out;
3820 /* talloc off frame, only move to ctx on success. */
3821 status = internal_resolve_name(frame,
3822 domain,
3823 auto_name_type,
3824 sitename,
3825 &dc_salist,
3826 &dc_count,
3827 resolve_order);
3828 if (!NT_STATUS_IS_OK(status)) {
3829 goto out;
3831 return_salist = dc_salist;
3832 local_count = dc_count;
3833 goto out;
3836 return_salist = talloc_zero_array(frame,
3837 struct samba_sockaddr,
3838 num_addresses);
3839 if (return_salist == NULL) {
3840 DEBUG(3,("get_dc_list: malloc fail !\n"));
3841 status = NT_STATUS_NO_MEMORY;
3842 goto out;
3845 p = pserver;
3846 local_count = 0;
3848 /* fill in the return list now with real IP's */
3850 while ((local_count<num_addresses) &&
3851 next_token_talloc(frame, &p, &name, LIST_SEP)) {
3852 struct samba_sockaddr name_sa = {0};
3854 /* copy any addresses from the auto lookup */
3856 if (strequal(name, "*")) {
3857 size_t j;
3858 for (j=0; j<auto_count; j++) {
3859 char addr[INET6_ADDRSTRLEN];
3860 print_sockaddr(addr,
3861 sizeof(addr),
3862 &auto_sa_list[j].u.ss);
3863 /* Check for and don't copy any
3864 * known bad DC IP's. */
3865 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
3866 domain,
3867 addr))) {
3868 DEBUG(5,("get_dc_list: "
3869 "negative entry %s removed "
3870 "from DC list\n",
3871 addr));
3872 continue;
3874 return_salist[local_count] = auto_sa_list[j];
3875 local_count++;
3877 continue;
3880 /* explicit lookup; resolve_name() will
3881 * handle names & IP addresses */
3882 if (resolve_name(name, &name_sa.u.ss, 0x20, true)) {
3883 char addr[INET6_ADDRSTRLEN];
3884 bool ok;
3887 * Ensure we set sa_socklen correctly.
3888 * Doesn't matter now, but eventually we
3889 * will remove ip_service and return samba_sockaddr
3890 * arrays directly.
3892 ok = sockaddr_storage_to_samba_sockaddr(
3893 &name_sa,
3894 &name_sa.u.ss);
3895 if (!ok) {
3896 status = NT_STATUS_INVALID_ADDRESS;
3897 goto out;
3900 print_sockaddr(addr,
3901 sizeof(addr),
3902 &name_sa.u.ss);
3904 /* Check for and don't copy any known bad DC IP's. */
3905 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
3906 addr)) ) {
3907 DEBUG(5,("get_dc_list: negative entry %s "
3908 "removed from DC list\n",
3909 name ));
3910 continue;
3913 return_salist[local_count] = name_sa;
3914 local_count++;
3915 *ordered = true;
3919 /* need to remove duplicates in the list if we have any
3920 explicit password servers */
3922 local_count = remove_duplicate_addrs2(return_salist, local_count );
3924 /* For DC's we always prioritize IPv4 due to W2K3 not
3925 * supporting LDAP, KRB5 or CLDAP over IPv6. */
3927 if (local_count && return_salist != NULL) {
3928 prioritize_ipv4_list(return_salist, local_count);
3931 if ( DEBUGLEVEL >= 4 ) {
3932 DEBUG(4,("get_dc_list: returning %zu ip addresses "
3933 "in an %sordered list\n",
3934 local_count,
3935 *ordered ? "":"un"));
3936 DEBUG(4,("get_dc_list: "));
3937 for ( i=0; i<local_count; i++ ) {
3938 char addr[INET6_ADDRSTRLEN];
3939 print_sockaddr(addr,
3940 sizeof(addr),
3941 &return_salist[i].u.ss);
3942 DEBUGADD(4,("%s ", addr));
3944 DEBUGADD(4,("\n"));
3947 status = (local_count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS);
3949 out:
3951 if (NT_STATUS_IS_OK(status)) {
3952 *sa_list_ret = talloc_move(ctx, &return_salist);
3953 *ret_count = local_count;
3955 TALLOC_FREE(return_salist);
3956 TALLOC_FREE(auto_sa_list);
3957 TALLOC_FREE(frame);
3958 return status;
3961 /*********************************************************************
3962 Small wrapper function to get the DC list and sort it if neccessary.
3963 Returns a samba_sockaddr array.
3964 *********************************************************************/
3966 NTSTATUS get_sorted_dc_list(TALLOC_CTX *ctx,
3967 const char *domain,
3968 const char *sitename,
3969 struct samba_sockaddr **sa_list_ret,
3970 size_t *ret_count,
3971 bool ads_only)
3973 bool ordered = false;
3974 NTSTATUS status;
3975 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
3976 struct samba_sockaddr *sa_list = NULL;
3977 size_t count = 0;
3979 DBG_INFO("attempting lookup for name %s (sitename %s)\n",
3980 domain,
3981 sitename ? sitename : "NULL");
3983 if (ads_only) {
3984 lookup_type = DC_ADS_ONLY;
3987 status = get_dc_list(ctx,
3988 domain,
3989 sitename,
3990 &sa_list,
3991 &count,
3992 lookup_type,
3993 &ordered);
3994 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
3995 && sitename) {
3996 DBG_NOTICE("no server for name %s available"
3997 " in site %s, fallback to all servers\n",
3998 domain,
3999 sitename);
4000 status = get_dc_list(ctx,
4001 domain,
4002 NULL,
4003 &sa_list,
4004 &count,
4005 lookup_type,
4006 &ordered);
4009 if (!NT_STATUS_IS_OK(status)) {
4010 return status;
4013 /* only sort if we don't already have an ordered list */
4014 if (!ordered) {
4015 sort_sa_list(sa_list, count);
4018 *ret_count = count;
4019 *sa_list_ret = sa_list;
4020 return status;
4023 /*********************************************************************
4024 Get the KDC list - re-use all the logic in get_dc_list.
4025 Returns a samba_sockaddr array.
4026 *********************************************************************/
4028 NTSTATUS get_kdc_list(TALLOC_CTX *ctx,
4029 const char *realm,
4030 const char *sitename,
4031 struct samba_sockaddr **sa_list_ret,
4032 size_t *ret_count)
4034 size_t count = 0;
4035 struct samba_sockaddr *sa_list = NULL;
4036 bool ordered = false;
4037 NTSTATUS status;
4039 status = get_dc_list(ctx,
4040 realm,
4041 sitename,
4042 &sa_list,
4043 &count,
4044 DC_KDC_ONLY,
4045 &ordered);
4047 if (!NT_STATUS_IS_OK(status)) {
4048 return status;
4051 /* only sort if we don't already have an ordered list */
4052 if (!ordered ) {
4053 sort_sa_list(sa_list, count);
4056 *ret_count = count;
4057 *sa_list_ret = sa_list;
4058 return status;