s3:net ads join: improve status evaluation for call to net_update_dns()
[Samba/bb.git] / source3 / libsmb / namequery.c
blobdf7fdc3d9f4ca9fe7142c49fc43dc97c9a912ecb
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"
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 static 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 remove duplicates */
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 /* one loop to clean up any holes we left */
1128 /* first ip should never be a zero_ip() */
1129 for (i = 0; i<count; ) {
1130 if (is_zero_addr(&iplist[i].ss) ) {
1131 if (i != count-1) {
1132 memmove(&iplist[i], &iplist[i+1],
1133 (count - i - 1)*sizeof(iplist[i]));
1135 count--;
1136 continue;
1138 i++;
1141 return count;
1144 static bool prioritize_ipv4_list(struct ip_service *iplist, int count)
1146 TALLOC_CTX *frame = talloc_stackframe();
1147 struct ip_service *iplist_new = talloc_array(frame, struct ip_service, count);
1148 int i, j;
1150 if (iplist_new == NULL) {
1151 TALLOC_FREE(frame);
1152 return false;
1155 j = 0;
1157 /* Copy IPv4 first. */
1158 for (i = 0; i < count; i++) {
1159 if (iplist[i].ss.ss_family == AF_INET) {
1160 iplist_new[j++] = iplist[i];
1164 /* Copy IPv6. */
1165 for (i = 0; i < count; i++) {
1166 if (iplist[i].ss.ss_family != AF_INET) {
1167 iplist_new[j++] = iplist[i];
1171 memcpy(iplist, iplist_new, sizeof(struct ip_service)*count);
1172 TALLOC_FREE(frame);
1173 return true;
1176 /****************************************************************************
1177 Do a netbios name query to find someones IP.
1178 Returns an array of IP addresses or NULL if none.
1179 *count will be set to the number of addresses returned.
1180 *timed_out is set if we failed by timing out
1181 ****************************************************************************/
1183 struct name_query_state {
1184 struct sockaddr_storage my_addr;
1185 struct sockaddr_storage addr;
1186 bool bcast;
1189 uint8_t buf[1024];
1190 ssize_t buflen;
1192 NTSTATUS validate_error;
1193 uint8_t flags;
1195 struct sockaddr_storage *addrs;
1196 int num_addrs;
1199 static bool name_query_validator(struct packet_struct *p, void *private_data);
1200 static void name_query_done(struct tevent_req *subreq);
1202 struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
1203 struct tevent_context *ev,
1204 const char *name, int name_type,
1205 bool bcast, bool recurse,
1206 const struct sockaddr_storage *addr)
1208 struct tevent_req *req, *subreq;
1209 struct name_query_state *state;
1210 struct packet_struct p;
1211 struct nmb_packet *nmb = &p.packet.nmb;
1212 struct sockaddr_in *in_addr;
1214 req = tevent_req_create(mem_ctx, &state, struct name_query_state);
1215 if (req == NULL) {
1216 return NULL;
1218 state->bcast = bcast;
1220 if (addr->ss_family != AF_INET) {
1221 /* Can't do node status to IPv6 */
1222 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
1223 return tevent_req_post(req, ev);
1226 if (lp_disable_netbios()) {
1227 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
1228 name, name_type));
1229 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
1230 return tevent_req_post(req, ev);
1233 state->addr = *addr;
1234 in_addr = (struct sockaddr_in *)(void *)&state->addr;
1235 in_addr->sin_port = htons(NMB_PORT);
1237 set_socket_addr_v4(&state->my_addr);
1239 ZERO_STRUCT(p);
1240 nmb->header.name_trn_id = generate_trn_id();
1241 nmb->header.opcode = 0;
1242 nmb->header.response = false;
1243 nmb->header.nm_flags.bcast = bcast;
1244 nmb->header.nm_flags.recursion_available = false;
1245 nmb->header.nm_flags.recursion_desired = recurse;
1246 nmb->header.nm_flags.trunc = false;
1247 nmb->header.nm_flags.authoritative = false;
1248 nmb->header.rcode = 0;
1249 nmb->header.qdcount = 1;
1250 nmb->header.ancount = 0;
1251 nmb->header.nscount = 0;
1252 nmb->header.arcount = 0;
1254 make_nmb_name(&nmb->question.question_name,name,name_type);
1256 nmb->question.question_type = 0x20;
1257 nmb->question.question_class = 0x1;
1259 state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
1260 &p);
1261 if (state->buflen == 0) {
1262 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1263 DEBUG(10, ("build_packet failed\n"));
1264 return tevent_req_post(req, ev);
1267 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, bcast,
1268 state->buf, state->buflen,
1269 NMB_PACKET, nmb->header.name_trn_id,
1270 name_query_validator, state);
1271 if (tevent_req_nomem(subreq, req)) {
1272 DEBUG(10, ("nb_trans_send failed\n"));
1273 return tevent_req_post(req, ev);
1275 tevent_req_set_callback(subreq, name_query_done, req);
1276 return req;
1279 static bool name_query_validator(struct packet_struct *p, void *private_data)
1281 struct name_query_state *state = talloc_get_type_abort(
1282 private_data, struct name_query_state);
1283 struct nmb_packet *nmb = &p->packet.nmb;
1284 struct sockaddr_storage *tmp_addrs;
1285 bool got_unique_netbios_name = false;
1286 int i;
1288 debug_nmb_packet(p);
1291 * If we get a Negative Name Query Response from a WINS
1292 * server, we should report it and give up.
1294 if( 0 == nmb->header.opcode /* A query response */
1295 && !state->bcast /* from a WINS server */
1296 && nmb->header.rcode /* Error returned */
1299 if( DEBUGLVL( 3 ) ) {
1300 /* Only executed if DEBUGLEVEL >= 3 */
1301 dbgtext( "Negative name query "
1302 "response, rcode 0x%02x: ",
1303 nmb->header.rcode );
1304 switch( nmb->header.rcode ) {
1305 case 0x01:
1306 dbgtext("Request was invalidly formatted.\n");
1307 break;
1308 case 0x02:
1309 dbgtext("Problem with NBNS, cannot process "
1310 "name.\n");
1311 break;
1312 case 0x03:
1313 dbgtext("The name requested does not "
1314 "exist.\n");
1315 break;
1316 case 0x04:
1317 dbgtext("Unsupported request error.\n");
1318 break;
1319 case 0x05:
1320 dbgtext("Query refused error.\n");
1321 break;
1322 default:
1323 dbgtext("Unrecognized error code.\n" );
1324 break;
1329 * We accept this packet as valid, but tell the upper
1330 * layers that it's a negative response.
1332 state->validate_error = NT_STATUS_NOT_FOUND;
1333 return true;
1336 if (nmb->header.opcode != 0 ||
1337 nmb->header.nm_flags.bcast ||
1338 nmb->header.rcode ||
1339 !nmb->header.ancount) {
1341 * XXXX what do we do with this? Could be a redirect,
1342 * but we'll discard it for the moment.
1344 return false;
1347 tmp_addrs = talloc_realloc(
1348 state, state->addrs, struct sockaddr_storage,
1349 state->num_addrs + nmb->answers->rdlength/6);
1350 if (tmp_addrs == NULL) {
1351 state->validate_error = NT_STATUS_NO_MEMORY;
1352 return true;
1354 state->addrs = tmp_addrs;
1356 DEBUG(2,("Got a positive name query response "
1357 "from %s ( ", inet_ntoa(p->ip)));
1359 for (i=0; i<nmb->answers->rdlength/6; i++) {
1360 uint16_t flags;
1361 struct in_addr ip;
1362 struct sockaddr_storage addr;
1363 int j;
1365 flags = RSVAL(&nmb->answers->rdata[i*6], 0);
1366 got_unique_netbios_name |= ((flags & 0x8000) == 0);
1368 putip((char *)&ip,&nmb->answers->rdata[2+i*6]);
1369 in_addr_to_sockaddr_storage(&addr, ip);
1371 for (j=0; j<state->num_addrs; j++) {
1372 if (sockaddr_equal(
1373 (struct sockaddr *)(void *)&addr,
1374 (struct sockaddr *)(void *)&state->addrs[j])) {
1375 break;
1378 if (j < state->num_addrs) {
1379 /* Already got it */
1380 continue;
1383 DEBUGADD(2,("%s ",inet_ntoa(ip)));
1385 state->addrs[state->num_addrs] = addr;
1386 state->num_addrs += 1;
1388 DEBUGADD(2,(")\n"));
1390 /* We add the flags back ... */
1391 if (nmb->header.response)
1392 state->flags |= NM_FLAGS_RS;
1393 if (nmb->header.nm_flags.authoritative)
1394 state->flags |= NM_FLAGS_AA;
1395 if (nmb->header.nm_flags.trunc)
1396 state->flags |= NM_FLAGS_TC;
1397 if (nmb->header.nm_flags.recursion_desired)
1398 state->flags |= NM_FLAGS_RD;
1399 if (nmb->header.nm_flags.recursion_available)
1400 state->flags |= NM_FLAGS_RA;
1401 if (nmb->header.nm_flags.bcast)
1402 state->flags |= NM_FLAGS_B;
1404 if (state->bcast) {
1406 * We have to collect all entries coming in from broadcast
1407 * queries. If we got a unique name, we're done.
1409 return got_unique_netbios_name;
1412 * WINS responses are accepted when they are received
1414 return true;
1417 static void name_query_done(struct tevent_req *subreq)
1419 struct tevent_req *req = tevent_req_callback_data(
1420 subreq, struct tevent_req);
1421 struct name_query_state *state = tevent_req_data(
1422 req, struct name_query_state);
1423 NTSTATUS status;
1424 struct packet_struct *p = NULL;
1426 status = nb_trans_recv(subreq, &p);
1427 TALLOC_FREE(subreq);
1428 if (tevent_req_nterror(req, status)) {
1429 return;
1431 if (!NT_STATUS_IS_OK(state->validate_error)) {
1432 tevent_req_nterror(req, state->validate_error);
1433 return;
1435 if (p != NULL) {
1437 * Free the packet here, we've collected the response in the
1438 * validator
1440 free_packet(p);
1442 tevent_req_done(req);
1445 NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1446 struct sockaddr_storage **addrs, int *num_addrs,
1447 uint8_t *flags)
1449 struct name_query_state *state = tevent_req_data(
1450 req, struct name_query_state);
1451 NTSTATUS status;
1453 if (tevent_req_is_nterror(req, &status)) {
1454 if (state->bcast &&
1455 NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1457 * In the broadcast case we collect replies until the
1458 * timeout.
1460 status = NT_STATUS_OK;
1462 if (!NT_STATUS_IS_OK(status)) {
1463 return status;
1466 if (state->num_addrs == 0) {
1467 return NT_STATUS_NOT_FOUND;
1469 *addrs = talloc_move(mem_ctx, &state->addrs);
1470 sort_addr_list(*addrs, state->num_addrs);
1471 *num_addrs = state->num_addrs;
1472 if (flags != NULL) {
1473 *flags = state->flags;
1475 return NT_STATUS_OK;
1478 NTSTATUS name_query(const char *name, int name_type,
1479 bool bcast, bool recurse,
1480 const struct sockaddr_storage *to_ss,
1481 TALLOC_CTX *mem_ctx,
1482 struct sockaddr_storage **addrs,
1483 int *num_addrs, uint8_t *flags)
1485 TALLOC_CTX *frame = talloc_stackframe();
1486 struct tevent_context *ev;
1487 struct tevent_req *req;
1488 struct timeval timeout;
1489 NTSTATUS status = NT_STATUS_NO_MEMORY;
1491 ev = tevent_context_init(frame);
1492 if (ev == NULL) {
1493 goto fail;
1495 req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss);
1496 if (req == NULL) {
1497 goto fail;
1499 if (bcast) {
1500 timeout = timeval_current_ofs(0, 250000);
1501 } else {
1502 timeout = timeval_current_ofs(2, 0);
1504 if (!tevent_req_set_endtime(req, ev, timeout)) {
1505 goto fail;
1507 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1508 goto fail;
1510 status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags);
1511 fail:
1512 TALLOC_FREE(frame);
1513 return status;
1516 /********************************************************
1517 convert an array if struct sockaddr_storage to struct ip_service
1518 return false on failure. Port is set to PORT_NONE;
1519 *********************************************************/
1521 static bool convert_ss2service(struct ip_service **return_iplist,
1522 const struct sockaddr_storage *ss_list,
1523 int count)
1525 int i;
1527 if ( count==0 || !ss_list )
1528 return False;
1530 /* copy the ip address; port will be PORT_NONE */
1531 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
1532 NULL) {
1533 DEBUG(0,("convert_ip2service: malloc failed "
1534 "for %d enetries!\n", count ));
1535 return False;
1538 for ( i=0; i<count; i++ ) {
1539 (*return_iplist)[i].ss = ss_list[i];
1540 (*return_iplist)[i].port = PORT_NONE;
1543 return true;
1546 struct name_queries_state {
1547 struct tevent_context *ev;
1548 const char *name;
1549 int name_type;
1550 bool bcast;
1551 bool recurse;
1552 const struct sockaddr_storage *addrs;
1553 int num_addrs;
1554 int wait_msec;
1555 int timeout_msec;
1557 struct tevent_req **subreqs;
1558 int num_received;
1559 int num_sent;
1561 int received_index;
1562 struct sockaddr_storage *result_addrs;
1563 int num_result_addrs;
1564 uint8_t flags;
1567 static void name_queries_done(struct tevent_req *subreq);
1568 static void name_queries_next(struct tevent_req *subreq);
1571 * Send a name query to multiple destinations with a wait time in between
1574 static struct tevent_req *name_queries_send(
1575 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1576 const char *name, int name_type,
1577 bool bcast, bool recurse,
1578 const struct sockaddr_storage *addrs,
1579 int num_addrs, int wait_msec, int timeout_msec)
1581 struct tevent_req *req, *subreq;
1582 struct name_queries_state *state;
1584 req = tevent_req_create(mem_ctx, &state,
1585 struct name_queries_state);
1586 if (req == NULL) {
1587 return NULL;
1589 state->ev = ev;
1590 state->name = name;
1591 state->name_type = name_type;
1592 state->bcast = bcast;
1593 state->recurse = recurse;
1594 state->addrs = addrs;
1595 state->num_addrs = num_addrs;
1596 state->wait_msec = wait_msec;
1597 state->timeout_msec = timeout_msec;
1599 state->subreqs = talloc_zero_array(
1600 state, struct tevent_req *, num_addrs);
1601 if (tevent_req_nomem(state->subreqs, req)) {
1602 return tevent_req_post(req, ev);
1604 state->num_sent = 0;
1606 subreq = name_query_send(
1607 state->subreqs, state->ev, name, name_type, bcast, recurse,
1608 &state->addrs[state->num_sent]);
1609 if (tevent_req_nomem(subreq, req)) {
1610 return tevent_req_post(req, ev);
1612 if (!tevent_req_set_endtime(
1613 subreq, state->ev,
1614 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1615 tevent_req_oom(req);
1616 return tevent_req_post(req, ev);
1618 tevent_req_set_callback(subreq, name_queries_done, req);
1620 state->subreqs[state->num_sent] = subreq;
1621 state->num_sent += 1;
1623 if (state->num_sent < state->num_addrs) {
1624 subreq = tevent_wakeup_send(
1625 state, state->ev,
1626 timeval_current_ofs(0, state->wait_msec * 1000));
1627 if (tevent_req_nomem(subreq, req)) {
1628 return tevent_req_post(req, ev);
1630 tevent_req_set_callback(subreq, name_queries_next, req);
1632 return req;
1635 static void name_queries_done(struct tevent_req *subreq)
1637 struct tevent_req *req = tevent_req_callback_data(
1638 subreq, struct tevent_req);
1639 struct name_queries_state *state = tevent_req_data(
1640 req, struct name_queries_state);
1641 int i;
1642 NTSTATUS status;
1644 status = name_query_recv(subreq, state, &state->result_addrs,
1645 &state->num_result_addrs, &state->flags);
1647 for (i=0; i<state->num_sent; i++) {
1648 if (state->subreqs[i] == subreq) {
1649 break;
1652 if (i == state->num_sent) {
1653 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1654 return;
1656 TALLOC_FREE(state->subreqs[i]);
1658 state->num_received += 1;
1660 if (!NT_STATUS_IS_OK(status)) {
1662 if (state->num_received >= state->num_addrs) {
1663 tevent_req_nterror(req, status);
1664 return;
1667 * Still outstanding requests, just wait
1669 return;
1671 state->received_index = i;
1672 tevent_req_done(req);
1675 static void name_queries_next(struct tevent_req *subreq)
1677 struct tevent_req *req = tevent_req_callback_data(
1678 subreq, struct tevent_req);
1679 struct name_queries_state *state = tevent_req_data(
1680 req, struct name_queries_state);
1682 if (!tevent_wakeup_recv(subreq)) {
1683 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1684 return;
1687 subreq = name_query_send(
1688 state->subreqs, state->ev,
1689 state->name, state->name_type, state->bcast, state->recurse,
1690 &state->addrs[state->num_sent]);
1691 if (tevent_req_nomem(subreq, req)) {
1692 return;
1694 tevent_req_set_callback(subreq, name_queries_done, req);
1695 if (!tevent_req_set_endtime(
1696 subreq, state->ev,
1697 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1698 tevent_req_oom(req);
1699 return;
1701 state->subreqs[state->num_sent] = subreq;
1702 state->num_sent += 1;
1704 if (state->num_sent < state->num_addrs) {
1705 subreq = tevent_wakeup_send(
1706 state, state->ev,
1707 timeval_current_ofs(0, state->wait_msec * 1000));
1708 if (tevent_req_nomem(subreq, req)) {
1709 return;
1711 tevent_req_set_callback(subreq, name_queries_next, req);
1715 static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1716 struct sockaddr_storage **result_addrs,
1717 int *num_result_addrs, uint8_t *flags,
1718 int *received_index)
1720 struct name_queries_state *state = tevent_req_data(
1721 req, struct name_queries_state);
1722 NTSTATUS status;
1724 if (tevent_req_is_nterror(req, &status)) {
1725 return status;
1728 if (result_addrs != NULL) {
1729 *result_addrs = talloc_move(mem_ctx, &state->result_addrs);
1731 if (num_result_addrs != NULL) {
1732 *num_result_addrs = state->num_result_addrs;
1734 if (flags != NULL) {
1735 *flags = state->flags;
1737 if (received_index != NULL) {
1738 *received_index = state->received_index;
1740 return NT_STATUS_OK;
1743 /********************************************************
1744 Resolve via "bcast" method.
1745 *********************************************************/
1747 struct name_resolve_bcast_state {
1748 struct sockaddr_storage *addrs;
1749 int num_addrs;
1752 static void name_resolve_bcast_done(struct tevent_req *subreq);
1754 struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx,
1755 struct tevent_context *ev,
1756 const char *name,
1757 int name_type)
1759 struct tevent_req *req, *subreq;
1760 struct name_resolve_bcast_state *state;
1761 struct sockaddr_storage *bcast_addrs;
1762 int i, num_addrs, num_bcast_addrs;
1764 req = tevent_req_create(mem_ctx, &state,
1765 struct name_resolve_bcast_state);
1766 if (req == NULL) {
1767 return NULL;
1770 if (lp_disable_netbios()) {
1771 DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n",
1772 name, name_type));
1773 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1774 return tevent_req_post(req, ev);
1778 * "bcast" means do a broadcast lookup on all the local interfaces.
1781 DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup "
1782 "for name %s<0x%x>\n", name, name_type));
1784 num_addrs = iface_count();
1785 bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs);
1786 if (tevent_req_nomem(bcast_addrs, req)) {
1787 return tevent_req_post(req, ev);
1791 * Lookup the name on all the interfaces, return on
1792 * the first successful match.
1794 num_bcast_addrs = 0;
1796 for (i=0; i<num_addrs; i++) {
1797 const struct sockaddr_storage *pss = iface_n_bcast(i);
1799 if (pss->ss_family != AF_INET) {
1800 continue;
1802 bcast_addrs[num_bcast_addrs] = *pss;
1803 num_bcast_addrs += 1;
1806 subreq = name_queries_send(state, ev, name, name_type, true, true,
1807 bcast_addrs, num_bcast_addrs, 0, 1000);
1808 if (tevent_req_nomem(subreq, req)) {
1809 return tevent_req_post(req, ev);
1811 tevent_req_set_callback(subreq, name_resolve_bcast_done, req);
1812 return req;
1815 static void name_resolve_bcast_done(struct tevent_req *subreq)
1817 struct tevent_req *req = tevent_req_callback_data(
1818 subreq, struct tevent_req);
1819 struct name_resolve_bcast_state *state = tevent_req_data(
1820 req, struct name_resolve_bcast_state);
1821 NTSTATUS status;
1823 status = name_queries_recv(subreq, state,
1824 &state->addrs, &state->num_addrs,
1825 NULL, NULL);
1826 TALLOC_FREE(subreq);
1827 if (tevent_req_nterror(req, status)) {
1828 return;
1830 tevent_req_done(req);
1833 NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1834 struct sockaddr_storage **addrs,
1835 int *num_addrs)
1837 struct name_resolve_bcast_state *state = tevent_req_data(
1838 req, struct name_resolve_bcast_state);
1839 NTSTATUS status;
1841 if (tevent_req_is_nterror(req, &status)) {
1842 return status;
1844 *addrs = talloc_move(mem_ctx, &state->addrs);
1845 *num_addrs = state->num_addrs;
1846 return NT_STATUS_OK;
1849 NTSTATUS name_resolve_bcast(const char *name,
1850 int name_type,
1851 TALLOC_CTX *mem_ctx,
1852 struct sockaddr_storage **return_iplist,
1853 int *return_count)
1855 TALLOC_CTX *frame = talloc_stackframe();
1856 struct event_context *ev;
1857 struct tevent_req *req;
1858 NTSTATUS status = NT_STATUS_NO_MEMORY;
1860 ev = event_context_init(frame);
1861 if (ev == NULL) {
1862 goto fail;
1864 req = name_resolve_bcast_send(frame, ev, name, name_type);
1865 if (req == NULL) {
1866 goto fail;
1868 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1869 goto fail;
1871 status = name_resolve_bcast_recv(req, mem_ctx, return_iplist,
1872 return_count);
1873 fail:
1874 TALLOC_FREE(frame);
1875 return status;
1878 struct query_wins_list_state {
1879 struct tevent_context *ev;
1880 const char *name;
1881 uint8_t name_type;
1882 struct in_addr *servers;
1883 uint32_t num_servers;
1884 struct sockaddr_storage server;
1885 uint32_t num_sent;
1887 struct sockaddr_storage *addrs;
1888 int num_addrs;
1889 uint8_t flags;
1892 static void query_wins_list_done(struct tevent_req *subreq);
1895 * Query a list of (replicating) wins servers in sequence, call them
1896 * dead if they don't reply
1899 static struct tevent_req *query_wins_list_send(
1900 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1901 struct in_addr src_ip, const char *name, uint8_t name_type,
1902 struct in_addr *servers, int num_servers)
1904 struct tevent_req *req, *subreq;
1905 struct query_wins_list_state *state;
1907 req = tevent_req_create(mem_ctx, &state,
1908 struct query_wins_list_state);
1909 if (req == NULL) {
1910 return NULL;
1912 state->ev = ev;
1913 state->name = name;
1914 state->name_type = name_type;
1915 state->servers = servers;
1916 state->num_servers = num_servers;
1918 if (state->num_servers == 0) {
1919 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
1920 return tevent_req_post(req, ev);
1923 in_addr_to_sockaddr_storage(
1924 &state->server, state->servers[state->num_sent]);
1926 subreq = name_query_send(state, state->ev,
1927 state->name, state->name_type,
1928 false, true, &state->server);
1929 state->num_sent += 1;
1930 if (tevent_req_nomem(subreq, req)) {
1931 return tevent_req_post(req, ev);
1933 if (!tevent_req_set_endtime(subreq, state->ev,
1934 timeval_current_ofs(2, 0))) {
1935 tevent_req_oom(req);
1936 return tevent_req_post(req, ev);
1938 tevent_req_set_callback(subreq, query_wins_list_done, req);
1939 return req;
1942 static void query_wins_list_done(struct tevent_req *subreq)
1944 struct tevent_req *req = tevent_req_callback_data(
1945 subreq, struct tevent_req);
1946 struct query_wins_list_state *state = tevent_req_data(
1947 req, struct query_wins_list_state);
1948 NTSTATUS status;
1950 status = name_query_recv(subreq, state,
1951 &state->addrs, &state->num_addrs,
1952 &state->flags);
1953 TALLOC_FREE(subreq);
1954 if (NT_STATUS_IS_OK(status)) {
1955 tevent_req_done(req);
1956 return;
1958 if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1959 tevent_req_nterror(req, status);
1960 return;
1962 wins_srv_died(state->servers[state->num_sent-1],
1963 my_socket_addr_v4());
1965 if (state->num_sent == state->num_servers) {
1966 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
1967 return;
1970 in_addr_to_sockaddr_storage(
1971 &state->server, state->servers[state->num_sent]);
1973 subreq = name_query_send(state, state->ev,
1974 state->name, state->name_type,
1975 false, true, &state->server);
1976 state->num_sent += 1;
1977 if (tevent_req_nomem(subreq, req)) {
1978 return;
1980 if (!tevent_req_set_endtime(subreq, state->ev,
1981 timeval_current_ofs(2, 0))) {
1982 tevent_req_oom(req);
1983 return;
1985 tevent_req_set_callback(subreq, query_wins_list_done, req);
1988 static NTSTATUS query_wins_list_recv(struct tevent_req *req,
1989 TALLOC_CTX *mem_ctx,
1990 struct sockaddr_storage **addrs,
1991 int *num_addrs,
1992 uint8_t *flags)
1994 struct query_wins_list_state *state = tevent_req_data(
1995 req, struct query_wins_list_state);
1996 NTSTATUS status;
1998 if (tevent_req_is_nterror(req, &status)) {
1999 return status;
2001 if (addrs != NULL) {
2002 *addrs = talloc_move(mem_ctx, &state->addrs);
2004 if (num_addrs != NULL) {
2005 *num_addrs = state->num_addrs;
2007 if (flags != NULL) {
2008 *flags = state->flags;
2010 return NT_STATUS_OK;
2013 struct resolve_wins_state {
2014 int num_sent;
2015 int num_received;
2017 struct sockaddr_storage *addrs;
2018 int num_addrs;
2019 uint8_t flags;
2022 static void resolve_wins_done(struct tevent_req *subreq);
2024 struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
2025 struct tevent_context *ev,
2026 const char *name,
2027 int name_type)
2029 struct tevent_req *req, *subreq;
2030 struct resolve_wins_state *state;
2031 char **wins_tags = NULL;
2032 struct sockaddr_storage src_ss;
2033 struct in_addr src_ip;
2034 int i, num_wins_tags;
2036 req = tevent_req_create(mem_ctx, &state,
2037 struct resolve_wins_state);
2038 if (req == NULL) {
2039 return NULL;
2042 if (wins_srv_count() < 1) {
2043 DEBUG(3,("resolve_wins: WINS server resolution selected "
2044 "and no WINS servers listed.\n"));
2045 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2046 goto fail;
2049 /* the address we will be sending from */
2050 if (!interpret_string_addr(&src_ss, lp_socket_address(),
2051 AI_NUMERICHOST|AI_PASSIVE)) {
2052 zero_sockaddr(&src_ss);
2055 if (src_ss.ss_family != AF_INET) {
2056 char addr[INET6_ADDRSTRLEN];
2057 print_sockaddr(addr, sizeof(addr), &src_ss);
2058 DEBUG(3,("resolve_wins: cannot receive WINS replies "
2059 "on IPv6 address %s\n",
2060 addr));
2061 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2062 goto fail;
2065 src_ip = ((const struct sockaddr_in *)(void *)&src_ss)->sin_addr;
2067 wins_tags = wins_srv_tags();
2068 if (wins_tags == NULL) {
2069 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2070 goto fail;
2073 num_wins_tags = 0;
2074 while (wins_tags[num_wins_tags] != NULL) {
2075 num_wins_tags += 1;
2078 for (i=0; i<num_wins_tags; i++) {
2079 int num_servers, num_alive;
2080 struct in_addr *servers, *alive;
2081 int j;
2083 if (!wins_server_tag_ips(wins_tags[i], talloc_tos(),
2084 &servers, &num_servers)) {
2085 DEBUG(10, ("wins_server_tag_ips failed for tag %s\n",
2086 wins_tags[i]));
2087 continue;
2090 alive = talloc_array(state, struct in_addr, num_servers);
2091 if (tevent_req_nomem(alive, req)) {
2092 goto fail;
2095 num_alive = 0;
2096 for (j=0; j<num_servers; j++) {
2097 struct in_addr wins_ip = servers[j];
2099 if (global_in_nmbd && ismyip_v4(wins_ip)) {
2100 /* yikes! we'll loop forever */
2101 continue;
2103 /* skip any that have been unresponsive lately */
2104 if (wins_srv_is_dead(wins_ip, src_ip)) {
2105 continue;
2107 DEBUG(3, ("resolve_wins: using WINS server %s "
2108 "and tag '%s'\n",
2109 inet_ntoa(wins_ip), wins_tags[i]));
2110 alive[num_alive] = wins_ip;
2111 num_alive += 1;
2113 TALLOC_FREE(servers);
2115 if (num_alive == 0) {
2116 continue;
2119 subreq = query_wins_list_send(
2120 state, ev, src_ip, name, name_type,
2121 alive, num_alive);
2122 if (tevent_req_nomem(subreq, req)) {
2123 goto fail;
2125 tevent_req_set_callback(subreq, resolve_wins_done, req);
2126 state->num_sent += 1;
2129 if (state->num_sent == 0) {
2130 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2131 goto fail;
2134 wins_srv_tags_free(wins_tags);
2135 return req;
2136 fail:
2137 wins_srv_tags_free(wins_tags);
2138 return tevent_req_post(req, ev);
2141 static void resolve_wins_done(struct tevent_req *subreq)
2143 struct tevent_req *req = tevent_req_callback_data(
2144 subreq, struct tevent_req);
2145 struct resolve_wins_state *state = tevent_req_data(
2146 req, struct resolve_wins_state);
2147 NTSTATUS status;
2149 status = query_wins_list_recv(subreq, state, &state->addrs,
2150 &state->num_addrs, &state->flags);
2151 if (NT_STATUS_IS_OK(status)) {
2152 tevent_req_done(req);
2153 return;
2156 state->num_received += 1;
2158 if (state->num_received < state->num_sent) {
2160 * Wait for the others
2162 return;
2164 tevent_req_nterror(req, status);
2167 NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2168 struct sockaddr_storage **addrs,
2169 int *num_addrs, uint8_t *flags)
2171 struct resolve_wins_state *state = tevent_req_data(
2172 req, struct resolve_wins_state);
2173 NTSTATUS status;
2175 if (tevent_req_is_nterror(req, &status)) {
2176 return status;
2178 if (addrs != NULL) {
2179 *addrs = talloc_move(mem_ctx, &state->addrs);
2181 if (num_addrs != NULL) {
2182 *num_addrs = state->num_addrs;
2184 if (flags != NULL) {
2185 *flags = state->flags;
2187 return NT_STATUS_OK;
2190 /********************************************************
2191 Resolve via "wins" method.
2192 *********************************************************/
2194 NTSTATUS resolve_wins(const char *name,
2195 int name_type,
2196 TALLOC_CTX *mem_ctx,
2197 struct sockaddr_storage **return_iplist,
2198 int *return_count)
2200 struct tevent_context *ev;
2201 struct tevent_req *req;
2202 NTSTATUS status = NT_STATUS_NO_MEMORY;
2204 ev = tevent_context_init(talloc_tos());
2205 if (ev == NULL) {
2206 goto fail;
2208 req = resolve_wins_send(ev, ev, name, name_type);
2209 if (req == NULL) {
2210 goto fail;
2212 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2213 goto fail;
2215 status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count,
2216 NULL);
2217 fail:
2218 TALLOC_FREE(ev);
2219 return status;
2222 /********************************************************
2223 Resolve via "lmhosts" method.
2224 *********************************************************/
2226 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
2227 struct ip_service **return_iplist,
2228 int *return_count)
2231 * "lmhosts" means parse the local lmhosts file.
2233 struct sockaddr_storage *ss_list;
2234 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2235 TALLOC_CTX *ctx = NULL;
2237 *return_iplist = NULL;
2238 *return_count = 0;
2240 DEBUG(3,("resolve_lmhosts: "
2241 "Attempting lmhosts lookup for name %s<0x%x>\n",
2242 name, name_type));
2244 ctx = talloc_init("resolve_lmhosts");
2245 if (!ctx) {
2246 return NT_STATUS_NO_MEMORY;
2249 status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(),
2250 name, name_type,
2251 ctx,
2252 &ss_list,
2253 return_count);
2254 if (NT_STATUS_IS_OK(status)) {
2255 if (convert_ss2service(return_iplist,
2256 ss_list,
2257 *return_count)) {
2258 talloc_free(ctx);
2259 return NT_STATUS_OK;
2260 } else {
2261 talloc_free(ctx);
2262 return NT_STATUS_NO_MEMORY;
2265 talloc_free(ctx);
2266 return status;
2270 /********************************************************
2271 Resolve via "hosts" method.
2272 *********************************************************/
2274 static NTSTATUS resolve_hosts(const char *name, int name_type,
2275 struct ip_service **return_iplist,
2276 int *return_count)
2279 * "host" means do a localhost, or dns lookup.
2281 struct addrinfo hints;
2282 struct addrinfo *ailist = NULL;
2283 struct addrinfo *res = NULL;
2284 int ret = -1;
2285 int i = 0;
2286 const char *dns_hosts_file;
2288 if ( name_type != 0x20 && name_type != 0x0) {
2289 DEBUG(5, ("resolve_hosts: not appropriate "
2290 "for name type <0x%x>\n",
2291 name_type));
2292 return NT_STATUS_INVALID_PARAMETER;
2295 *return_iplist = NULL;
2296 *return_count = 0;
2298 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
2299 name, name_type));
2301 ZERO_STRUCT(hints);
2302 /* By default make sure it supports TCP. */
2303 hints.ai_socktype = SOCK_STREAM;
2304 hints.ai_flags = AI_ADDRCONFIG;
2306 #if !defined(HAVE_IPV6)
2307 /* Unless we have IPv6, we really only want IPv4 addresses back. */
2308 hints.ai_family = AF_INET;
2309 #endif
2311 dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL);
2312 if (dns_hosts_file) {
2313 struct sockaddr_storage *ss_list;
2314 NTSTATUS status;
2315 TALLOC_CTX *ctx = talloc_stackframe();
2316 if (!ctx) {
2317 return NT_STATUS_NO_MEMORY;
2320 status = resolve_dns_hosts_file_as_sockaddr(dns_hosts_file, name, false,
2321 ctx, &ss_list, return_count);
2322 if (NT_STATUS_IS_OK(status)) {
2323 if (convert_ss2service(return_iplist,
2324 ss_list,
2325 *return_count)) {
2326 talloc_free(ctx);
2327 return NT_STATUS_OK;
2328 } else {
2329 talloc_free(ctx);
2330 return NT_STATUS_NO_MEMORY;
2333 talloc_free(ctx);
2334 return NT_STATUS_UNSUCCESSFUL;
2337 ret = getaddrinfo(name,
2338 NULL,
2339 &hints,
2340 &ailist);
2341 if (ret) {
2342 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
2343 name,
2344 gai_strerror(ret) ));
2347 for (res = ailist; res; res = res->ai_next) {
2348 struct sockaddr_storage ss;
2350 if (!res->ai_addr || res->ai_addrlen == 0) {
2351 continue;
2354 ZERO_STRUCT(ss);
2355 memcpy(&ss, res->ai_addr, res->ai_addrlen);
2357 *return_count += 1;
2359 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
2360 struct ip_service,
2361 *return_count);
2362 if (!*return_iplist) {
2363 DEBUG(3,("resolve_hosts: malloc fail !\n"));
2364 freeaddrinfo(ailist);
2365 return NT_STATUS_NO_MEMORY;
2367 (*return_iplist)[i].ss = ss;
2368 (*return_iplist)[i].port = PORT_NONE;
2369 i++;
2371 if (ailist) {
2372 freeaddrinfo(ailist);
2374 if (*return_count) {
2375 return NT_STATUS_OK;
2377 return NT_STATUS_UNSUCCESSFUL;
2380 /********************************************************
2381 Resolve via "ADS" method.
2382 *********************************************************/
2384 /* Special name type used to cause a _kerberos DNS lookup. */
2385 #define KDC_NAME_TYPE 0xDCDC
2387 static NTSTATUS resolve_ads(const char *name,
2388 int name_type,
2389 const char *sitename,
2390 struct ip_service **return_iplist,
2391 int *return_count)
2393 int i, j;
2394 NTSTATUS status;
2395 TALLOC_CTX *ctx;
2396 struct dns_rr_srv *dcs = NULL;
2397 int numdcs = 0;
2398 int numaddrs = 0;
2400 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
2401 (name_type != 0x1b)) {
2402 return NT_STATUS_INVALID_PARAMETER;
2405 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
2406 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
2407 return NT_STATUS_NO_MEMORY;
2410 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
2412 switch (name_type) {
2413 case 0x1b:
2414 DEBUG(5,("resolve_ads: Attempting to resolve "
2415 "PDC for %s using DNS\n", name));
2416 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
2417 break;
2419 case 0x1c:
2420 DEBUG(5,("resolve_ads: Attempting to resolve "
2421 "DCs for %s using DNS\n", name));
2422 status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
2423 &numdcs);
2424 break;
2425 case KDC_NAME_TYPE:
2426 DEBUG(5,("resolve_ads: Attempting to resolve "
2427 "KDCs for %s using DNS\n", name));
2428 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
2429 &numdcs);
2430 break;
2431 default:
2432 status = NT_STATUS_INVALID_PARAMETER;
2433 break;
2436 if ( !NT_STATUS_IS_OK( status ) ) {
2437 talloc_destroy(ctx);
2438 return status;
2441 for (i=0;i<numdcs;i++) {
2442 numaddrs += MAX(dcs[i].num_ips,1);
2445 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
2446 NULL ) {
2447 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
2448 numaddrs ));
2449 talloc_destroy(ctx);
2450 return NT_STATUS_NO_MEMORY;
2453 /* now unroll the list of IP addresses */
2455 *return_count = 0;
2456 i = 0;
2457 j = 0;
2458 while ( i < numdcs && (*return_count<numaddrs) ) {
2459 struct ip_service *r = &(*return_iplist)[*return_count];
2461 r->port = dcs[i].port;
2463 /* If we don't have an IP list for a name, lookup it up */
2465 if (!dcs[i].ss_s) {
2466 interpret_string_addr(&r->ss, dcs[i].hostname, 0);
2467 i++;
2468 j = 0;
2469 } else {
2470 /* use the IP addresses from the SRV sresponse */
2472 if ( j >= dcs[i].num_ips ) {
2473 i++;
2474 j = 0;
2475 continue;
2478 r->ss = dcs[i].ss_s[j];
2479 j++;
2482 /* make sure it is a valid IP. I considered checking the
2483 * negative connection cache, but this is the wrong place
2484 * for it. Maybe only as a hack. After think about it, if
2485 * all of the IP addresses returned from DNS are dead, what
2486 * hope does a netbios name lookup have ? The standard reason
2487 * for falling back to netbios lookups is that our DNS server
2488 * doesn't know anything about the DC's -- jerry */
2490 if (!is_zero_addr(&r->ss)) {
2491 (*return_count)++;
2495 talloc_destroy(ctx);
2496 return NT_STATUS_OK;
2499 /*******************************************************************
2500 Internal interface to resolve a name into an IP address.
2501 Use this function if the string is either an IP address, DNS
2502 or host name or NetBIOS name. This uses the name switch in the
2503 smb.conf to determine the order of name resolution.
2505 Added support for ip addr/port to support ADS ldap servers.
2506 the only place we currently care about the port is in the
2507 resolve_hosts() when looking up DC's via SRV RR entries in DNS
2508 **********************************************************************/
2510 NTSTATUS internal_resolve_name(const char *name,
2511 int name_type,
2512 const char *sitename,
2513 struct ip_service **return_iplist,
2514 int *return_count,
2515 const char *resolve_order)
2517 char *tok;
2518 const char *ptr;
2519 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2520 int i;
2521 TALLOC_CTX *frame = NULL;
2523 *return_iplist = NULL;
2524 *return_count = 0;
2526 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
2527 name, name_type, sitename ? sitename : "(null)"));
2529 if (is_ipaddress(name)) {
2530 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
2531 NULL) {
2532 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
2533 return NT_STATUS_NO_MEMORY;
2536 /* ignore the port here */
2537 (*return_iplist)->port = PORT_NONE;
2539 /* if it's in the form of an IP address then get the lib to interpret it */
2540 if (!interpret_string_addr(&(*return_iplist)->ss,
2541 name, AI_NUMERICHOST)) {
2542 DEBUG(1,("internal_resolve_name: interpret_string_addr "
2543 "failed on %s\n",
2544 name));
2545 SAFE_FREE(*return_iplist);
2546 return NT_STATUS_INVALID_PARAMETER;
2548 *return_count = 1;
2549 return NT_STATUS_OK;
2552 /* Check name cache */
2554 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
2555 /* This could be a negative response */
2556 if (*return_count > 0) {
2557 return NT_STATUS_OK;
2558 } else {
2559 return NT_STATUS_UNSUCCESSFUL;
2563 /* set the name resolution order */
2565 if (strcmp( resolve_order, "NULL") == 0) {
2566 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
2567 return NT_STATUS_INVALID_PARAMETER;
2570 if (!resolve_order[0]) {
2571 ptr = "host";
2572 } else {
2573 ptr = resolve_order;
2576 /* iterate through the name resolution backends */
2578 frame = talloc_stackframe();
2579 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
2580 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
2581 status = resolve_hosts(name, name_type, return_iplist,
2582 return_count);
2583 if (NT_STATUS_IS_OK(status)) {
2584 goto done;
2586 } else if(strequal( tok, "kdc")) {
2587 /* deal with KDC_NAME_TYPE names here.
2588 * This will result in a SRV record lookup */
2589 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
2590 return_iplist, return_count);
2591 if (NT_STATUS_IS_OK(status)) {
2592 /* Ensure we don't namecache
2593 * this with the KDC port. */
2594 name_type = KDC_NAME_TYPE;
2595 goto done;
2597 } else if(strequal( tok, "ads")) {
2598 /* deal with 0x1c and 0x1b names here.
2599 * This will result in a SRV record lookup */
2600 status = resolve_ads(name, name_type, sitename,
2601 return_iplist, return_count);
2602 if (NT_STATUS_IS_OK(status)) {
2603 goto done;
2605 } else if(strequal( tok, "lmhosts")) {
2606 status = resolve_lmhosts(name, name_type,
2607 return_iplist, return_count);
2608 if (NT_STATUS_IS_OK(status)) {
2609 goto done;
2611 } else if(strequal( tok, "wins")) {
2612 /* don't resolve 1D via WINS */
2613 struct sockaddr_storage *ss_list;
2614 if (name_type != 0x1D) {
2615 status = resolve_wins(name, name_type,
2616 talloc_tos(),
2617 &ss_list,
2618 return_count);
2619 if (NT_STATUS_IS_OK(status)) {
2620 if (!convert_ss2service(return_iplist,
2621 ss_list,
2622 *return_count)) {
2623 status = NT_STATUS_NO_MEMORY;
2625 goto done;
2628 } else if(strequal( tok, "bcast")) {
2629 struct sockaddr_storage *ss_list;
2630 status = name_resolve_bcast(
2631 name, name_type, talloc_tos(),
2632 &ss_list, return_count);
2633 if (NT_STATUS_IS_OK(status)) {
2634 if (!convert_ss2service(return_iplist,
2635 ss_list,
2636 *return_count)) {
2637 status = NT_STATUS_NO_MEMORY;
2639 goto done;
2641 } else {
2642 DEBUG(0,("resolve_name: unknown name switch type %s\n",
2643 tok));
2647 /* All of the resolve_* functions above have returned false. */
2649 TALLOC_FREE(frame);
2650 SAFE_FREE(*return_iplist);
2651 *return_count = 0;
2653 return NT_STATUS_UNSUCCESSFUL;
2655 done:
2657 /* Remove duplicate entries. Some queries, notably #1c (domain
2658 controllers) return the PDC in iplist[0] and then all domain
2659 controllers including the PDC in iplist[1..n]. Iterating over
2660 the iplist when the PDC is down will cause two sets of timeouts. */
2662 if ( *return_count ) {
2663 *return_count = remove_duplicate_addrs2(*return_iplist,
2664 *return_count );
2667 /* Save in name cache */
2668 if ( DEBUGLEVEL >= 100 ) {
2669 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
2670 char addr[INET6_ADDRSTRLEN];
2671 print_sockaddr(addr, sizeof(addr),
2672 &(*return_iplist)[i].ss);
2673 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
2674 name,
2675 name_type,
2676 addr,
2677 (*return_iplist)[i].port));
2681 namecache_store(name, name_type, *return_count, *return_iplist);
2683 /* Display some debugging info */
2685 if ( DEBUGLEVEL >= 10 ) {
2686 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
2687 *return_count));
2689 for (i = 0; i < *return_count; i++) {
2690 char addr[INET6_ADDRSTRLEN];
2691 print_sockaddr(addr, sizeof(addr),
2692 &(*return_iplist)[i].ss);
2693 DEBUGADD(10, ("%s:%d ",
2694 addr,
2695 (*return_iplist)[i].port));
2697 DEBUG(10, ("\n"));
2700 TALLOC_FREE(frame);
2701 return status;
2704 /********************************************************
2705 Internal interface to resolve a name into one IP address.
2706 Use this function if the string is either an IP address, DNS
2707 or host name or NetBIOS name. This uses the name switch in the
2708 smb.conf to determine the order of name resolution.
2709 *********************************************************/
2711 bool resolve_name(const char *name,
2712 struct sockaddr_storage *return_ss,
2713 int name_type,
2714 bool prefer_ipv4)
2716 struct ip_service *ss_list = NULL;
2717 char *sitename = NULL;
2718 int count = 0;
2719 NTSTATUS status;
2721 if (is_ipaddress(name)) {
2722 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
2725 sitename = sitename_fetch(lp_realm()); /* wild guess */
2727 status = internal_resolve_name(name, name_type, sitename,
2728 &ss_list, &count,
2729 lp_name_resolve_order());
2730 if (NT_STATUS_IS_OK(status)) {
2731 int i;
2733 if (prefer_ipv4) {
2734 for (i=0; i<count; i++) {
2735 if (!is_zero_addr(&ss_list[i].ss) &&
2736 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss) &&
2737 (ss_list[i].ss.ss_family == AF_INET)) {
2738 *return_ss = ss_list[i].ss;
2739 SAFE_FREE(ss_list);
2740 SAFE_FREE(sitename);
2741 return True;
2746 /* only return valid addresses for TCP connections */
2747 for (i=0; i<count; i++) {
2748 if (!is_zero_addr(&ss_list[i].ss) &&
2749 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2750 *return_ss = ss_list[i].ss;
2751 SAFE_FREE(ss_list);
2752 SAFE_FREE(sitename);
2753 return True;
2758 SAFE_FREE(ss_list);
2759 SAFE_FREE(sitename);
2760 return False;
2763 /********************************************************
2764 Internal interface to resolve a name into a list of IP addresses.
2765 Use this function if the string is either an IP address, DNS
2766 or host name or NetBIOS name. This uses the name switch in the
2767 smb.conf to determine the order of name resolution.
2768 *********************************************************/
2770 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
2771 const char *name,
2772 int name_type,
2773 struct sockaddr_storage **return_ss_arr,
2774 unsigned int *p_num_entries)
2776 struct ip_service *ss_list = NULL;
2777 char *sitename = NULL;
2778 int count = 0;
2779 int i;
2780 unsigned int num_entries;
2781 NTSTATUS status;
2783 *p_num_entries = 0;
2784 *return_ss_arr = NULL;
2786 if (is_ipaddress(name)) {
2787 *return_ss_arr = talloc(ctx, struct sockaddr_storage);
2788 if (!*return_ss_arr) {
2789 return NT_STATUS_NO_MEMORY;
2791 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
2792 TALLOC_FREE(*return_ss_arr);
2793 return NT_STATUS_BAD_NETWORK_NAME;
2795 *p_num_entries = 1;
2796 return NT_STATUS_OK;
2799 sitename = sitename_fetch(lp_realm()); /* wild guess */
2801 status = internal_resolve_name(name, name_type, sitename,
2802 &ss_list, &count,
2803 lp_name_resolve_order());
2804 SAFE_FREE(sitename);
2806 if (!NT_STATUS_IS_OK(status)) {
2807 return status;
2810 /* only return valid addresses for TCP connections */
2811 for (i=0, num_entries = 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 num_entries++;
2817 if (num_entries == 0) {
2818 SAFE_FREE(ss_list);
2819 return NT_STATUS_BAD_NETWORK_NAME;
2822 *return_ss_arr = talloc_array(ctx,
2823 struct sockaddr_storage,
2824 num_entries);
2825 if (!(*return_ss_arr)) {
2826 SAFE_FREE(ss_list);
2827 return NT_STATUS_NO_MEMORY;
2830 for (i=0, num_entries = 0; i<count; i++) {
2831 if (!is_zero_addr(&ss_list[i].ss) &&
2832 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2833 (*return_ss_arr)[num_entries++] = ss_list[i].ss;
2837 status = NT_STATUS_OK;
2838 *p_num_entries = num_entries;
2840 SAFE_FREE(ss_list);
2841 return NT_STATUS_OK;
2844 /********************************************************
2845 Find the IP address of the master browser or DMB for a workgroup.
2846 *********************************************************/
2848 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
2850 struct ip_service *ip_list = NULL;
2851 int count = 0;
2852 NTSTATUS status;
2854 if (lp_disable_netbios()) {
2855 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
2856 return false;
2859 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
2860 lp_name_resolve_order());
2861 if (NT_STATUS_IS_OK(status)) {
2862 *master_ss = ip_list[0].ss;
2863 SAFE_FREE(ip_list);
2864 return true;
2867 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
2868 lp_name_resolve_order());
2869 if (NT_STATUS_IS_OK(status)) {
2870 *master_ss = ip_list[0].ss;
2871 SAFE_FREE(ip_list);
2872 return true;
2875 SAFE_FREE(ip_list);
2876 return false;
2879 /********************************************************
2880 Get the IP address list of the primary domain controller
2881 for a domain.
2882 *********************************************************/
2884 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
2886 struct ip_service *ip_list = NULL;
2887 int count = 0;
2888 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2890 /* Look up #1B name */
2892 if (lp_security() == SEC_ADS) {
2893 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
2894 &count, "ads");
2897 if (!NT_STATUS_IS_OK(status) || count == 0) {
2898 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
2899 &count,
2900 lp_name_resolve_order());
2901 if (!NT_STATUS_IS_OK(status)) {
2902 return false;
2906 /* if we get more than 1 IP back we have to assume it is a
2907 multi-homed PDC and not a mess up */
2909 if ( count > 1 ) {
2910 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
2911 sort_service_list(ip_list, count);
2914 *pss = ip_list[0].ss;
2915 SAFE_FREE(ip_list);
2916 return true;
2919 /* Private enum type for lookups. */
2921 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
2923 /********************************************************
2924 Get the IP address list of the domain controllers for
2925 a domain.
2926 *********************************************************/
2928 static NTSTATUS get_dc_list(const char *domain,
2929 const char *sitename,
2930 struct ip_service **ip_list,
2931 int *count,
2932 enum dc_lookup_type lookup_type,
2933 bool *ordered)
2935 char *resolve_order = NULL;
2936 char *saf_servername = NULL;
2937 char *pserver = NULL;
2938 const char *p;
2939 char *port_str = NULL;
2940 int port;
2941 char *name;
2942 int num_addresses = 0;
2943 int local_count, i, j;
2944 struct ip_service *return_iplist = NULL;
2945 struct ip_service *auto_ip_list = NULL;
2946 bool done_auto_lookup = false;
2947 int auto_count = 0;
2948 NTSTATUS status;
2949 TALLOC_CTX *ctx = talloc_init("get_dc_list");
2951 *ip_list = NULL;
2952 *count = 0;
2954 if (!ctx) {
2955 return NT_STATUS_NO_MEMORY;
2958 *ordered = False;
2960 /* if we are restricted to solely using DNS for looking
2961 up a domain controller, make sure that host lookups
2962 are enabled for the 'name resolve order'. If host lookups
2963 are disabled and ads_only is True, then set the string to
2964 NULL. */
2966 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
2967 if (!resolve_order) {
2968 status = NT_STATUS_NO_MEMORY;
2969 goto out;
2971 strlower_m(resolve_order);
2972 if (lookup_type == DC_ADS_ONLY) {
2973 if (strstr( resolve_order, "host")) {
2974 resolve_order = talloc_strdup(ctx, "ads");
2976 /* DNS SRV lookups used by the ads resolver
2977 are already sorted by priority and weight */
2978 *ordered = true;
2979 } else {
2980 resolve_order = talloc_strdup(ctx, "NULL");
2982 } else if (lookup_type == DC_KDC_ONLY) {
2983 /* DNS SRV lookups used by the ads/kdc resolver
2984 are already sorted by priority and weight */
2985 *ordered = true;
2986 resolve_order = talloc_strdup(ctx, "kdc");
2988 if (!resolve_order) {
2989 status = NT_STATUS_NO_MEMORY;
2990 goto out;
2993 /* fetch the server we have affinity for. Add the
2994 'password server' list to a search for our domain controllers */
2996 saf_servername = saf_fetch( domain);
2998 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
2999 pserver = talloc_asprintf(ctx, "%s, %s",
3000 saf_servername ? saf_servername : "",
3001 lp_passwordserver());
3002 } else {
3003 pserver = talloc_asprintf(ctx, "%s, *",
3004 saf_servername ? saf_servername : "");
3007 SAFE_FREE(saf_servername);
3008 if (!pserver) {
3009 status = NT_STATUS_NO_MEMORY;
3010 goto out;
3013 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
3015 if (!*pserver ) {
3016 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
3017 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
3018 count, resolve_order);
3019 goto out;
3022 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
3025 * if '*' appears in the "password server" list then add
3026 * an auto lookup to the list of manually configured
3027 * DC's. If any DC is listed by name, then the list should be
3028 * considered to be ordered
3031 p = pserver;
3032 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
3033 if (!done_auto_lookup && strequal(name, "*")) {
3034 status = internal_resolve_name(domain, 0x1C, sitename,
3035 &auto_ip_list,
3036 &auto_count,
3037 resolve_order);
3038 if (NT_STATUS_IS_OK(status)) {
3039 num_addresses += auto_count;
3041 done_auto_lookup = true;
3042 DEBUG(8,("Adding %d DC's from auto lookup\n",
3043 auto_count));
3044 } else {
3045 num_addresses++;
3049 /* if we have no addresses and haven't done the auto lookup, then
3050 just return the list of DC's. Or maybe we just failed. */
3052 if ((num_addresses == 0)) {
3053 if (done_auto_lookup) {
3054 DEBUG(4,("get_dc_list: no servers found\n"));
3055 status = NT_STATUS_NO_LOGON_SERVERS;
3056 goto out;
3058 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
3059 count, resolve_order);
3060 goto out;
3063 if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
3064 num_addresses)) == NULL) {
3065 DEBUG(3,("get_dc_list: malloc fail !\n"));
3066 status = NT_STATUS_NO_MEMORY;
3067 goto out;
3070 p = pserver;
3071 local_count = 0;
3073 /* fill in the return list now with real IP's */
3075 while ((local_count<num_addresses) &&
3076 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
3077 struct sockaddr_storage name_ss;
3079 /* copy any addersses from the auto lookup */
3081 if (strequal(name, "*")) {
3082 for (j=0; j<auto_count; j++) {
3083 char addr[INET6_ADDRSTRLEN];
3084 print_sockaddr(addr,
3085 sizeof(addr),
3086 &auto_ip_list[j].ss);
3087 /* Check for and don't copy any
3088 * known bad DC IP's. */
3089 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
3090 domain,
3091 addr))) {
3092 DEBUG(5,("get_dc_list: "
3093 "negative entry %s removed "
3094 "from DC list\n",
3095 addr));
3096 continue;
3098 return_iplist[local_count].ss =
3099 auto_ip_list[j].ss;
3100 return_iplist[local_count].port =
3101 auto_ip_list[j].port;
3102 local_count++;
3104 continue;
3107 /* added support for address:port syntax for ads
3108 * (not that I think anyone will ever run the LDAP
3109 * server in an AD domain on something other than
3110 * port 389 */
3112 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
3113 if ((port_str=strchr(name, ':')) != NULL) {
3114 *port_str = '\0';
3115 port_str++;
3116 port = atoi(port_str);
3119 /* explicit lookup; resolve_name() will
3120 * handle names & IP addresses */
3121 if (resolve_name( name, &name_ss, 0x20, true )) {
3122 char addr[INET6_ADDRSTRLEN];
3123 print_sockaddr(addr,
3124 sizeof(addr),
3125 &name_ss);
3127 /* Check for and don't copy any known bad DC IP's. */
3128 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
3129 addr)) ) {
3130 DEBUG(5,("get_dc_list: negative entry %s "
3131 "removed from DC list\n",
3132 name ));
3133 continue;
3136 return_iplist[local_count].ss = name_ss;
3137 return_iplist[local_count].port = port;
3138 local_count++;
3139 *ordered = true;
3143 /* need to remove duplicates in the list if we have any
3144 explicit password servers */
3146 if (local_count) {
3147 local_count = remove_duplicate_addrs2(return_iplist,
3148 local_count );
3151 /* For DC's we always prioritize IPv4 due to W2K3 not
3152 * supporting LDAP, KRB5 or CLDAP over IPv6. */
3154 if (local_count && return_iplist) {
3155 prioritize_ipv4_list(return_iplist, local_count);
3158 if ( DEBUGLEVEL >= 4 ) {
3159 DEBUG(4,("get_dc_list: returning %d ip addresses "
3160 "in an %sordered list\n",
3161 local_count,
3162 *ordered ? "":"un"));
3163 DEBUG(4,("get_dc_list: "));
3164 for ( i=0; i<local_count; i++ ) {
3165 char addr[INET6_ADDRSTRLEN];
3166 print_sockaddr(addr,
3167 sizeof(addr),
3168 &return_iplist[i].ss);
3169 DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
3171 DEBUGADD(4,("\n"));
3174 *ip_list = return_iplist;
3175 *count = local_count;
3177 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
3179 out:
3181 if (!NT_STATUS_IS_OK(status)) {
3182 SAFE_FREE(return_iplist);
3183 *ip_list = NULL;
3184 *count = 0;
3187 SAFE_FREE(auto_ip_list);
3188 TALLOC_FREE(ctx);
3189 return status;
3192 /*********************************************************************
3193 Small wrapper function to get the DC list and sort it if neccessary.
3194 *********************************************************************/
3196 NTSTATUS get_sorted_dc_list( const char *domain,
3197 const char *sitename,
3198 struct ip_service **ip_list,
3199 int *count,
3200 bool ads_only )
3202 bool ordered = false;
3203 NTSTATUS status;
3204 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
3206 *ip_list = NULL;
3207 *count = 0;
3209 DEBUG(8,("get_sorted_dc_list: attempting lookup "
3210 "for name %s (sitename %s) using [%s]\n",
3211 domain,
3212 sitename ? sitename : "NULL",
3213 (ads_only ? "ads" : lp_name_resolve_order())));
3215 if (ads_only) {
3216 lookup_type = DC_ADS_ONLY;
3219 status = get_dc_list(domain, sitename, ip_list,
3220 count, lookup_type, &ordered);
3221 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
3222 && sitename) {
3223 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
3224 " in site %s, fallback to all servers\n",
3225 domain, sitename));
3226 status = get_dc_list(domain, NULL, ip_list,
3227 count, lookup_type, &ordered);
3230 if (!NT_STATUS_IS_OK(status)) {
3231 SAFE_FREE(*ip_list);
3232 *count = 0;
3233 return status;
3236 /* only sort if we don't already have an ordered list */
3237 if (!ordered) {
3238 sort_service_list(*ip_list, *count);
3241 return NT_STATUS_OK;
3244 /*********************************************************************
3245 Get the KDC list - re-use all the logic in get_dc_list.
3246 *********************************************************************/
3248 NTSTATUS get_kdc_list( const char *realm,
3249 const char *sitename,
3250 struct ip_service **ip_list,
3251 int *count)
3253 bool ordered;
3254 NTSTATUS status;
3256 *count = 0;
3257 *ip_list = NULL;
3259 status = get_dc_list(realm, sitename, ip_list,
3260 count, DC_KDC_ONLY, &ordered);
3262 if (!NT_STATUS_IS_OK(status)) {
3263 SAFE_FREE(*ip_list);
3264 *count = 0;
3265 return status;
3268 /* only sort if we don't already have an ordered list */
3269 if ( !ordered ) {
3270 sort_service_list(*ip_list, *count);
3273 return NT_STATUS_OK;