tevent: expose tevent_context_init_ops
[Samba/gebeck_regimport.git] / source3 / libsmb / namequery.c
blob4c05e4f4189c2540b9c6d0edfaaf69e1cb55974c
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 "../lib/addns/dnsquery.h"
25 #include "../libcli/netlogon/netlogon.h"
26 #include "lib/async_req/async_sock.h"
27 #include "libsmb/nmblib.h"
28 #include "../libcli/nbt/libnbt.h"
30 /* nmbd.c sets this to True. */
31 bool global_in_nmbd = False;
33 /****************************
34 * SERVER AFFINITY ROUTINES *
35 ****************************/
37 /* Server affinity is the concept of preferring the last domain
38 controller with whom you had a successful conversation */
40 /****************************************************************************
41 ****************************************************************************/
42 #define SAFKEY_FMT "SAF/DOMAIN/%s"
43 #define SAF_TTL 900
44 #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
45 #define SAFJOIN_TTL 3600
47 static char *saf_key(TALLOC_CTX *mem_ctx, const char *domain)
49 return talloc_asprintf_strupper_m(mem_ctx, SAFKEY_FMT, domain);
52 static char *saf_join_key(TALLOC_CTX *mem_ctx, const char *domain)
54 return talloc_asprintf_strupper_m(mem_ctx, SAFJOINKEY_FMT, domain);
57 /****************************************************************************
58 ****************************************************************************/
60 bool saf_store( const char *domain, const char *servername )
62 char *key;
63 time_t expire;
64 bool ret = False;
66 if ( !domain || !servername ) {
67 DEBUG(2,("saf_store: "
68 "Refusing to store empty domain or servername!\n"));
69 return False;
72 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
73 DEBUG(0,("saf_store: "
74 "refusing to store 0 length domain or servername!\n"));
75 return False;
78 key = saf_key(talloc_tos(), domain);
79 if (key == NULL) {
80 DEBUG(1, ("saf_key() failed\n"));
81 return false;
83 expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
85 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
86 domain, servername, (unsigned int)expire ));
88 ret = gencache_set( key, servername, expire );
90 TALLOC_FREE( key );
92 return ret;
95 bool saf_join_store( const char *domain, const char *servername )
97 char *key;
98 time_t expire;
99 bool ret = False;
101 if ( !domain || !servername ) {
102 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
103 return False;
106 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
107 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
108 return False;
111 key = saf_join_key(talloc_tos(), domain);
112 if (key == NULL) {
113 DEBUG(1, ("saf_join_key() failed\n"));
114 return false;
116 expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
118 DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
119 domain, servername, (unsigned int)expire ));
121 ret = gencache_set( key, servername, expire );
123 TALLOC_FREE( key );
125 return ret;
128 bool saf_delete( const char *domain )
130 char *key;
131 bool ret = False;
133 if ( !domain ) {
134 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
135 return False;
138 key = saf_join_key(talloc_tos(), domain);
139 if (key == NULL) {
140 DEBUG(1, ("saf_join_key() failed\n"));
141 return false;
143 ret = gencache_del(key);
144 TALLOC_FREE(key);
146 if (ret) {
147 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
150 key = saf_key(talloc_tos(), domain);
151 if (key == NULL) {
152 DEBUG(1, ("saf_key() failed\n"));
153 return false;
155 ret = gencache_del(key);
156 TALLOC_FREE(key);
158 if (ret) {
159 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
162 return ret;
165 /****************************************************************************
166 ****************************************************************************/
168 char *saf_fetch( const char *domain )
170 char *server = NULL;
171 time_t timeout;
172 bool ret = False;
173 char *key = NULL;
175 if ( !domain || strlen(domain) == 0) {
176 DEBUG(2,("saf_fetch: Empty domain name!\n"));
177 return NULL;
180 key = saf_join_key(talloc_tos(), domain);
181 if (key == NULL) {
182 DEBUG(1, ("saf_join_key() failed\n"));
183 return NULL;
186 ret = gencache_get( key, &server, &timeout );
188 TALLOC_FREE( key );
190 if ( ret ) {
191 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
192 server, domain ));
193 return server;
196 key = saf_key(talloc_tos(), domain);
197 if (key == NULL) {
198 DEBUG(1, ("saf_key() failed\n"));
199 return NULL;
202 ret = gencache_get( key, &server, &timeout );
204 TALLOC_FREE( key );
206 if ( !ret ) {
207 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
208 domain ));
209 } else {
210 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
211 server, domain ));
214 return server;
217 static void set_socket_addr_v4(struct sockaddr_storage *addr)
219 if (!interpret_string_addr(addr, lp_socket_address(),
220 AI_NUMERICHOST|AI_PASSIVE)) {
221 zero_sockaddr(addr);
223 if (addr->ss_family != AF_INET) {
224 zero_sockaddr(addr);
228 static struct in_addr my_socket_addr_v4(void)
230 struct sockaddr_storage my_addr;
231 struct sockaddr_in *in_addr = (struct sockaddr_in *)((char *)&my_addr);
233 set_socket_addr_v4(&my_addr);
234 return in_addr->sin_addr;
237 /****************************************************************************
238 Generate a random trn_id.
239 ****************************************************************************/
241 static int generate_trn_id(void)
243 uint16 id;
245 generate_random_buffer((uint8 *)&id, sizeof(id));
247 return id % (unsigned)0x7FFF;
250 /****************************************************************************
251 Parse a node status response into an array of structures.
252 ****************************************************************************/
254 static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p,
255 int *num_names,
256 struct node_status_extra *extra)
258 struct node_status *ret;
259 int i;
261 *num_names = CVAL(p,0);
263 if (*num_names == 0)
264 return NULL;
266 ret = talloc_array(mem_ctx, struct node_status,*num_names);
267 if (!ret)
268 return NULL;
270 p++;
271 for (i=0;i< *num_names;i++) {
272 StrnCpy(ret[i].name,p,15);
273 trim_char(ret[i].name,'\0',' ');
274 ret[i].type = CVAL(p,15);
275 ret[i].flags = p[16];
276 p += 18;
277 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
278 ret[i].type, ret[i].flags));
281 * Also, pick up the MAC address ...
283 if (extra) {
284 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
286 return ret;
289 struct sock_packet_read_state {
290 struct tevent_context *ev;
291 enum packet_type type;
292 int trn_id;
294 struct nb_packet_reader *reader;
295 struct tevent_req *reader_req;
297 int sock;
298 struct tevent_req *socket_req;
299 uint8_t buf[1024];
300 struct sockaddr_storage addr;
301 socklen_t addr_len;
303 bool (*validator)(struct packet_struct *p,
304 void *private_data);
305 void *private_data;
307 struct packet_struct *packet;
310 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s);
311 static void sock_packet_read_got_packet(struct tevent_req *subreq);
312 static void sock_packet_read_got_socket(struct tevent_req *subreq);
314 static struct tevent_req *sock_packet_read_send(
315 TALLOC_CTX *mem_ctx,
316 struct tevent_context *ev,
317 int sock, /* dgram socket */
318 struct nb_packet_reader *reader,
319 enum packet_type type,
320 int trn_id,
321 bool (*validator)(struct packet_struct *p, void *private_data),
322 void *private_data)
324 struct tevent_req *req;
325 struct sock_packet_read_state *state;
327 req = tevent_req_create(mem_ctx, &state,
328 struct sock_packet_read_state);
329 if (req == NULL) {
330 return NULL;
332 talloc_set_destructor(state, sock_packet_read_state_destructor);
333 state->ev = ev;
334 state->reader = reader;
335 state->sock = sock;
336 state->type = type;
337 state->trn_id = trn_id;
338 state->validator = validator;
339 state->private_data = private_data;
341 if (reader != NULL) {
342 state->reader_req = nb_packet_read_send(state, ev, reader);
343 if (tevent_req_nomem(state->reader_req, req)) {
344 return tevent_req_post(req, ev);
346 tevent_req_set_callback(
347 state->reader_req, sock_packet_read_got_packet, req);
350 state->addr_len = sizeof(state->addr);
351 state->socket_req = recvfrom_send(state, ev, sock,
352 state->buf, sizeof(state->buf), 0,
353 &state->addr, &state->addr_len);
354 if (tevent_req_nomem(state->socket_req, req)) {
355 return tevent_req_post(req, ev);
357 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
358 req);
360 return req;
363 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s)
365 if (s->packet != NULL) {
366 free_packet(s->packet);
367 s->packet = NULL;
369 return 0;
372 static void sock_packet_read_got_packet(struct tevent_req *subreq)
374 struct tevent_req *req = tevent_req_callback_data(
375 subreq, struct tevent_req);
376 struct sock_packet_read_state *state = tevent_req_data(
377 req, struct sock_packet_read_state);
378 NTSTATUS status;
380 status = nb_packet_read_recv(subreq, &state->packet);
382 TALLOC_FREE(state->reader_req);
384 if (!NT_STATUS_IS_OK(status)) {
385 if (state->socket_req != NULL) {
387 * Still waiting for socket
389 return;
392 * Both socket and packet reader failed
394 tevent_req_nterror(req, status);
395 return;
398 if ((state->validator != NULL) &&
399 !state->validator(state->packet, state->private_data)) {
400 DEBUG(10, ("validator failed\n"));
402 free_packet(state->packet);
403 state->packet = NULL;
405 state->reader_req = nb_packet_read_send(state, state->ev,
406 state->reader);
407 if (tevent_req_nomem(state->reader_req, req)) {
408 return;
410 tevent_req_set_callback(
411 state->reader_req, sock_packet_read_got_packet, req);
412 return;
415 TALLOC_FREE(state->socket_req);
416 tevent_req_done(req);
419 static void sock_packet_read_got_socket(struct tevent_req *subreq)
421 struct tevent_req *req = tevent_req_callback_data(
422 subreq, struct tevent_req);
423 struct sock_packet_read_state *state = tevent_req_data(
424 req, struct sock_packet_read_state);
425 struct sockaddr_in *in_addr;
426 ssize_t received;
427 int err;
429 received = recvfrom_recv(subreq, &err);
431 TALLOC_FREE(state->socket_req);
433 if (received == -1) {
434 if (state->reader_req != NULL) {
436 * Still waiting for reader
438 return;
441 * Both socket and reader failed
443 tevent_req_nterror(req, map_nt_error_from_unix(err));
444 return;
446 if (state->addr.ss_family != AF_INET) {
447 goto retry;
449 in_addr = (struct sockaddr_in *)(void *)&state->addr;
451 state->packet = parse_packet((char *)state->buf, received, state->type,
452 in_addr->sin_addr, in_addr->sin_port);
453 if (state->packet == NULL) {
454 DEBUG(10, ("parse_packet failed\n"));
455 goto retry;
457 if ((state->trn_id != -1) &&
458 (state->trn_id != packet_trn_id(state->packet))) {
459 DEBUG(10, ("Expected transaction id %d, got %d\n",
460 state->trn_id, packet_trn_id(state->packet)));
461 goto retry;
464 if ((state->validator != NULL) &&
465 !state->validator(state->packet, state->private_data)) {
466 DEBUG(10, ("validator failed\n"));
467 goto retry;
470 tevent_req_done(req);
471 return;
473 retry:
474 if (state->packet != NULL) {
475 free_packet(state->packet);
476 state->packet = NULL;
478 state->socket_req = recvfrom_send(state, state->ev, state->sock,
479 state->buf, sizeof(state->buf), 0,
480 &state->addr, &state->addr_len);
481 if (tevent_req_nomem(state->socket_req, req)) {
482 return;
484 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
485 req);
488 static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
489 struct packet_struct **ppacket)
491 struct sock_packet_read_state *state = tevent_req_data(
492 req, struct sock_packet_read_state);
493 NTSTATUS status;
495 if (tevent_req_is_nterror(req, &status)) {
496 return status;
498 *ppacket = state->packet;
499 state->packet = NULL;
500 return NT_STATUS_OK;
503 struct nb_trans_state {
504 struct tevent_context *ev;
505 int sock;
506 struct nb_packet_reader *reader;
508 const struct sockaddr_storage *dst_addr;
509 uint8_t *buf;
510 size_t buflen;
511 enum packet_type type;
512 int trn_id;
514 bool (*validator)(struct packet_struct *p,
515 void *private_data);
516 void *private_data;
518 struct packet_struct *packet;
521 static int nb_trans_state_destructor(struct nb_trans_state *s);
522 static void nb_trans_got_reader(struct tevent_req *subreq);
523 static void nb_trans_done(struct tevent_req *subreq);
524 static void nb_trans_sent(struct tevent_req *subreq);
525 static void nb_trans_send_next(struct tevent_req *subreq);
527 static struct tevent_req *nb_trans_send(
528 TALLOC_CTX *mem_ctx,
529 struct tevent_context *ev,
530 const struct sockaddr_storage *my_addr,
531 const struct sockaddr_storage *dst_addr,
532 bool bcast,
533 uint8_t *buf, size_t buflen,
534 enum packet_type type, int trn_id,
535 bool (*validator)(struct packet_struct *p,
536 void *private_data),
537 void *private_data)
539 struct tevent_req *req, *subreq;
540 struct nb_trans_state *state;
542 req = tevent_req_create(mem_ctx, &state, struct nb_trans_state);
543 if (req == NULL) {
544 return NULL;
546 talloc_set_destructor(state, nb_trans_state_destructor);
547 state->ev = ev;
548 state->dst_addr = dst_addr;
549 state->buf = buf;
550 state->buflen = buflen;
551 state->type = type;
552 state->trn_id = trn_id;
553 state->validator = validator;
554 state->private_data = private_data;
556 state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True);
557 if (state->sock == -1) {
558 tevent_req_nterror(req, map_nt_error_from_unix(errno));
559 DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno)));
560 return tevent_req_post(req, ev);
563 if (bcast) {
564 set_socket_options(state->sock,"SO_BROADCAST");
567 subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL);
568 if (tevent_req_nomem(subreq, req)) {
569 return tevent_req_post(req, ev);
571 tevent_req_set_callback(subreq, nb_trans_got_reader, req);
572 return req;
575 static int nb_trans_state_destructor(struct nb_trans_state *s)
577 if (s->sock != -1) {
578 close(s->sock);
579 s->sock = -1;
581 if (s->packet != NULL) {
582 free_packet(s->packet);
583 s->packet = NULL;
585 return 0;
588 static void nb_trans_got_reader(struct tevent_req *subreq)
590 struct tevent_req *req = tevent_req_callback_data(
591 subreq, struct tevent_req);
592 struct nb_trans_state *state = tevent_req_data(
593 req, struct nb_trans_state);
594 NTSTATUS status;
596 status = nb_packet_reader_recv(subreq, state, &state->reader);
597 TALLOC_FREE(subreq);
599 if (!NT_STATUS_IS_OK(status)) {
600 DEBUG(10, ("nmbd not around\n"));
601 state->reader = NULL;
604 subreq = sock_packet_read_send(
605 state, state->ev, state->sock,
606 state->reader, state->type, state->trn_id,
607 state->validator, state->private_data);
608 if (tevent_req_nomem(subreq, req)) {
609 return;
611 tevent_req_set_callback(subreq, nb_trans_done, req);
613 subreq = sendto_send(state, state->ev, state->sock,
614 state->buf, state->buflen, 0, state->dst_addr);
615 if (tevent_req_nomem(subreq, req)) {
616 return;
618 tevent_req_set_callback(subreq, nb_trans_sent, req);
621 static void nb_trans_sent(struct tevent_req *subreq)
623 struct tevent_req *req = tevent_req_callback_data(
624 subreq, struct tevent_req);
625 struct nb_trans_state *state = tevent_req_data(
626 req, struct nb_trans_state);
627 ssize_t sent;
628 int err;
630 sent = sendto_recv(subreq, &err);
631 TALLOC_FREE(subreq);
632 if (sent == -1) {
633 DEBUG(10, ("sendto failed: %s\n", strerror(err)));
634 tevent_req_nterror(req, map_nt_error_from_unix(err));
635 return;
637 subreq = tevent_wakeup_send(state, state->ev,
638 timeval_current_ofs(1, 0));
639 if (tevent_req_nomem(subreq, req)) {
640 return;
642 tevent_req_set_callback(subreq, nb_trans_send_next, req);
645 static void nb_trans_send_next(struct tevent_req *subreq)
647 struct tevent_req *req = tevent_req_callback_data(
648 subreq, struct tevent_req);
649 struct nb_trans_state *state = tevent_req_data(
650 req, struct nb_trans_state);
651 bool ret;
653 ret = tevent_wakeup_recv(subreq);
654 TALLOC_FREE(subreq);
655 if (!ret) {
656 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
657 return;
659 subreq = sendto_send(state, state->ev, state->sock,
660 state->buf, state->buflen, 0, state->dst_addr);
661 if (tevent_req_nomem(subreq, req)) {
662 return;
664 tevent_req_set_callback(subreq, nb_trans_sent, req);
667 static void nb_trans_done(struct tevent_req *subreq)
669 struct tevent_req *req = tevent_req_callback_data(
670 subreq, struct tevent_req);
671 struct nb_trans_state *state = tevent_req_data(
672 req, struct nb_trans_state);
673 NTSTATUS status;
675 status = sock_packet_read_recv(subreq, &state->packet);
676 TALLOC_FREE(subreq);
677 if (tevent_req_nterror(req, status)) {
678 return;
680 tevent_req_done(req);
683 static NTSTATUS nb_trans_recv(struct tevent_req *req,
684 struct packet_struct **ppacket)
686 struct nb_trans_state *state = tevent_req_data(
687 req, struct nb_trans_state);
688 NTSTATUS status;
690 if (tevent_req_is_nterror(req, &status)) {
691 return status;
693 *ppacket = state->packet;
694 state->packet = NULL;
695 return NT_STATUS_OK;
698 /****************************************************************************
699 Do a NBT node status query on an open socket and return an array of
700 structures holding the returned names or NULL if the query failed.
701 **************************************************************************/
703 struct node_status_query_state {
704 struct sockaddr_storage my_addr;
705 struct sockaddr_storage addr;
706 uint8_t buf[1024];
707 ssize_t buflen;
708 struct packet_struct *packet;
711 static int node_status_query_state_destructor(
712 struct node_status_query_state *s);
713 static bool node_status_query_validator(struct packet_struct *p,
714 void *private_data);
715 static void node_status_query_done(struct tevent_req *subreq);
717 struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
718 struct tevent_context *ev,
719 struct nmb_name *name,
720 const struct sockaddr_storage *addr)
722 struct tevent_req *req, *subreq;
723 struct node_status_query_state *state;
724 struct packet_struct p;
725 struct nmb_packet *nmb = &p.packet.nmb;
726 struct sockaddr_in *in_addr;
728 req = tevent_req_create(mem_ctx, &state,
729 struct node_status_query_state);
730 if (req == NULL) {
731 return NULL;
733 talloc_set_destructor(state, node_status_query_state_destructor);
735 if (addr->ss_family != AF_INET) {
736 /* Can't do node status to IPv6 */
737 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
738 return tevent_req_post(req, ev);
741 state->addr = *addr;
742 in_addr = (struct sockaddr_in *)(void *)&state->addr;
743 in_addr->sin_port = htons(NMB_PORT);
745 set_socket_addr_v4(&state->my_addr);
747 ZERO_STRUCT(p);
748 nmb->header.name_trn_id = generate_trn_id();
749 nmb->header.opcode = 0;
750 nmb->header.response = false;
751 nmb->header.nm_flags.bcast = false;
752 nmb->header.nm_flags.recursion_available = false;
753 nmb->header.nm_flags.recursion_desired = false;
754 nmb->header.nm_flags.trunc = false;
755 nmb->header.nm_flags.authoritative = false;
756 nmb->header.rcode = 0;
757 nmb->header.qdcount = 1;
758 nmb->header.ancount = 0;
759 nmb->header.nscount = 0;
760 nmb->header.arcount = 0;
761 nmb->question.question_name = *name;
762 nmb->question.question_type = 0x21;
763 nmb->question.question_class = 0x1;
765 state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
766 &p);
767 if (state->buflen == 0) {
768 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
769 DEBUG(10, ("build_packet failed\n"));
770 return tevent_req_post(req, ev);
773 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, false,
774 state->buf, state->buflen,
775 NMB_PACKET, nmb->header.name_trn_id,
776 node_status_query_validator, NULL);
777 if (tevent_req_nomem(subreq, req)) {
778 DEBUG(10, ("nb_trans_send failed\n"));
779 return tevent_req_post(req, ev);
781 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(10, 0))) {
782 return tevent_req_post(req, ev);
784 tevent_req_set_callback(subreq, node_status_query_done, req);
785 return req;
788 static bool node_status_query_validator(struct packet_struct *p,
789 void *private_data)
791 struct nmb_packet *nmb = &p->packet.nmb;
792 debug_nmb_packet(p);
794 if (nmb->header.opcode != 0 ||
795 nmb->header.nm_flags.bcast ||
796 nmb->header.rcode ||
797 !nmb->header.ancount ||
798 nmb->answers->rr_type != 0x21) {
800 * XXXX what do we do with this? could be a redirect,
801 * but we'll discard it for the moment
803 return false;
805 return true;
808 static int node_status_query_state_destructor(
809 struct node_status_query_state *s)
811 if (s->packet != NULL) {
812 free_packet(s->packet);
813 s->packet = NULL;
815 return 0;
818 static void node_status_query_done(struct tevent_req *subreq)
820 struct tevent_req *req = tevent_req_callback_data(
821 subreq, struct tevent_req);
822 struct node_status_query_state *state = tevent_req_data(
823 req, struct node_status_query_state);
824 NTSTATUS status;
826 status = nb_trans_recv(subreq, &state->packet);
827 TALLOC_FREE(subreq);
828 if (tevent_req_nterror(req, status)) {
829 return;
831 tevent_req_done(req);
834 NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
835 struct node_status **pnode_status,
836 int *pnum_names,
837 struct node_status_extra *extra)
839 struct node_status_query_state *state = tevent_req_data(
840 req, struct node_status_query_state);
841 struct node_status *node_status;
842 int num_names;
843 NTSTATUS status;
845 if (tevent_req_is_nterror(req, &status)) {
846 return status;
848 node_status = parse_node_status(
849 mem_ctx, &state->packet->packet.nmb.answers->rdata[0],
850 &num_names, extra);
851 if (node_status == NULL) {
852 return NT_STATUS_NO_MEMORY;
854 *pnode_status = node_status;
855 *pnum_names = num_names;
856 return NT_STATUS_OK;
859 NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name,
860 const struct sockaddr_storage *addr,
861 struct node_status **pnode_status,
862 int *pnum_names,
863 struct node_status_extra *extra)
865 TALLOC_CTX *frame = talloc_stackframe();
866 struct tevent_context *ev;
867 struct tevent_req *req;
868 NTSTATUS status = NT_STATUS_NO_MEMORY;
870 ev = tevent_context_init(frame);
871 if (ev == NULL) {
872 goto fail;
874 req = node_status_query_send(ev, ev, name, addr);
875 if (req == NULL) {
876 goto fail;
878 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
879 goto fail;
881 status = node_status_query_recv(req, mem_ctx, pnode_status,
882 pnum_names, extra);
883 fail:
884 TALLOC_FREE(frame);
885 return status;
888 /****************************************************************************
889 Find the first type XX name in a node status reply - used for finding
890 a servers name given its IP. Return the matched name in *name.
891 **************************************************************************/
893 bool name_status_find(const char *q_name,
894 int q_type,
895 int type,
896 const struct sockaddr_storage *to_ss,
897 fstring name)
899 char addr[INET6_ADDRSTRLEN];
900 struct sockaddr_storage ss;
901 struct node_status *addrs = NULL;
902 struct nmb_name nname;
903 int count, i;
904 bool result = false;
905 NTSTATUS status;
907 if (lp_disable_netbios()) {
908 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
909 q_name, q_type));
910 return False;
913 print_sockaddr(addr, sizeof(addr), to_ss);
915 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
916 q_type, addr));
918 /* Check the cache first. */
920 if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
921 return True;
924 if (to_ss->ss_family != AF_INET) {
925 /* Can't do node status to IPv6 */
926 return false;
929 set_socket_addr_v4(&ss);
931 /* W2K PDC's seem not to respond to '*'#0. JRA */
932 make_nmb_name(&nname, q_name, q_type);
933 status = node_status_query(talloc_tos(), &nname, to_ss,
934 &addrs, &count, NULL);
935 if (!NT_STATUS_IS_OK(status)) {
936 goto done;
939 for (i=0;i<count;i++) {
940 /* Find first one of the requested type that's not a GROUP. */
941 if (addrs[i].type == type && ! (addrs[i].flags & 0x80))
942 break;
944 if (i == count)
945 goto done;
947 pull_ascii_nstring(name, sizeof(fstring), addrs[i].name);
949 /* Store the result in the cache. */
950 /* but don't store an entry for 0x1c names here. Here we have
951 a single host and DOMAIN<0x1c> names should be a list of hosts */
953 if ( q_type != 0x1c ) {
954 namecache_status_store(q_name, q_type, type, to_ss, name);
957 result = true;
959 done:
960 TALLOC_FREE(addrs);
962 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
964 if (result)
965 DEBUGADD(10, (", name %s ip address is %s", name, addr));
967 DEBUG(10, ("\n"));
969 return result;
973 comparison function used by sort_addr_list
976 static int addr_compare(const struct sockaddr_storage *ss1,
977 const struct sockaddr_storage *ss2)
979 int max_bits1=0, max_bits2=0;
980 int num_interfaces = iface_count();
981 int i;
983 /* Sort IPv4 addresses first. */
984 if (ss1->ss_family != ss2->ss_family) {
985 if (ss2->ss_family == AF_INET) {
986 return 1;
987 } else {
988 return -1;
992 /* Here we know both addresses are of the same
993 * family. */
995 for (i=0;i<num_interfaces;i++) {
996 const struct sockaddr_storage *pss = iface_n_bcast(i);
997 const unsigned char *p_ss1 = NULL;
998 const unsigned char *p_ss2 = NULL;
999 const unsigned char *p_if = NULL;
1000 size_t len = 0;
1001 int bits1, bits2;
1003 if (pss->ss_family != ss1->ss_family) {
1004 /* Ignore interfaces of the wrong type. */
1005 continue;
1007 if (pss->ss_family == AF_INET) {
1008 p_if = (const unsigned char *)
1009 &((const struct sockaddr_in *)pss)->sin_addr;
1010 p_ss1 = (const unsigned char *)
1011 &((const struct sockaddr_in *)ss1)->sin_addr;
1012 p_ss2 = (const unsigned char *)
1013 &((const struct sockaddr_in *)ss2)->sin_addr;
1014 len = 4;
1016 #if defined(HAVE_IPV6)
1017 if (pss->ss_family == AF_INET6) {
1018 p_if = (const unsigned char *)
1019 &((const struct sockaddr_in6 *)pss)->sin6_addr;
1020 p_ss1 = (const unsigned char *)
1021 &((const struct sockaddr_in6 *)ss1)->sin6_addr;
1022 p_ss2 = (const unsigned char *)
1023 &((const struct sockaddr_in6 *)ss2)->sin6_addr;
1024 len = 16;
1026 #endif
1027 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
1028 continue;
1030 bits1 = matching_len_bits(p_ss1, p_if, len);
1031 bits2 = matching_len_bits(p_ss2, p_if, len);
1032 max_bits1 = MAX(bits1, max_bits1);
1033 max_bits2 = MAX(bits2, max_bits2);
1036 /* Bias towards directly reachable IPs */
1037 if (iface_local((const struct sockaddr *)ss1)) {
1038 if (ss1->ss_family == AF_INET) {
1039 max_bits1 += 32;
1040 } else {
1041 max_bits1 += 128;
1044 if (iface_local((const struct sockaddr *)ss2)) {
1045 if (ss2->ss_family == AF_INET) {
1046 max_bits2 += 32;
1047 } else {
1048 max_bits2 += 128;
1051 return max_bits2 - max_bits1;
1054 /*******************************************************************
1055 compare 2 ldap IPs by nearness to our interfaces - used in qsort
1056 *******************************************************************/
1058 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
1060 int result;
1062 if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) {
1063 return result;
1066 if (ss1->port > ss2->port) {
1067 return 1;
1070 if (ss1->port < ss2->port) {
1071 return -1;
1074 return 0;
1078 sort an IP list so that names that are close to one of our interfaces
1079 are at the top. This prevents the problem where a WINS server returns an IP
1080 that is not reachable from our subnet as the first match
1083 static void sort_addr_list(struct sockaddr_storage *sslist, int count)
1085 if (count <= 1) {
1086 return;
1089 TYPESAFE_QSORT(sslist, count, addr_compare);
1092 static void sort_service_list(struct ip_service *servlist, int count)
1094 if (count <= 1) {
1095 return;
1098 TYPESAFE_QSORT(servlist, count, ip_service_compare);
1101 /**********************************************************************
1102 Remove any duplicate address/port pairs in the list
1103 *********************************************************************/
1105 int remove_duplicate_addrs2(struct ip_service *iplist, int count )
1107 int i, j;
1109 DEBUG(10,("remove_duplicate_addrs2: "
1110 "looking for duplicate address/port pairs\n"));
1112 /* One loop to set duplicates to a zero addr. */
1113 for ( i=0; i<count; i++ ) {
1114 if ( is_zero_addr(&iplist[i].ss)) {
1115 continue;
1118 for ( j=i+1; j<count; j++ ) {
1119 if (sockaddr_equal((struct sockaddr *)(void *)&iplist[i].ss,
1120 (struct sockaddr *)(void *)&iplist[j].ss) &&
1121 iplist[i].port == iplist[j].port) {
1122 zero_sockaddr(&iplist[j].ss);
1127 /* Now remove any addresses set to zero above. */
1128 for (i = 0; i < count; i++) {
1129 while (i < count &&
1130 is_zero_addr(&iplist[i].ss)) {
1131 if (count-i-1>0) {
1132 memmove(&iplist[i],
1133 &iplist[i+1],
1134 (count-i-1)*sizeof(struct ip_service));
1136 count--;
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 if (is_zero_addr(&addr)) {
1371 continue;
1374 for (j=0; j<state->num_addrs; j++) {
1375 if (sockaddr_equal(
1376 (struct sockaddr *)(void *)&addr,
1377 (struct sockaddr *)(void *)&state->addrs[j])) {
1378 break;
1381 if (j < state->num_addrs) {
1382 /* Already got it */
1383 continue;
1386 DEBUGADD(2,("%s ",inet_ntoa(ip)));
1388 state->addrs[state->num_addrs] = addr;
1389 state->num_addrs += 1;
1391 DEBUGADD(2,(")\n"));
1393 /* We add the flags back ... */
1394 if (nmb->header.response)
1395 state->flags |= NM_FLAGS_RS;
1396 if (nmb->header.nm_flags.authoritative)
1397 state->flags |= NM_FLAGS_AA;
1398 if (nmb->header.nm_flags.trunc)
1399 state->flags |= NM_FLAGS_TC;
1400 if (nmb->header.nm_flags.recursion_desired)
1401 state->flags |= NM_FLAGS_RD;
1402 if (nmb->header.nm_flags.recursion_available)
1403 state->flags |= NM_FLAGS_RA;
1404 if (nmb->header.nm_flags.bcast)
1405 state->flags |= NM_FLAGS_B;
1407 if (state->bcast) {
1409 * We have to collect all entries coming in from broadcast
1410 * queries. If we got a unique name, we're done.
1412 return got_unique_netbios_name;
1415 * WINS responses are accepted when they are received
1417 return true;
1420 static void name_query_done(struct tevent_req *subreq)
1422 struct tevent_req *req = tevent_req_callback_data(
1423 subreq, struct tevent_req);
1424 struct name_query_state *state = tevent_req_data(
1425 req, struct name_query_state);
1426 NTSTATUS status;
1427 struct packet_struct *p = NULL;
1429 status = nb_trans_recv(subreq, &p);
1430 TALLOC_FREE(subreq);
1431 if (tevent_req_nterror(req, status)) {
1432 return;
1434 if (!NT_STATUS_IS_OK(state->validate_error)) {
1435 tevent_req_nterror(req, state->validate_error);
1436 return;
1438 if (p != NULL) {
1440 * Free the packet here, we've collected the response in the
1441 * validator
1443 free_packet(p);
1445 tevent_req_done(req);
1448 NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1449 struct sockaddr_storage **addrs, int *num_addrs,
1450 uint8_t *flags)
1452 struct name_query_state *state = tevent_req_data(
1453 req, struct name_query_state);
1454 NTSTATUS status;
1456 if (tevent_req_is_nterror(req, &status)) {
1457 if (state->bcast &&
1458 NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1460 * In the broadcast case we collect replies until the
1461 * timeout.
1463 status = NT_STATUS_OK;
1465 if (!NT_STATUS_IS_OK(status)) {
1466 return status;
1469 if (state->num_addrs == 0) {
1470 return NT_STATUS_NOT_FOUND;
1472 *addrs = talloc_move(mem_ctx, &state->addrs);
1473 sort_addr_list(*addrs, state->num_addrs);
1474 *num_addrs = state->num_addrs;
1475 if (flags != NULL) {
1476 *flags = state->flags;
1478 return NT_STATUS_OK;
1481 NTSTATUS name_query(const char *name, int name_type,
1482 bool bcast, bool recurse,
1483 const struct sockaddr_storage *to_ss,
1484 TALLOC_CTX *mem_ctx,
1485 struct sockaddr_storage **addrs,
1486 int *num_addrs, uint8_t *flags)
1488 TALLOC_CTX *frame = talloc_stackframe();
1489 struct tevent_context *ev;
1490 struct tevent_req *req;
1491 struct timeval timeout;
1492 NTSTATUS status = NT_STATUS_NO_MEMORY;
1494 ev = tevent_context_init(frame);
1495 if (ev == NULL) {
1496 goto fail;
1498 req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss);
1499 if (req == NULL) {
1500 goto fail;
1502 if (bcast) {
1503 timeout = timeval_current_ofs(0, 250000);
1504 } else {
1505 timeout = timeval_current_ofs(2, 0);
1507 if (!tevent_req_set_endtime(req, ev, timeout)) {
1508 goto fail;
1510 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1511 goto fail;
1513 status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags);
1514 fail:
1515 TALLOC_FREE(frame);
1516 return status;
1519 /********************************************************
1520 Convert an array if struct sockaddr_storage to struct ip_service
1521 return false on failure. Port is set to PORT_NONE;
1522 pcount is [in/out] - it is the length of ss_list on input,
1523 and the length of return_iplist on output as we remove any
1524 zero addresses from ss_list.
1525 *********************************************************/
1527 static bool convert_ss2service(struct ip_service **return_iplist,
1528 const struct sockaddr_storage *ss_list,
1529 int *pcount)
1531 int i;
1532 int orig_count = *pcount;
1533 int real_count = 0;
1535 if (orig_count==0 || !ss_list )
1536 return False;
1538 /* Filter out zero addrs. */
1539 for ( i=0; i<orig_count; i++ ) {
1540 if (is_zero_addr(&ss_list[i])) {
1541 continue;
1543 real_count++;
1545 if (real_count==0) {
1546 return false;
1549 /* copy the ip address; port will be PORT_NONE */
1550 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, real_count)) ==
1551 NULL) {
1552 DEBUG(0,("convert_ip2service: malloc failed "
1553 "for %d enetries!\n", real_count ));
1554 return False;
1557 for ( i=0, real_count = 0; i<orig_count; i++ ) {
1558 if (is_zero_addr(&ss_list[i])) {
1559 continue;
1561 (*return_iplist)[real_count].ss = ss_list[i];
1562 (*return_iplist)[real_count].port = PORT_NONE;
1563 real_count++;
1566 *pcount = real_count;
1567 return true;
1570 struct name_queries_state {
1571 struct tevent_context *ev;
1572 const char *name;
1573 int name_type;
1574 bool bcast;
1575 bool recurse;
1576 const struct sockaddr_storage *addrs;
1577 int num_addrs;
1578 int wait_msec;
1579 int timeout_msec;
1581 struct tevent_req **subreqs;
1582 int num_received;
1583 int num_sent;
1585 int received_index;
1586 struct sockaddr_storage *result_addrs;
1587 int num_result_addrs;
1588 uint8_t flags;
1591 static void name_queries_done(struct tevent_req *subreq);
1592 static void name_queries_next(struct tevent_req *subreq);
1595 * Send a name query to multiple destinations with a wait time in between
1598 static struct tevent_req *name_queries_send(
1599 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1600 const char *name, int name_type,
1601 bool bcast, bool recurse,
1602 const struct sockaddr_storage *addrs,
1603 int num_addrs, int wait_msec, int timeout_msec)
1605 struct tevent_req *req, *subreq;
1606 struct name_queries_state *state;
1608 req = tevent_req_create(mem_ctx, &state,
1609 struct name_queries_state);
1610 if (req == NULL) {
1611 return NULL;
1613 state->ev = ev;
1614 state->name = name;
1615 state->name_type = name_type;
1616 state->bcast = bcast;
1617 state->recurse = recurse;
1618 state->addrs = addrs;
1619 state->num_addrs = num_addrs;
1620 state->wait_msec = wait_msec;
1621 state->timeout_msec = timeout_msec;
1623 state->subreqs = talloc_zero_array(
1624 state, struct tevent_req *, num_addrs);
1625 if (tevent_req_nomem(state->subreqs, req)) {
1626 return tevent_req_post(req, ev);
1628 state->num_sent = 0;
1630 subreq = name_query_send(
1631 state->subreqs, state->ev, name, name_type, bcast, recurse,
1632 &state->addrs[state->num_sent]);
1633 if (tevent_req_nomem(subreq, req)) {
1634 return tevent_req_post(req, ev);
1636 if (!tevent_req_set_endtime(
1637 subreq, state->ev,
1638 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1639 tevent_req_oom(req);
1640 return tevent_req_post(req, ev);
1642 tevent_req_set_callback(subreq, name_queries_done, req);
1644 state->subreqs[state->num_sent] = subreq;
1645 state->num_sent += 1;
1647 if (state->num_sent < state->num_addrs) {
1648 subreq = tevent_wakeup_send(
1649 state, state->ev,
1650 timeval_current_ofs(0, state->wait_msec * 1000));
1651 if (tevent_req_nomem(subreq, req)) {
1652 return tevent_req_post(req, ev);
1654 tevent_req_set_callback(subreq, name_queries_next, req);
1656 return req;
1659 static void name_queries_done(struct tevent_req *subreq)
1661 struct tevent_req *req = tevent_req_callback_data(
1662 subreq, struct tevent_req);
1663 struct name_queries_state *state = tevent_req_data(
1664 req, struct name_queries_state);
1665 int i;
1666 NTSTATUS status;
1668 status = name_query_recv(subreq, state, &state->result_addrs,
1669 &state->num_result_addrs, &state->flags);
1671 for (i=0; i<state->num_sent; i++) {
1672 if (state->subreqs[i] == subreq) {
1673 break;
1676 if (i == state->num_sent) {
1677 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1678 return;
1680 TALLOC_FREE(state->subreqs[i]);
1682 state->num_received += 1;
1684 if (!NT_STATUS_IS_OK(status)) {
1686 if (state->num_received >= state->num_addrs) {
1687 tevent_req_nterror(req, status);
1688 return;
1691 * Still outstanding requests, just wait
1693 return;
1695 state->received_index = i;
1696 tevent_req_done(req);
1699 static void name_queries_next(struct tevent_req *subreq)
1701 struct tevent_req *req = tevent_req_callback_data(
1702 subreq, struct tevent_req);
1703 struct name_queries_state *state = tevent_req_data(
1704 req, struct name_queries_state);
1706 if (!tevent_wakeup_recv(subreq)) {
1707 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1708 return;
1711 subreq = name_query_send(
1712 state->subreqs, state->ev,
1713 state->name, state->name_type, state->bcast, state->recurse,
1714 &state->addrs[state->num_sent]);
1715 if (tevent_req_nomem(subreq, req)) {
1716 return;
1718 tevent_req_set_callback(subreq, name_queries_done, req);
1719 if (!tevent_req_set_endtime(
1720 subreq, state->ev,
1721 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1722 tevent_req_oom(req);
1723 return;
1725 state->subreqs[state->num_sent] = subreq;
1726 state->num_sent += 1;
1728 if (state->num_sent < state->num_addrs) {
1729 subreq = tevent_wakeup_send(
1730 state, state->ev,
1731 timeval_current_ofs(0, state->wait_msec * 1000));
1732 if (tevent_req_nomem(subreq, req)) {
1733 return;
1735 tevent_req_set_callback(subreq, name_queries_next, req);
1739 static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1740 struct sockaddr_storage **result_addrs,
1741 int *num_result_addrs, uint8_t *flags,
1742 int *received_index)
1744 struct name_queries_state *state = tevent_req_data(
1745 req, struct name_queries_state);
1746 NTSTATUS status;
1748 if (tevent_req_is_nterror(req, &status)) {
1749 return status;
1752 if (result_addrs != NULL) {
1753 *result_addrs = talloc_move(mem_ctx, &state->result_addrs);
1755 if (num_result_addrs != NULL) {
1756 *num_result_addrs = state->num_result_addrs;
1758 if (flags != NULL) {
1759 *flags = state->flags;
1761 if (received_index != NULL) {
1762 *received_index = state->received_index;
1764 return NT_STATUS_OK;
1767 /********************************************************
1768 Resolve via "bcast" method.
1769 *********************************************************/
1771 struct name_resolve_bcast_state {
1772 struct sockaddr_storage *addrs;
1773 int num_addrs;
1776 static void name_resolve_bcast_done(struct tevent_req *subreq);
1778 struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx,
1779 struct tevent_context *ev,
1780 const char *name,
1781 int name_type)
1783 struct tevent_req *req, *subreq;
1784 struct name_resolve_bcast_state *state;
1785 struct sockaddr_storage *bcast_addrs;
1786 int i, num_addrs, num_bcast_addrs;
1788 req = tevent_req_create(mem_ctx, &state,
1789 struct name_resolve_bcast_state);
1790 if (req == NULL) {
1791 return NULL;
1794 if (lp_disable_netbios()) {
1795 DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n",
1796 name, name_type));
1797 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1798 return tevent_req_post(req, ev);
1802 * "bcast" means do a broadcast lookup on all the local interfaces.
1805 DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup "
1806 "for name %s<0x%x>\n", name, name_type));
1808 num_addrs = iface_count();
1809 bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs);
1810 if (tevent_req_nomem(bcast_addrs, req)) {
1811 return tevent_req_post(req, ev);
1815 * Lookup the name on all the interfaces, return on
1816 * the first successful match.
1818 num_bcast_addrs = 0;
1820 for (i=0; i<num_addrs; i++) {
1821 const struct sockaddr_storage *pss = iface_n_bcast(i);
1823 if (pss->ss_family != AF_INET) {
1824 continue;
1826 bcast_addrs[num_bcast_addrs] = *pss;
1827 num_bcast_addrs += 1;
1830 subreq = name_queries_send(state, ev, name, name_type, true, true,
1831 bcast_addrs, num_bcast_addrs, 0, 1000);
1832 if (tevent_req_nomem(subreq, req)) {
1833 return tevent_req_post(req, ev);
1835 tevent_req_set_callback(subreq, name_resolve_bcast_done, req);
1836 return req;
1839 static void name_resolve_bcast_done(struct tevent_req *subreq)
1841 struct tevent_req *req = tevent_req_callback_data(
1842 subreq, struct tevent_req);
1843 struct name_resolve_bcast_state *state = tevent_req_data(
1844 req, struct name_resolve_bcast_state);
1845 NTSTATUS status;
1847 status = name_queries_recv(subreq, state,
1848 &state->addrs, &state->num_addrs,
1849 NULL, NULL);
1850 TALLOC_FREE(subreq);
1851 if (tevent_req_nterror(req, status)) {
1852 return;
1854 tevent_req_done(req);
1857 NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1858 struct sockaddr_storage **addrs,
1859 int *num_addrs)
1861 struct name_resolve_bcast_state *state = tevent_req_data(
1862 req, struct name_resolve_bcast_state);
1863 NTSTATUS status;
1865 if (tevent_req_is_nterror(req, &status)) {
1866 return status;
1868 *addrs = talloc_move(mem_ctx, &state->addrs);
1869 *num_addrs = state->num_addrs;
1870 return NT_STATUS_OK;
1873 NTSTATUS name_resolve_bcast(const char *name,
1874 int name_type,
1875 TALLOC_CTX *mem_ctx,
1876 struct sockaddr_storage **return_iplist,
1877 int *return_count)
1879 TALLOC_CTX *frame = talloc_stackframe();
1880 struct event_context *ev;
1881 struct tevent_req *req;
1882 NTSTATUS status = NT_STATUS_NO_MEMORY;
1884 ev = event_context_init(frame);
1885 if (ev == NULL) {
1886 goto fail;
1888 req = name_resolve_bcast_send(frame, ev, name, name_type);
1889 if (req == NULL) {
1890 goto fail;
1892 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1893 goto fail;
1895 status = name_resolve_bcast_recv(req, mem_ctx, return_iplist,
1896 return_count);
1897 fail:
1898 TALLOC_FREE(frame);
1899 return status;
1902 struct query_wins_list_state {
1903 struct tevent_context *ev;
1904 const char *name;
1905 uint8_t name_type;
1906 struct in_addr *servers;
1907 uint32_t num_servers;
1908 struct sockaddr_storage server;
1909 uint32_t num_sent;
1911 struct sockaddr_storage *addrs;
1912 int num_addrs;
1913 uint8_t flags;
1916 static void query_wins_list_done(struct tevent_req *subreq);
1919 * Query a list of (replicating) wins servers in sequence, call them
1920 * dead if they don't reply
1923 static struct tevent_req *query_wins_list_send(
1924 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1925 struct in_addr src_ip, const char *name, uint8_t name_type,
1926 struct in_addr *servers, int num_servers)
1928 struct tevent_req *req, *subreq;
1929 struct query_wins_list_state *state;
1931 req = tevent_req_create(mem_ctx, &state,
1932 struct query_wins_list_state);
1933 if (req == NULL) {
1934 return NULL;
1936 state->ev = ev;
1937 state->name = name;
1938 state->name_type = name_type;
1939 state->servers = servers;
1940 state->num_servers = num_servers;
1942 if (state->num_servers == 0) {
1943 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
1944 return tevent_req_post(req, ev);
1947 in_addr_to_sockaddr_storage(
1948 &state->server, state->servers[state->num_sent]);
1950 subreq = name_query_send(state, state->ev,
1951 state->name, state->name_type,
1952 false, true, &state->server);
1953 state->num_sent += 1;
1954 if (tevent_req_nomem(subreq, req)) {
1955 return tevent_req_post(req, ev);
1957 if (!tevent_req_set_endtime(subreq, state->ev,
1958 timeval_current_ofs(2, 0))) {
1959 tevent_req_oom(req);
1960 return tevent_req_post(req, ev);
1962 tevent_req_set_callback(subreq, query_wins_list_done, req);
1963 return req;
1966 static void query_wins_list_done(struct tevent_req *subreq)
1968 struct tevent_req *req = tevent_req_callback_data(
1969 subreq, struct tevent_req);
1970 struct query_wins_list_state *state = tevent_req_data(
1971 req, struct query_wins_list_state);
1972 NTSTATUS status;
1974 status = name_query_recv(subreq, state,
1975 &state->addrs, &state->num_addrs,
1976 &state->flags);
1977 TALLOC_FREE(subreq);
1978 if (NT_STATUS_IS_OK(status)) {
1979 tevent_req_done(req);
1980 return;
1982 if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1983 tevent_req_nterror(req, status);
1984 return;
1986 wins_srv_died(state->servers[state->num_sent-1],
1987 my_socket_addr_v4());
1989 if (state->num_sent == state->num_servers) {
1990 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
1991 return;
1994 in_addr_to_sockaddr_storage(
1995 &state->server, state->servers[state->num_sent]);
1997 subreq = name_query_send(state, state->ev,
1998 state->name, state->name_type,
1999 false, true, &state->server);
2000 state->num_sent += 1;
2001 if (tevent_req_nomem(subreq, req)) {
2002 return;
2004 if (!tevent_req_set_endtime(subreq, state->ev,
2005 timeval_current_ofs(2, 0))) {
2006 tevent_req_oom(req);
2007 return;
2009 tevent_req_set_callback(subreq, query_wins_list_done, req);
2012 static NTSTATUS query_wins_list_recv(struct tevent_req *req,
2013 TALLOC_CTX *mem_ctx,
2014 struct sockaddr_storage **addrs,
2015 int *num_addrs,
2016 uint8_t *flags)
2018 struct query_wins_list_state *state = tevent_req_data(
2019 req, struct query_wins_list_state);
2020 NTSTATUS status;
2022 if (tevent_req_is_nterror(req, &status)) {
2023 return status;
2025 if (addrs != NULL) {
2026 *addrs = talloc_move(mem_ctx, &state->addrs);
2028 if (num_addrs != NULL) {
2029 *num_addrs = state->num_addrs;
2031 if (flags != NULL) {
2032 *flags = state->flags;
2034 return NT_STATUS_OK;
2037 struct resolve_wins_state {
2038 int num_sent;
2039 int num_received;
2041 struct sockaddr_storage *addrs;
2042 int num_addrs;
2043 uint8_t flags;
2046 static void resolve_wins_done(struct tevent_req *subreq);
2048 struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
2049 struct tevent_context *ev,
2050 const char *name,
2051 int name_type)
2053 struct tevent_req *req, *subreq;
2054 struct resolve_wins_state *state;
2055 char **wins_tags = NULL;
2056 struct sockaddr_storage src_ss;
2057 struct in_addr src_ip;
2058 int i, num_wins_tags;
2060 req = tevent_req_create(mem_ctx, &state,
2061 struct resolve_wins_state);
2062 if (req == NULL) {
2063 return NULL;
2066 if (wins_srv_count() < 1) {
2067 DEBUG(3,("resolve_wins: WINS server resolution selected "
2068 "and no WINS servers listed.\n"));
2069 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2070 goto fail;
2073 /* the address we will be sending from */
2074 if (!interpret_string_addr(&src_ss, lp_socket_address(),
2075 AI_NUMERICHOST|AI_PASSIVE)) {
2076 zero_sockaddr(&src_ss);
2079 if (src_ss.ss_family != AF_INET) {
2080 char addr[INET6_ADDRSTRLEN];
2081 print_sockaddr(addr, sizeof(addr), &src_ss);
2082 DEBUG(3,("resolve_wins: cannot receive WINS replies "
2083 "on IPv6 address %s\n",
2084 addr));
2085 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2086 goto fail;
2089 src_ip = ((const struct sockaddr_in *)(void *)&src_ss)->sin_addr;
2091 wins_tags = wins_srv_tags();
2092 if (wins_tags == NULL) {
2093 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2094 goto fail;
2097 num_wins_tags = 0;
2098 while (wins_tags[num_wins_tags] != NULL) {
2099 num_wins_tags += 1;
2102 for (i=0; i<num_wins_tags; i++) {
2103 int num_servers, num_alive;
2104 struct in_addr *servers, *alive;
2105 int j;
2107 if (!wins_server_tag_ips(wins_tags[i], talloc_tos(),
2108 &servers, &num_servers)) {
2109 DEBUG(10, ("wins_server_tag_ips failed for tag %s\n",
2110 wins_tags[i]));
2111 continue;
2114 alive = talloc_array(state, struct in_addr, num_servers);
2115 if (tevent_req_nomem(alive, req)) {
2116 goto fail;
2119 num_alive = 0;
2120 for (j=0; j<num_servers; j++) {
2121 struct in_addr wins_ip = servers[j];
2123 if (global_in_nmbd && ismyip_v4(wins_ip)) {
2124 /* yikes! we'll loop forever */
2125 continue;
2127 /* skip any that have been unresponsive lately */
2128 if (wins_srv_is_dead(wins_ip, src_ip)) {
2129 continue;
2131 DEBUG(3, ("resolve_wins: using WINS server %s "
2132 "and tag '%s'\n",
2133 inet_ntoa(wins_ip), wins_tags[i]));
2134 alive[num_alive] = wins_ip;
2135 num_alive += 1;
2137 TALLOC_FREE(servers);
2139 if (num_alive == 0) {
2140 continue;
2143 subreq = query_wins_list_send(
2144 state, ev, src_ip, name, name_type,
2145 alive, num_alive);
2146 if (tevent_req_nomem(subreq, req)) {
2147 goto fail;
2149 tevent_req_set_callback(subreq, resolve_wins_done, req);
2150 state->num_sent += 1;
2153 if (state->num_sent == 0) {
2154 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2155 goto fail;
2158 wins_srv_tags_free(wins_tags);
2159 return req;
2160 fail:
2161 wins_srv_tags_free(wins_tags);
2162 return tevent_req_post(req, ev);
2165 static void resolve_wins_done(struct tevent_req *subreq)
2167 struct tevent_req *req = tevent_req_callback_data(
2168 subreq, struct tevent_req);
2169 struct resolve_wins_state *state = tevent_req_data(
2170 req, struct resolve_wins_state);
2171 NTSTATUS status;
2173 status = query_wins_list_recv(subreq, state, &state->addrs,
2174 &state->num_addrs, &state->flags);
2175 if (NT_STATUS_IS_OK(status)) {
2176 tevent_req_done(req);
2177 return;
2180 state->num_received += 1;
2182 if (state->num_received < state->num_sent) {
2184 * Wait for the others
2186 return;
2188 tevent_req_nterror(req, status);
2191 NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2192 struct sockaddr_storage **addrs,
2193 int *num_addrs, uint8_t *flags)
2195 struct resolve_wins_state *state = tevent_req_data(
2196 req, struct resolve_wins_state);
2197 NTSTATUS status;
2199 if (tevent_req_is_nterror(req, &status)) {
2200 return status;
2202 if (addrs != NULL) {
2203 *addrs = talloc_move(mem_ctx, &state->addrs);
2205 if (num_addrs != NULL) {
2206 *num_addrs = state->num_addrs;
2208 if (flags != NULL) {
2209 *flags = state->flags;
2211 return NT_STATUS_OK;
2214 /********************************************************
2215 Resolve via "wins" method.
2216 *********************************************************/
2218 NTSTATUS resolve_wins(const char *name,
2219 int name_type,
2220 TALLOC_CTX *mem_ctx,
2221 struct sockaddr_storage **return_iplist,
2222 int *return_count)
2224 struct tevent_context *ev;
2225 struct tevent_req *req;
2226 NTSTATUS status = NT_STATUS_NO_MEMORY;
2228 ev = tevent_context_init(talloc_tos());
2229 if (ev == NULL) {
2230 goto fail;
2232 req = resolve_wins_send(ev, ev, name, name_type);
2233 if (req == NULL) {
2234 goto fail;
2236 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2237 goto fail;
2239 status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count,
2240 NULL);
2241 fail:
2242 TALLOC_FREE(ev);
2243 return status;
2246 /********************************************************
2247 Resolve via "lmhosts" method.
2248 *********************************************************/
2250 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
2251 struct ip_service **return_iplist,
2252 int *return_count)
2255 * "lmhosts" means parse the local lmhosts file.
2257 struct sockaddr_storage *ss_list;
2258 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2259 TALLOC_CTX *ctx = NULL;
2261 *return_iplist = NULL;
2262 *return_count = 0;
2264 DEBUG(3,("resolve_lmhosts: "
2265 "Attempting lmhosts lookup for name %s<0x%x>\n",
2266 name, name_type));
2268 ctx = talloc_init("resolve_lmhosts");
2269 if (!ctx) {
2270 return NT_STATUS_NO_MEMORY;
2273 status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(),
2274 name, name_type,
2275 ctx,
2276 &ss_list,
2277 return_count);
2278 if (NT_STATUS_IS_OK(status)) {
2279 if (convert_ss2service(return_iplist,
2280 ss_list,
2281 return_count)) {
2282 talloc_free(ctx);
2283 return NT_STATUS_OK;
2284 } else {
2285 talloc_free(ctx);
2286 return NT_STATUS_NO_MEMORY;
2289 talloc_free(ctx);
2290 return status;
2294 /********************************************************
2295 Resolve via "hosts" method.
2296 *********************************************************/
2298 static NTSTATUS resolve_hosts(const char *name, int name_type,
2299 struct ip_service **return_iplist,
2300 int *return_count)
2303 * "host" means do a localhost, or dns lookup.
2305 struct addrinfo hints;
2306 struct addrinfo *ailist = NULL;
2307 struct addrinfo *res = NULL;
2308 int ret = -1;
2309 int i = 0;
2310 const char *dns_hosts_file;
2312 if ( name_type != 0x20 && name_type != 0x0) {
2313 DEBUG(5, ("resolve_hosts: not appropriate "
2314 "for name type <0x%x>\n",
2315 name_type));
2316 return NT_STATUS_INVALID_PARAMETER;
2319 *return_iplist = NULL;
2320 *return_count = 0;
2322 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
2323 name, name_type));
2325 ZERO_STRUCT(hints);
2326 /* By default make sure it supports TCP. */
2327 hints.ai_socktype = SOCK_STREAM;
2328 hints.ai_flags = AI_ADDRCONFIG;
2330 #if !defined(HAVE_IPV6)
2331 /* Unless we have IPv6, we really only want IPv4 addresses back. */
2332 hints.ai_family = AF_INET;
2333 #endif
2335 dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL);
2336 if (dns_hosts_file) {
2337 struct sockaddr_storage *ss_list;
2338 NTSTATUS status;
2339 TALLOC_CTX *ctx = talloc_stackframe();
2340 if (!ctx) {
2341 return NT_STATUS_NO_MEMORY;
2344 status = resolve_dns_hosts_file_as_sockaddr(dns_hosts_file, name, false,
2345 ctx, &ss_list, return_count);
2346 if (NT_STATUS_IS_OK(status)) {
2347 if (convert_ss2service(return_iplist,
2348 ss_list,
2349 return_count)) {
2350 talloc_free(ctx);
2351 return NT_STATUS_OK;
2352 } else {
2353 talloc_free(ctx);
2354 return NT_STATUS_NO_MEMORY;
2357 talloc_free(ctx);
2358 return NT_STATUS_UNSUCCESSFUL;
2361 ret = getaddrinfo(name,
2362 NULL,
2363 &hints,
2364 &ailist);
2365 if (ret) {
2366 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
2367 name,
2368 gai_strerror(ret) ));
2371 for (res = ailist; res; res = res->ai_next) {
2372 struct sockaddr_storage ss;
2374 if (!res->ai_addr || res->ai_addrlen == 0) {
2375 continue;
2378 ZERO_STRUCT(ss);
2379 memcpy(&ss, res->ai_addr, res->ai_addrlen);
2381 if (is_zero_addr(&ss)) {
2382 continue;
2385 *return_count += 1;
2387 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
2388 struct ip_service,
2389 *return_count);
2390 if (!*return_iplist) {
2391 DEBUG(3,("resolve_hosts: malloc fail !\n"));
2392 freeaddrinfo(ailist);
2393 return NT_STATUS_NO_MEMORY;
2395 (*return_iplist)[i].ss = ss;
2396 (*return_iplist)[i].port = PORT_NONE;
2397 i++;
2399 if (ailist) {
2400 freeaddrinfo(ailist);
2402 if (*return_count) {
2403 return NT_STATUS_OK;
2405 return NT_STATUS_UNSUCCESSFUL;
2408 /********************************************************
2409 Resolve via "ADS" method.
2410 *********************************************************/
2412 /* Special name type used to cause a _kerberos DNS lookup. */
2413 #define KDC_NAME_TYPE 0xDCDC
2415 static NTSTATUS resolve_ads(const char *name,
2416 int name_type,
2417 const char *sitename,
2418 struct ip_service **return_iplist,
2419 int *return_count)
2421 int i;
2422 NTSTATUS status;
2423 TALLOC_CTX *ctx;
2424 struct dns_rr_srv *dcs = NULL;
2425 int numdcs = 0;
2426 int numaddrs = 0;
2427 const char *dns_hosts_file;
2429 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
2430 (name_type != 0x1b)) {
2431 return NT_STATUS_INVALID_PARAMETER;
2434 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
2435 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
2436 return NT_STATUS_NO_MEMORY;
2439 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
2441 dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL);
2442 switch (name_type) {
2443 case 0x1b:
2444 DEBUG(5,("resolve_ads: Attempting to resolve "
2445 "PDC for %s using DNS\n", name));
2446 status = ads_dns_query_pdc(ctx, dns_hosts_file,
2447 name, &dcs, &numdcs);
2448 break;
2450 case 0x1c:
2451 DEBUG(5,("resolve_ads: Attempting to resolve "
2452 "DCs for %s using DNS\n", name));
2453 status = ads_dns_query_dcs(ctx, dns_hosts_file,
2454 name, sitename, &dcs,
2455 &numdcs);
2456 break;
2457 case KDC_NAME_TYPE:
2458 DEBUG(5,("resolve_ads: Attempting to resolve "
2459 "KDCs for %s using DNS\n", name));
2460 status = ads_dns_query_kdcs(ctx, dns_hosts_file,
2461 name, sitename, &dcs,
2462 &numdcs);
2463 break;
2464 default:
2465 status = NT_STATUS_INVALID_PARAMETER;
2466 break;
2469 if ( !NT_STATUS_IS_OK( status ) ) {
2470 talloc_destroy(ctx);
2471 return status;
2474 for (i=0;i<numdcs;i++) {
2475 if (!dcs[i].ss_s) {
2476 numaddrs += 1;
2477 } else {
2478 numaddrs += dcs[i].num_ips;
2482 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
2483 NULL ) {
2484 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
2485 numaddrs ));
2486 talloc_destroy(ctx);
2487 return NT_STATUS_NO_MEMORY;
2490 /* now unroll the list of IP addresses */
2492 *return_count = 0;
2494 for (i = 0; i < numdcs && (*return_count<numaddrs); i++ ) {
2495 /* If we don't have an IP list for a name, lookup it up */
2496 if (!dcs[i].ss_s) {
2497 /* We need to get all IP addresses here. */
2498 struct addrinfo *res = NULL;
2499 struct addrinfo *p;
2500 int extra_addrs = 0;
2502 if (!interpret_string_addr_internal(&res,
2503 dcs[i].hostname,
2504 0)) {
2505 continue;
2507 /* Add in every IP from the lookup. How
2508 many is that ? */
2509 for (p = res; p; p = p->ai_next) {
2510 struct sockaddr_storage ss;
2511 memcpy(&ss, p->ai_addr, p->ai_addrlen);
2512 if (is_zero_addr(&ss)) {
2513 continue;
2515 extra_addrs++;
2517 if (extra_addrs > 1) {
2518 /* We need to expand the return_iplist array
2519 as we only budgeted for one address. */
2520 numaddrs += (extra_addrs-1);
2521 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
2522 struct ip_service,
2523 numaddrs);
2524 if (*return_iplist == NULL) {
2525 if (res) {
2526 freeaddrinfo(res);
2528 talloc_destroy(ctx);
2529 return NT_STATUS_NO_MEMORY;
2532 for (p = res; p; p = p->ai_next) {
2533 (*return_iplist)[*return_count].port = dcs[i].port;
2534 memcpy(&(*return_iplist)[*return_count].ss,
2535 p->ai_addr,
2536 p->ai_addrlen);
2537 if (is_zero_addr(&(*return_iplist)[*return_count].ss)) {
2538 continue;
2540 (*return_count)++;
2541 /* Should never happen, but still... */
2542 if (*return_count>=numaddrs) {
2543 break;
2546 if (res) {
2547 freeaddrinfo(res);
2549 } else {
2550 /* use all the IP addresses from the SRV sresponse */
2551 int j;
2552 for (j = 0; j < dcs[i].num_ips; j++) {
2553 (*return_iplist)[*return_count].port = dcs[i].port;
2554 (*return_iplist)[*return_count].ss = dcs[i].ss_s[j];
2555 if (is_zero_addr(&(*return_iplist)[*return_count].ss)) {
2556 continue;
2558 (*return_count)++;
2559 /* Should never happen, but still... */
2560 if (*return_count>=numaddrs) {
2561 break;
2567 talloc_destroy(ctx);
2568 return NT_STATUS_OK;
2571 /*******************************************************************
2572 Internal interface to resolve a name into an IP address.
2573 Use this function if the string is either an IP address, DNS
2574 or host name or NetBIOS name. This uses the name switch in the
2575 smb.conf to determine the order of name resolution.
2577 Added support for ip addr/port to support ADS ldap servers.
2578 the only place we currently care about the port is in the
2579 resolve_hosts() when looking up DC's via SRV RR entries in DNS
2580 **********************************************************************/
2582 NTSTATUS internal_resolve_name(const char *name,
2583 int name_type,
2584 const char *sitename,
2585 struct ip_service **return_iplist,
2586 int *return_count,
2587 const char *resolve_order)
2589 char *tok;
2590 const char *ptr;
2591 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2592 int i;
2593 TALLOC_CTX *frame = NULL;
2595 *return_iplist = NULL;
2596 *return_count = 0;
2598 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
2599 name, name_type, sitename ? sitename : "(null)"));
2601 if (is_ipaddress(name)) {
2602 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
2603 NULL) {
2604 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
2605 return NT_STATUS_NO_MEMORY;
2608 /* ignore the port here */
2609 (*return_iplist)->port = PORT_NONE;
2611 /* if it's in the form of an IP address then get the lib to interpret it */
2612 if (!interpret_string_addr(&(*return_iplist)->ss,
2613 name, AI_NUMERICHOST)) {
2614 DEBUG(1,("internal_resolve_name: interpret_string_addr "
2615 "failed on %s\n",
2616 name));
2617 SAFE_FREE(*return_iplist);
2618 return NT_STATUS_INVALID_PARAMETER;
2620 if (is_zero_addr(&(*return_iplist)->ss)) {
2621 SAFE_FREE(*return_iplist);
2622 return NT_STATUS_UNSUCCESSFUL;
2624 *return_count = 1;
2625 return NT_STATUS_OK;
2628 /* Check name cache */
2630 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
2631 *return_count = remove_duplicate_addrs2(*return_iplist,
2632 *return_count );
2633 /* This could be a negative response */
2634 if (*return_count > 0) {
2635 return NT_STATUS_OK;
2636 } else {
2637 return NT_STATUS_UNSUCCESSFUL;
2641 /* set the name resolution order */
2643 if (strcmp( resolve_order, "NULL") == 0) {
2644 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
2645 return NT_STATUS_INVALID_PARAMETER;
2648 if (!resolve_order[0]) {
2649 ptr = "host";
2650 } else {
2651 ptr = resolve_order;
2654 /* iterate through the name resolution backends */
2656 frame = talloc_stackframe();
2657 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
2658 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
2659 status = resolve_hosts(name, name_type, return_iplist,
2660 return_count);
2661 if (NT_STATUS_IS_OK(status)) {
2662 goto done;
2664 } else if(strequal( tok, "kdc")) {
2665 /* deal with KDC_NAME_TYPE names here.
2666 * This will result in a SRV record lookup */
2667 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
2668 return_iplist, return_count);
2669 if (NT_STATUS_IS_OK(status)) {
2670 /* Ensure we don't namecache
2671 * this with the KDC port. */
2672 name_type = KDC_NAME_TYPE;
2673 goto done;
2675 } else if(strequal( tok, "ads")) {
2676 /* deal with 0x1c and 0x1b names here.
2677 * This will result in a SRV record lookup */
2678 status = resolve_ads(name, name_type, sitename,
2679 return_iplist, return_count);
2680 if (NT_STATUS_IS_OK(status)) {
2681 goto done;
2683 } else if(strequal( tok, "lmhosts")) {
2684 status = resolve_lmhosts(name, name_type,
2685 return_iplist, return_count);
2686 if (NT_STATUS_IS_OK(status)) {
2687 goto done;
2689 } else if(strequal( tok, "wins")) {
2690 /* don't resolve 1D via WINS */
2691 struct sockaddr_storage *ss_list;
2692 if (name_type != 0x1D) {
2693 status = resolve_wins(name, name_type,
2694 talloc_tos(),
2695 &ss_list,
2696 return_count);
2697 if (NT_STATUS_IS_OK(status)) {
2698 if (!convert_ss2service(return_iplist,
2699 ss_list,
2700 return_count)) {
2701 status = NT_STATUS_NO_MEMORY;
2703 goto done;
2706 } else if(strequal( tok, "bcast")) {
2707 struct sockaddr_storage *ss_list;
2708 status = name_resolve_bcast(
2709 name, name_type, talloc_tos(),
2710 &ss_list, return_count);
2711 if (NT_STATUS_IS_OK(status)) {
2712 if (!convert_ss2service(return_iplist,
2713 ss_list,
2714 return_count)) {
2715 status = NT_STATUS_NO_MEMORY;
2717 goto done;
2719 } else {
2720 DEBUG(0,("resolve_name: unknown name switch type %s\n",
2721 tok));
2725 /* All of the resolve_* functions above have returned false. */
2727 TALLOC_FREE(frame);
2728 SAFE_FREE(*return_iplist);
2729 *return_count = 0;
2731 return NT_STATUS_UNSUCCESSFUL;
2733 done:
2735 /* Remove duplicate entries. Some queries, notably #1c (domain
2736 controllers) return the PDC in iplist[0] and then all domain
2737 controllers including the PDC in iplist[1..n]. Iterating over
2738 the iplist when the PDC is down will cause two sets of timeouts. */
2740 *return_count = remove_duplicate_addrs2(*return_iplist, *return_count );
2742 /* Save in name cache */
2743 if ( DEBUGLEVEL >= 100 ) {
2744 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
2745 char addr[INET6_ADDRSTRLEN];
2746 print_sockaddr(addr, sizeof(addr),
2747 &(*return_iplist)[i].ss);
2748 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
2749 name,
2750 name_type,
2751 addr,
2752 (*return_iplist)[i].port));
2756 if (*return_count) {
2757 namecache_store(name, name_type, *return_count, *return_iplist);
2760 /* Display some debugging info */
2762 if ( DEBUGLEVEL >= 10 ) {
2763 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
2764 *return_count));
2766 for (i = 0; i < *return_count; i++) {
2767 char addr[INET6_ADDRSTRLEN];
2768 print_sockaddr(addr, sizeof(addr),
2769 &(*return_iplist)[i].ss);
2770 DEBUGADD(10, ("%s:%d ",
2771 addr,
2772 (*return_iplist)[i].port));
2774 DEBUG(10, ("\n"));
2777 TALLOC_FREE(frame);
2778 return status;
2781 /********************************************************
2782 Internal interface to resolve a name into one IP address.
2783 Use this function if the string is either an IP address, DNS
2784 or host name or NetBIOS name. This uses the name switch in the
2785 smb.conf to determine the order of name resolution.
2786 *********************************************************/
2788 bool resolve_name(const char *name,
2789 struct sockaddr_storage *return_ss,
2790 int name_type,
2791 bool prefer_ipv4)
2793 struct ip_service *ss_list = NULL;
2794 char *sitename = NULL;
2795 int count = 0;
2796 NTSTATUS status;
2798 if (is_ipaddress(name)) {
2799 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
2802 sitename = sitename_fetch(lp_realm()); /* wild guess */
2804 status = internal_resolve_name(name, name_type, sitename,
2805 &ss_list, &count,
2806 lp_name_resolve_order());
2807 if (NT_STATUS_IS_OK(status)) {
2808 int i;
2810 if (prefer_ipv4) {
2811 for (i=0; i<count; i++) {
2812 if (!is_zero_addr(&ss_list[i].ss) &&
2813 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss) &&
2814 (ss_list[i].ss.ss_family == AF_INET)) {
2815 *return_ss = ss_list[i].ss;
2816 SAFE_FREE(ss_list);
2817 SAFE_FREE(sitename);
2818 return True;
2823 /* only return valid addresses for TCP connections */
2824 for (i=0; i<count; i++) {
2825 if (!is_zero_addr(&ss_list[i].ss) &&
2826 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2827 *return_ss = ss_list[i].ss;
2828 SAFE_FREE(ss_list);
2829 SAFE_FREE(sitename);
2830 return True;
2835 SAFE_FREE(ss_list);
2836 SAFE_FREE(sitename);
2837 return False;
2840 /********************************************************
2841 Internal interface to resolve a name into a list of IP addresses.
2842 Use this function if the string is either an IP address, DNS
2843 or host name or NetBIOS name. This uses the name switch in the
2844 smb.conf to determine the order of name resolution.
2845 *********************************************************/
2847 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
2848 const char *name,
2849 int name_type,
2850 struct sockaddr_storage **return_ss_arr,
2851 unsigned int *p_num_entries)
2853 struct ip_service *ss_list = NULL;
2854 char *sitename = NULL;
2855 int count = 0;
2856 int i;
2857 unsigned int num_entries;
2858 NTSTATUS status;
2860 *p_num_entries = 0;
2861 *return_ss_arr = NULL;
2863 if (is_ipaddress(name)) {
2864 *return_ss_arr = talloc(ctx, struct sockaddr_storage);
2865 if (!*return_ss_arr) {
2866 return NT_STATUS_NO_MEMORY;
2868 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
2869 TALLOC_FREE(*return_ss_arr);
2870 return NT_STATUS_BAD_NETWORK_NAME;
2872 *p_num_entries = 1;
2873 return NT_STATUS_OK;
2876 sitename = sitename_fetch(lp_realm()); /* wild guess */
2878 status = internal_resolve_name(name, name_type, sitename,
2879 &ss_list, &count,
2880 lp_name_resolve_order());
2881 SAFE_FREE(sitename);
2883 if (!NT_STATUS_IS_OK(status)) {
2884 return status;
2887 /* only return valid addresses for TCP connections */
2888 for (i=0, num_entries = 0; i<count; i++) {
2889 if (!is_zero_addr(&ss_list[i].ss) &&
2890 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2891 num_entries++;
2894 if (num_entries == 0) {
2895 SAFE_FREE(ss_list);
2896 return NT_STATUS_BAD_NETWORK_NAME;
2899 *return_ss_arr = talloc_array(ctx,
2900 struct sockaddr_storage,
2901 num_entries);
2902 if (!(*return_ss_arr)) {
2903 SAFE_FREE(ss_list);
2904 return NT_STATUS_NO_MEMORY;
2907 for (i=0, num_entries = 0; i<count; i++) {
2908 if (!is_zero_addr(&ss_list[i].ss) &&
2909 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2910 (*return_ss_arr)[num_entries++] = ss_list[i].ss;
2914 status = NT_STATUS_OK;
2915 *p_num_entries = num_entries;
2917 SAFE_FREE(ss_list);
2918 return NT_STATUS_OK;
2921 /********************************************************
2922 Find the IP address of the master browser or DMB for a workgroup.
2923 *********************************************************/
2925 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
2927 struct ip_service *ip_list = NULL;
2928 int count = 0;
2929 NTSTATUS status;
2931 if (lp_disable_netbios()) {
2932 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
2933 return false;
2936 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
2937 lp_name_resolve_order());
2938 if (NT_STATUS_IS_OK(status)) {
2939 *master_ss = ip_list[0].ss;
2940 SAFE_FREE(ip_list);
2941 return true;
2944 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
2945 lp_name_resolve_order());
2946 if (NT_STATUS_IS_OK(status)) {
2947 *master_ss = ip_list[0].ss;
2948 SAFE_FREE(ip_list);
2949 return true;
2952 SAFE_FREE(ip_list);
2953 return false;
2956 /********************************************************
2957 Get the IP address list of the primary domain controller
2958 for a domain.
2959 *********************************************************/
2961 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
2963 struct ip_service *ip_list = NULL;
2964 int count = 0;
2965 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2967 /* Look up #1B name */
2969 if (lp_security() == SEC_ADS) {
2970 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
2971 &count, "ads");
2974 if (!NT_STATUS_IS_OK(status) || count == 0) {
2975 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
2976 &count,
2977 lp_name_resolve_order());
2978 if (!NT_STATUS_IS_OK(status)) {
2979 return false;
2983 /* if we get more than 1 IP back we have to assume it is a
2984 multi-homed PDC and not a mess up */
2986 if ( count > 1 ) {
2987 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
2988 sort_service_list(ip_list, count);
2991 *pss = ip_list[0].ss;
2992 SAFE_FREE(ip_list);
2993 return true;
2996 /* Private enum type for lookups. */
2998 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
3000 /********************************************************
3001 Get the IP address list of the domain controllers for
3002 a domain.
3003 *********************************************************/
3005 static NTSTATUS get_dc_list(const char *domain,
3006 const char *sitename,
3007 struct ip_service **ip_list,
3008 int *count,
3009 enum dc_lookup_type lookup_type,
3010 bool *ordered)
3012 char *resolve_order = NULL;
3013 char *saf_servername = NULL;
3014 char *pserver = NULL;
3015 const char *p;
3016 char *port_str = NULL;
3017 int port;
3018 char *name;
3019 int num_addresses = 0;
3020 int local_count, i, j;
3021 struct ip_service *return_iplist = NULL;
3022 struct ip_service *auto_ip_list = NULL;
3023 bool done_auto_lookup = false;
3024 int auto_count = 0;
3025 NTSTATUS status;
3026 TALLOC_CTX *ctx = talloc_init("get_dc_list");
3028 *ip_list = NULL;
3029 *count = 0;
3031 if (!ctx) {
3032 return NT_STATUS_NO_MEMORY;
3035 *ordered = False;
3037 /* if we are restricted to solely using DNS for looking
3038 up a domain controller, make sure that host lookups
3039 are enabled for the 'name resolve order'. If host lookups
3040 are disabled and ads_only is True, then set the string to
3041 NULL. */
3043 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
3044 if (!resolve_order) {
3045 status = NT_STATUS_NO_MEMORY;
3046 goto out;
3048 strlower_m(resolve_order);
3049 if (lookup_type == DC_ADS_ONLY) {
3050 if (strstr( resolve_order, "host")) {
3051 resolve_order = talloc_strdup(ctx, "ads");
3053 /* DNS SRV lookups used by the ads resolver
3054 are already sorted by priority and weight */
3055 *ordered = true;
3056 } else {
3057 resolve_order = talloc_strdup(ctx, "NULL");
3059 } else if (lookup_type == DC_KDC_ONLY) {
3060 /* DNS SRV lookups used by the ads/kdc resolver
3061 are already sorted by priority and weight */
3062 *ordered = true;
3063 resolve_order = talloc_strdup(ctx, "kdc");
3065 if (!resolve_order) {
3066 status = NT_STATUS_NO_MEMORY;
3067 goto out;
3070 /* fetch the server we have affinity for. Add the
3071 'password server' list to a search for our domain controllers */
3073 saf_servername = saf_fetch( domain);
3075 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
3076 pserver = talloc_asprintf(ctx, "%s, %s",
3077 saf_servername ? saf_servername : "",
3078 lp_passwordserver());
3079 } else {
3080 pserver = talloc_asprintf(ctx, "%s, *",
3081 saf_servername ? saf_servername : "");
3084 SAFE_FREE(saf_servername);
3085 if (!pserver) {
3086 status = NT_STATUS_NO_MEMORY;
3087 goto out;
3090 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
3092 if (!*pserver ) {
3093 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
3094 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
3095 count, resolve_order);
3096 goto out;
3099 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
3102 * if '*' appears in the "password server" list then add
3103 * an auto lookup to the list of manually configured
3104 * DC's. If any DC is listed by name, then the list should be
3105 * considered to be ordered
3108 p = pserver;
3109 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
3110 if (!done_auto_lookup && strequal(name, "*")) {
3111 status = internal_resolve_name(domain, 0x1C, sitename,
3112 &auto_ip_list,
3113 &auto_count,
3114 resolve_order);
3115 if (NT_STATUS_IS_OK(status)) {
3116 num_addresses += auto_count;
3118 done_auto_lookup = true;
3119 DEBUG(8,("Adding %d DC's from auto lookup\n",
3120 auto_count));
3121 } else {
3122 num_addresses++;
3126 /* if we have no addresses and haven't done the auto lookup, then
3127 just return the list of DC's. Or maybe we just failed. */
3129 if (num_addresses == 0) {
3130 if (done_auto_lookup) {
3131 DEBUG(4,("get_dc_list: no servers found\n"));
3132 status = NT_STATUS_NO_LOGON_SERVERS;
3133 goto out;
3135 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
3136 count, resolve_order);
3137 goto out;
3140 if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
3141 num_addresses)) == NULL) {
3142 DEBUG(3,("get_dc_list: malloc fail !\n"));
3143 status = NT_STATUS_NO_MEMORY;
3144 goto out;
3147 p = pserver;
3148 local_count = 0;
3150 /* fill in the return list now with real IP's */
3152 while ((local_count<num_addresses) &&
3153 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
3154 struct sockaddr_storage name_ss;
3156 /* copy any addersses from the auto lookup */
3158 if (strequal(name, "*")) {
3159 for (j=0; j<auto_count; j++) {
3160 char addr[INET6_ADDRSTRLEN];
3161 print_sockaddr(addr,
3162 sizeof(addr),
3163 &auto_ip_list[j].ss);
3164 /* Check for and don't copy any
3165 * known bad DC IP's. */
3166 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
3167 domain,
3168 addr))) {
3169 DEBUG(5,("get_dc_list: "
3170 "negative entry %s removed "
3171 "from DC list\n",
3172 addr));
3173 continue;
3175 return_iplist[local_count].ss =
3176 auto_ip_list[j].ss;
3177 return_iplist[local_count].port =
3178 auto_ip_list[j].port;
3179 local_count++;
3181 continue;
3184 /* added support for address:port syntax for ads
3185 * (not that I think anyone will ever run the LDAP
3186 * server in an AD domain on something other than
3187 * port 389 */
3189 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
3190 if ((port_str=strchr(name, ':')) != NULL) {
3191 *port_str = '\0';
3192 port_str++;
3193 port = atoi(port_str);
3196 /* explicit lookup; resolve_name() will
3197 * handle names & IP addresses */
3198 if (resolve_name( name, &name_ss, 0x20, true )) {
3199 char addr[INET6_ADDRSTRLEN];
3200 print_sockaddr(addr,
3201 sizeof(addr),
3202 &name_ss);
3204 /* Check for and don't copy any known bad DC IP's. */
3205 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
3206 addr)) ) {
3207 DEBUG(5,("get_dc_list: negative entry %s "
3208 "removed from DC list\n",
3209 name ));
3210 continue;
3213 return_iplist[local_count].ss = name_ss;
3214 return_iplist[local_count].port = port;
3215 local_count++;
3216 *ordered = true;
3220 /* need to remove duplicates in the list if we have any
3221 explicit password servers */
3223 local_count = remove_duplicate_addrs2(return_iplist, local_count );
3225 /* For DC's we always prioritize IPv4 due to W2K3 not
3226 * supporting LDAP, KRB5 or CLDAP over IPv6. */
3228 if (local_count && return_iplist) {
3229 prioritize_ipv4_list(return_iplist, local_count);
3232 if ( DEBUGLEVEL >= 4 ) {
3233 DEBUG(4,("get_dc_list: returning %d ip addresses "
3234 "in an %sordered list\n",
3235 local_count,
3236 *ordered ? "":"un"));
3237 DEBUG(4,("get_dc_list: "));
3238 for ( i=0; i<local_count; i++ ) {
3239 char addr[INET6_ADDRSTRLEN];
3240 print_sockaddr(addr,
3241 sizeof(addr),
3242 &return_iplist[i].ss);
3243 DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
3245 DEBUGADD(4,("\n"));
3248 *ip_list = return_iplist;
3249 *count = local_count;
3251 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
3253 out:
3255 if (!NT_STATUS_IS_OK(status)) {
3256 SAFE_FREE(return_iplist);
3257 *ip_list = NULL;
3258 *count = 0;
3261 SAFE_FREE(auto_ip_list);
3262 TALLOC_FREE(ctx);
3263 return status;
3266 /*********************************************************************
3267 Small wrapper function to get the DC list and sort it if neccessary.
3268 *********************************************************************/
3270 NTSTATUS get_sorted_dc_list( const char *domain,
3271 const char *sitename,
3272 struct ip_service **ip_list,
3273 int *count,
3274 bool ads_only )
3276 bool ordered = false;
3277 NTSTATUS status;
3278 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
3280 *ip_list = NULL;
3281 *count = 0;
3283 DEBUG(8,("get_sorted_dc_list: attempting lookup "
3284 "for name %s (sitename %s) using [%s]\n",
3285 domain,
3286 sitename ? sitename : "NULL",
3287 (ads_only ? "ads" : lp_name_resolve_order())));
3289 if (ads_only) {
3290 lookup_type = DC_ADS_ONLY;
3293 status = get_dc_list(domain, sitename, ip_list,
3294 count, lookup_type, &ordered);
3295 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
3296 && sitename) {
3297 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
3298 " in site %s, fallback to all servers\n",
3299 domain, sitename));
3300 status = get_dc_list(domain, NULL, ip_list,
3301 count, lookup_type, &ordered);
3304 if (!NT_STATUS_IS_OK(status)) {
3305 SAFE_FREE(*ip_list);
3306 *count = 0;
3307 return status;
3310 /* only sort if we don't already have an ordered list */
3311 if (!ordered) {
3312 sort_service_list(*ip_list, *count);
3315 return NT_STATUS_OK;
3318 /*********************************************************************
3319 Get the KDC list - re-use all the logic in get_dc_list.
3320 *********************************************************************/
3322 NTSTATUS get_kdc_list( const char *realm,
3323 const char *sitename,
3324 struct ip_service **ip_list,
3325 int *count)
3327 bool ordered;
3328 NTSTATUS status;
3330 *count = 0;
3331 *ip_list = NULL;
3333 status = get_dc_list(realm, sitename, ip_list,
3334 count, DC_KDC_ONLY, &ordered);
3336 if (!NT_STATUS_IS_OK(status)) {
3337 SAFE_FREE(*ip_list);
3338 *count = 0;
3339 return status;
3342 /* only sort if we don't already have an ordered list */
3343 if ( !ordered ) {
3344 sort_service_list(*ip_list, *count);
3347 return NT_STATUS_OK;