s4:selftest: skip flakey samba4.drs.repl_schema.python for now
[Samba/vl.git] / source3 / libsmb / namequery.c
blobc70e68b10333e6540a4052a189d8bb30ccd77069
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 "../lib/util/tevent_ntstatus.h"
23 #include "libads/sitename_cache.h"
24 #include "libads/dns.h"
25 #include "../libcli/netlogon/netlogon.h"
26 #include "lib/async_req/async_sock.h"
27 #include "libsmb/nmblib.h"
29 /* nmbd.c sets this to True. */
30 bool global_in_nmbd = False;
32 /****************************
33 * SERVER AFFINITY ROUTINES *
34 ****************************/
36 /* Server affinity is the concept of preferring the last domain
37 controller with whom you had a successful conversation */
39 /****************************************************************************
40 ****************************************************************************/
41 #define SAFKEY_FMT "SAF/DOMAIN/%s"
42 #define SAF_TTL 900
43 #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
44 #define SAFJOIN_TTL 3600
46 static char *saf_key(TALLOC_CTX *mem_ctx, const char *domain)
48 return talloc_asprintf_strupper_m(mem_ctx, SAFKEY_FMT, domain);
51 static char *saf_join_key(TALLOC_CTX *mem_ctx, const char *domain)
53 return talloc_asprintf_strupper_m(mem_ctx, SAFJOINKEY_FMT, domain);
56 /****************************************************************************
57 ****************************************************************************/
59 bool saf_store( const char *domain, const char *servername )
61 char *key;
62 time_t expire;
63 bool ret = False;
65 if ( !domain || !servername ) {
66 DEBUG(2,("saf_store: "
67 "Refusing to store empty domain or servername!\n"));
68 return False;
71 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
72 DEBUG(0,("saf_store: "
73 "refusing to store 0 length domain or servername!\n"));
74 return False;
77 key = saf_key(talloc_tos(), domain);
78 if (key == NULL) {
79 DEBUG(1, ("saf_key() failed\n"));
80 return false;
82 expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
84 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
85 domain, servername, (unsigned int)expire ));
87 ret = gencache_set( key, servername, expire );
89 TALLOC_FREE( key );
91 return ret;
94 bool saf_join_store( const char *domain, const char *servername )
96 char *key;
97 time_t expire;
98 bool ret = False;
100 if ( !domain || !servername ) {
101 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
102 return False;
105 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
106 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
107 return False;
110 key = saf_join_key(talloc_tos(), domain);
111 if (key == NULL) {
112 DEBUG(1, ("saf_join_key() failed\n"));
113 return false;
115 expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
117 DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
118 domain, servername, (unsigned int)expire ));
120 ret = gencache_set( key, servername, expire );
122 TALLOC_FREE( key );
124 return ret;
127 bool saf_delete( const char *domain )
129 char *key;
130 bool ret = False;
132 if ( !domain ) {
133 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
134 return False;
137 key = saf_join_key(talloc_tos(), domain);
138 if (key == NULL) {
139 DEBUG(1, ("saf_join_key() failed\n"));
140 return false;
142 ret = gencache_del(key);
143 TALLOC_FREE(key);
145 if (ret) {
146 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
149 key = saf_key(talloc_tos(), domain);
150 if (key == NULL) {
151 DEBUG(1, ("saf_key() failed\n"));
152 return false;
154 ret = gencache_del(key);
155 TALLOC_FREE(key);
157 if (ret) {
158 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
161 return ret;
164 /****************************************************************************
165 ****************************************************************************/
167 char *saf_fetch( const char *domain )
169 char *server = NULL;
170 time_t timeout;
171 bool ret = False;
172 char *key = NULL;
174 if ( !domain || strlen(domain) == 0) {
175 DEBUG(2,("saf_fetch: Empty domain name!\n"));
176 return NULL;
179 key = saf_join_key(talloc_tos(), domain);
180 if (key == NULL) {
181 DEBUG(1, ("saf_join_key() failed\n"));
182 return NULL;
185 ret = gencache_get( key, &server, &timeout );
187 TALLOC_FREE( key );
189 if ( ret ) {
190 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
191 server, domain ));
192 return server;
195 key = saf_key(talloc_tos(), domain);
196 if (key == NULL) {
197 DEBUG(1, ("saf_key() failed\n"));
198 return NULL;
201 ret = gencache_get( key, &server, &timeout );
203 TALLOC_FREE( key );
205 if ( !ret ) {
206 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
207 domain ));
208 } else {
209 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
210 server, domain ));
213 return server;
216 static void set_socket_addr_v4(struct sockaddr_storage *addr)
218 if (!interpret_string_addr(addr, lp_socket_address(),
219 AI_NUMERICHOST|AI_PASSIVE)) {
220 zero_sockaddr(addr);
222 if (addr->ss_family != AF_INET) {
223 zero_sockaddr(addr);
227 static struct in_addr my_socket_addr_v4(void)
229 struct sockaddr_storage my_addr;
230 struct sockaddr_in *in_addr = (struct sockaddr_in *)((char *)&my_addr);
232 set_socket_addr_v4(&my_addr);
233 return in_addr->sin_addr;
236 /****************************************************************************
237 Generate a random trn_id.
238 ****************************************************************************/
240 static int generate_trn_id(void)
242 uint16 id;
244 generate_random_buffer((uint8 *)&id, sizeof(id));
246 return id % (unsigned)0x7FFF;
249 /****************************************************************************
250 Parse a node status response into an array of structures.
251 ****************************************************************************/
253 static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p,
254 int *num_names,
255 struct node_status_extra *extra)
257 struct node_status *ret;
258 int i;
260 *num_names = CVAL(p,0);
262 if (*num_names == 0)
263 return NULL;
265 ret = talloc_array(mem_ctx, struct node_status,*num_names);
266 if (!ret)
267 return NULL;
269 p++;
270 for (i=0;i< *num_names;i++) {
271 StrnCpy(ret[i].name,p,15);
272 trim_char(ret[i].name,'\0',' ');
273 ret[i].type = CVAL(p,15);
274 ret[i].flags = p[16];
275 p += 18;
276 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
277 ret[i].type, ret[i].flags));
280 * Also, pick up the MAC address ...
282 if (extra) {
283 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
285 return ret;
288 struct sock_packet_read_state {
289 struct tevent_context *ev;
290 enum packet_type type;
291 int trn_id;
293 struct nb_packet_reader *reader;
294 struct tevent_req *reader_req;
296 int sock;
297 struct tevent_req *socket_req;
298 uint8_t buf[1024];
299 struct sockaddr_storage addr;
300 socklen_t addr_len;
302 bool (*validator)(struct packet_struct *p,
303 void *private_data);
304 void *private_data;
306 struct packet_struct *packet;
309 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s);
310 static void sock_packet_read_got_packet(struct tevent_req *subreq);
311 static void sock_packet_read_got_socket(struct tevent_req *subreq);
313 static struct tevent_req *sock_packet_read_send(
314 TALLOC_CTX *mem_ctx,
315 struct tevent_context *ev,
316 int sock, /* dgram socket */
317 struct nb_packet_reader *reader,
318 enum packet_type type,
319 int trn_id,
320 bool (*validator)(struct packet_struct *p, void *private_data),
321 void *private_data)
323 struct tevent_req *req;
324 struct sock_packet_read_state *state;
326 req = tevent_req_create(mem_ctx, &state,
327 struct sock_packet_read_state);
328 if (req == NULL) {
329 return NULL;
331 talloc_set_destructor(state, sock_packet_read_state_destructor);
332 state->ev = ev;
333 state->reader = reader;
334 state->sock = sock;
335 state->type = type;
336 state->trn_id = trn_id;
337 state->validator = validator;
338 state->private_data = private_data;
340 if (reader != NULL) {
341 state->reader_req = nb_packet_read_send(state, ev, reader);
342 if (tevent_req_nomem(state->reader_req, req)) {
343 return tevent_req_post(req, ev);
345 tevent_req_set_callback(
346 state->reader_req, sock_packet_read_got_packet, req);
349 state->addr_len = sizeof(state->addr);
350 state->socket_req = recvfrom_send(state, ev, sock,
351 state->buf, sizeof(state->buf), 0,
352 &state->addr, &state->addr_len);
353 if (tevent_req_nomem(state->socket_req, req)) {
354 return tevent_req_post(req, ev);
356 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
357 req);
359 return req;
362 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s)
364 if (s->packet != NULL) {
365 free_packet(s->packet);
366 s->packet = NULL;
368 return 0;
371 static void sock_packet_read_got_packet(struct tevent_req *subreq)
373 struct tevent_req *req = tevent_req_callback_data(
374 subreq, struct tevent_req);
375 struct sock_packet_read_state *state = tevent_req_data(
376 req, struct sock_packet_read_state);
377 NTSTATUS status;
379 status = nb_packet_read_recv(subreq, &state->packet);
381 TALLOC_FREE(state->reader_req);
383 if (!NT_STATUS_IS_OK(status)) {
384 if (state->socket_req != NULL) {
386 * Still waiting for socket
388 return;
391 * Both socket and packet reader failed
393 tevent_req_nterror(req, status);
394 return;
397 if ((state->validator != NULL) &&
398 !state->validator(state->packet, state->private_data)) {
399 DEBUG(10, ("validator failed\n"));
401 free_packet(state->packet);
402 state->packet = NULL;
404 state->reader_req = nb_packet_read_send(state, state->ev,
405 state->reader);
406 if (tevent_req_nomem(state->reader_req, req)) {
407 return;
409 tevent_req_set_callback(
410 state->reader_req, sock_packet_read_got_packet, req);
411 return;
414 TALLOC_FREE(state->socket_req);
415 tevent_req_done(req);
418 static void sock_packet_read_got_socket(struct tevent_req *subreq)
420 struct tevent_req *req = tevent_req_callback_data(
421 subreq, struct tevent_req);
422 struct sock_packet_read_state *state = tevent_req_data(
423 req, struct sock_packet_read_state);
424 struct sockaddr_in *in_addr;
425 ssize_t received;
426 int err;
428 received = recvfrom_recv(subreq, &err);
430 TALLOC_FREE(state->socket_req);
432 if (received == -1) {
433 if (state->reader_req != NULL) {
435 * Still waiting for reader
437 return;
440 * Both socket and reader failed
442 tevent_req_nterror(req, map_nt_error_from_unix(err));
443 return;
445 if (state->addr.ss_family != AF_INET) {
446 goto retry;
448 in_addr = (struct sockaddr_in *)(void *)&state->addr;
450 state->packet = parse_packet((char *)state->buf, received, state->type,
451 in_addr->sin_addr, in_addr->sin_port);
452 if (state->packet == NULL) {
453 DEBUG(10, ("parse_packet failed\n"));
454 goto retry;
456 if ((state->trn_id != -1) &&
457 (state->trn_id != packet_trn_id(state->packet))) {
458 DEBUG(10, ("Expected transaction id %d, got %d\n",
459 state->trn_id, packet_trn_id(state->packet)));
460 goto retry;
463 if ((state->validator != NULL) &&
464 !state->validator(state->packet, state->private_data)) {
465 DEBUG(10, ("validator failed\n"));
466 goto retry;
469 tevent_req_done(req);
470 return;
472 retry:
473 if (state->packet != NULL) {
474 free_packet(state->packet);
475 state->packet = NULL;
477 state->socket_req = recvfrom_send(state, state->ev, state->sock,
478 state->buf, sizeof(state->buf), 0,
479 &state->addr, &state->addr_len);
480 if (tevent_req_nomem(state->socket_req, req)) {
481 return;
483 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
484 req);
487 static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
488 struct packet_struct **ppacket)
490 struct sock_packet_read_state *state = tevent_req_data(
491 req, struct sock_packet_read_state);
492 NTSTATUS status;
494 if (tevent_req_is_nterror(req, &status)) {
495 return status;
497 *ppacket = state->packet;
498 state->packet = NULL;
499 return NT_STATUS_OK;
502 struct nb_trans_state {
503 struct tevent_context *ev;
504 int sock;
505 struct nb_packet_reader *reader;
507 const struct sockaddr_storage *dst_addr;
508 uint8_t *buf;
509 size_t buflen;
510 enum packet_type type;
511 int trn_id;
513 bool (*validator)(struct packet_struct *p,
514 void *private_data);
515 void *private_data;
517 struct packet_struct *packet;
520 static int nb_trans_state_destructor(struct nb_trans_state *s);
521 static void nb_trans_got_reader(struct tevent_req *subreq);
522 static void nb_trans_done(struct tevent_req *subreq);
523 static void nb_trans_sent(struct tevent_req *subreq);
524 static void nb_trans_send_next(struct tevent_req *subreq);
526 static struct tevent_req *nb_trans_send(
527 TALLOC_CTX *mem_ctx,
528 struct tevent_context *ev,
529 const struct sockaddr_storage *my_addr,
530 const struct sockaddr_storage *dst_addr,
531 bool bcast,
532 uint8_t *buf, size_t buflen,
533 enum packet_type type, int trn_id,
534 bool (*validator)(struct packet_struct *p,
535 void *private_data),
536 void *private_data)
538 struct tevent_req *req, *subreq;
539 struct nb_trans_state *state;
541 req = tevent_req_create(mem_ctx, &state, struct nb_trans_state);
542 if (req == NULL) {
543 return NULL;
545 talloc_set_destructor(state, nb_trans_state_destructor);
546 state->ev = ev;
547 state->dst_addr = dst_addr;
548 state->buf = buf;
549 state->buflen = buflen;
550 state->type = type;
551 state->trn_id = trn_id;
552 state->validator = validator;
553 state->private_data = private_data;
555 state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True);
556 if (state->sock == -1) {
557 tevent_req_nterror(req, map_nt_error_from_unix(errno));
558 DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno)));
559 return tevent_req_post(req, ev);
562 if (bcast) {
563 set_socket_options(state->sock,"SO_BROADCAST");
566 subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL);
567 if (tevent_req_nomem(subreq, req)) {
568 return tevent_req_post(req, ev);
570 tevent_req_set_callback(subreq, nb_trans_got_reader, req);
571 return req;
574 static int nb_trans_state_destructor(struct nb_trans_state *s)
576 if (s->sock != -1) {
577 close(s->sock);
578 s->sock = -1;
580 if (s->packet != NULL) {
581 free_packet(s->packet);
582 s->packet = NULL;
584 return 0;
587 static void nb_trans_got_reader(struct tevent_req *subreq)
589 struct tevent_req *req = tevent_req_callback_data(
590 subreq, struct tevent_req);
591 struct nb_trans_state *state = tevent_req_data(
592 req, struct nb_trans_state);
593 NTSTATUS status;
595 status = nb_packet_reader_recv(subreq, state, &state->reader);
596 TALLOC_FREE(subreq);
598 if (!NT_STATUS_IS_OK(status)) {
599 DEBUG(10, ("nmbd not around\n"));
600 state->reader = NULL;
603 subreq = sock_packet_read_send(
604 state, state->ev, state->sock,
605 state->reader, state->type, state->trn_id,
606 state->validator, state->private_data);
607 if (tevent_req_nomem(subreq, req)) {
608 return;
610 tevent_req_set_callback(subreq, nb_trans_done, req);
612 subreq = sendto_send(state, state->ev, state->sock,
613 state->buf, state->buflen, 0, state->dst_addr);
614 if (tevent_req_nomem(subreq, req)) {
615 return;
617 tevent_req_set_callback(subreq, nb_trans_sent, req);
620 static void nb_trans_sent(struct tevent_req *subreq)
622 struct tevent_req *req = tevent_req_callback_data(
623 subreq, struct tevent_req);
624 struct nb_trans_state *state = tevent_req_data(
625 req, struct nb_trans_state);
626 ssize_t sent;
627 int err;
629 sent = sendto_recv(subreq, &err);
630 TALLOC_FREE(subreq);
631 if (sent == -1) {
632 DEBUG(10, ("sendto failed: %s\n", strerror(err)));
633 tevent_req_nterror(req, map_nt_error_from_unix(err));
634 return;
636 subreq = tevent_wakeup_send(state, state->ev,
637 timeval_current_ofs(1, 0));
638 if (tevent_req_nomem(subreq, req)) {
639 return;
641 tevent_req_set_callback(subreq, nb_trans_send_next, req);
644 static void nb_trans_send_next(struct tevent_req *subreq)
646 struct tevent_req *req = tevent_req_callback_data(
647 subreq, struct tevent_req);
648 struct nb_trans_state *state = tevent_req_data(
649 req, struct nb_trans_state);
650 bool ret;
652 ret = tevent_wakeup_recv(subreq);
653 TALLOC_FREE(subreq);
654 if (!ret) {
655 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
656 return;
658 subreq = sendto_send(state, state->ev, state->sock,
659 state->buf, state->buflen, 0, state->dst_addr);
660 if (tevent_req_nomem(subreq, req)) {
661 return;
663 tevent_req_set_callback(subreq, nb_trans_sent, req);
666 static void nb_trans_done(struct tevent_req *subreq)
668 struct tevent_req *req = tevent_req_callback_data(
669 subreq, struct tevent_req);
670 struct nb_trans_state *state = tevent_req_data(
671 req, struct nb_trans_state);
672 NTSTATUS status;
674 status = sock_packet_read_recv(subreq, &state->packet);
675 TALLOC_FREE(subreq);
676 if (tevent_req_nterror(req, status)) {
677 return;
679 tevent_req_done(req);
682 static NTSTATUS nb_trans_recv(struct tevent_req *req,
683 struct packet_struct **ppacket)
685 struct nb_trans_state *state = tevent_req_data(
686 req, struct nb_trans_state);
687 NTSTATUS status;
689 if (tevent_req_is_nterror(req, &status)) {
690 return status;
692 *ppacket = state->packet;
693 state->packet = NULL;
694 return NT_STATUS_OK;
697 /****************************************************************************
698 Do a NBT node status query on an open socket and return an array of
699 structures holding the returned names or NULL if the query failed.
700 **************************************************************************/
702 struct node_status_query_state {
703 struct sockaddr_storage my_addr;
704 struct sockaddr_storage addr;
705 uint8_t buf[1024];
706 ssize_t buflen;
707 struct packet_struct *packet;
710 static int node_status_query_state_destructor(
711 struct node_status_query_state *s);
712 static bool node_status_query_validator(struct packet_struct *p,
713 void *private_data);
714 static void node_status_query_done(struct tevent_req *subreq);
716 struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
717 struct tevent_context *ev,
718 struct nmb_name *name,
719 const struct sockaddr_storage *addr)
721 struct tevent_req *req, *subreq;
722 struct node_status_query_state *state;
723 struct packet_struct p;
724 struct nmb_packet *nmb = &p.packet.nmb;
725 struct sockaddr_in *in_addr;
727 req = tevent_req_create(mem_ctx, &state,
728 struct node_status_query_state);
729 if (req == NULL) {
730 return NULL;
732 talloc_set_destructor(state, node_status_query_state_destructor);
734 if (addr->ss_family != AF_INET) {
735 /* Can't do node status to IPv6 */
736 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
737 return tevent_req_post(req, ev);
740 state->addr = *addr;
741 in_addr = (struct sockaddr_in *)(void *)&state->addr;
742 in_addr->sin_port = htons(NMB_PORT);
744 set_socket_addr_v4(&state->my_addr);
746 ZERO_STRUCT(p);
747 nmb->header.name_trn_id = generate_trn_id();
748 nmb->header.opcode = 0;
749 nmb->header.response = false;
750 nmb->header.nm_flags.bcast = false;
751 nmb->header.nm_flags.recursion_available = false;
752 nmb->header.nm_flags.recursion_desired = false;
753 nmb->header.nm_flags.trunc = false;
754 nmb->header.nm_flags.authoritative = false;
755 nmb->header.rcode = 0;
756 nmb->header.qdcount = 1;
757 nmb->header.ancount = 0;
758 nmb->header.nscount = 0;
759 nmb->header.arcount = 0;
760 nmb->question.question_name = *name;
761 nmb->question.question_type = 0x21;
762 nmb->question.question_class = 0x1;
764 state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
765 &p);
766 if (state->buflen == 0) {
767 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
768 DEBUG(10, ("build_packet failed\n"));
769 return tevent_req_post(req, ev);
772 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, false,
773 state->buf, state->buflen,
774 NMB_PACKET, nmb->header.name_trn_id,
775 node_status_query_validator, NULL);
776 if (tevent_req_nomem(subreq, req)) {
777 DEBUG(10, ("nb_trans_send failed\n"));
778 return tevent_req_post(req, ev);
780 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(10, 0))) {
781 return tevent_req_post(req, ev);
783 tevent_req_set_callback(subreq, node_status_query_done, req);
784 return req;
787 static bool node_status_query_validator(struct packet_struct *p,
788 void *private_data)
790 struct nmb_packet *nmb = &p->packet.nmb;
791 debug_nmb_packet(p);
793 if (nmb->header.opcode != 0 ||
794 nmb->header.nm_flags.bcast ||
795 nmb->header.rcode ||
796 !nmb->header.ancount ||
797 nmb->answers->rr_type != 0x21) {
799 * XXXX what do we do with this? could be a redirect,
800 * but we'll discard it for the moment
802 return false;
804 return true;
807 static int node_status_query_state_destructor(
808 struct node_status_query_state *s)
810 if (s->packet != NULL) {
811 free_packet(s->packet);
812 s->packet = NULL;
814 return 0;
817 static void node_status_query_done(struct tevent_req *subreq)
819 struct tevent_req *req = tevent_req_callback_data(
820 subreq, struct tevent_req);
821 struct node_status_query_state *state = tevent_req_data(
822 req, struct node_status_query_state);
823 NTSTATUS status;
825 status = nb_trans_recv(subreq, &state->packet);
826 TALLOC_FREE(subreq);
827 if (tevent_req_nterror(req, status)) {
828 return;
830 tevent_req_done(req);
833 NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
834 struct node_status **pnode_status,
835 int *pnum_names,
836 struct node_status_extra *extra)
838 struct node_status_query_state *state = tevent_req_data(
839 req, struct node_status_query_state);
840 struct node_status *node_status;
841 int num_names;
842 NTSTATUS status;
844 if (tevent_req_is_nterror(req, &status)) {
845 return status;
847 node_status = parse_node_status(
848 mem_ctx, &state->packet->packet.nmb.answers->rdata[0],
849 &num_names, extra);
850 if (node_status == NULL) {
851 return NT_STATUS_NO_MEMORY;
853 *pnode_status = node_status;
854 *pnum_names = num_names;
855 return NT_STATUS_OK;
858 NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name,
859 const struct sockaddr_storage *addr,
860 struct node_status **pnode_status,
861 int *pnum_names,
862 struct node_status_extra *extra)
864 TALLOC_CTX *frame = talloc_stackframe();
865 struct tevent_context *ev;
866 struct tevent_req *req;
867 NTSTATUS status = NT_STATUS_NO_MEMORY;
869 ev = tevent_context_init(frame);
870 if (ev == NULL) {
871 goto fail;
873 req = node_status_query_send(ev, ev, name, addr);
874 if (req == NULL) {
875 goto fail;
877 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
878 goto fail;
880 status = node_status_query_recv(req, mem_ctx, pnode_status,
881 pnum_names, extra);
882 fail:
883 TALLOC_FREE(frame);
884 return status;
887 /****************************************************************************
888 Find the first type XX name in a node status reply - used for finding
889 a servers name given its IP. Return the matched name in *name.
890 **************************************************************************/
892 bool name_status_find(const char *q_name,
893 int q_type,
894 int type,
895 const struct sockaddr_storage *to_ss,
896 fstring name)
898 char addr[INET6_ADDRSTRLEN];
899 struct sockaddr_storage ss;
900 struct node_status *addrs = NULL;
901 struct nmb_name nname;
902 int count, i;
903 bool result = false;
904 NTSTATUS status;
906 if (lp_disable_netbios()) {
907 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
908 q_name, q_type));
909 return False;
912 print_sockaddr(addr, sizeof(addr), to_ss);
914 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
915 q_type, addr));
917 /* Check the cache first. */
919 if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
920 return True;
923 if (to_ss->ss_family != AF_INET) {
924 /* Can't do node status to IPv6 */
925 return false;
928 set_socket_addr_v4(&ss);
930 /* W2K PDC's seem not to respond to '*'#0. JRA */
931 make_nmb_name(&nname, q_name, q_type);
932 status = node_status_query(talloc_tos(), &nname, to_ss,
933 &addrs, &count, NULL);
934 if (!NT_STATUS_IS_OK(status)) {
935 goto done;
938 for (i=0;i<count;i++) {
939 /* Find first one of the requested type that's not a GROUP. */
940 if (addrs[i].type == type && ! (addrs[i].flags & 0x80))
941 break;
943 if (i == count)
944 goto done;
946 pull_ascii_nstring(name, sizeof(fstring), addrs[i].name);
948 /* Store the result in the cache. */
949 /* but don't store an entry for 0x1c names here. Here we have
950 a single host and DOMAIN<0x1c> names should be a list of hosts */
952 if ( q_type != 0x1c ) {
953 namecache_status_store(q_name, q_type, type, to_ss, name);
956 result = true;
958 done:
959 TALLOC_FREE(addrs);
961 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
963 if (result)
964 DEBUGADD(10, (", name %s ip address is %s", name, addr));
966 DEBUG(10, ("\n"));
968 return result;
972 comparison function used by sort_addr_list
975 static int addr_compare(const struct sockaddr_storage *ss1,
976 const struct sockaddr_storage *ss2)
978 int max_bits1=0, max_bits2=0;
979 int num_interfaces = iface_count();
980 int i;
982 /* Sort IPv4 addresses first. */
983 if (ss1->ss_family != ss2->ss_family) {
984 if (ss2->ss_family == AF_INET) {
985 return 1;
986 } else {
987 return -1;
991 /* Here we know both addresses are of the same
992 * family. */
994 for (i=0;i<num_interfaces;i++) {
995 const struct sockaddr_storage *pss = iface_n_bcast(i);
996 const unsigned char *p_ss1 = NULL;
997 const unsigned char *p_ss2 = NULL;
998 const unsigned char *p_if = NULL;
999 size_t len = 0;
1000 int bits1, bits2;
1002 if (pss->ss_family != ss1->ss_family) {
1003 /* Ignore interfaces of the wrong type. */
1004 continue;
1006 if (pss->ss_family == AF_INET) {
1007 p_if = (const unsigned char *)
1008 &((const struct sockaddr_in *)pss)->sin_addr;
1009 p_ss1 = (const unsigned char *)
1010 &((const struct sockaddr_in *)ss1)->sin_addr;
1011 p_ss2 = (const unsigned char *)
1012 &((const struct sockaddr_in *)ss2)->sin_addr;
1013 len = 4;
1015 #if defined(HAVE_IPV6)
1016 if (pss->ss_family == AF_INET6) {
1017 p_if = (const unsigned char *)
1018 &((const struct sockaddr_in6 *)pss)->sin6_addr;
1019 p_ss1 = (const unsigned char *)
1020 &((const struct sockaddr_in6 *)ss1)->sin6_addr;
1021 p_ss2 = (const unsigned char *)
1022 &((const struct sockaddr_in6 *)ss2)->sin6_addr;
1023 len = 16;
1025 #endif
1026 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
1027 continue;
1029 bits1 = matching_len_bits(p_ss1, p_if, len);
1030 bits2 = matching_len_bits(p_ss2, p_if, len);
1031 max_bits1 = MAX(bits1, max_bits1);
1032 max_bits2 = MAX(bits2, max_bits2);
1035 /* Bias towards directly reachable IPs */
1036 if (iface_local((const struct sockaddr *)ss1)) {
1037 if (ss1->ss_family == AF_INET) {
1038 max_bits1 += 32;
1039 } else {
1040 max_bits1 += 128;
1043 if (iface_local((const struct sockaddr *)ss2)) {
1044 if (ss2->ss_family == AF_INET) {
1045 max_bits2 += 32;
1046 } else {
1047 max_bits2 += 128;
1050 return max_bits2 - max_bits1;
1053 /*******************************************************************
1054 compare 2 ldap IPs by nearness to our interfaces - used in qsort
1055 *******************************************************************/
1057 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
1059 int result;
1061 if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) {
1062 return result;
1065 if (ss1->port > ss2->port) {
1066 return 1;
1069 if (ss1->port < ss2->port) {
1070 return -1;
1073 return 0;
1077 sort an IP list so that names that are close to one of our interfaces
1078 are at the top. This prevents the problem where a WINS server returns an IP
1079 that is not reachable from our subnet as the first match
1082 static void sort_addr_list(struct sockaddr_storage *sslist, int count)
1084 if (count <= 1) {
1085 return;
1088 TYPESAFE_QSORT(sslist, count, addr_compare);
1091 static void sort_service_list(struct ip_service *servlist, int count)
1093 if (count <= 1) {
1094 return;
1097 TYPESAFE_QSORT(servlist, count, ip_service_compare);
1100 /**********************************************************************
1101 Remove any duplicate address/port pairs in the list
1102 *********************************************************************/
1104 static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
1106 int i, j;
1108 DEBUG(10,("remove_duplicate_addrs2: "
1109 "looking for duplicate address/port pairs\n"));
1111 /* one loop to remove duplicates */
1112 for ( i=0; i<count; i++ ) {
1113 if ( is_zero_addr(&iplist[i].ss)) {
1114 continue;
1117 for ( j=i+1; j<count; j++ ) {
1118 if (sockaddr_equal((struct sockaddr *)(void *)&iplist[i].ss,
1119 (struct sockaddr *)(void *)&iplist[j].ss) &&
1120 iplist[i].port == iplist[j].port) {
1121 zero_sockaddr(&iplist[j].ss);
1126 /* one loop to clean up any holes we left */
1127 /* first ip should never be a zero_ip() */
1128 for (i = 0; i<count; ) {
1129 if (is_zero_addr(&iplist[i].ss) ) {
1130 if (i != count-1) {
1131 memmove(&iplist[i], &iplist[i+1],
1132 (count - i - 1)*sizeof(iplist[i]));
1134 count--;
1135 continue;
1137 i++;
1140 return count;
1143 static bool prioritize_ipv4_list(struct ip_service *iplist, int count)
1145 TALLOC_CTX *frame = talloc_stackframe();
1146 struct ip_service *iplist_new = talloc_array(frame, struct ip_service, count);
1147 int i, j;
1149 if (iplist_new == NULL) {
1150 TALLOC_FREE(frame);
1151 return false;
1154 j = 0;
1156 /* Copy IPv4 first. */
1157 for (i = 0; i < count; i++) {
1158 if (iplist[i].ss.ss_family == AF_INET) {
1159 iplist_new[j++] = iplist[i];
1163 /* Copy IPv6. */
1164 for (i = 0; i < count; i++) {
1165 if (iplist[i].ss.ss_family != AF_INET) {
1166 iplist_new[j++] = iplist[i];
1170 memcpy(iplist, iplist_new, sizeof(struct ip_service)*count);
1171 TALLOC_FREE(frame);
1172 return true;
1175 /****************************************************************************
1176 Do a netbios name query to find someones IP.
1177 Returns an array of IP addresses or NULL if none.
1178 *count will be set to the number of addresses returned.
1179 *timed_out is set if we failed by timing out
1180 ****************************************************************************/
1182 struct name_query_state {
1183 struct sockaddr_storage my_addr;
1184 struct sockaddr_storage addr;
1185 bool bcast;
1188 uint8_t buf[1024];
1189 ssize_t buflen;
1191 NTSTATUS validate_error;
1192 uint8_t flags;
1194 struct sockaddr_storage *addrs;
1195 int num_addrs;
1198 static bool name_query_validator(struct packet_struct *p, void *private_data);
1199 static void name_query_done(struct tevent_req *subreq);
1201 struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
1202 struct tevent_context *ev,
1203 const char *name, int name_type,
1204 bool bcast, bool recurse,
1205 const struct sockaddr_storage *addr)
1207 struct tevent_req *req, *subreq;
1208 struct name_query_state *state;
1209 struct packet_struct p;
1210 struct nmb_packet *nmb = &p.packet.nmb;
1211 struct sockaddr_in *in_addr;
1213 req = tevent_req_create(mem_ctx, &state, struct name_query_state);
1214 if (req == NULL) {
1215 return NULL;
1217 state->bcast = bcast;
1219 if (addr->ss_family != AF_INET) {
1220 /* Can't do node status to IPv6 */
1221 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
1222 return tevent_req_post(req, ev);
1225 if (lp_disable_netbios()) {
1226 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
1227 name, name_type));
1228 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
1229 return tevent_req_post(req, ev);
1232 state->addr = *addr;
1233 in_addr = (struct sockaddr_in *)(void *)&state->addr;
1234 in_addr->sin_port = htons(NMB_PORT);
1236 set_socket_addr_v4(&state->my_addr);
1238 ZERO_STRUCT(p);
1239 nmb->header.name_trn_id = generate_trn_id();
1240 nmb->header.opcode = 0;
1241 nmb->header.response = false;
1242 nmb->header.nm_flags.bcast = bcast;
1243 nmb->header.nm_flags.recursion_available = false;
1244 nmb->header.nm_flags.recursion_desired = recurse;
1245 nmb->header.nm_flags.trunc = false;
1246 nmb->header.nm_flags.authoritative = false;
1247 nmb->header.rcode = 0;
1248 nmb->header.qdcount = 1;
1249 nmb->header.ancount = 0;
1250 nmb->header.nscount = 0;
1251 nmb->header.arcount = 0;
1253 make_nmb_name(&nmb->question.question_name,name,name_type);
1255 nmb->question.question_type = 0x20;
1256 nmb->question.question_class = 0x1;
1258 state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
1259 &p);
1260 if (state->buflen == 0) {
1261 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1262 DEBUG(10, ("build_packet failed\n"));
1263 return tevent_req_post(req, ev);
1266 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, bcast,
1267 state->buf, state->buflen,
1268 NMB_PACKET, nmb->header.name_trn_id,
1269 name_query_validator, state);
1270 if (tevent_req_nomem(subreq, req)) {
1271 DEBUG(10, ("nb_trans_send failed\n"));
1272 return tevent_req_post(req, ev);
1274 tevent_req_set_callback(subreq, name_query_done, req);
1275 return req;
1278 static bool name_query_validator(struct packet_struct *p, void *private_data)
1280 struct name_query_state *state = talloc_get_type_abort(
1281 private_data, struct name_query_state);
1282 struct nmb_packet *nmb = &p->packet.nmb;
1283 struct sockaddr_storage *tmp_addrs;
1284 bool got_unique_netbios_name = false;
1285 int i;
1287 debug_nmb_packet(p);
1290 * If we get a Negative Name Query Response from a WINS
1291 * server, we should report it and give up.
1293 if( 0 == nmb->header.opcode /* A query response */
1294 && !state->bcast /* from a WINS server */
1295 && nmb->header.rcode /* Error returned */
1298 if( DEBUGLVL( 3 ) ) {
1299 /* Only executed if DEBUGLEVEL >= 3 */
1300 dbgtext( "Negative name query "
1301 "response, rcode 0x%02x: ",
1302 nmb->header.rcode );
1303 switch( nmb->header.rcode ) {
1304 case 0x01:
1305 dbgtext("Request was invalidly formatted.\n");
1306 break;
1307 case 0x02:
1308 dbgtext("Problem with NBNS, cannot process "
1309 "name.\n");
1310 break;
1311 case 0x03:
1312 dbgtext("The name requested does not "
1313 "exist.\n");
1314 break;
1315 case 0x04:
1316 dbgtext("Unsupported request error.\n");
1317 break;
1318 case 0x05:
1319 dbgtext("Query refused error.\n");
1320 break;
1321 default:
1322 dbgtext("Unrecognized error code.\n" );
1323 break;
1328 * We accept this packet as valid, but tell the upper
1329 * layers that it's a negative response.
1331 state->validate_error = NT_STATUS_NOT_FOUND;
1332 return true;
1335 if (nmb->header.opcode != 0 ||
1336 nmb->header.nm_flags.bcast ||
1337 nmb->header.rcode ||
1338 !nmb->header.ancount) {
1340 * XXXX what do we do with this? Could be a redirect,
1341 * but we'll discard it for the moment.
1343 return false;
1346 tmp_addrs = talloc_realloc(
1347 state, state->addrs, struct sockaddr_storage,
1348 state->num_addrs + nmb->answers->rdlength/6);
1349 if (tmp_addrs == NULL) {
1350 state->validate_error = NT_STATUS_NO_MEMORY;
1351 return true;
1353 state->addrs = tmp_addrs;
1355 DEBUG(2,("Got a positive name query response "
1356 "from %s ( ", inet_ntoa(p->ip)));
1358 for (i=0; i<nmb->answers->rdlength/6; i++) {
1359 uint16_t flags;
1360 struct in_addr ip;
1361 struct sockaddr_storage addr;
1362 int j;
1364 flags = RSVAL(&nmb->answers->rdata[i*6], 0);
1365 got_unique_netbios_name |= ((flags & 0x8000) == 0);
1367 putip((char *)&ip,&nmb->answers->rdata[2+i*6]);
1368 in_addr_to_sockaddr_storage(&addr, ip);
1370 for (j=0; j<state->num_addrs; j++) {
1371 if (sockaddr_equal(
1372 (struct sockaddr *)(void *)&addr,
1373 (struct sockaddr *)(void *)&state->addrs[j])) {
1374 break;
1377 if (j < state->num_addrs) {
1378 /* Already got it */
1379 continue;
1382 DEBUGADD(2,("%s ",inet_ntoa(ip)));
1384 state->addrs[state->num_addrs] = addr;
1385 state->num_addrs += 1;
1387 DEBUGADD(2,(")\n"));
1389 /* We add the flags back ... */
1390 if (nmb->header.response)
1391 state->flags |= NM_FLAGS_RS;
1392 if (nmb->header.nm_flags.authoritative)
1393 state->flags |= NM_FLAGS_AA;
1394 if (nmb->header.nm_flags.trunc)
1395 state->flags |= NM_FLAGS_TC;
1396 if (nmb->header.nm_flags.recursion_desired)
1397 state->flags |= NM_FLAGS_RD;
1398 if (nmb->header.nm_flags.recursion_available)
1399 state->flags |= NM_FLAGS_RA;
1400 if (nmb->header.nm_flags.bcast)
1401 state->flags |= NM_FLAGS_B;
1403 if (state->bcast) {
1405 * We have to collect all entries coming in from broadcast
1406 * queries. If we got a unique name, we're done.
1408 return got_unique_netbios_name;
1411 * WINS responses are accepted when they are received
1413 return true;
1416 static void name_query_done(struct tevent_req *subreq)
1418 struct tevent_req *req = tevent_req_callback_data(
1419 subreq, struct tevent_req);
1420 struct name_query_state *state = tevent_req_data(
1421 req, struct name_query_state);
1422 NTSTATUS status;
1423 struct packet_struct *p = NULL;
1425 status = nb_trans_recv(subreq, &p);
1426 TALLOC_FREE(subreq);
1427 if (tevent_req_nterror(req, status)) {
1428 return;
1430 if (!NT_STATUS_IS_OK(state->validate_error)) {
1431 tevent_req_nterror(req, state->validate_error);
1432 return;
1434 if (p != NULL) {
1436 * Free the packet here, we've collected the response in the
1437 * validator
1439 free_packet(p);
1441 tevent_req_done(req);
1444 NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1445 struct sockaddr_storage **addrs, int *num_addrs,
1446 uint8_t *flags)
1448 struct name_query_state *state = tevent_req_data(
1449 req, struct name_query_state);
1450 NTSTATUS status;
1452 if (tevent_req_is_nterror(req, &status)) {
1453 if (state->bcast &&
1454 NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1456 * In the broadcast case we collect replies until the
1457 * timeout.
1459 status = NT_STATUS_OK;
1461 if (!NT_STATUS_IS_OK(status)) {
1462 return status;
1465 if (state->num_addrs == 0) {
1466 return NT_STATUS_NOT_FOUND;
1468 *addrs = talloc_move(mem_ctx, &state->addrs);
1469 sort_addr_list(*addrs, state->num_addrs);
1470 *num_addrs = state->num_addrs;
1471 if (flags != NULL) {
1472 *flags = state->flags;
1474 return NT_STATUS_OK;
1477 NTSTATUS name_query(const char *name, int name_type,
1478 bool bcast, bool recurse,
1479 const struct sockaddr_storage *to_ss,
1480 TALLOC_CTX *mem_ctx,
1481 struct sockaddr_storage **addrs,
1482 int *num_addrs, uint8_t *flags)
1484 TALLOC_CTX *frame = talloc_stackframe();
1485 struct tevent_context *ev;
1486 struct tevent_req *req;
1487 struct timeval timeout;
1488 NTSTATUS status = NT_STATUS_NO_MEMORY;
1490 ev = tevent_context_init(frame);
1491 if (ev == NULL) {
1492 goto fail;
1494 req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss);
1495 if (req == NULL) {
1496 goto fail;
1498 if (bcast) {
1499 timeout = timeval_current_ofs(0, 250000);
1500 } else {
1501 timeout = timeval_current_ofs(2, 0);
1503 if (!tevent_req_set_endtime(req, ev, timeout)) {
1504 goto fail;
1506 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1507 goto fail;
1509 status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags);
1510 fail:
1511 TALLOC_FREE(frame);
1512 return status;
1515 /********************************************************
1516 convert an array if struct sockaddr_storage to struct ip_service
1517 return false on failure. Port is set to PORT_NONE;
1518 *********************************************************/
1520 static bool convert_ss2service(struct ip_service **return_iplist,
1521 const struct sockaddr_storage *ss_list,
1522 int count)
1524 int i;
1526 if ( count==0 || !ss_list )
1527 return False;
1529 /* copy the ip address; port will be PORT_NONE */
1530 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
1531 NULL) {
1532 DEBUG(0,("convert_ip2service: malloc failed "
1533 "for %d enetries!\n", count ));
1534 return False;
1537 for ( i=0; i<count; i++ ) {
1538 (*return_iplist)[i].ss = ss_list[i];
1539 (*return_iplist)[i].port = PORT_NONE;
1542 return true;
1545 struct name_queries_state {
1546 struct tevent_context *ev;
1547 const char *name;
1548 int name_type;
1549 bool bcast;
1550 bool recurse;
1551 const struct sockaddr_storage *addrs;
1552 int num_addrs;
1553 int wait_msec;
1554 int timeout_msec;
1556 struct tevent_req **subreqs;
1557 int num_received;
1558 int num_sent;
1560 int received_index;
1561 struct sockaddr_storage *result_addrs;
1562 int num_result_addrs;
1563 uint8_t flags;
1566 static void name_queries_done(struct tevent_req *subreq);
1567 static void name_queries_next(struct tevent_req *subreq);
1570 * Send a name query to multiple destinations with a wait time in between
1573 static struct tevent_req *name_queries_send(
1574 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1575 const char *name, int name_type,
1576 bool bcast, bool recurse,
1577 const struct sockaddr_storage *addrs,
1578 int num_addrs, int wait_msec, int timeout_msec)
1580 struct tevent_req *req, *subreq;
1581 struct name_queries_state *state;
1583 req = tevent_req_create(mem_ctx, &state,
1584 struct name_queries_state);
1585 if (req == NULL) {
1586 return NULL;
1588 state->ev = ev;
1589 state->name = name;
1590 state->name_type = name_type;
1591 state->bcast = bcast;
1592 state->recurse = recurse;
1593 state->addrs = addrs;
1594 state->num_addrs = num_addrs;
1595 state->wait_msec = wait_msec;
1596 state->timeout_msec = timeout_msec;
1598 state->subreqs = talloc_zero_array(
1599 state, struct tevent_req *, num_addrs);
1600 if (tevent_req_nomem(state->subreqs, req)) {
1601 return tevent_req_post(req, ev);
1603 state->num_sent = 0;
1605 subreq = name_query_send(
1606 state->subreqs, state->ev, name, name_type, bcast, recurse,
1607 &state->addrs[state->num_sent]);
1608 if (tevent_req_nomem(subreq, req)) {
1609 return tevent_req_post(req, ev);
1611 if (!tevent_req_set_endtime(
1612 subreq, state->ev,
1613 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1614 tevent_req_oom(req);
1615 return tevent_req_post(req, ev);
1617 tevent_req_set_callback(subreq, name_queries_done, req);
1619 state->subreqs[state->num_sent] = subreq;
1620 state->num_sent += 1;
1622 if (state->num_sent < state->num_addrs) {
1623 subreq = tevent_wakeup_send(
1624 state, state->ev,
1625 timeval_current_ofs(0, state->wait_msec * 1000));
1626 if (tevent_req_nomem(subreq, req)) {
1627 return tevent_req_post(req, ev);
1629 tevent_req_set_callback(subreq, name_queries_next, req);
1631 return req;
1634 static void name_queries_done(struct tevent_req *subreq)
1636 struct tevent_req *req = tevent_req_callback_data(
1637 subreq, struct tevent_req);
1638 struct name_queries_state *state = tevent_req_data(
1639 req, struct name_queries_state);
1640 int i;
1641 NTSTATUS status;
1643 status = name_query_recv(subreq, state, &state->result_addrs,
1644 &state->num_result_addrs, &state->flags);
1646 for (i=0; i<state->num_sent; i++) {
1647 if (state->subreqs[i] == subreq) {
1648 break;
1651 if (i == state->num_sent) {
1652 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1653 return;
1655 TALLOC_FREE(state->subreqs[i]);
1657 state->num_received += 1;
1659 if (!NT_STATUS_IS_OK(status)) {
1661 if (state->num_received >= state->num_addrs) {
1662 tevent_req_nterror(req, status);
1663 return;
1666 * Still outstanding requests, just wait
1668 return;
1670 state->received_index = i;
1671 tevent_req_done(req);
1674 static void name_queries_next(struct tevent_req *subreq)
1676 struct tevent_req *req = tevent_req_callback_data(
1677 subreq, struct tevent_req);
1678 struct name_queries_state *state = tevent_req_data(
1679 req, struct name_queries_state);
1681 if (!tevent_wakeup_recv(subreq)) {
1682 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1683 return;
1686 subreq = name_query_send(
1687 state->subreqs, state->ev,
1688 state->name, state->name_type, state->bcast, state->recurse,
1689 &state->addrs[state->num_sent]);
1690 if (tevent_req_nomem(subreq, req)) {
1691 return;
1693 tevent_req_set_callback(subreq, name_queries_done, req);
1694 if (!tevent_req_set_endtime(
1695 subreq, state->ev,
1696 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1697 tevent_req_oom(req);
1698 return;
1700 state->subreqs[state->num_sent] = subreq;
1701 state->num_sent += 1;
1703 if (state->num_sent < state->num_addrs) {
1704 subreq = tevent_wakeup_send(
1705 state, state->ev,
1706 timeval_current_ofs(0, state->wait_msec * 1000));
1707 if (tevent_req_nomem(subreq, req)) {
1708 return;
1710 tevent_req_set_callback(subreq, name_queries_next, req);
1714 static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1715 struct sockaddr_storage **result_addrs,
1716 int *num_result_addrs, uint8_t *flags,
1717 int *received_index)
1719 struct name_queries_state *state = tevent_req_data(
1720 req, struct name_queries_state);
1721 NTSTATUS status;
1723 if (tevent_req_is_nterror(req, &status)) {
1724 return status;
1727 if (result_addrs != NULL) {
1728 *result_addrs = talloc_move(mem_ctx, &state->result_addrs);
1730 if (num_result_addrs != NULL) {
1731 *num_result_addrs = state->num_result_addrs;
1733 if (flags != NULL) {
1734 *flags = state->flags;
1736 if (received_index != NULL) {
1737 *received_index = state->received_index;
1739 return NT_STATUS_OK;
1742 /********************************************************
1743 Resolve via "bcast" method.
1744 *********************************************************/
1746 struct name_resolve_bcast_state {
1747 struct sockaddr_storage *addrs;
1748 int num_addrs;
1751 static void name_resolve_bcast_done(struct tevent_req *subreq);
1753 struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx,
1754 struct tevent_context *ev,
1755 const char *name,
1756 int name_type)
1758 struct tevent_req *req, *subreq;
1759 struct name_resolve_bcast_state *state;
1760 struct sockaddr_storage *bcast_addrs;
1761 int i, num_addrs, num_bcast_addrs;
1763 req = tevent_req_create(mem_ctx, &state,
1764 struct name_resolve_bcast_state);
1765 if (req == NULL) {
1766 return NULL;
1769 if (lp_disable_netbios()) {
1770 DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n",
1771 name, name_type));
1772 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1773 return tevent_req_post(req, ev);
1777 * "bcast" means do a broadcast lookup on all the local interfaces.
1780 DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup "
1781 "for name %s<0x%x>\n", name, name_type));
1783 num_addrs = iface_count();
1784 bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs);
1785 if (tevent_req_nomem(bcast_addrs, req)) {
1786 return tevent_req_post(req, ev);
1790 * Lookup the name on all the interfaces, return on
1791 * the first successful match.
1793 num_bcast_addrs = 0;
1795 for (i=0; i<num_addrs; i++) {
1796 const struct sockaddr_storage *pss = iface_n_bcast(i);
1798 if (pss->ss_family != AF_INET) {
1799 continue;
1801 bcast_addrs[num_bcast_addrs] = *pss;
1802 num_bcast_addrs += 1;
1805 subreq = name_queries_send(state, ev, name, name_type, true, true,
1806 bcast_addrs, num_bcast_addrs, 0, 1000);
1807 if (tevent_req_nomem(subreq, req)) {
1808 return tevent_req_post(req, ev);
1810 tevent_req_set_callback(subreq, name_resolve_bcast_done, req);
1811 return req;
1814 static void name_resolve_bcast_done(struct tevent_req *subreq)
1816 struct tevent_req *req = tevent_req_callback_data(
1817 subreq, struct tevent_req);
1818 struct name_resolve_bcast_state *state = tevent_req_data(
1819 req, struct name_resolve_bcast_state);
1820 NTSTATUS status;
1822 status = name_queries_recv(subreq, state,
1823 &state->addrs, &state->num_addrs,
1824 NULL, NULL);
1825 TALLOC_FREE(subreq);
1826 if (tevent_req_nterror(req, status)) {
1827 return;
1829 tevent_req_done(req);
1832 NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1833 struct sockaddr_storage **addrs,
1834 int *num_addrs)
1836 struct name_resolve_bcast_state *state = tevent_req_data(
1837 req, struct name_resolve_bcast_state);
1838 NTSTATUS status;
1840 if (tevent_req_is_nterror(req, &status)) {
1841 return status;
1843 *addrs = talloc_move(mem_ctx, &state->addrs);
1844 *num_addrs = state->num_addrs;
1845 return NT_STATUS_OK;
1848 NTSTATUS name_resolve_bcast(const char *name,
1849 int name_type,
1850 TALLOC_CTX *mem_ctx,
1851 struct sockaddr_storage **return_iplist,
1852 int *return_count)
1854 TALLOC_CTX *frame = talloc_stackframe();
1855 struct event_context *ev;
1856 struct tevent_req *req;
1857 NTSTATUS status = NT_STATUS_NO_MEMORY;
1859 ev = event_context_init(frame);
1860 if (ev == NULL) {
1861 goto fail;
1863 req = name_resolve_bcast_send(frame, ev, name, name_type);
1864 if (req == NULL) {
1865 goto fail;
1867 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1868 goto fail;
1870 status = name_resolve_bcast_recv(req, mem_ctx, return_iplist,
1871 return_count);
1872 fail:
1873 TALLOC_FREE(frame);
1874 return status;
1877 struct query_wins_list_state {
1878 struct tevent_context *ev;
1879 const char *name;
1880 uint8_t name_type;
1881 struct in_addr *servers;
1882 uint32_t num_servers;
1883 struct sockaddr_storage server;
1884 uint32_t num_sent;
1886 struct sockaddr_storage *addrs;
1887 int num_addrs;
1888 uint8_t flags;
1891 static void query_wins_list_done(struct tevent_req *subreq);
1894 * Query a list of (replicating) wins servers in sequence, call them
1895 * dead if they don't reply
1898 static struct tevent_req *query_wins_list_send(
1899 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1900 struct in_addr src_ip, const char *name, uint8_t name_type,
1901 struct in_addr *servers, int num_servers)
1903 struct tevent_req *req, *subreq;
1904 struct query_wins_list_state *state;
1906 req = tevent_req_create(mem_ctx, &state,
1907 struct query_wins_list_state);
1908 if (req == NULL) {
1909 return NULL;
1911 state->ev = ev;
1912 state->name = name;
1913 state->name_type = name_type;
1914 state->servers = servers;
1915 state->num_servers = num_servers;
1917 if (state->num_servers == 0) {
1918 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
1919 return tevent_req_post(req, ev);
1922 in_addr_to_sockaddr_storage(
1923 &state->server, state->servers[state->num_sent]);
1925 subreq = name_query_send(state, state->ev,
1926 state->name, state->name_type,
1927 false, true, &state->server);
1928 state->num_sent += 1;
1929 if (tevent_req_nomem(subreq, req)) {
1930 return tevent_req_post(req, ev);
1932 if (!tevent_req_set_endtime(subreq, state->ev,
1933 timeval_current_ofs(2, 0))) {
1934 tevent_req_oom(req);
1935 return tevent_req_post(req, ev);
1937 tevent_req_set_callback(subreq, query_wins_list_done, req);
1938 return req;
1941 static void query_wins_list_done(struct tevent_req *subreq)
1943 struct tevent_req *req = tevent_req_callback_data(
1944 subreq, struct tevent_req);
1945 struct query_wins_list_state *state = tevent_req_data(
1946 req, struct query_wins_list_state);
1947 NTSTATUS status;
1949 status = name_query_recv(subreq, state,
1950 &state->addrs, &state->num_addrs,
1951 &state->flags);
1952 TALLOC_FREE(subreq);
1953 if (NT_STATUS_IS_OK(status)) {
1954 tevent_req_done(req);
1955 return;
1957 if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1958 tevent_req_nterror(req, status);
1959 return;
1961 wins_srv_died(state->servers[state->num_sent-1],
1962 my_socket_addr_v4());
1964 if (state->num_sent == state->num_servers) {
1965 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
1966 return;
1969 in_addr_to_sockaddr_storage(
1970 &state->server, state->servers[state->num_sent]);
1972 subreq = name_query_send(state, state->ev,
1973 state->name, state->name_type,
1974 false, true, &state->server);
1975 state->num_sent += 1;
1976 if (tevent_req_nomem(subreq, req)) {
1977 return;
1979 if (!tevent_req_set_endtime(subreq, state->ev,
1980 timeval_current_ofs(2, 0))) {
1981 tevent_req_oom(req);
1982 return;
1984 tevent_req_set_callback(subreq, query_wins_list_done, req);
1987 static NTSTATUS query_wins_list_recv(struct tevent_req *req,
1988 TALLOC_CTX *mem_ctx,
1989 struct sockaddr_storage **addrs,
1990 int *num_addrs,
1991 uint8_t *flags)
1993 struct query_wins_list_state *state = tevent_req_data(
1994 req, struct query_wins_list_state);
1995 NTSTATUS status;
1997 if (tevent_req_is_nterror(req, &status)) {
1998 return status;
2000 if (addrs != NULL) {
2001 *addrs = talloc_move(mem_ctx, &state->addrs);
2003 if (num_addrs != NULL) {
2004 *num_addrs = state->num_addrs;
2006 if (flags != NULL) {
2007 *flags = state->flags;
2009 return NT_STATUS_OK;
2012 struct resolve_wins_state {
2013 int num_sent;
2014 int num_received;
2016 struct sockaddr_storage *addrs;
2017 int num_addrs;
2018 uint8_t flags;
2021 static void resolve_wins_done(struct tevent_req *subreq);
2023 struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
2024 struct tevent_context *ev,
2025 const char *name,
2026 int name_type)
2028 struct tevent_req *req, *subreq;
2029 struct resolve_wins_state *state;
2030 char **wins_tags = NULL;
2031 struct sockaddr_storage src_ss;
2032 struct in_addr src_ip;
2033 int i, num_wins_tags;
2035 req = tevent_req_create(mem_ctx, &state,
2036 struct resolve_wins_state);
2037 if (req == NULL) {
2038 return NULL;
2041 if (wins_srv_count() < 1) {
2042 DEBUG(3,("resolve_wins: WINS server resolution selected "
2043 "and no WINS servers listed.\n"));
2044 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2045 goto fail;
2048 /* the address we will be sending from */
2049 if (!interpret_string_addr(&src_ss, lp_socket_address(),
2050 AI_NUMERICHOST|AI_PASSIVE)) {
2051 zero_sockaddr(&src_ss);
2054 if (src_ss.ss_family != AF_INET) {
2055 char addr[INET6_ADDRSTRLEN];
2056 print_sockaddr(addr, sizeof(addr), &src_ss);
2057 DEBUG(3,("resolve_wins: cannot receive WINS replies "
2058 "on IPv6 address %s\n",
2059 addr));
2060 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2061 goto fail;
2064 src_ip = ((const struct sockaddr_in *)(void *)&src_ss)->sin_addr;
2066 wins_tags = wins_srv_tags();
2067 if (wins_tags == NULL) {
2068 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2069 goto fail;
2072 num_wins_tags = 0;
2073 while (wins_tags[num_wins_tags] != NULL) {
2074 num_wins_tags += 1;
2077 for (i=0; i<num_wins_tags; i++) {
2078 int num_servers, num_alive;
2079 struct in_addr *servers, *alive;
2080 int j;
2082 if (!wins_server_tag_ips(wins_tags[i], talloc_tos(),
2083 &servers, &num_servers)) {
2084 DEBUG(10, ("wins_server_tag_ips failed for tag %s\n",
2085 wins_tags[i]));
2086 continue;
2089 alive = talloc_array(state, struct in_addr, num_servers);
2090 if (tevent_req_nomem(alive, req)) {
2091 goto fail;
2094 num_alive = 0;
2095 for (j=0; j<num_servers; j++) {
2096 struct in_addr wins_ip = servers[j];
2098 if (global_in_nmbd && ismyip_v4(wins_ip)) {
2099 /* yikes! we'll loop forever */
2100 continue;
2102 /* skip any that have been unresponsive lately */
2103 if (wins_srv_is_dead(wins_ip, src_ip)) {
2104 continue;
2106 DEBUG(3, ("resolve_wins: using WINS server %s "
2107 "and tag '%s'\n",
2108 inet_ntoa(wins_ip), wins_tags[i]));
2109 alive[num_alive] = wins_ip;
2110 num_alive += 1;
2112 TALLOC_FREE(servers);
2114 if (num_alive == 0) {
2115 continue;
2118 subreq = query_wins_list_send(
2119 state, ev, src_ip, name, name_type,
2120 alive, num_alive);
2121 if (tevent_req_nomem(subreq, req)) {
2122 goto fail;
2124 tevent_req_set_callback(subreq, resolve_wins_done, req);
2125 state->num_sent += 1;
2128 if (state->num_sent == 0) {
2129 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2130 goto fail;
2133 wins_srv_tags_free(wins_tags);
2134 return req;
2135 fail:
2136 wins_srv_tags_free(wins_tags);
2137 return tevent_req_post(req, ev);
2140 static void resolve_wins_done(struct tevent_req *subreq)
2142 struct tevent_req *req = tevent_req_callback_data(
2143 subreq, struct tevent_req);
2144 struct resolve_wins_state *state = tevent_req_data(
2145 req, struct resolve_wins_state);
2146 NTSTATUS status;
2148 status = query_wins_list_recv(subreq, state, &state->addrs,
2149 &state->num_addrs, &state->flags);
2150 if (NT_STATUS_IS_OK(status)) {
2151 tevent_req_done(req);
2152 return;
2155 state->num_received += 1;
2157 if (state->num_received < state->num_sent) {
2159 * Wait for the others
2161 return;
2163 tevent_req_nterror(req, status);
2166 NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2167 struct sockaddr_storage **addrs,
2168 int *num_addrs, uint8_t *flags)
2170 struct resolve_wins_state *state = tevent_req_data(
2171 req, struct resolve_wins_state);
2172 NTSTATUS status;
2174 if (tevent_req_is_nterror(req, &status)) {
2175 return status;
2177 if (addrs != NULL) {
2178 *addrs = talloc_move(mem_ctx, &state->addrs);
2180 if (num_addrs != NULL) {
2181 *num_addrs = state->num_addrs;
2183 if (flags != NULL) {
2184 *flags = state->flags;
2186 return NT_STATUS_OK;
2189 /********************************************************
2190 Resolve via "wins" method.
2191 *********************************************************/
2193 NTSTATUS resolve_wins(const char *name,
2194 int name_type,
2195 TALLOC_CTX *mem_ctx,
2196 struct sockaddr_storage **return_iplist,
2197 int *return_count)
2199 struct tevent_context *ev;
2200 struct tevent_req *req;
2201 NTSTATUS status = NT_STATUS_NO_MEMORY;
2203 ev = tevent_context_init(talloc_tos());
2204 if (ev == NULL) {
2205 goto fail;
2207 req = resolve_wins_send(ev, ev, name, name_type);
2208 if (req == NULL) {
2209 goto fail;
2211 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2212 goto fail;
2214 status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count,
2215 NULL);
2216 fail:
2217 TALLOC_FREE(ev);
2218 return status;
2221 /********************************************************
2222 Resolve via "lmhosts" method.
2223 *********************************************************/
2225 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
2226 struct ip_service **return_iplist,
2227 int *return_count)
2230 * "lmhosts" means parse the local lmhosts file.
2232 struct sockaddr_storage *ss_list;
2233 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2234 TALLOC_CTX *ctx = NULL;
2236 *return_iplist = NULL;
2237 *return_count = 0;
2239 DEBUG(3,("resolve_lmhosts: "
2240 "Attempting lmhosts lookup for name %s<0x%x>\n",
2241 name, name_type));
2243 ctx = talloc_init("resolve_lmhosts");
2244 if (!ctx) {
2245 return NT_STATUS_NO_MEMORY;
2248 status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(),
2249 name, name_type,
2250 ctx,
2251 &ss_list,
2252 return_count);
2253 if (NT_STATUS_IS_OK(status)) {
2254 if (convert_ss2service(return_iplist,
2255 ss_list,
2256 *return_count)) {
2257 talloc_free(ctx);
2258 return NT_STATUS_OK;
2259 } else {
2260 talloc_free(ctx);
2261 return NT_STATUS_NO_MEMORY;
2264 talloc_free(ctx);
2265 return status;
2269 /********************************************************
2270 Resolve via "hosts" method.
2271 *********************************************************/
2273 static NTSTATUS resolve_hosts(const char *name, int name_type,
2274 struct ip_service **return_iplist,
2275 int *return_count)
2278 * "host" means do a localhost, or dns lookup.
2280 struct addrinfo hints;
2281 struct addrinfo *ailist = NULL;
2282 struct addrinfo *res = NULL;
2283 int ret = -1;
2284 int i = 0;
2285 const char *dns_hosts_file;
2287 if ( name_type != 0x20 && name_type != 0x0) {
2288 DEBUG(5, ("resolve_hosts: not appropriate "
2289 "for name type <0x%x>\n",
2290 name_type));
2291 return NT_STATUS_INVALID_PARAMETER;
2294 *return_iplist = NULL;
2295 *return_count = 0;
2297 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
2298 name, name_type));
2300 ZERO_STRUCT(hints);
2301 /* By default make sure it supports TCP. */
2302 hints.ai_socktype = SOCK_STREAM;
2303 hints.ai_flags = AI_ADDRCONFIG;
2305 #if !defined(HAVE_IPV6)
2306 /* Unless we have IPv6, we really only want IPv4 addresses back. */
2307 hints.ai_family = AF_INET;
2308 #endif
2310 dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL);
2311 if (dns_hosts_file) {
2312 struct sockaddr_storage *ss_list;
2313 NTSTATUS status;
2314 TALLOC_CTX *ctx = talloc_stackframe();
2315 if (!ctx) {
2316 return NT_STATUS_NO_MEMORY;
2319 status = resolve_dns_hosts_file_as_sockaddr(dns_hosts_file, name, false,
2320 ctx, &ss_list, return_count);
2321 if (NT_STATUS_IS_OK(status)) {
2322 if (convert_ss2service(return_iplist,
2323 ss_list,
2324 *return_count)) {
2325 talloc_free(ctx);
2326 return NT_STATUS_OK;
2327 } else {
2328 talloc_free(ctx);
2329 return NT_STATUS_NO_MEMORY;
2332 talloc_free(ctx);
2333 return NT_STATUS_UNSUCCESSFUL;
2336 ret = getaddrinfo(name,
2337 NULL,
2338 &hints,
2339 &ailist);
2340 if (ret) {
2341 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
2342 name,
2343 gai_strerror(ret) ));
2346 for (res = ailist; res; res = res->ai_next) {
2347 struct sockaddr_storage ss;
2349 if (!res->ai_addr || res->ai_addrlen == 0) {
2350 continue;
2353 ZERO_STRUCT(ss);
2354 memcpy(&ss, res->ai_addr, res->ai_addrlen);
2356 *return_count += 1;
2358 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
2359 struct ip_service,
2360 *return_count);
2361 if (!*return_iplist) {
2362 DEBUG(3,("resolve_hosts: malloc fail !\n"));
2363 freeaddrinfo(ailist);
2364 return NT_STATUS_NO_MEMORY;
2366 (*return_iplist)[i].ss = ss;
2367 (*return_iplist)[i].port = PORT_NONE;
2368 i++;
2370 if (ailist) {
2371 freeaddrinfo(ailist);
2373 if (*return_count) {
2374 return NT_STATUS_OK;
2376 return NT_STATUS_UNSUCCESSFUL;
2379 /********************************************************
2380 Resolve via "ADS" method.
2381 *********************************************************/
2383 /* Special name type used to cause a _kerberos DNS lookup. */
2384 #define KDC_NAME_TYPE 0xDCDC
2386 static NTSTATUS resolve_ads(const char *name,
2387 int name_type,
2388 const char *sitename,
2389 struct ip_service **return_iplist,
2390 int *return_count)
2392 int i, j;
2393 NTSTATUS status;
2394 TALLOC_CTX *ctx;
2395 struct dns_rr_srv *dcs = NULL;
2396 int numdcs = 0;
2397 int numaddrs = 0;
2399 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
2400 (name_type != 0x1b)) {
2401 return NT_STATUS_INVALID_PARAMETER;
2404 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
2405 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
2406 return NT_STATUS_NO_MEMORY;
2409 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
2411 switch (name_type) {
2412 case 0x1b:
2413 DEBUG(5,("resolve_ads: Attempting to resolve "
2414 "PDC for %s using DNS\n", name));
2415 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
2416 break;
2418 case 0x1c:
2419 DEBUG(5,("resolve_ads: Attempting to resolve "
2420 "DCs for %s using DNS\n", name));
2421 status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
2422 &numdcs);
2423 break;
2424 case KDC_NAME_TYPE:
2425 DEBUG(5,("resolve_ads: Attempting to resolve "
2426 "KDCs for %s using DNS\n", name));
2427 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
2428 &numdcs);
2429 break;
2430 default:
2431 status = NT_STATUS_INVALID_PARAMETER;
2432 break;
2435 if ( !NT_STATUS_IS_OK( status ) ) {
2436 talloc_destroy(ctx);
2437 return status;
2440 for (i=0;i<numdcs;i++) {
2441 numaddrs += MAX(dcs[i].num_ips,1);
2444 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
2445 NULL ) {
2446 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
2447 numaddrs ));
2448 talloc_destroy(ctx);
2449 return NT_STATUS_NO_MEMORY;
2452 /* now unroll the list of IP addresses */
2454 *return_count = 0;
2455 i = 0;
2456 j = 0;
2457 while ( i < numdcs && (*return_count<numaddrs) ) {
2458 struct ip_service *r = &(*return_iplist)[*return_count];
2460 r->port = dcs[i].port;
2462 /* If we don't have an IP list for a name, lookup it up */
2464 if (!dcs[i].ss_s) {
2465 interpret_string_addr(&r->ss, dcs[i].hostname, 0);
2466 i++;
2467 j = 0;
2468 } else {
2469 /* use the IP addresses from the SRV sresponse */
2471 if ( j >= dcs[i].num_ips ) {
2472 i++;
2473 j = 0;
2474 continue;
2477 r->ss = dcs[i].ss_s[j];
2478 j++;
2481 /* make sure it is a valid IP. I considered checking the
2482 * negative connection cache, but this is the wrong place
2483 * for it. Maybe only as a hack. After think about it, if
2484 * all of the IP addresses returned from DNS are dead, what
2485 * hope does a netbios name lookup have ? The standard reason
2486 * for falling back to netbios lookups is that our DNS server
2487 * doesn't know anything about the DC's -- jerry */
2489 if (!is_zero_addr(&r->ss)) {
2490 (*return_count)++;
2494 talloc_destroy(ctx);
2495 return NT_STATUS_OK;
2498 /*******************************************************************
2499 Internal interface to resolve a name into an IP address.
2500 Use this function if the string is either an IP address, DNS
2501 or host name or NetBIOS name. This uses the name switch in the
2502 smb.conf to determine the order of name resolution.
2504 Added support for ip addr/port to support ADS ldap servers.
2505 the only place we currently care about the port is in the
2506 resolve_hosts() when looking up DC's via SRV RR entries in DNS
2507 **********************************************************************/
2509 NTSTATUS internal_resolve_name(const char *name,
2510 int name_type,
2511 const char *sitename,
2512 struct ip_service **return_iplist,
2513 int *return_count,
2514 const char *resolve_order)
2516 char *tok;
2517 const char *ptr;
2518 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2519 int i;
2520 TALLOC_CTX *frame = NULL;
2522 *return_iplist = NULL;
2523 *return_count = 0;
2525 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
2526 name, name_type, sitename ? sitename : "(null)"));
2528 if (is_ipaddress(name)) {
2529 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
2530 NULL) {
2531 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
2532 return NT_STATUS_NO_MEMORY;
2535 /* ignore the port here */
2536 (*return_iplist)->port = PORT_NONE;
2538 /* if it's in the form of an IP address then get the lib to interpret it */
2539 if (!interpret_string_addr(&(*return_iplist)->ss,
2540 name, AI_NUMERICHOST)) {
2541 DEBUG(1,("internal_resolve_name: interpret_string_addr "
2542 "failed on %s\n",
2543 name));
2544 SAFE_FREE(*return_iplist);
2545 return NT_STATUS_INVALID_PARAMETER;
2547 *return_count = 1;
2548 return NT_STATUS_OK;
2551 /* Check name cache */
2553 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
2554 /* This could be a negative response */
2555 if (*return_count > 0) {
2556 return NT_STATUS_OK;
2557 } else {
2558 return NT_STATUS_UNSUCCESSFUL;
2562 /* set the name resolution order */
2564 if (strcmp( resolve_order, "NULL") == 0) {
2565 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
2566 return NT_STATUS_INVALID_PARAMETER;
2569 if (!resolve_order[0]) {
2570 ptr = "host";
2571 } else {
2572 ptr = resolve_order;
2575 /* iterate through the name resolution backends */
2577 frame = talloc_stackframe();
2578 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
2579 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
2580 status = resolve_hosts(name, name_type, return_iplist,
2581 return_count);
2582 if (NT_STATUS_IS_OK(status)) {
2583 goto done;
2585 } else if(strequal( tok, "kdc")) {
2586 /* deal with KDC_NAME_TYPE names here.
2587 * This will result in a SRV record lookup */
2588 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
2589 return_iplist, return_count);
2590 if (NT_STATUS_IS_OK(status)) {
2591 /* Ensure we don't namecache
2592 * this with the KDC port. */
2593 name_type = KDC_NAME_TYPE;
2594 goto done;
2596 } else if(strequal( tok, "ads")) {
2597 /* deal with 0x1c and 0x1b names here.
2598 * This will result in a SRV record lookup */
2599 status = resolve_ads(name, name_type, sitename,
2600 return_iplist, return_count);
2601 if (NT_STATUS_IS_OK(status)) {
2602 goto done;
2604 } else if(strequal( tok, "lmhosts")) {
2605 status = resolve_lmhosts(name, name_type,
2606 return_iplist, return_count);
2607 if (NT_STATUS_IS_OK(status)) {
2608 goto done;
2610 } else if(strequal( tok, "wins")) {
2611 /* don't resolve 1D via WINS */
2612 struct sockaddr_storage *ss_list;
2613 if (name_type != 0x1D) {
2614 status = resolve_wins(name, name_type,
2615 talloc_tos(),
2616 &ss_list,
2617 return_count);
2618 if (NT_STATUS_IS_OK(status)) {
2619 if (!convert_ss2service(return_iplist,
2620 ss_list,
2621 *return_count)) {
2622 status = NT_STATUS_NO_MEMORY;
2624 goto done;
2627 } else if(strequal( tok, "bcast")) {
2628 struct sockaddr_storage *ss_list;
2629 status = name_resolve_bcast(
2630 name, name_type, talloc_tos(),
2631 &ss_list, return_count);
2632 if (NT_STATUS_IS_OK(status)) {
2633 if (!convert_ss2service(return_iplist,
2634 ss_list,
2635 *return_count)) {
2636 status = NT_STATUS_NO_MEMORY;
2638 goto done;
2640 } else {
2641 DEBUG(0,("resolve_name: unknown name switch type %s\n",
2642 tok));
2646 /* All of the resolve_* functions above have returned false. */
2648 TALLOC_FREE(frame);
2649 SAFE_FREE(*return_iplist);
2650 *return_count = 0;
2652 return NT_STATUS_UNSUCCESSFUL;
2654 done:
2656 /* Remove duplicate entries. Some queries, notably #1c (domain
2657 controllers) return the PDC in iplist[0] and then all domain
2658 controllers including the PDC in iplist[1..n]. Iterating over
2659 the iplist when the PDC is down will cause two sets of timeouts. */
2661 if ( *return_count ) {
2662 *return_count = remove_duplicate_addrs2(*return_iplist,
2663 *return_count );
2666 /* Save in name cache */
2667 if ( DEBUGLEVEL >= 100 ) {
2668 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
2669 char addr[INET6_ADDRSTRLEN];
2670 print_sockaddr(addr, sizeof(addr),
2671 &(*return_iplist)[i].ss);
2672 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
2673 name,
2674 name_type,
2675 addr,
2676 (*return_iplist)[i].port));
2680 namecache_store(name, name_type, *return_count, *return_iplist);
2682 /* Display some debugging info */
2684 if ( DEBUGLEVEL >= 10 ) {
2685 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
2686 *return_count));
2688 for (i = 0; i < *return_count; i++) {
2689 char addr[INET6_ADDRSTRLEN];
2690 print_sockaddr(addr, sizeof(addr),
2691 &(*return_iplist)[i].ss);
2692 DEBUGADD(10, ("%s:%d ",
2693 addr,
2694 (*return_iplist)[i].port));
2696 DEBUG(10, ("\n"));
2699 TALLOC_FREE(frame);
2700 return status;
2703 /********************************************************
2704 Internal interface to resolve a name into one IP address.
2705 Use this function if the string is either an IP address, DNS
2706 or host name or NetBIOS name. This uses the name switch in the
2707 smb.conf to determine the order of name resolution.
2708 *********************************************************/
2710 bool resolve_name(const char *name,
2711 struct sockaddr_storage *return_ss,
2712 int name_type,
2713 bool prefer_ipv4)
2715 struct ip_service *ss_list = NULL;
2716 char *sitename = NULL;
2717 int count = 0;
2718 NTSTATUS status;
2720 if (is_ipaddress(name)) {
2721 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
2724 sitename = sitename_fetch(lp_realm()); /* wild guess */
2726 status = internal_resolve_name(name, name_type, sitename,
2727 &ss_list, &count,
2728 lp_name_resolve_order());
2729 if (NT_STATUS_IS_OK(status)) {
2730 int i;
2732 if (prefer_ipv4) {
2733 for (i=0; i<count; i++) {
2734 if (!is_zero_addr(&ss_list[i].ss) &&
2735 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss) &&
2736 (ss_list[i].ss.ss_family == AF_INET)) {
2737 *return_ss = ss_list[i].ss;
2738 SAFE_FREE(ss_list);
2739 SAFE_FREE(sitename);
2740 return True;
2745 /* only return valid addresses for TCP connections */
2746 for (i=0; i<count; i++) {
2747 if (!is_zero_addr(&ss_list[i].ss) &&
2748 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2749 *return_ss = ss_list[i].ss;
2750 SAFE_FREE(ss_list);
2751 SAFE_FREE(sitename);
2752 return True;
2757 SAFE_FREE(ss_list);
2758 SAFE_FREE(sitename);
2759 return False;
2762 /********************************************************
2763 Internal interface to resolve a name into a list of IP addresses.
2764 Use this function if the string is either an IP address, DNS
2765 or host name or NetBIOS name. This uses the name switch in the
2766 smb.conf to determine the order of name resolution.
2767 *********************************************************/
2769 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
2770 const char *name,
2771 int name_type,
2772 struct sockaddr_storage **return_ss_arr,
2773 unsigned int *p_num_entries)
2775 struct ip_service *ss_list = NULL;
2776 char *sitename = NULL;
2777 int count = 0;
2778 int i;
2779 unsigned int num_entries;
2780 NTSTATUS status;
2782 *p_num_entries = 0;
2783 *return_ss_arr = NULL;
2785 if (is_ipaddress(name)) {
2786 *return_ss_arr = talloc(ctx, struct sockaddr_storage);
2787 if (!*return_ss_arr) {
2788 return NT_STATUS_NO_MEMORY;
2790 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
2791 TALLOC_FREE(*return_ss_arr);
2792 return NT_STATUS_BAD_NETWORK_NAME;
2794 *p_num_entries = 1;
2795 return NT_STATUS_OK;
2798 sitename = sitename_fetch(lp_realm()); /* wild guess */
2800 status = internal_resolve_name(name, name_type, sitename,
2801 &ss_list, &count,
2802 lp_name_resolve_order());
2803 SAFE_FREE(sitename);
2805 if (!NT_STATUS_IS_OK(status)) {
2806 return status;
2809 /* only return valid addresses for TCP connections */
2810 for (i=0, num_entries = 0; i<count; i++) {
2811 if (!is_zero_addr(&ss_list[i].ss) &&
2812 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2813 num_entries++;
2816 if (num_entries == 0) {
2817 SAFE_FREE(ss_list);
2818 return NT_STATUS_BAD_NETWORK_NAME;
2821 *return_ss_arr = talloc_array(ctx,
2822 struct sockaddr_storage,
2823 num_entries);
2824 if (!(*return_ss_arr)) {
2825 SAFE_FREE(ss_list);
2826 return NT_STATUS_NO_MEMORY;
2829 for (i=0, num_entries = 0; i<count; i++) {
2830 if (!is_zero_addr(&ss_list[i].ss) &&
2831 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2832 (*return_ss_arr)[num_entries++] = ss_list[i].ss;
2836 status = NT_STATUS_OK;
2837 *p_num_entries = num_entries;
2839 SAFE_FREE(ss_list);
2840 return NT_STATUS_OK;
2843 /********************************************************
2844 Find the IP address of the master browser or DMB for a workgroup.
2845 *********************************************************/
2847 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
2849 struct ip_service *ip_list = NULL;
2850 int count = 0;
2851 NTSTATUS status;
2853 if (lp_disable_netbios()) {
2854 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
2855 return false;
2858 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
2859 lp_name_resolve_order());
2860 if (NT_STATUS_IS_OK(status)) {
2861 *master_ss = ip_list[0].ss;
2862 SAFE_FREE(ip_list);
2863 return true;
2866 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
2867 lp_name_resolve_order());
2868 if (NT_STATUS_IS_OK(status)) {
2869 *master_ss = ip_list[0].ss;
2870 SAFE_FREE(ip_list);
2871 return true;
2874 SAFE_FREE(ip_list);
2875 return false;
2878 /********************************************************
2879 Get the IP address list of the primary domain controller
2880 for a domain.
2881 *********************************************************/
2883 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
2885 struct ip_service *ip_list = NULL;
2886 int count = 0;
2887 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2889 /* Look up #1B name */
2891 if (lp_security() == SEC_ADS) {
2892 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
2893 &count, "ads");
2896 if (!NT_STATUS_IS_OK(status) || count == 0) {
2897 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
2898 &count,
2899 lp_name_resolve_order());
2900 if (!NT_STATUS_IS_OK(status)) {
2901 return false;
2905 /* if we get more than 1 IP back we have to assume it is a
2906 multi-homed PDC and not a mess up */
2908 if ( count > 1 ) {
2909 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
2910 sort_service_list(ip_list, count);
2913 *pss = ip_list[0].ss;
2914 SAFE_FREE(ip_list);
2915 return true;
2918 /* Private enum type for lookups. */
2920 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
2922 /********************************************************
2923 Get the IP address list of the domain controllers for
2924 a domain.
2925 *********************************************************/
2927 static NTSTATUS get_dc_list(const char *domain,
2928 const char *sitename,
2929 struct ip_service **ip_list,
2930 int *count,
2931 enum dc_lookup_type lookup_type,
2932 bool *ordered)
2934 char *resolve_order = NULL;
2935 char *saf_servername = NULL;
2936 char *pserver = NULL;
2937 const char *p;
2938 char *port_str = NULL;
2939 int port;
2940 char *name;
2941 int num_addresses = 0;
2942 int local_count, i, j;
2943 struct ip_service *return_iplist = NULL;
2944 struct ip_service *auto_ip_list = NULL;
2945 bool done_auto_lookup = false;
2946 int auto_count = 0;
2947 NTSTATUS status;
2948 TALLOC_CTX *ctx = talloc_init("get_dc_list");
2950 *ip_list = NULL;
2951 *count = 0;
2953 if (!ctx) {
2954 return NT_STATUS_NO_MEMORY;
2957 *ordered = False;
2959 /* if we are restricted to solely using DNS for looking
2960 up a domain controller, make sure that host lookups
2961 are enabled for the 'name resolve order'. If host lookups
2962 are disabled and ads_only is True, then set the string to
2963 NULL. */
2965 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
2966 if (!resolve_order) {
2967 status = NT_STATUS_NO_MEMORY;
2968 goto out;
2970 strlower_m(resolve_order);
2971 if (lookup_type == DC_ADS_ONLY) {
2972 if (strstr( resolve_order, "host")) {
2973 resolve_order = talloc_strdup(ctx, "ads");
2975 /* DNS SRV lookups used by the ads resolver
2976 are already sorted by priority and weight */
2977 *ordered = true;
2978 } else {
2979 resolve_order = talloc_strdup(ctx, "NULL");
2981 } else if (lookup_type == DC_KDC_ONLY) {
2982 /* DNS SRV lookups used by the ads/kdc resolver
2983 are already sorted by priority and weight */
2984 *ordered = true;
2985 resolve_order = talloc_strdup(ctx, "kdc");
2987 if (!resolve_order) {
2988 status = NT_STATUS_NO_MEMORY;
2989 goto out;
2992 /* fetch the server we have affinity for. Add the
2993 'password server' list to a search for our domain controllers */
2995 saf_servername = saf_fetch( domain);
2997 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
2998 pserver = talloc_asprintf(ctx, "%s, %s",
2999 saf_servername ? saf_servername : "",
3000 lp_passwordserver());
3001 } else {
3002 pserver = talloc_asprintf(ctx, "%s, *",
3003 saf_servername ? saf_servername : "");
3006 SAFE_FREE(saf_servername);
3007 if (!pserver) {
3008 status = NT_STATUS_NO_MEMORY;
3009 goto out;
3012 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
3014 if (!*pserver ) {
3015 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
3016 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
3017 count, resolve_order);
3018 goto out;
3021 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
3024 * if '*' appears in the "password server" list then add
3025 * an auto lookup to the list of manually configured
3026 * DC's. If any DC is listed by name, then the list should be
3027 * considered to be ordered
3030 p = pserver;
3031 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
3032 if (!done_auto_lookup && strequal(name, "*")) {
3033 status = internal_resolve_name(domain, 0x1C, sitename,
3034 &auto_ip_list,
3035 &auto_count,
3036 resolve_order);
3037 if (NT_STATUS_IS_OK(status)) {
3038 num_addresses += auto_count;
3040 done_auto_lookup = true;
3041 DEBUG(8,("Adding %d DC's from auto lookup\n",
3042 auto_count));
3043 } else {
3044 num_addresses++;
3048 /* if we have no addresses and haven't done the auto lookup, then
3049 just return the list of DC's. Or maybe we just failed. */
3051 if ((num_addresses == 0)) {
3052 if (done_auto_lookup) {
3053 DEBUG(4,("get_dc_list: no servers found\n"));
3054 status = NT_STATUS_NO_LOGON_SERVERS;
3055 goto out;
3057 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
3058 count, resolve_order);
3059 goto out;
3062 if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
3063 num_addresses)) == NULL) {
3064 DEBUG(3,("get_dc_list: malloc fail !\n"));
3065 status = NT_STATUS_NO_MEMORY;
3066 goto out;
3069 p = pserver;
3070 local_count = 0;
3072 /* fill in the return list now with real IP's */
3074 while ((local_count<num_addresses) &&
3075 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
3076 struct sockaddr_storage name_ss;
3078 /* copy any addersses from the auto lookup */
3080 if (strequal(name, "*")) {
3081 for (j=0; j<auto_count; j++) {
3082 char addr[INET6_ADDRSTRLEN];
3083 print_sockaddr(addr,
3084 sizeof(addr),
3085 &auto_ip_list[j].ss);
3086 /* Check for and don't copy any
3087 * known bad DC IP's. */
3088 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
3089 domain,
3090 addr))) {
3091 DEBUG(5,("get_dc_list: "
3092 "negative entry %s removed "
3093 "from DC list\n",
3094 addr));
3095 continue;
3097 return_iplist[local_count].ss =
3098 auto_ip_list[j].ss;
3099 return_iplist[local_count].port =
3100 auto_ip_list[j].port;
3101 local_count++;
3103 continue;
3106 /* added support for address:port syntax for ads
3107 * (not that I think anyone will ever run the LDAP
3108 * server in an AD domain on something other than
3109 * port 389 */
3111 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
3112 if ((port_str=strchr(name, ':')) != NULL) {
3113 *port_str = '\0';
3114 port_str++;
3115 port = atoi(port_str);
3118 /* explicit lookup; resolve_name() will
3119 * handle names & IP addresses */
3120 if (resolve_name( name, &name_ss, 0x20, true )) {
3121 char addr[INET6_ADDRSTRLEN];
3122 print_sockaddr(addr,
3123 sizeof(addr),
3124 &name_ss);
3126 /* Check for and don't copy any known bad DC IP's. */
3127 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
3128 addr)) ) {
3129 DEBUG(5,("get_dc_list: negative entry %s "
3130 "removed from DC list\n",
3131 name ));
3132 continue;
3135 return_iplist[local_count].ss = name_ss;
3136 return_iplist[local_count].port = port;
3137 local_count++;
3138 *ordered = true;
3142 /* need to remove duplicates in the list if we have any
3143 explicit password servers */
3145 if (local_count) {
3146 local_count = remove_duplicate_addrs2(return_iplist,
3147 local_count );
3150 /* For DC's we always prioritize IPv4 due to W2K3 not
3151 * supporting LDAP, KRB5 or CLDAP over IPv6. */
3153 if (local_count && return_iplist) {
3154 prioritize_ipv4_list(return_iplist, local_count);
3157 if ( DEBUGLEVEL >= 4 ) {
3158 DEBUG(4,("get_dc_list: returning %d ip addresses "
3159 "in an %sordered list\n",
3160 local_count,
3161 *ordered ? "":"un"));
3162 DEBUG(4,("get_dc_list: "));
3163 for ( i=0; i<local_count; i++ ) {
3164 char addr[INET6_ADDRSTRLEN];
3165 print_sockaddr(addr,
3166 sizeof(addr),
3167 &return_iplist[i].ss);
3168 DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
3170 DEBUGADD(4,("\n"));
3173 *ip_list = return_iplist;
3174 *count = local_count;
3176 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
3178 out:
3180 if (!NT_STATUS_IS_OK(status)) {
3181 SAFE_FREE(return_iplist);
3182 *ip_list = NULL;
3183 *count = 0;
3186 SAFE_FREE(auto_ip_list);
3187 TALLOC_FREE(ctx);
3188 return status;
3191 /*********************************************************************
3192 Small wrapper function to get the DC list and sort it if neccessary.
3193 *********************************************************************/
3195 NTSTATUS get_sorted_dc_list( const char *domain,
3196 const char *sitename,
3197 struct ip_service **ip_list,
3198 int *count,
3199 bool ads_only )
3201 bool ordered = false;
3202 NTSTATUS status;
3203 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
3205 *ip_list = NULL;
3206 *count = 0;
3208 DEBUG(8,("get_sorted_dc_list: attempting lookup "
3209 "for name %s (sitename %s) using [%s]\n",
3210 domain,
3211 sitename ? sitename : "NULL",
3212 (ads_only ? "ads" : lp_name_resolve_order())));
3214 if (ads_only) {
3215 lookup_type = DC_ADS_ONLY;
3218 status = get_dc_list(domain, sitename, ip_list,
3219 count, lookup_type, &ordered);
3220 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
3221 && sitename) {
3222 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
3223 " in site %s, fallback to all servers\n",
3224 domain, sitename));
3225 status = get_dc_list(domain, NULL, ip_list,
3226 count, lookup_type, &ordered);
3229 if (!NT_STATUS_IS_OK(status)) {
3230 SAFE_FREE(*ip_list);
3231 *count = 0;
3232 return status;
3235 /* only sort if we don't already have an ordered list */
3236 if (!ordered) {
3237 sort_service_list(*ip_list, *count);
3240 return NT_STATUS_OK;
3243 /*********************************************************************
3244 Get the KDC list - re-use all the logic in get_dc_list.
3245 *********************************************************************/
3247 NTSTATUS get_kdc_list( const char *realm,
3248 const char *sitename,
3249 struct ip_service **ip_list,
3250 int *count)
3252 bool ordered;
3253 NTSTATUS status;
3255 *count = 0;
3256 *ip_list = NULL;
3258 status = get_dc_list(realm, sitename, ip_list,
3259 count, DC_KDC_ONLY, &ordered);
3261 if (!NT_STATUS_IS_OK(status)) {
3262 SAFE_FREE(*ip_list);
3263 *count = 0;
3264 return status;
3267 /* only sort if we don't already have an ordered list */
3268 if ( !ordered ) {
3269 sort_service_list(*ip_list, *count);
3272 return NT_STATUS_OK;