s3:lib/afs fix some compiler warnings
[Samba/bb.git] / source3 / libsmb / namequery.c
blobdca740d3e6bb8d737c1d95ad2b82f411f33774c4
1 /*
2 Unix SMB/CIFS implementation.
3 name query routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2007.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/util/tevent_ntstatus.h"
23 #include "libads/sitename_cache.h"
24 #include "libads/dns.h"
25 #include "../libcli/netlogon/netlogon.h"
26 #include "lib/async_req/async_sock.h"
27 #include "libsmb/nmblib.h"
29 /* nmbd.c sets this to True. */
30 bool global_in_nmbd = False;
32 /****************************
33 * SERVER AFFINITY ROUTINES *
34 ****************************/
36 /* Server affinity is the concept of preferring the last domain
37 controller with whom you had a successful conversation */
39 /****************************************************************************
40 ****************************************************************************/
41 #define SAFKEY_FMT "SAF/DOMAIN/%s"
42 #define SAF_TTL 900
43 #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
44 #define SAFJOIN_TTL 3600
46 static char *saf_key(const char *domain)
48 char *keystr;
50 asprintf_strupper_m(&keystr, SAFKEY_FMT, domain);
52 return keystr;
55 static char *saf_join_key(const char *domain)
57 char *keystr;
59 asprintf_strupper_m(&keystr, SAFJOINKEY_FMT, domain);
61 return keystr;
64 /****************************************************************************
65 ****************************************************************************/
67 bool saf_store( const char *domain, const char *servername )
69 char *key;
70 time_t expire;
71 bool ret = False;
73 if ( !domain || !servername ) {
74 DEBUG(2,("saf_store: "
75 "Refusing to store empty domain or servername!\n"));
76 return False;
79 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
80 DEBUG(0,("saf_store: "
81 "refusing to store 0 length domain or servername!\n"));
82 return False;
85 key = saf_key( domain );
86 expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
88 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
89 domain, servername, (unsigned int)expire ));
91 ret = gencache_set( key, servername, expire );
93 SAFE_FREE( key );
95 return ret;
98 bool saf_join_store( const char *domain, const char *servername )
100 char *key;
101 time_t expire;
102 bool ret = False;
104 if ( !domain || !servername ) {
105 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
106 return False;
109 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
110 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
111 return False;
114 key = saf_join_key( domain );
115 expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
117 DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
118 domain, servername, (unsigned int)expire ));
120 ret = gencache_set( key, servername, expire );
122 SAFE_FREE( key );
124 return ret;
127 bool saf_delete( const char *domain )
129 char *key;
130 bool ret = False;
132 if ( !domain ) {
133 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
134 return False;
137 key = saf_join_key(domain);
138 ret = gencache_del(key);
139 SAFE_FREE(key);
141 if (ret) {
142 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
145 key = saf_key(domain);
146 ret = gencache_del(key);
147 SAFE_FREE(key);
149 if (ret) {
150 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
153 return ret;
156 /****************************************************************************
157 ****************************************************************************/
159 char *saf_fetch( const char *domain )
161 char *server = NULL;
162 time_t timeout;
163 bool ret = False;
164 char *key = NULL;
166 if ( !domain || strlen(domain) == 0) {
167 DEBUG(2,("saf_fetch: Empty domain name!\n"));
168 return NULL;
171 key = saf_join_key( domain );
173 ret = gencache_get( key, &server, &timeout );
175 SAFE_FREE( key );
177 if ( ret ) {
178 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
179 server, domain ));
180 return server;
183 key = saf_key( domain );
185 ret = gencache_get( key, &server, &timeout );
187 SAFE_FREE( key );
189 if ( !ret ) {
190 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
191 domain ));
192 } else {
193 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
194 server, domain ));
197 return server;
200 static void set_socket_addr_v4(struct sockaddr_storage *addr)
202 if (!interpret_string_addr(addr, lp_socket_address(),
203 AI_NUMERICHOST|AI_PASSIVE)) {
204 zero_sockaddr(addr);
206 if (addr->ss_family != AF_INET) {
207 zero_sockaddr(addr);
211 static struct in_addr my_socket_addr_v4(void)
213 struct sockaddr_storage my_addr;
214 struct sockaddr_in *in_addr = (struct sockaddr_in *)((char *)&my_addr);
216 set_socket_addr_v4(&my_addr);
217 return in_addr->sin_addr;
220 /****************************************************************************
221 Generate a random trn_id.
222 ****************************************************************************/
224 static int generate_trn_id(void)
226 uint16 id;
228 generate_random_buffer((uint8 *)&id, sizeof(id));
230 return id % (unsigned)0x7FFF;
233 /****************************************************************************
234 Parse a node status response into an array of structures.
235 ****************************************************************************/
237 static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p,
238 int *num_names,
239 struct node_status_extra *extra)
241 struct node_status *ret;
242 int i;
244 *num_names = CVAL(p,0);
246 if (*num_names == 0)
247 return NULL;
249 ret = talloc_array(mem_ctx, struct node_status,*num_names);
250 if (!ret)
251 return NULL;
253 p++;
254 for (i=0;i< *num_names;i++) {
255 StrnCpy(ret[i].name,p,15);
256 trim_char(ret[i].name,'\0',' ');
257 ret[i].type = CVAL(p,15);
258 ret[i].flags = p[16];
259 p += 18;
260 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
261 ret[i].type, ret[i].flags));
264 * Also, pick up the MAC address ...
266 if (extra) {
267 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
269 return ret;
272 struct sock_packet_read_state {
273 struct tevent_context *ev;
274 enum packet_type type;
275 int trn_id;
277 struct nb_packet_reader *reader;
278 struct tevent_req *reader_req;
280 int sock;
281 struct tevent_req *socket_req;
282 uint8_t buf[1024];
283 struct sockaddr_storage addr;
284 socklen_t addr_len;
286 bool (*validator)(struct packet_struct *p,
287 void *private_data);
288 void *private_data;
290 struct packet_struct *packet;
293 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s);
294 static void sock_packet_read_got_packet(struct tevent_req *subreq);
295 static void sock_packet_read_got_socket(struct tevent_req *subreq);
297 static struct tevent_req *sock_packet_read_send(
298 TALLOC_CTX *mem_ctx,
299 struct tevent_context *ev,
300 int sock, /* dgram socket */
301 struct nb_packet_reader *reader,
302 enum packet_type type,
303 int trn_id,
304 bool (*validator)(struct packet_struct *p, void *private_data),
305 void *private_data)
307 struct tevent_req *req;
308 struct sock_packet_read_state *state;
310 req = tevent_req_create(mem_ctx, &state,
311 struct sock_packet_read_state);
312 if (req == NULL) {
313 return NULL;
315 talloc_set_destructor(state, sock_packet_read_state_destructor);
316 state->ev = ev;
317 state->reader = reader;
318 state->sock = sock;
319 state->type = type;
320 state->trn_id = trn_id;
321 state->validator = validator;
322 state->private_data = private_data;
324 if (reader != NULL) {
325 state->reader_req = nb_packet_read_send(state, ev, reader);
326 if (tevent_req_nomem(state->reader_req, req)) {
327 return tevent_req_post(req, ev);
329 tevent_req_set_callback(
330 state->reader_req, sock_packet_read_got_packet, req);
333 state->addr_len = sizeof(state->addr);
334 state->socket_req = recvfrom_send(state, ev, sock,
335 state->buf, sizeof(state->buf), 0,
336 &state->addr, &state->addr_len);
337 if (tevent_req_nomem(state->socket_req, req)) {
338 return tevent_req_post(req, ev);
340 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
341 req);
343 return req;
346 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s)
348 if (s->packet != NULL) {
349 free_packet(s->packet);
350 s->packet = NULL;
352 return 0;
355 static void sock_packet_read_got_packet(struct tevent_req *subreq)
357 struct tevent_req *req = tevent_req_callback_data(
358 subreq, struct tevent_req);
359 struct sock_packet_read_state *state = tevent_req_data(
360 req, struct sock_packet_read_state);
361 NTSTATUS status;
363 status = nb_packet_read_recv(subreq, &state->packet);
365 TALLOC_FREE(state->reader_req);
367 if (!NT_STATUS_IS_OK(status)) {
368 if (state->socket_req != NULL) {
370 * Still waiting for socket
372 return;
375 * Both socket and packet reader failed
377 tevent_req_nterror(req, status);
378 return;
381 if ((state->validator != NULL) &&
382 !state->validator(state->packet, state->private_data)) {
383 DEBUG(10, ("validator failed\n"));
385 free_packet(state->packet);
386 state->packet = NULL;
388 state->reader_req = nb_packet_read_send(state, state->ev,
389 state->reader);
390 if (tevent_req_nomem(state->reader_req, req)) {
391 return;
393 tevent_req_set_callback(
394 state->reader_req, sock_packet_read_got_packet, req);
395 return;
398 TALLOC_FREE(state->socket_req);
399 tevent_req_done(req);
402 static void sock_packet_read_got_socket(struct tevent_req *subreq)
404 struct tevent_req *req = tevent_req_callback_data(
405 subreq, struct tevent_req);
406 struct sock_packet_read_state *state = tevent_req_data(
407 req, struct sock_packet_read_state);
408 struct sockaddr_in *in_addr;
409 ssize_t received;
410 int err;
412 received = recvfrom_recv(subreq, &err);
414 TALLOC_FREE(state->socket_req);
416 if (received == -1) {
417 if (state->reader_req != NULL) {
419 * Still waiting for reader
421 return;
424 * Both socket and reader failed
426 tevent_req_nterror(req, map_nt_error_from_unix(err));
427 return;
429 if (state->addr.ss_family != AF_INET) {
430 goto retry;
432 in_addr = (struct sockaddr_in *)(void *)&state->addr;
434 state->packet = parse_packet((char *)state->buf, received, state->type,
435 in_addr->sin_addr, in_addr->sin_port);
436 if (state->packet == NULL) {
437 DEBUG(10, ("parse_packet failed\n"));
438 goto retry;
440 if ((state->trn_id != -1) &&
441 (state->trn_id != packet_trn_id(state->packet))) {
442 DEBUG(10, ("Expected transaction id %d, got %d\n",
443 state->trn_id, packet_trn_id(state->packet)));
444 goto retry;
447 if ((state->validator != NULL) &&
448 !state->validator(state->packet, state->private_data)) {
449 DEBUG(10, ("validator failed\n"));
450 goto retry;
453 tevent_req_done(req);
454 return;
456 retry:
457 if (state->packet != NULL) {
458 free_packet(state->packet);
459 state->packet = NULL;
461 state->socket_req = recvfrom_send(state, state->ev, state->sock,
462 state->buf, sizeof(state->buf), 0,
463 &state->addr, &state->addr_len);
464 if (tevent_req_nomem(state->socket_req, req)) {
465 return;
467 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket,
468 req);
471 static NTSTATUS sock_packet_read_recv(struct tevent_req *req,
472 struct packet_struct **ppacket)
474 struct sock_packet_read_state *state = tevent_req_data(
475 req, struct sock_packet_read_state);
476 NTSTATUS status;
478 if (tevent_req_is_nterror(req, &status)) {
479 return status;
481 *ppacket = state->packet;
482 state->packet = NULL;
483 return NT_STATUS_OK;
486 struct nb_trans_state {
487 struct tevent_context *ev;
488 int sock;
489 struct nb_packet_reader *reader;
491 const struct sockaddr_storage *dst_addr;
492 uint8_t *buf;
493 size_t buflen;
494 enum packet_type type;
495 int trn_id;
497 bool (*validator)(struct packet_struct *p,
498 void *private_data);
499 void *private_data;
501 struct packet_struct *packet;
504 static int nb_trans_state_destructor(struct nb_trans_state *s);
505 static void nb_trans_got_reader(struct tevent_req *subreq);
506 static void nb_trans_done(struct tevent_req *subreq);
507 static void nb_trans_sent(struct tevent_req *subreq);
508 static void nb_trans_send_next(struct tevent_req *subreq);
510 static struct tevent_req *nb_trans_send(
511 TALLOC_CTX *mem_ctx,
512 struct tevent_context *ev,
513 const struct sockaddr_storage *my_addr,
514 const struct sockaddr_storage *dst_addr,
515 bool bcast,
516 uint8_t *buf, size_t buflen,
517 enum packet_type type, int trn_id,
518 bool (*validator)(struct packet_struct *p,
519 void *private_data),
520 void *private_data)
522 struct tevent_req *req, *subreq;
523 struct nb_trans_state *state;
525 req = tevent_req_create(mem_ctx, &state, struct nb_trans_state);
526 if (req == NULL) {
527 return NULL;
529 talloc_set_destructor(state, nb_trans_state_destructor);
530 state->ev = ev;
531 state->dst_addr = dst_addr;
532 state->buf = buf;
533 state->buflen = buflen;
534 state->type = type;
535 state->trn_id = trn_id;
536 state->validator = validator;
537 state->private_data = private_data;
539 state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True);
540 if (state->sock == -1) {
541 tevent_req_nterror(req, map_nt_error_from_unix(errno));
542 DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno)));
543 return tevent_req_post(req, ev);
546 if (bcast) {
547 set_socket_options(state->sock,"SO_BROADCAST");
550 subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL);
551 if (tevent_req_nomem(subreq, req)) {
552 return tevent_req_post(req, ev);
554 tevent_req_set_callback(subreq, nb_trans_got_reader, req);
555 return req;
558 static int nb_trans_state_destructor(struct nb_trans_state *s)
560 if (s->sock != -1) {
561 close(s->sock);
562 s->sock = -1;
564 if (s->packet != NULL) {
565 free_packet(s->packet);
566 s->packet = NULL;
568 return 0;
571 static void nb_trans_got_reader(struct tevent_req *subreq)
573 struct tevent_req *req = tevent_req_callback_data(
574 subreq, struct tevent_req);
575 struct nb_trans_state *state = tevent_req_data(
576 req, struct nb_trans_state);
577 NTSTATUS status;
579 status = nb_packet_reader_recv(subreq, state, &state->reader);
580 TALLOC_FREE(subreq);
582 if (!NT_STATUS_IS_OK(status)) {
583 DEBUG(10, ("nmbd not around\n"));
584 state->reader = NULL;
587 subreq = sock_packet_read_send(
588 state, state->ev, state->sock,
589 state->reader, state->type, state->trn_id,
590 state->validator, state->private_data);
591 if (tevent_req_nomem(subreq, req)) {
592 return;
594 tevent_req_set_callback(subreq, nb_trans_done, req);
596 subreq = sendto_send(state, state->ev, state->sock,
597 state->buf, state->buflen, 0, state->dst_addr);
598 if (tevent_req_nomem(subreq, req)) {
599 return;
601 tevent_req_set_callback(subreq, nb_trans_sent, req);
604 static void nb_trans_sent(struct tevent_req *subreq)
606 struct tevent_req *req = tevent_req_callback_data(
607 subreq, struct tevent_req);
608 struct nb_trans_state *state = tevent_req_data(
609 req, struct nb_trans_state);
610 ssize_t sent;
611 int err;
613 sent = sendto_recv(subreq, &err);
614 TALLOC_FREE(subreq);
615 if (sent == -1) {
616 DEBUG(10, ("sendto failed: %s\n", strerror(err)));
617 tevent_req_nterror(req, map_nt_error_from_unix(err));
618 return;
620 subreq = tevent_wakeup_send(state, state->ev,
621 timeval_current_ofs(1, 0));
622 if (tevent_req_nomem(subreq, req)) {
623 return;
625 tevent_req_set_callback(subreq, nb_trans_send_next, req);
628 static void nb_trans_send_next(struct tevent_req *subreq)
630 struct tevent_req *req = tevent_req_callback_data(
631 subreq, struct tevent_req);
632 struct nb_trans_state *state = tevent_req_data(
633 req, struct nb_trans_state);
634 bool ret;
636 ret = tevent_wakeup_recv(subreq);
637 TALLOC_FREE(subreq);
638 if (!ret) {
639 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
640 return;
642 subreq = sendto_send(state, state->ev, state->sock,
643 state->buf, state->buflen, 0, state->dst_addr);
644 if (tevent_req_nomem(subreq, req)) {
645 return;
647 tevent_req_set_callback(subreq, nb_trans_sent, req);
650 static void nb_trans_done(struct tevent_req *subreq)
652 struct tevent_req *req = tevent_req_callback_data(
653 subreq, struct tevent_req);
654 struct nb_trans_state *state = tevent_req_data(
655 req, struct nb_trans_state);
656 NTSTATUS status;
658 status = sock_packet_read_recv(subreq, &state->packet);
659 TALLOC_FREE(subreq);
660 if (tevent_req_nterror(req, status)) {
661 return;
663 tevent_req_done(req);
666 static NTSTATUS nb_trans_recv(struct tevent_req *req,
667 struct packet_struct **ppacket)
669 struct nb_trans_state *state = tevent_req_data(
670 req, struct nb_trans_state);
671 NTSTATUS status;
673 if (tevent_req_is_nterror(req, &status)) {
674 return status;
676 *ppacket = state->packet;
677 state->packet = NULL;
678 return NT_STATUS_OK;
681 /****************************************************************************
682 Do a NBT node status query on an open socket and return an array of
683 structures holding the returned names or NULL if the query failed.
684 **************************************************************************/
686 struct node_status_query_state {
687 struct sockaddr_storage my_addr;
688 struct sockaddr_storage addr;
689 uint8_t buf[1024];
690 ssize_t buflen;
691 struct packet_struct *packet;
694 static int node_status_query_state_destructor(
695 struct node_status_query_state *s);
696 static bool node_status_query_validator(struct packet_struct *p,
697 void *private_data);
698 static void node_status_query_done(struct tevent_req *subreq);
700 struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx,
701 struct tevent_context *ev,
702 struct nmb_name *name,
703 const struct sockaddr_storage *addr)
705 struct tevent_req *req, *subreq;
706 struct node_status_query_state *state;
707 struct packet_struct p;
708 struct nmb_packet *nmb = &p.packet.nmb;
709 struct sockaddr_in *in_addr;
711 req = tevent_req_create(mem_ctx, &state,
712 struct node_status_query_state);
713 if (req == NULL) {
714 return NULL;
716 talloc_set_destructor(state, node_status_query_state_destructor);
718 if (addr->ss_family != AF_INET) {
719 /* Can't do node status to IPv6 */
720 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
721 return tevent_req_post(req, ev);
724 state->addr = *addr;
725 in_addr = (struct sockaddr_in *)(void *)&state->addr;
726 in_addr->sin_port = htons(NMB_PORT);
728 set_socket_addr_v4(&state->my_addr);
730 ZERO_STRUCT(p);
731 nmb->header.name_trn_id = generate_trn_id();
732 nmb->header.opcode = 0;
733 nmb->header.response = false;
734 nmb->header.nm_flags.bcast = false;
735 nmb->header.nm_flags.recursion_available = false;
736 nmb->header.nm_flags.recursion_desired = false;
737 nmb->header.nm_flags.trunc = false;
738 nmb->header.nm_flags.authoritative = false;
739 nmb->header.rcode = 0;
740 nmb->header.qdcount = 1;
741 nmb->header.ancount = 0;
742 nmb->header.nscount = 0;
743 nmb->header.arcount = 0;
744 nmb->question.question_name = *name;
745 nmb->question.question_type = 0x21;
746 nmb->question.question_class = 0x1;
748 state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
749 &p);
750 if (state->buflen == 0) {
751 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
752 DEBUG(10, ("build_packet failed\n"));
753 return tevent_req_post(req, ev);
756 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, false,
757 state->buf, state->buflen,
758 NMB_PACKET, nmb->header.name_trn_id,
759 node_status_query_validator, NULL);
760 if (tevent_req_nomem(subreq, req)) {
761 DEBUG(10, ("nb_trans_send failed\n"));
762 return tevent_req_post(req, ev);
764 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(10, 0))) {
765 return tevent_req_post(req, ev);
767 tevent_req_set_callback(subreq, node_status_query_done, req);
768 return req;
771 static bool node_status_query_validator(struct packet_struct *p,
772 void *private_data)
774 struct nmb_packet *nmb = &p->packet.nmb;
775 debug_nmb_packet(p);
777 if (nmb->header.opcode != 0 ||
778 nmb->header.nm_flags.bcast ||
779 nmb->header.rcode ||
780 !nmb->header.ancount ||
781 nmb->answers->rr_type != 0x21) {
783 * XXXX what do we do with this? could be a redirect,
784 * but we'll discard it for the moment
786 return false;
788 return true;
791 static int node_status_query_state_destructor(
792 struct node_status_query_state *s)
794 if (s->packet != NULL) {
795 free_packet(s->packet);
796 s->packet = NULL;
798 return 0;
801 static void node_status_query_done(struct tevent_req *subreq)
803 struct tevent_req *req = tevent_req_callback_data(
804 subreq, struct tevent_req);
805 struct node_status_query_state *state = tevent_req_data(
806 req, struct node_status_query_state);
807 NTSTATUS status;
809 status = nb_trans_recv(subreq, &state->packet);
810 TALLOC_FREE(subreq);
811 if (tevent_req_nterror(req, status)) {
812 return;
814 tevent_req_done(req);
817 NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
818 struct node_status **pnode_status,
819 int *pnum_names,
820 struct node_status_extra *extra)
822 struct node_status_query_state *state = tevent_req_data(
823 req, struct node_status_query_state);
824 struct node_status *node_status;
825 int num_names;
826 NTSTATUS status;
828 if (tevent_req_is_nterror(req, &status)) {
829 return status;
831 node_status = parse_node_status(
832 mem_ctx, &state->packet->packet.nmb.answers->rdata[0],
833 &num_names, extra);
834 if (node_status == NULL) {
835 return NT_STATUS_NO_MEMORY;
837 *pnode_status = node_status;
838 *pnum_names = num_names;
839 return NT_STATUS_OK;
842 NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name,
843 const struct sockaddr_storage *addr,
844 struct node_status **pnode_status,
845 int *pnum_names,
846 struct node_status_extra *extra)
848 TALLOC_CTX *frame = talloc_stackframe();
849 struct tevent_context *ev;
850 struct tevent_req *req;
851 NTSTATUS status = NT_STATUS_NO_MEMORY;
853 ev = tevent_context_init(frame);
854 if (ev == NULL) {
855 goto fail;
857 req = node_status_query_send(ev, ev, name, addr);
858 if (req == NULL) {
859 goto fail;
861 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
862 goto fail;
864 status = node_status_query_recv(req, mem_ctx, pnode_status,
865 pnum_names, extra);
866 fail:
867 TALLOC_FREE(frame);
868 return status;
871 /****************************************************************************
872 Find the first type XX name in a node status reply - used for finding
873 a servers name given its IP. Return the matched name in *name.
874 **************************************************************************/
876 bool name_status_find(const char *q_name,
877 int q_type,
878 int type,
879 const struct sockaddr_storage *to_ss,
880 fstring name)
882 char addr[INET6_ADDRSTRLEN];
883 struct sockaddr_storage ss;
884 struct node_status *addrs = NULL;
885 struct nmb_name nname;
886 int count, i;
887 bool result = false;
888 NTSTATUS status;
890 if (lp_disable_netbios()) {
891 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
892 q_name, q_type));
893 return False;
896 print_sockaddr(addr, sizeof(addr), to_ss);
898 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
899 q_type, addr));
901 /* Check the cache first. */
903 if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
904 return True;
907 if (to_ss->ss_family != AF_INET) {
908 /* Can't do node status to IPv6 */
909 return false;
912 set_socket_addr_v4(&ss);
914 /* W2K PDC's seem not to respond to '*'#0. JRA */
915 make_nmb_name(&nname, q_name, q_type);
916 status = node_status_query(talloc_tos(), &nname, to_ss,
917 &addrs, &count, NULL);
918 if (!NT_STATUS_IS_OK(status)) {
919 goto done;
922 for (i=0;i<count;i++) {
923 /* Find first one of the requested type that's not a GROUP. */
924 if (addrs[i].type == type && ! (addrs[i].flags & 0x80))
925 break;
927 if (i == count)
928 goto done;
930 pull_ascii_nstring(name, sizeof(fstring), addrs[i].name);
932 /* Store the result in the cache. */
933 /* but don't store an entry for 0x1c names here. Here we have
934 a single host and DOMAIN<0x1c> names should be a list of hosts */
936 if ( q_type != 0x1c ) {
937 namecache_status_store(q_name, q_type, type, to_ss, name);
940 result = true;
942 done:
943 TALLOC_FREE(addrs);
945 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
947 if (result)
948 DEBUGADD(10, (", name %s ip address is %s", name, addr));
950 DEBUG(10, ("\n"));
952 return result;
956 comparison function used by sort_addr_list
959 static int addr_compare(const struct sockaddr_storage *ss1,
960 const struct sockaddr_storage *ss2)
962 int max_bits1=0, max_bits2=0;
963 int num_interfaces = iface_count();
964 int i;
966 /* Sort IPv4 addresses first. */
967 if (ss1->ss_family != ss2->ss_family) {
968 if (ss2->ss_family == AF_INET) {
969 return 1;
970 } else {
971 return -1;
975 /* Here we know both addresses are of the same
976 * family. */
978 for (i=0;i<num_interfaces;i++) {
979 const struct sockaddr_storage *pss = iface_n_bcast(i);
980 const unsigned char *p_ss1 = NULL;
981 const unsigned char *p_ss2 = NULL;
982 const unsigned char *p_if = NULL;
983 size_t len = 0;
984 int bits1, bits2;
986 if (pss->ss_family != ss1->ss_family) {
987 /* Ignore interfaces of the wrong type. */
988 continue;
990 if (pss->ss_family == AF_INET) {
991 p_if = (const unsigned char *)
992 &((const struct sockaddr_in *)pss)->sin_addr;
993 p_ss1 = (const unsigned char *)
994 &((const struct sockaddr_in *)ss1)->sin_addr;
995 p_ss2 = (const unsigned char *)
996 &((const struct sockaddr_in *)ss2)->sin_addr;
997 len = 4;
999 #if defined(HAVE_IPV6)
1000 if (pss->ss_family == AF_INET6) {
1001 p_if = (const unsigned char *)
1002 &((const struct sockaddr_in6 *)pss)->sin6_addr;
1003 p_ss1 = (const unsigned char *)
1004 &((const struct sockaddr_in6 *)ss1)->sin6_addr;
1005 p_ss2 = (const unsigned char *)
1006 &((const struct sockaddr_in6 *)ss2)->sin6_addr;
1007 len = 16;
1009 #endif
1010 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
1011 continue;
1013 bits1 = matching_len_bits(p_ss1, p_if, len);
1014 bits2 = matching_len_bits(p_ss2, p_if, len);
1015 max_bits1 = MAX(bits1, max_bits1);
1016 max_bits2 = MAX(bits2, max_bits2);
1019 /* Bias towards directly reachable IPs */
1020 if (iface_local((const struct sockaddr *)ss1)) {
1021 if (ss1->ss_family == AF_INET) {
1022 max_bits1 += 32;
1023 } else {
1024 max_bits1 += 128;
1027 if (iface_local((const struct sockaddr *)ss2)) {
1028 if (ss2->ss_family == AF_INET) {
1029 max_bits2 += 32;
1030 } else {
1031 max_bits2 += 128;
1034 return max_bits2 - max_bits1;
1037 /*******************************************************************
1038 compare 2 ldap IPs by nearness to our interfaces - used in qsort
1039 *******************************************************************/
1041 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
1043 int result;
1045 if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) {
1046 return result;
1049 if (ss1->port > ss2->port) {
1050 return 1;
1053 if (ss1->port < ss2->port) {
1054 return -1;
1057 return 0;
1061 sort an IP list so that names that are close to one of our interfaces
1062 are at the top. This prevents the problem where a WINS server returns an IP
1063 that is not reachable from our subnet as the first match
1066 static void sort_addr_list(struct sockaddr_storage *sslist, int count)
1068 if (count <= 1) {
1069 return;
1072 TYPESAFE_QSORT(sslist, count, addr_compare);
1075 static void sort_service_list(struct ip_service *servlist, int count)
1077 if (count <= 1) {
1078 return;
1081 TYPESAFE_QSORT(servlist, count, ip_service_compare);
1084 /**********************************************************************
1085 Remove any duplicate address/port pairs in the list
1086 *********************************************************************/
1088 static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
1090 int i, j;
1092 DEBUG(10,("remove_duplicate_addrs2: "
1093 "looking for duplicate address/port pairs\n"));
1095 /* one loop to remove duplicates */
1096 for ( i=0; i<count; i++ ) {
1097 if ( is_zero_addr(&iplist[i].ss)) {
1098 continue;
1101 for ( j=i+1; j<count; j++ ) {
1102 if (sockaddr_equal((struct sockaddr *)(void *)&iplist[i].ss,
1103 (struct sockaddr *)(void *)&iplist[j].ss) &&
1104 iplist[i].port == iplist[j].port) {
1105 zero_sockaddr(&iplist[j].ss);
1110 /* one loop to clean up any holes we left */
1111 /* first ip should never be a zero_ip() */
1112 for (i = 0; i<count; ) {
1113 if (is_zero_addr(&iplist[i].ss) ) {
1114 if (i != count-1) {
1115 memmove(&iplist[i], &iplist[i+1],
1116 (count - i - 1)*sizeof(iplist[i]));
1118 count--;
1119 continue;
1121 i++;
1124 return count;
1127 static bool prioritize_ipv4_list(struct ip_service *iplist, int count)
1129 TALLOC_CTX *frame = talloc_stackframe();
1130 struct ip_service *iplist_new = talloc_array(frame, struct ip_service, count);
1131 int i, j;
1133 if (iplist_new == NULL) {
1134 TALLOC_FREE(frame);
1135 return false;
1138 j = 0;
1140 /* Copy IPv4 first. */
1141 for (i = 0; i < count; i++) {
1142 if (iplist[i].ss.ss_family == AF_INET) {
1143 iplist_new[j++] = iplist[i];
1147 /* Copy IPv6. */
1148 for (i = 0; i < count; i++) {
1149 if (iplist[i].ss.ss_family != AF_INET) {
1150 iplist_new[j++] = iplist[i];
1154 memcpy(iplist, iplist_new, sizeof(struct ip_service)*count);
1155 TALLOC_FREE(frame);
1156 return true;
1159 /****************************************************************************
1160 Do a netbios name query to find someones IP.
1161 Returns an array of IP addresses or NULL if none.
1162 *count will be set to the number of addresses returned.
1163 *timed_out is set if we failed by timing out
1164 ****************************************************************************/
1166 struct name_query_state {
1167 struct sockaddr_storage my_addr;
1168 struct sockaddr_storage addr;
1169 bool bcast;
1172 uint8_t buf[1024];
1173 ssize_t buflen;
1175 NTSTATUS validate_error;
1176 uint8_t flags;
1178 struct sockaddr_storage *addrs;
1179 int num_addrs;
1182 static bool name_query_validator(struct packet_struct *p, void *private_data);
1183 static void name_query_done(struct tevent_req *subreq);
1185 struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx,
1186 struct tevent_context *ev,
1187 const char *name, int name_type,
1188 bool bcast, bool recurse,
1189 const struct sockaddr_storage *addr)
1191 struct tevent_req *req, *subreq;
1192 struct name_query_state *state;
1193 struct packet_struct p;
1194 struct nmb_packet *nmb = &p.packet.nmb;
1195 struct sockaddr_in *in_addr;
1197 req = tevent_req_create(mem_ctx, &state, struct name_query_state);
1198 if (req == NULL) {
1199 return NULL;
1201 state->bcast = bcast;
1203 if (addr->ss_family != AF_INET) {
1204 /* Can't do node status to IPv6 */
1205 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS);
1206 return tevent_req_post(req, ev);
1209 if (lp_disable_netbios()) {
1210 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
1211 name, name_type));
1212 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
1213 return tevent_req_post(req, ev);
1216 state->addr = *addr;
1217 in_addr = (struct sockaddr_in *)(void *)&state->addr;
1218 in_addr->sin_port = htons(NMB_PORT);
1220 set_socket_addr_v4(&state->my_addr);
1222 ZERO_STRUCT(p);
1223 nmb->header.name_trn_id = generate_trn_id();
1224 nmb->header.opcode = 0;
1225 nmb->header.response = false;
1226 nmb->header.nm_flags.bcast = bcast;
1227 nmb->header.nm_flags.recursion_available = false;
1228 nmb->header.nm_flags.recursion_desired = recurse;
1229 nmb->header.nm_flags.trunc = false;
1230 nmb->header.nm_flags.authoritative = false;
1231 nmb->header.rcode = 0;
1232 nmb->header.qdcount = 1;
1233 nmb->header.ancount = 0;
1234 nmb->header.nscount = 0;
1235 nmb->header.arcount = 0;
1237 make_nmb_name(&nmb->question.question_name,name,name_type);
1239 nmb->question.question_type = 0x20;
1240 nmb->question.question_class = 0x1;
1242 state->buflen = build_packet((char *)state->buf, sizeof(state->buf),
1243 &p);
1244 if (state->buflen == 0) {
1245 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1246 DEBUG(10, ("build_packet failed\n"));
1247 return tevent_req_post(req, ev);
1250 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, bcast,
1251 state->buf, state->buflen,
1252 NMB_PACKET, nmb->header.name_trn_id,
1253 name_query_validator, state);
1254 if (tevent_req_nomem(subreq, req)) {
1255 DEBUG(10, ("nb_trans_send failed\n"));
1256 return tevent_req_post(req, ev);
1258 tevent_req_set_callback(subreq, name_query_done, req);
1259 return req;
1262 static bool name_query_validator(struct packet_struct *p, void *private_data)
1264 struct name_query_state *state = talloc_get_type_abort(
1265 private_data, struct name_query_state);
1266 struct nmb_packet *nmb = &p->packet.nmb;
1267 struct sockaddr_storage *tmp_addrs;
1268 bool got_unique_netbios_name = false;
1269 int i;
1271 debug_nmb_packet(p);
1274 * If we get a Negative Name Query Response from a WINS
1275 * server, we should report it and give up.
1277 if( 0 == nmb->header.opcode /* A query response */
1278 && !state->bcast /* from a WINS server */
1279 && nmb->header.rcode /* Error returned */
1282 if( DEBUGLVL( 3 ) ) {
1283 /* Only executed if DEBUGLEVEL >= 3 */
1284 dbgtext( "Negative name query "
1285 "response, rcode 0x%02x: ",
1286 nmb->header.rcode );
1287 switch( nmb->header.rcode ) {
1288 case 0x01:
1289 dbgtext("Request was invalidly formatted.\n");
1290 break;
1291 case 0x02:
1292 dbgtext("Problem with NBNS, cannot process "
1293 "name.\n");
1294 break;
1295 case 0x03:
1296 dbgtext("The name requested does not "
1297 "exist.\n");
1298 break;
1299 case 0x04:
1300 dbgtext("Unsupported request error.\n");
1301 break;
1302 case 0x05:
1303 dbgtext("Query refused error.\n");
1304 break;
1305 default:
1306 dbgtext("Unrecognized error code.\n" );
1307 break;
1312 * We accept this packet as valid, but tell the upper
1313 * layers that it's a negative response.
1315 state->validate_error = NT_STATUS_NOT_FOUND;
1316 return true;
1319 if (nmb->header.opcode != 0 ||
1320 nmb->header.nm_flags.bcast ||
1321 nmb->header.rcode ||
1322 !nmb->header.ancount) {
1324 * XXXX what do we do with this? Could be a redirect,
1325 * but we'll discard it for the moment.
1327 return false;
1330 tmp_addrs = talloc_realloc(
1331 state, state->addrs, struct sockaddr_storage,
1332 state->num_addrs + nmb->answers->rdlength/6);
1333 if (tmp_addrs == NULL) {
1334 state->validate_error = NT_STATUS_NO_MEMORY;
1335 return true;
1337 state->addrs = tmp_addrs;
1339 DEBUG(2,("Got a positive name query response "
1340 "from %s ( ", inet_ntoa(p->ip)));
1342 for (i=0; i<nmb->answers->rdlength/6; i++) {
1343 uint16_t flags;
1344 struct in_addr ip;
1345 struct sockaddr_storage addr;
1346 int j;
1348 flags = RSVAL(&nmb->answers->rdata[i*6], 0);
1349 got_unique_netbios_name |= ((flags & 0x8000) == 0);
1351 putip((char *)&ip,&nmb->answers->rdata[2+i*6]);
1352 in_addr_to_sockaddr_storage(&addr, ip);
1354 for (j=0; j<state->num_addrs; j++) {
1355 if (sockaddr_equal(
1356 (struct sockaddr *)(void *)&addr,
1357 (struct sockaddr *)(void *)&state->addrs[j])) {
1358 break;
1361 if (j < state->num_addrs) {
1362 /* Already got it */
1363 continue;
1366 DEBUGADD(2,("%s ",inet_ntoa(ip)));
1368 state->addrs[state->num_addrs] = addr;
1369 state->num_addrs += 1;
1371 DEBUGADD(2,(")\n"));
1373 /* We add the flags back ... */
1374 if (nmb->header.response)
1375 state->flags |= NM_FLAGS_RS;
1376 if (nmb->header.nm_flags.authoritative)
1377 state->flags |= NM_FLAGS_AA;
1378 if (nmb->header.nm_flags.trunc)
1379 state->flags |= NM_FLAGS_TC;
1380 if (nmb->header.nm_flags.recursion_desired)
1381 state->flags |= NM_FLAGS_RD;
1382 if (nmb->header.nm_flags.recursion_available)
1383 state->flags |= NM_FLAGS_RA;
1384 if (nmb->header.nm_flags.bcast)
1385 state->flags |= NM_FLAGS_B;
1387 if (state->bcast) {
1389 * We have to collect all entries coming in from broadcast
1390 * queries. If we got a unique name, we're done.
1392 return got_unique_netbios_name;
1395 * WINS responses are accepted when they are received
1397 return true;
1400 static void name_query_done(struct tevent_req *subreq)
1402 struct tevent_req *req = tevent_req_callback_data(
1403 subreq, struct tevent_req);
1404 struct name_query_state *state = tevent_req_data(
1405 req, struct name_query_state);
1406 NTSTATUS status;
1407 struct packet_struct *p = NULL;
1409 status = nb_trans_recv(subreq, &p);
1410 TALLOC_FREE(subreq);
1411 if (tevent_req_nterror(req, status)) {
1412 return;
1414 if (!NT_STATUS_IS_OK(state->validate_error)) {
1415 tevent_req_nterror(req, state->validate_error);
1416 return;
1418 if (p != NULL) {
1420 * Free the packet here, we've collected the response in the
1421 * validator
1423 free_packet(p);
1425 tevent_req_done(req);
1428 NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1429 struct sockaddr_storage **addrs, int *num_addrs,
1430 uint8_t *flags)
1432 struct name_query_state *state = tevent_req_data(
1433 req, struct name_query_state);
1434 NTSTATUS status;
1436 if (tevent_req_is_nterror(req, &status)) {
1437 if (state->bcast &&
1438 NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1440 * In the broadcast case we collect replies until the
1441 * timeout.
1443 status = NT_STATUS_OK;
1445 if (!NT_STATUS_IS_OK(status)) {
1446 return status;
1449 if (state->num_addrs == 0) {
1450 return NT_STATUS_NOT_FOUND;
1452 *addrs = talloc_move(mem_ctx, &state->addrs);
1453 sort_addr_list(*addrs, state->num_addrs);
1454 *num_addrs = state->num_addrs;
1455 if (flags != NULL) {
1456 *flags = state->flags;
1458 return NT_STATUS_OK;
1461 NTSTATUS name_query(const char *name, int name_type,
1462 bool bcast, bool recurse,
1463 const struct sockaddr_storage *to_ss,
1464 TALLOC_CTX *mem_ctx,
1465 struct sockaddr_storage **addrs,
1466 int *num_addrs, uint8_t *flags)
1468 TALLOC_CTX *frame = talloc_stackframe();
1469 struct tevent_context *ev;
1470 struct tevent_req *req;
1471 struct timeval timeout;
1472 NTSTATUS status = NT_STATUS_NO_MEMORY;
1474 ev = tevent_context_init(frame);
1475 if (ev == NULL) {
1476 goto fail;
1478 req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss);
1479 if (req == NULL) {
1480 goto fail;
1482 if (bcast) {
1483 timeout = timeval_current_ofs(0, 250000);
1484 } else {
1485 timeout = timeval_current_ofs(2, 0);
1487 if (!tevent_req_set_endtime(req, ev, timeout)) {
1488 goto fail;
1490 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1491 goto fail;
1493 status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags);
1494 fail:
1495 TALLOC_FREE(frame);
1496 return status;
1499 /********************************************************
1500 convert an array if struct sockaddr_storage to struct ip_service
1501 return false on failure. Port is set to PORT_NONE;
1502 *********************************************************/
1504 static bool convert_ss2service(struct ip_service **return_iplist,
1505 const struct sockaddr_storage *ss_list,
1506 int count)
1508 int i;
1510 if ( count==0 || !ss_list )
1511 return False;
1513 /* copy the ip address; port will be PORT_NONE */
1514 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
1515 NULL) {
1516 DEBUG(0,("convert_ip2service: malloc failed "
1517 "for %d enetries!\n", count ));
1518 return False;
1521 for ( i=0; i<count; i++ ) {
1522 (*return_iplist)[i].ss = ss_list[i];
1523 (*return_iplist)[i].port = PORT_NONE;
1526 return true;
1529 struct name_queries_state {
1530 struct tevent_context *ev;
1531 const char *name;
1532 int name_type;
1533 bool bcast;
1534 bool recurse;
1535 const struct sockaddr_storage *addrs;
1536 int num_addrs;
1537 int wait_msec;
1538 int timeout_msec;
1540 struct tevent_req **subreqs;
1541 int num_received;
1542 int num_sent;
1544 int received_index;
1545 struct sockaddr_storage *result_addrs;
1546 int num_result_addrs;
1547 uint8_t flags;
1550 static void name_queries_done(struct tevent_req *subreq);
1551 static void name_queries_next(struct tevent_req *subreq);
1554 * Send a name query to multiple destinations with a wait time in between
1557 static struct tevent_req *name_queries_send(
1558 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1559 const char *name, int name_type,
1560 bool bcast, bool recurse,
1561 const struct sockaddr_storage *addrs,
1562 int num_addrs, int wait_msec, int timeout_msec)
1564 struct tevent_req *req, *subreq;
1565 struct name_queries_state *state;
1567 req = tevent_req_create(mem_ctx, &state,
1568 struct name_queries_state);
1569 if (req == NULL) {
1570 return NULL;
1572 state->ev = ev;
1573 state->name = name;
1574 state->name_type = name_type;
1575 state->bcast = bcast;
1576 state->recurse = recurse;
1577 state->addrs = addrs;
1578 state->num_addrs = num_addrs;
1579 state->wait_msec = wait_msec;
1580 state->timeout_msec = timeout_msec;
1582 state->subreqs = talloc_zero_array(
1583 state, struct tevent_req *, num_addrs);
1584 if (tevent_req_nomem(state->subreqs, req)) {
1585 return tevent_req_post(req, ev);
1587 state->num_sent = 0;
1589 subreq = name_query_send(
1590 state->subreqs, state->ev, name, name_type, bcast, recurse,
1591 &state->addrs[state->num_sent]);
1592 if (tevent_req_nomem(subreq, req)) {
1593 return tevent_req_post(req, ev);
1595 if (!tevent_req_set_endtime(
1596 subreq, state->ev,
1597 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1598 tevent_req_oom(req);
1599 return tevent_req_post(req, ev);
1601 tevent_req_set_callback(subreq, name_queries_done, req);
1603 state->subreqs[state->num_sent] = subreq;
1604 state->num_sent += 1;
1606 if (state->num_sent < state->num_addrs) {
1607 subreq = tevent_wakeup_send(
1608 state, state->ev,
1609 timeval_current_ofs(0, state->wait_msec * 1000));
1610 if (tevent_req_nomem(subreq, req)) {
1611 return tevent_req_post(req, ev);
1613 tevent_req_set_callback(subreq, name_queries_next, req);
1615 return req;
1618 static void name_queries_done(struct tevent_req *subreq)
1620 struct tevent_req *req = tevent_req_callback_data(
1621 subreq, struct tevent_req);
1622 struct name_queries_state *state = tevent_req_data(
1623 req, struct name_queries_state);
1624 int i;
1625 NTSTATUS status;
1627 status = name_query_recv(subreq, state, &state->result_addrs,
1628 &state->num_result_addrs, &state->flags);
1630 for (i=0; i<state->num_sent; i++) {
1631 if (state->subreqs[i] == subreq) {
1632 break;
1635 if (i == state->num_sent) {
1636 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1637 return;
1639 TALLOC_FREE(state->subreqs[i]);
1641 state->num_received += 1;
1643 if (!NT_STATUS_IS_OK(status)) {
1645 if (state->num_received >= state->num_addrs) {
1646 tevent_req_nterror(req, status);
1647 return;
1650 * Still outstanding requests, just wait
1652 return;
1654 state->received_index = i;
1655 tevent_req_done(req);
1658 static void name_queries_next(struct tevent_req *subreq)
1660 struct tevent_req *req = tevent_req_callback_data(
1661 subreq, struct tevent_req);
1662 struct name_queries_state *state = tevent_req_data(
1663 req, struct name_queries_state);
1665 if (!tevent_wakeup_recv(subreq)) {
1666 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1667 return;
1670 subreq = name_query_send(
1671 state->subreqs, state->ev,
1672 state->name, state->name_type, state->bcast, state->recurse,
1673 &state->addrs[state->num_sent]);
1674 if (tevent_req_nomem(subreq, req)) {
1675 return;
1677 tevent_req_set_callback(subreq, name_queries_done, req);
1678 if (!tevent_req_set_endtime(
1679 subreq, state->ev,
1680 timeval_current_ofs(0, state->timeout_msec * 1000))) {
1681 tevent_req_oom(req);
1682 return;
1684 state->subreqs[state->num_sent] = subreq;
1685 state->num_sent += 1;
1687 if (state->num_sent < state->num_addrs) {
1688 subreq = tevent_wakeup_send(
1689 state, state->ev,
1690 timeval_current_ofs(0, state->wait_msec * 1000));
1691 if (tevent_req_nomem(subreq, req)) {
1692 return;
1694 tevent_req_set_callback(subreq, name_queries_next, req);
1698 static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1699 struct sockaddr_storage **result_addrs,
1700 int *num_result_addrs, uint8_t *flags,
1701 int *received_index)
1703 struct name_queries_state *state = tevent_req_data(
1704 req, struct name_queries_state);
1705 NTSTATUS status;
1707 if (tevent_req_is_nterror(req, &status)) {
1708 return status;
1711 if (result_addrs != NULL) {
1712 *result_addrs = talloc_move(mem_ctx, &state->result_addrs);
1714 if (num_result_addrs != NULL) {
1715 *num_result_addrs = state->num_result_addrs;
1717 if (flags != NULL) {
1718 *flags = state->flags;
1720 if (received_index != NULL) {
1721 *received_index = state->received_index;
1723 return NT_STATUS_OK;
1726 /********************************************************
1727 Resolve via "bcast" method.
1728 *********************************************************/
1730 struct name_resolve_bcast_state {
1731 struct sockaddr_storage *addrs;
1732 int num_addrs;
1735 static void name_resolve_bcast_done(struct tevent_req *subreq);
1737 struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx,
1738 struct tevent_context *ev,
1739 const char *name,
1740 int name_type)
1742 struct tevent_req *req, *subreq;
1743 struct name_resolve_bcast_state *state;
1744 struct sockaddr_storage *bcast_addrs;
1745 int i, num_addrs, num_bcast_addrs;
1747 req = tevent_req_create(mem_ctx, &state,
1748 struct name_resolve_bcast_state);
1749 if (req == NULL) {
1750 return NULL;
1753 if (lp_disable_netbios()) {
1754 DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n",
1755 name, name_type));
1756 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1757 return tevent_req_post(req, ev);
1761 * "bcast" means do a broadcast lookup on all the local interfaces.
1764 DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup "
1765 "for name %s<0x%x>\n", name, name_type));
1767 num_addrs = iface_count();
1768 bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs);
1769 if (tevent_req_nomem(bcast_addrs, req)) {
1770 return tevent_req_post(req, ev);
1774 * Lookup the name on all the interfaces, return on
1775 * the first successful match.
1777 num_bcast_addrs = 0;
1779 for (i=0; i<num_addrs; i++) {
1780 const struct sockaddr_storage *pss = iface_n_bcast(i);
1782 if (pss->ss_family != AF_INET) {
1783 continue;
1785 bcast_addrs[num_bcast_addrs] = *pss;
1786 num_bcast_addrs += 1;
1789 subreq = name_queries_send(state, ev, name, name_type, true, true,
1790 bcast_addrs, num_bcast_addrs, 0, 1000);
1791 if (tevent_req_nomem(subreq, req)) {
1792 return tevent_req_post(req, ev);
1794 tevent_req_set_callback(subreq, name_resolve_bcast_done, req);
1795 return req;
1798 static void name_resolve_bcast_done(struct tevent_req *subreq)
1800 struct tevent_req *req = tevent_req_callback_data(
1801 subreq, struct tevent_req);
1802 struct name_resolve_bcast_state *state = tevent_req_data(
1803 req, struct name_resolve_bcast_state);
1804 NTSTATUS status;
1806 status = name_queries_recv(subreq, state,
1807 &state->addrs, &state->num_addrs,
1808 NULL, NULL);
1809 TALLOC_FREE(subreq);
1810 if (tevent_req_nterror(req, status)) {
1811 return;
1813 tevent_req_done(req);
1816 NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1817 struct sockaddr_storage **addrs,
1818 int *num_addrs)
1820 struct name_resolve_bcast_state *state = tevent_req_data(
1821 req, struct name_resolve_bcast_state);
1822 NTSTATUS status;
1824 if (tevent_req_is_nterror(req, &status)) {
1825 return status;
1827 *addrs = talloc_move(mem_ctx, &state->addrs);
1828 *num_addrs = state->num_addrs;
1829 return NT_STATUS_OK;
1832 NTSTATUS name_resolve_bcast(const char *name,
1833 int name_type,
1834 TALLOC_CTX *mem_ctx,
1835 struct sockaddr_storage **return_iplist,
1836 int *return_count)
1838 TALLOC_CTX *frame = talloc_stackframe();
1839 struct event_context *ev;
1840 struct tevent_req *req;
1841 NTSTATUS status = NT_STATUS_NO_MEMORY;
1843 ev = event_context_init(frame);
1844 if (ev == NULL) {
1845 goto fail;
1847 req = name_resolve_bcast_send(frame, ev, name, name_type);
1848 if (req == NULL) {
1849 goto fail;
1851 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
1852 goto fail;
1854 status = name_resolve_bcast_recv(req, mem_ctx, return_iplist,
1855 return_count);
1856 fail:
1857 TALLOC_FREE(frame);
1858 return status;
1861 struct query_wins_list_state {
1862 struct tevent_context *ev;
1863 const char *name;
1864 uint8_t name_type;
1865 struct in_addr *servers;
1866 uint32_t num_servers;
1867 struct sockaddr_storage server;
1868 uint32_t num_sent;
1870 struct sockaddr_storage *addrs;
1871 int num_addrs;
1872 uint8_t flags;
1875 static void query_wins_list_done(struct tevent_req *subreq);
1878 * Query a list of (replicating) wins servers in sequence, call them
1879 * dead if they don't reply
1882 static struct tevent_req *query_wins_list_send(
1883 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
1884 struct in_addr src_ip, const char *name, uint8_t name_type,
1885 struct in_addr *servers, int num_servers)
1887 struct tevent_req *req, *subreq;
1888 struct query_wins_list_state *state;
1890 req = tevent_req_create(mem_ctx, &state,
1891 struct query_wins_list_state);
1892 if (req == NULL) {
1893 return NULL;
1895 state->ev = ev;
1896 state->name = name;
1897 state->name_type = name_type;
1898 state->servers = servers;
1899 state->num_servers = num_servers;
1901 if (state->num_servers == 0) {
1902 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
1903 return tevent_req_post(req, ev);
1906 in_addr_to_sockaddr_storage(
1907 &state->server, state->servers[state->num_sent]);
1909 subreq = name_query_send(state, state->ev,
1910 state->name, state->name_type,
1911 false, true, &state->server);
1912 state->num_sent += 1;
1913 if (tevent_req_nomem(subreq, req)) {
1914 return tevent_req_post(req, ev);
1916 if (!tevent_req_set_endtime(subreq, state->ev,
1917 timeval_current_ofs(2, 0))) {
1918 tevent_req_oom(req);
1919 return tevent_req_post(req, ev);
1921 tevent_req_set_callback(subreq, query_wins_list_done, req);
1922 return req;
1925 static void query_wins_list_done(struct tevent_req *subreq)
1927 struct tevent_req *req = tevent_req_callback_data(
1928 subreq, struct tevent_req);
1929 struct query_wins_list_state *state = tevent_req_data(
1930 req, struct query_wins_list_state);
1931 NTSTATUS status;
1933 status = name_query_recv(subreq, state,
1934 &state->addrs, &state->num_addrs,
1935 &state->flags);
1936 TALLOC_FREE(subreq);
1937 if (NT_STATUS_IS_OK(status)) {
1938 tevent_req_done(req);
1939 return;
1941 if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1942 tevent_req_nterror(req, status);
1943 return;
1945 wins_srv_died(state->servers[state->num_sent-1],
1946 my_socket_addr_v4());
1948 if (state->num_sent == state->num_servers) {
1949 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
1950 return;
1953 in_addr_to_sockaddr_storage(
1954 &state->server, state->servers[state->num_sent]);
1956 subreq = name_query_send(state, state->ev,
1957 state->name, state->name_type,
1958 false, true, &state->server);
1959 state->num_sent += 1;
1960 if (tevent_req_nomem(subreq, req)) {
1961 return;
1963 if (!tevent_req_set_endtime(subreq, state->ev,
1964 timeval_current_ofs(2, 0))) {
1965 tevent_req_oom(req);
1966 return;
1968 tevent_req_set_callback(subreq, query_wins_list_done, req);
1971 static NTSTATUS query_wins_list_recv(struct tevent_req *req,
1972 TALLOC_CTX *mem_ctx,
1973 struct sockaddr_storage **addrs,
1974 int *num_addrs,
1975 uint8_t *flags)
1977 struct query_wins_list_state *state = tevent_req_data(
1978 req, struct query_wins_list_state);
1979 NTSTATUS status;
1981 if (tevent_req_is_nterror(req, &status)) {
1982 return status;
1984 if (addrs != NULL) {
1985 *addrs = talloc_move(mem_ctx, &state->addrs);
1987 if (num_addrs != NULL) {
1988 *num_addrs = state->num_addrs;
1990 if (flags != NULL) {
1991 *flags = state->flags;
1993 return NT_STATUS_OK;
1996 struct resolve_wins_state {
1997 int num_sent;
1998 int num_received;
2000 struct sockaddr_storage *addrs;
2001 int num_addrs;
2002 uint8_t flags;
2005 static void resolve_wins_done(struct tevent_req *subreq);
2007 struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
2008 struct tevent_context *ev,
2009 const char *name,
2010 int name_type)
2012 struct tevent_req *req, *subreq;
2013 struct resolve_wins_state *state;
2014 char **wins_tags = NULL;
2015 struct sockaddr_storage src_ss;
2016 struct in_addr src_ip;
2017 int i, num_wins_tags;
2019 req = tevent_req_create(mem_ctx, &state,
2020 struct resolve_wins_state);
2021 if (req == NULL) {
2022 return NULL;
2025 if (wins_srv_count() < 1) {
2026 DEBUG(3,("resolve_wins: WINS server resolution selected "
2027 "and no WINS servers listed.\n"));
2028 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2029 goto fail;
2032 /* the address we will be sending from */
2033 if (!interpret_string_addr(&src_ss, lp_socket_address(),
2034 AI_NUMERICHOST|AI_PASSIVE)) {
2035 zero_sockaddr(&src_ss);
2038 if (src_ss.ss_family != AF_INET) {
2039 char addr[INET6_ADDRSTRLEN];
2040 print_sockaddr(addr, sizeof(addr), &src_ss);
2041 DEBUG(3,("resolve_wins: cannot receive WINS replies "
2042 "on IPv6 address %s\n",
2043 addr));
2044 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2045 goto fail;
2048 src_ip = ((const struct sockaddr_in *)(void *)&src_ss)->sin_addr;
2050 wins_tags = wins_srv_tags();
2051 if (wins_tags == NULL) {
2052 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2053 goto fail;
2056 num_wins_tags = 0;
2057 while (wins_tags[num_wins_tags] != NULL) {
2058 num_wins_tags += 1;
2061 for (i=0; i<num_wins_tags; i++) {
2062 int num_servers, num_alive;
2063 struct in_addr *servers, *alive;
2064 int j;
2066 if (!wins_server_tag_ips(wins_tags[i], talloc_tos(),
2067 &servers, &num_servers)) {
2068 DEBUG(10, ("wins_server_tag_ips failed for tag %s\n",
2069 wins_tags[i]));
2070 continue;
2073 alive = talloc_array(state, struct in_addr, num_servers);
2074 if (tevent_req_nomem(alive, req)) {
2075 goto fail;
2078 num_alive = 0;
2079 for (j=0; j<num_servers; j++) {
2080 struct in_addr wins_ip = servers[j];
2082 if (global_in_nmbd && ismyip_v4(wins_ip)) {
2083 /* yikes! we'll loop forever */
2084 continue;
2086 /* skip any that have been unresponsive lately */
2087 if (wins_srv_is_dead(wins_ip, src_ip)) {
2088 continue;
2090 DEBUG(3, ("resolve_wins: using WINS server %s "
2091 "and tag '%s'\n",
2092 inet_ntoa(wins_ip), wins_tags[i]));
2093 alive[num_alive] = wins_ip;
2094 num_alive += 1;
2096 TALLOC_FREE(servers);
2098 if (num_alive == 0) {
2099 continue;
2102 subreq = query_wins_list_send(
2103 state, ev, src_ip, name, name_type,
2104 alive, num_alive);
2105 if (tevent_req_nomem(subreq, req)) {
2106 goto fail;
2108 tevent_req_set_callback(subreq, resolve_wins_done, req);
2109 state->num_sent += 1;
2112 if (state->num_sent == 0) {
2113 tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
2114 goto fail;
2117 wins_srv_tags_free(wins_tags);
2118 return req;
2119 fail:
2120 wins_srv_tags_free(wins_tags);
2121 return tevent_req_post(req, ev);
2124 static void resolve_wins_done(struct tevent_req *subreq)
2126 struct tevent_req *req = tevent_req_callback_data(
2127 subreq, struct tevent_req);
2128 struct resolve_wins_state *state = tevent_req_data(
2129 req, struct resolve_wins_state);
2130 NTSTATUS status;
2132 status = query_wins_list_recv(subreq, state, &state->addrs,
2133 &state->num_addrs, &state->flags);
2134 if (NT_STATUS_IS_OK(status)) {
2135 tevent_req_done(req);
2136 return;
2139 state->num_received += 1;
2141 if (state->num_received < state->num_sent) {
2143 * Wait for the others
2145 return;
2147 tevent_req_nterror(req, status);
2150 NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2151 struct sockaddr_storage **addrs,
2152 int *num_addrs, uint8_t *flags)
2154 struct resolve_wins_state *state = tevent_req_data(
2155 req, struct resolve_wins_state);
2156 NTSTATUS status;
2158 if (tevent_req_is_nterror(req, &status)) {
2159 return status;
2161 if (addrs != NULL) {
2162 *addrs = talloc_move(mem_ctx, &state->addrs);
2164 if (num_addrs != NULL) {
2165 *num_addrs = state->num_addrs;
2167 if (flags != NULL) {
2168 *flags = state->flags;
2170 return NT_STATUS_OK;
2173 /********************************************************
2174 Resolve via "wins" method.
2175 *********************************************************/
2177 NTSTATUS resolve_wins(const char *name,
2178 int name_type,
2179 TALLOC_CTX *mem_ctx,
2180 struct sockaddr_storage **return_iplist,
2181 int *return_count)
2183 struct tevent_context *ev;
2184 struct tevent_req *req;
2185 NTSTATUS status = NT_STATUS_NO_MEMORY;
2187 ev = tevent_context_init(talloc_tos());
2188 if (ev == NULL) {
2189 goto fail;
2191 req = resolve_wins_send(ev, ev, name, name_type);
2192 if (req == NULL) {
2193 goto fail;
2195 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2196 goto fail;
2198 status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count,
2199 NULL);
2200 fail:
2201 TALLOC_FREE(ev);
2202 return status;
2205 /********************************************************
2206 Resolve via "lmhosts" method.
2207 *********************************************************/
2209 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
2210 struct ip_service **return_iplist,
2211 int *return_count)
2214 * "lmhosts" means parse the local lmhosts file.
2216 struct sockaddr_storage *ss_list;
2217 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2218 TALLOC_CTX *ctx = NULL;
2220 *return_iplist = NULL;
2221 *return_count = 0;
2223 DEBUG(3,("resolve_lmhosts: "
2224 "Attempting lmhosts lookup for name %s<0x%x>\n",
2225 name, name_type));
2227 ctx = talloc_init("resolve_lmhosts");
2228 if (!ctx) {
2229 return NT_STATUS_NO_MEMORY;
2232 status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(),
2233 name, name_type,
2234 ctx,
2235 &ss_list,
2236 return_count);
2237 if (NT_STATUS_IS_OK(status)) {
2238 if (convert_ss2service(return_iplist,
2239 ss_list,
2240 *return_count)) {
2241 talloc_free(ctx);
2242 return NT_STATUS_OK;
2243 } else {
2244 talloc_free(ctx);
2245 return NT_STATUS_NO_MEMORY;
2248 talloc_free(ctx);
2249 return status;
2253 /********************************************************
2254 Resolve via "hosts" method.
2255 *********************************************************/
2257 static NTSTATUS resolve_hosts(const char *name, int name_type,
2258 struct ip_service **return_iplist,
2259 int *return_count)
2262 * "host" means do a localhost, or dns lookup.
2264 struct addrinfo hints;
2265 struct addrinfo *ailist = NULL;
2266 struct addrinfo *res = NULL;
2267 int ret = -1;
2268 int i = 0;
2269 const char *dns_hosts_file;
2271 if ( name_type != 0x20 && name_type != 0x0) {
2272 DEBUG(5, ("resolve_hosts: not appropriate "
2273 "for name type <0x%x>\n",
2274 name_type));
2275 return NT_STATUS_INVALID_PARAMETER;
2278 *return_iplist = NULL;
2279 *return_count = 0;
2281 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
2282 name, name_type));
2284 ZERO_STRUCT(hints);
2285 /* By default make sure it supports TCP. */
2286 hints.ai_socktype = SOCK_STREAM;
2287 hints.ai_flags = AI_ADDRCONFIG;
2289 #if !defined(HAVE_IPV6)
2290 /* Unless we have IPv6, we really only want IPv4 addresses back. */
2291 hints.ai_family = AF_INET;
2292 #endif
2294 dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL);
2295 if (dns_hosts_file) {
2296 struct sockaddr_storage *ss_list;
2297 NTSTATUS status;
2298 TALLOC_CTX *ctx = talloc_stackframe();
2299 if (!ctx) {
2300 return NT_STATUS_NO_MEMORY;
2303 status = resolve_dns_hosts_file_as_sockaddr(dns_hosts_file, name, false,
2304 ctx, &ss_list, return_count);
2305 if (NT_STATUS_IS_OK(status)) {
2306 if (convert_ss2service(return_iplist,
2307 ss_list,
2308 *return_count)) {
2309 talloc_free(ctx);
2310 return NT_STATUS_OK;
2311 } else {
2312 talloc_free(ctx);
2313 return NT_STATUS_NO_MEMORY;
2316 talloc_free(ctx);
2317 return NT_STATUS_UNSUCCESSFUL;
2320 ret = getaddrinfo(name,
2321 NULL,
2322 &hints,
2323 &ailist);
2324 if (ret) {
2325 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
2326 name,
2327 gai_strerror(ret) ));
2330 for (res = ailist; res; res = res->ai_next) {
2331 struct sockaddr_storage ss;
2333 if (!res->ai_addr || res->ai_addrlen == 0) {
2334 continue;
2337 ZERO_STRUCT(ss);
2338 memcpy(&ss, res->ai_addr, res->ai_addrlen);
2340 *return_count += 1;
2342 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
2343 struct ip_service,
2344 *return_count);
2345 if (!*return_iplist) {
2346 DEBUG(3,("resolve_hosts: malloc fail !\n"));
2347 freeaddrinfo(ailist);
2348 return NT_STATUS_NO_MEMORY;
2350 (*return_iplist)[i].ss = ss;
2351 (*return_iplist)[i].port = PORT_NONE;
2352 i++;
2354 if (ailist) {
2355 freeaddrinfo(ailist);
2357 if (*return_count) {
2358 return NT_STATUS_OK;
2360 return NT_STATUS_UNSUCCESSFUL;
2363 /********************************************************
2364 Resolve via "ADS" method.
2365 *********************************************************/
2367 /* Special name type used to cause a _kerberos DNS lookup. */
2368 #define KDC_NAME_TYPE 0xDCDC
2370 static NTSTATUS resolve_ads(const char *name,
2371 int name_type,
2372 const char *sitename,
2373 struct ip_service **return_iplist,
2374 int *return_count)
2376 int i, j;
2377 NTSTATUS status;
2378 TALLOC_CTX *ctx;
2379 struct dns_rr_srv *dcs = NULL;
2380 int numdcs = 0;
2381 int numaddrs = 0;
2383 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
2384 (name_type != 0x1b)) {
2385 return NT_STATUS_INVALID_PARAMETER;
2388 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
2389 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
2390 return NT_STATUS_NO_MEMORY;
2393 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
2395 switch (name_type) {
2396 case 0x1b:
2397 DEBUG(5,("resolve_ads: Attempting to resolve "
2398 "PDC for %s using DNS\n", name));
2399 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
2400 break;
2402 case 0x1c:
2403 DEBUG(5,("resolve_ads: Attempting to resolve "
2404 "DCs for %s using DNS\n", name));
2405 status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
2406 &numdcs);
2407 break;
2408 case KDC_NAME_TYPE:
2409 DEBUG(5,("resolve_ads: Attempting to resolve "
2410 "KDCs for %s using DNS\n", name));
2411 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
2412 &numdcs);
2413 break;
2414 default:
2415 status = NT_STATUS_INVALID_PARAMETER;
2416 break;
2419 if ( !NT_STATUS_IS_OK( status ) ) {
2420 talloc_destroy(ctx);
2421 return status;
2424 for (i=0;i<numdcs;i++) {
2425 numaddrs += MAX(dcs[i].num_ips,1);
2428 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
2429 NULL ) {
2430 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
2431 numaddrs ));
2432 talloc_destroy(ctx);
2433 return NT_STATUS_NO_MEMORY;
2436 /* now unroll the list of IP addresses */
2438 *return_count = 0;
2439 i = 0;
2440 j = 0;
2441 while ( i < numdcs && (*return_count<numaddrs) ) {
2442 struct ip_service *r = &(*return_iplist)[*return_count];
2444 r->port = dcs[i].port;
2446 /* If we don't have an IP list for a name, lookup it up */
2448 if (!dcs[i].ss_s) {
2449 interpret_string_addr(&r->ss, dcs[i].hostname, 0);
2450 i++;
2451 j = 0;
2452 } else {
2453 /* use the IP addresses from the SRV sresponse */
2455 if ( j >= dcs[i].num_ips ) {
2456 i++;
2457 j = 0;
2458 continue;
2461 r->ss = dcs[i].ss_s[j];
2462 j++;
2465 /* make sure it is a valid IP. I considered checking the
2466 * negative connection cache, but this is the wrong place
2467 * for it. Maybe only as a hack. After think about it, if
2468 * all of the IP addresses returned from DNS are dead, what
2469 * hope does a netbios name lookup have ? The standard reason
2470 * for falling back to netbios lookups is that our DNS server
2471 * doesn't know anything about the DC's -- jerry */
2473 if (!is_zero_addr(&r->ss)) {
2474 (*return_count)++;
2478 talloc_destroy(ctx);
2479 return NT_STATUS_OK;
2482 /*******************************************************************
2483 Internal interface to resolve a name into an IP address.
2484 Use this function if the string is either an IP address, DNS
2485 or host name or NetBIOS name. This uses the name switch in the
2486 smb.conf to determine the order of name resolution.
2488 Added support for ip addr/port to support ADS ldap servers.
2489 the only place we currently care about the port is in the
2490 resolve_hosts() when looking up DC's via SRV RR entries in DNS
2491 **********************************************************************/
2493 NTSTATUS internal_resolve_name(const char *name,
2494 int name_type,
2495 const char *sitename,
2496 struct ip_service **return_iplist,
2497 int *return_count,
2498 const char *resolve_order)
2500 char *tok;
2501 const char *ptr;
2502 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2503 int i;
2504 TALLOC_CTX *frame = NULL;
2506 *return_iplist = NULL;
2507 *return_count = 0;
2509 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
2510 name, name_type, sitename ? sitename : "(null)"));
2512 if (is_ipaddress(name)) {
2513 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
2514 NULL) {
2515 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
2516 return NT_STATUS_NO_MEMORY;
2519 /* ignore the port here */
2520 (*return_iplist)->port = PORT_NONE;
2522 /* if it's in the form of an IP address then get the lib to interpret it */
2523 if (!interpret_string_addr(&(*return_iplist)->ss,
2524 name, AI_NUMERICHOST)) {
2525 DEBUG(1,("internal_resolve_name: interpret_string_addr "
2526 "failed on %s\n",
2527 name));
2528 SAFE_FREE(*return_iplist);
2529 return NT_STATUS_INVALID_PARAMETER;
2531 *return_count = 1;
2532 return NT_STATUS_OK;
2535 /* Check name cache */
2537 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
2538 /* This could be a negative response */
2539 if (*return_count > 0) {
2540 return NT_STATUS_OK;
2541 } else {
2542 return NT_STATUS_UNSUCCESSFUL;
2546 /* set the name resolution order */
2548 if (strcmp( resolve_order, "NULL") == 0) {
2549 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
2550 return NT_STATUS_INVALID_PARAMETER;
2553 if (!resolve_order[0]) {
2554 ptr = "host";
2555 } else {
2556 ptr = resolve_order;
2559 /* iterate through the name resolution backends */
2561 frame = talloc_stackframe();
2562 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
2563 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
2564 status = resolve_hosts(name, name_type, return_iplist,
2565 return_count);
2566 if (NT_STATUS_IS_OK(status)) {
2567 goto done;
2569 } else if(strequal( tok, "kdc")) {
2570 /* deal with KDC_NAME_TYPE names here.
2571 * This will result in a SRV record lookup */
2572 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
2573 return_iplist, return_count);
2574 if (NT_STATUS_IS_OK(status)) {
2575 /* Ensure we don't namecache
2576 * this with the KDC port. */
2577 name_type = KDC_NAME_TYPE;
2578 goto done;
2580 } else if(strequal( tok, "ads")) {
2581 /* deal with 0x1c and 0x1b names here.
2582 * This will result in a SRV record lookup */
2583 status = resolve_ads(name, name_type, sitename,
2584 return_iplist, return_count);
2585 if (NT_STATUS_IS_OK(status)) {
2586 goto done;
2588 } else if(strequal( tok, "lmhosts")) {
2589 status = resolve_lmhosts(name, name_type,
2590 return_iplist, return_count);
2591 if (NT_STATUS_IS_OK(status)) {
2592 goto done;
2594 } else if(strequal( tok, "wins")) {
2595 /* don't resolve 1D via WINS */
2596 struct sockaddr_storage *ss_list;
2597 if (name_type != 0x1D) {
2598 status = resolve_wins(name, name_type,
2599 talloc_tos(),
2600 &ss_list,
2601 return_count);
2602 if (NT_STATUS_IS_OK(status)) {
2603 if (!convert_ss2service(return_iplist,
2604 ss_list,
2605 *return_count)) {
2606 status = NT_STATUS_NO_MEMORY;
2608 goto done;
2611 } else if(strequal( tok, "bcast")) {
2612 struct sockaddr_storage *ss_list;
2613 status = name_resolve_bcast(
2614 name, name_type, talloc_tos(),
2615 &ss_list, return_count);
2616 if (NT_STATUS_IS_OK(status)) {
2617 if (!convert_ss2service(return_iplist,
2618 ss_list,
2619 *return_count)) {
2620 status = NT_STATUS_NO_MEMORY;
2622 goto done;
2624 } else {
2625 DEBUG(0,("resolve_name: unknown name switch type %s\n",
2626 tok));
2630 /* All of the resolve_* functions above have returned false. */
2632 TALLOC_FREE(frame);
2633 SAFE_FREE(*return_iplist);
2634 *return_count = 0;
2636 return NT_STATUS_UNSUCCESSFUL;
2638 done:
2640 /* Remove duplicate entries. Some queries, notably #1c (domain
2641 controllers) return the PDC in iplist[0] and then all domain
2642 controllers including the PDC in iplist[1..n]. Iterating over
2643 the iplist when the PDC is down will cause two sets of timeouts. */
2645 if ( *return_count ) {
2646 *return_count = remove_duplicate_addrs2(*return_iplist,
2647 *return_count );
2650 /* Save in name cache */
2651 if ( DEBUGLEVEL >= 100 ) {
2652 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
2653 char addr[INET6_ADDRSTRLEN];
2654 print_sockaddr(addr, sizeof(addr),
2655 &(*return_iplist)[i].ss);
2656 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
2657 name,
2658 name_type,
2659 addr,
2660 (*return_iplist)[i].port));
2664 namecache_store(name, name_type, *return_count, *return_iplist);
2666 /* Display some debugging info */
2668 if ( DEBUGLEVEL >= 10 ) {
2669 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
2670 *return_count));
2672 for (i = 0; i < *return_count; i++) {
2673 char addr[INET6_ADDRSTRLEN];
2674 print_sockaddr(addr, sizeof(addr),
2675 &(*return_iplist)[i].ss);
2676 DEBUGADD(10, ("%s:%d ",
2677 addr,
2678 (*return_iplist)[i].port));
2680 DEBUG(10, ("\n"));
2683 TALLOC_FREE(frame);
2684 return status;
2687 /********************************************************
2688 Internal interface to resolve a name into one IP address.
2689 Use this function if the string is either an IP address, DNS
2690 or host name or NetBIOS name. This uses the name switch in the
2691 smb.conf to determine the order of name resolution.
2692 *********************************************************/
2694 bool resolve_name(const char *name,
2695 struct sockaddr_storage *return_ss,
2696 int name_type,
2697 bool prefer_ipv4)
2699 struct ip_service *ss_list = NULL;
2700 char *sitename = NULL;
2701 int count = 0;
2703 if (is_ipaddress(name)) {
2704 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
2707 sitename = sitename_fetch(lp_realm()); /* wild guess */
2709 if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
2710 &ss_list, &count,
2711 lp_name_resolve_order()))) {
2712 int i;
2714 if (prefer_ipv4) {
2715 for (i=0; i<count; i++) {
2716 if (!is_zero_addr(&ss_list[i].ss) &&
2717 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss) &&
2718 (ss_list[i].ss.ss_family == AF_INET)) {
2719 *return_ss = ss_list[i].ss;
2720 SAFE_FREE(ss_list);
2721 SAFE_FREE(sitename);
2722 return True;
2727 /* only return valid addresses for TCP connections */
2728 for (i=0; i<count; i++) {
2729 if (!is_zero_addr(&ss_list[i].ss) &&
2730 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2731 *return_ss = ss_list[i].ss;
2732 SAFE_FREE(ss_list);
2733 SAFE_FREE(sitename);
2734 return True;
2739 SAFE_FREE(ss_list);
2740 SAFE_FREE(sitename);
2741 return False;
2744 /********************************************************
2745 Internal interface to resolve a name into a list of IP addresses.
2746 Use this function if the string is either an IP address, DNS
2747 or host name or NetBIOS name. This uses the name switch in the
2748 smb.conf to determine the order of name resolution.
2749 *********************************************************/
2751 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
2752 const char *name,
2753 int name_type,
2754 struct sockaddr_storage **return_ss_arr,
2755 unsigned int *p_num_entries)
2757 struct ip_service *ss_list = NULL;
2758 char *sitename = NULL;
2759 int count = 0;
2760 int i;
2761 unsigned int num_entries;
2762 NTSTATUS status;
2764 *p_num_entries = 0;
2765 *return_ss_arr = NULL;
2767 if (is_ipaddress(name)) {
2768 *return_ss_arr = talloc(ctx, struct sockaddr_storage);
2769 if (!*return_ss_arr) {
2770 return NT_STATUS_NO_MEMORY;
2772 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
2773 TALLOC_FREE(*return_ss_arr);
2774 return NT_STATUS_BAD_NETWORK_NAME;
2776 *p_num_entries = 1;
2777 return NT_STATUS_OK;
2780 sitename = sitename_fetch(lp_realm()); /* wild guess */
2782 status = internal_resolve_name(name, name_type, sitename,
2783 &ss_list, &count,
2784 lp_name_resolve_order());
2785 SAFE_FREE(sitename);
2787 if (!NT_STATUS_IS_OK(status)) {
2788 return status;
2791 /* only return valid addresses for TCP connections */
2792 for (i=0, num_entries = 0; i<count; i++) {
2793 if (!is_zero_addr(&ss_list[i].ss) &&
2794 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) {
2795 num_entries++;
2798 if (num_entries == 0) {
2799 SAFE_FREE(ss_list);
2800 return NT_STATUS_BAD_NETWORK_NAME;
2803 *return_ss_arr = talloc_array(ctx,
2804 struct sockaddr_storage,
2805 num_entries);
2806 if (!(*return_ss_arr)) {
2807 SAFE_FREE(ss_list);
2808 return NT_STATUS_NO_MEMORY;
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 (*return_ss_arr)[num_entries++] = ss_list[i].ss;
2818 status = NT_STATUS_OK;
2819 *p_num_entries = num_entries;
2821 SAFE_FREE(ss_list);
2822 return NT_STATUS_OK;
2825 /********************************************************
2826 Find the IP address of the master browser or DMB for a workgroup.
2827 *********************************************************/
2829 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
2831 struct ip_service *ip_list = NULL;
2832 int count = 0;
2833 NTSTATUS status;
2835 if (lp_disable_netbios()) {
2836 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
2837 return false;
2840 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
2841 lp_name_resolve_order());
2842 if (NT_STATUS_IS_OK(status)) {
2843 *master_ss = ip_list[0].ss;
2844 SAFE_FREE(ip_list);
2845 return true;
2848 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
2849 lp_name_resolve_order());
2850 if (NT_STATUS_IS_OK(status)) {
2851 *master_ss = ip_list[0].ss;
2852 SAFE_FREE(ip_list);
2853 return true;
2856 SAFE_FREE(ip_list);
2857 return false;
2860 /********************************************************
2861 Get the IP address list of the primary domain controller
2862 for a domain.
2863 *********************************************************/
2865 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
2867 struct ip_service *ip_list = NULL;
2868 int count = 0;
2869 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2871 /* Look up #1B name */
2873 if (lp_security() == SEC_ADS) {
2874 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
2875 &count, "ads");
2878 if (!NT_STATUS_IS_OK(status) || count == 0) {
2879 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
2880 &count,
2881 lp_name_resolve_order());
2882 if (!NT_STATUS_IS_OK(status)) {
2883 return false;
2887 /* if we get more than 1 IP back we have to assume it is a
2888 multi-homed PDC and not a mess up */
2890 if ( count > 1 ) {
2891 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
2892 sort_service_list(ip_list, count);
2895 *pss = ip_list[0].ss;
2896 SAFE_FREE(ip_list);
2897 return true;
2900 /* Private enum type for lookups. */
2902 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
2904 /********************************************************
2905 Get the IP address list of the domain controllers for
2906 a domain.
2907 *********************************************************/
2909 static NTSTATUS get_dc_list(const char *domain,
2910 const char *sitename,
2911 struct ip_service **ip_list,
2912 int *count,
2913 enum dc_lookup_type lookup_type,
2914 bool *ordered)
2916 char *resolve_order = NULL;
2917 char *saf_servername = NULL;
2918 char *pserver = NULL;
2919 const char *p;
2920 char *port_str = NULL;
2921 int port;
2922 char *name;
2923 int num_addresses = 0;
2924 int local_count, i, j;
2925 struct ip_service *return_iplist = NULL;
2926 struct ip_service *auto_ip_list = NULL;
2927 bool done_auto_lookup = false;
2928 int auto_count = 0;
2929 NTSTATUS status;
2930 TALLOC_CTX *ctx = talloc_init("get_dc_list");
2932 *ip_list = NULL;
2933 *count = 0;
2935 if (!ctx) {
2936 return NT_STATUS_NO_MEMORY;
2939 *ordered = False;
2941 /* if we are restricted to solely using DNS for looking
2942 up a domain controller, make sure that host lookups
2943 are enabled for the 'name resolve order'. If host lookups
2944 are disabled and ads_only is True, then set the string to
2945 NULL. */
2947 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
2948 if (!resolve_order) {
2949 status = NT_STATUS_NO_MEMORY;
2950 goto out;
2952 strlower_m(resolve_order);
2953 if (lookup_type == DC_ADS_ONLY) {
2954 if (strstr( resolve_order, "host")) {
2955 resolve_order = talloc_strdup(ctx, "ads");
2957 /* DNS SRV lookups used by the ads resolver
2958 are already sorted by priority and weight */
2959 *ordered = true;
2960 } else {
2961 resolve_order = talloc_strdup(ctx, "NULL");
2963 } else if (lookup_type == DC_KDC_ONLY) {
2964 /* DNS SRV lookups used by the ads/kdc resolver
2965 are already sorted by priority and weight */
2966 *ordered = true;
2967 resolve_order = talloc_strdup(ctx, "kdc");
2969 if (!resolve_order) {
2970 status = NT_STATUS_NO_MEMORY;
2971 goto out;
2974 /* fetch the server we have affinity for. Add the
2975 'password server' list to a search for our domain controllers */
2977 saf_servername = saf_fetch( domain);
2979 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
2980 pserver = talloc_asprintf(ctx, "%s, %s",
2981 saf_servername ? saf_servername : "",
2982 lp_passwordserver());
2983 } else {
2984 pserver = talloc_asprintf(ctx, "%s, *",
2985 saf_servername ? saf_servername : "");
2988 SAFE_FREE(saf_servername);
2989 if (!pserver) {
2990 status = NT_STATUS_NO_MEMORY;
2991 goto out;
2994 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
2996 if (!*pserver ) {
2997 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
2998 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
2999 count, resolve_order);
3000 goto out;
3003 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
3006 * if '*' appears in the "password server" list then add
3007 * an auto lookup to the list of manually configured
3008 * DC's. If any DC is listed by name, then the list should be
3009 * considered to be ordered
3012 p = pserver;
3013 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
3014 if (!done_auto_lookup && strequal(name, "*")) {
3015 status = internal_resolve_name(domain, 0x1C, sitename,
3016 &auto_ip_list,
3017 &auto_count,
3018 resolve_order);
3019 if (NT_STATUS_IS_OK(status)) {
3020 num_addresses += auto_count;
3022 done_auto_lookup = true;
3023 DEBUG(8,("Adding %d DC's from auto lookup\n",
3024 auto_count));
3025 } else {
3026 num_addresses++;
3030 /* if we have no addresses and haven't done the auto lookup, then
3031 just return the list of DC's. Or maybe we just failed. */
3033 if ((num_addresses == 0)) {
3034 if (done_auto_lookup) {
3035 DEBUG(4,("get_dc_list: no servers found\n"));
3036 status = NT_STATUS_NO_LOGON_SERVERS;
3037 goto out;
3039 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
3040 count, resolve_order);
3041 goto out;
3044 if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
3045 num_addresses)) == NULL) {
3046 DEBUG(3,("get_dc_list: malloc fail !\n"));
3047 status = NT_STATUS_NO_MEMORY;
3048 goto out;
3051 p = pserver;
3052 local_count = 0;
3054 /* fill in the return list now with real IP's */
3056 while ((local_count<num_addresses) &&
3057 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
3058 struct sockaddr_storage name_ss;
3060 /* copy any addersses from the auto lookup */
3062 if (strequal(name, "*")) {
3063 for (j=0; j<auto_count; j++) {
3064 char addr[INET6_ADDRSTRLEN];
3065 print_sockaddr(addr,
3066 sizeof(addr),
3067 &auto_ip_list[j].ss);
3068 /* Check for and don't copy any
3069 * known bad DC IP's. */
3070 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
3071 domain,
3072 addr))) {
3073 DEBUG(5,("get_dc_list: "
3074 "negative entry %s removed "
3075 "from DC list\n",
3076 addr));
3077 continue;
3079 return_iplist[local_count].ss =
3080 auto_ip_list[j].ss;
3081 return_iplist[local_count].port =
3082 auto_ip_list[j].port;
3083 local_count++;
3085 continue;
3088 /* added support for address:port syntax for ads
3089 * (not that I think anyone will ever run the LDAP
3090 * server in an AD domain on something other than
3091 * port 389 */
3093 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
3094 if ((port_str=strchr(name, ':')) != NULL) {
3095 *port_str = '\0';
3096 port_str++;
3097 port = atoi(port_str);
3100 /* explicit lookup; resolve_name() will
3101 * handle names & IP addresses */
3102 if (resolve_name( name, &name_ss, 0x20, true )) {
3103 char addr[INET6_ADDRSTRLEN];
3104 print_sockaddr(addr,
3105 sizeof(addr),
3106 &name_ss);
3108 /* Check for and don't copy any known bad DC IP's. */
3109 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
3110 addr)) ) {
3111 DEBUG(5,("get_dc_list: negative entry %s "
3112 "removed from DC list\n",
3113 name ));
3114 continue;
3117 return_iplist[local_count].ss = name_ss;
3118 return_iplist[local_count].port = port;
3119 local_count++;
3120 *ordered = true;
3124 /* need to remove duplicates in the list if we have any
3125 explicit password servers */
3127 if (local_count) {
3128 local_count = remove_duplicate_addrs2(return_iplist,
3129 local_count );
3132 /* For DC's we always prioritize IPv4 due to W2K3 not
3133 * supporting LDAP, KRB5 or CLDAP over IPv6. */
3135 if (local_count && return_iplist) {
3136 prioritize_ipv4_list(return_iplist, local_count);
3139 if ( DEBUGLEVEL >= 4 ) {
3140 DEBUG(4,("get_dc_list: returning %d ip addresses "
3141 "in an %sordered list\n",
3142 local_count,
3143 *ordered ? "":"un"));
3144 DEBUG(4,("get_dc_list: "));
3145 for ( i=0; i<local_count; i++ ) {
3146 char addr[INET6_ADDRSTRLEN];
3147 print_sockaddr(addr,
3148 sizeof(addr),
3149 &return_iplist[i].ss);
3150 DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
3152 DEBUGADD(4,("\n"));
3155 *ip_list = return_iplist;
3156 *count = local_count;
3158 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
3160 out:
3162 if (!NT_STATUS_IS_OK(status)) {
3163 SAFE_FREE(return_iplist);
3164 *ip_list = NULL;
3165 *count = 0;
3168 SAFE_FREE(auto_ip_list);
3169 TALLOC_FREE(ctx);
3170 return status;
3173 /*********************************************************************
3174 Small wrapper function to get the DC list and sort it if neccessary.
3175 *********************************************************************/
3177 NTSTATUS get_sorted_dc_list( const char *domain,
3178 const char *sitename,
3179 struct ip_service **ip_list,
3180 int *count,
3181 bool ads_only )
3183 bool ordered = false;
3184 NTSTATUS status;
3185 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
3187 *ip_list = NULL;
3188 *count = 0;
3190 DEBUG(8,("get_sorted_dc_list: attempting lookup "
3191 "for name %s (sitename %s) using [%s]\n",
3192 domain,
3193 sitename ? sitename : "NULL",
3194 (ads_only ? "ads" : lp_name_resolve_order())));
3196 if (ads_only) {
3197 lookup_type = DC_ADS_ONLY;
3200 status = get_dc_list(domain, sitename, ip_list,
3201 count, lookup_type, &ordered);
3202 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
3203 && sitename) {
3204 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
3205 " in site %s, fallback to all servers\n",
3206 domain, sitename));
3207 status = get_dc_list(domain, NULL, ip_list,
3208 count, lookup_type, &ordered);
3211 if (!NT_STATUS_IS_OK(status)) {
3212 SAFE_FREE(*ip_list);
3213 *count = 0;
3214 return status;
3217 /* only sort if we don't already have an ordered list */
3218 if (!ordered) {
3219 sort_service_list(*ip_list, *count);
3222 return NT_STATUS_OK;
3225 /*********************************************************************
3226 Get the KDC list - re-use all the logic in get_dc_list.
3227 *********************************************************************/
3229 NTSTATUS get_kdc_list( const char *realm,
3230 const char *sitename,
3231 struct ip_service **ip_list,
3232 int *count)
3234 bool ordered;
3235 NTSTATUS status;
3237 *count = 0;
3238 *ip_list = NULL;
3240 status = get_dc_list(realm, sitename, ip_list,
3241 count, DC_KDC_ONLY, &ordered);
3243 if (!NT_STATUS_IS_OK(status)) {
3244 SAFE_FREE(*ip_list);
3245 *count = 0;
3246 return status;
3249 /* only sort if we don't already have an ordered list */
3250 if ( !ordered ) {
3251 sort_service_list(*ip_list, *count);
3254 return NT_STATUS_OK;