2 Unix SMB/CIFS implementation.
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/>.
22 #include "libads/sitename_cache.h"
23 #include "libads/dns.h"
24 #include "../libcli/netlogon/netlogon.h"
25 #include "librpc/gen_ndr/messaging.h"
26 #include "lib/async_req/async_sock.h"
28 /* nmbd.c sets this to True. */
29 bool global_in_nmbd
= False
;
31 /****************************
32 * SERVER AFFINITY ROUTINES *
33 ****************************/
35 /* Server affinity is the concept of preferring the last domain
36 controller with whom you had a successful conversation */
38 /****************************************************************************
39 ****************************************************************************/
40 #define SAFKEY_FMT "SAF/DOMAIN/%s"
42 #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
43 #define SAFJOIN_TTL 3600
45 static char *saf_key(const char *domain
)
49 asprintf_strupper_m(&keystr
, SAFKEY_FMT
, domain
);
54 static char *saf_join_key(const char *domain
)
58 asprintf_strupper_m(&keystr
, SAFJOINKEY_FMT
, domain
);
63 /****************************************************************************
64 ****************************************************************************/
66 bool saf_store( const char *domain
, const char *servername
)
72 if ( !domain
|| !servername
) {
73 DEBUG(2,("saf_store: "
74 "Refusing to store empty domain or servername!\n"));
78 if ( (strlen(domain
) == 0) || (strlen(servername
) == 0) ) {
79 DEBUG(0,("saf_store: "
80 "refusing to store 0 length domain or servername!\n"));
84 key
= saf_key( domain
);
85 expire
= time( NULL
) + lp_parm_int(-1, "saf","ttl", SAF_TTL
);
87 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
88 domain
, servername
, (unsigned int)expire
));
90 ret
= gencache_set( key
, servername
, expire
);
97 bool saf_join_store( const char *domain
, const char *servername
)
103 if ( !domain
|| !servername
) {
104 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
108 if ( (strlen(domain
) == 0) || (strlen(servername
) == 0) ) {
109 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
113 key
= saf_join_key( domain
);
114 expire
= time( NULL
) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL
);
116 DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
117 domain
, servername
, (unsigned int)expire
));
119 ret
= gencache_set( key
, servername
, expire
);
126 bool saf_delete( const char *domain
)
132 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
136 key
= saf_join_key(domain
);
137 ret
= gencache_del(key
);
141 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain
));
144 key
= saf_key(domain
);
145 ret
= gencache_del(key
);
149 DEBUG(10,("saf_delete: domain = [%s]\n", domain
));
155 /****************************************************************************
156 ****************************************************************************/
158 char *saf_fetch( const char *domain
)
165 if ( !domain
|| strlen(domain
) == 0) {
166 DEBUG(2,("saf_fetch: Empty domain name!\n"));
170 key
= saf_join_key( domain
);
172 ret
= gencache_get( key
, &server
, &timeout
);
177 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
182 key
= saf_key( domain
);
184 ret
= gencache_get( key
, &server
, &timeout
);
189 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
192 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
199 /****************************************************************************
200 Generate a random trn_id.
201 ****************************************************************************/
203 static int generate_trn_id(void)
207 generate_random_buffer((uint8
*)&id
, sizeof(id
));
209 return id
% (unsigned)0x7FFF;
212 /****************************************************************************
213 Parse a node status response into an array of structures.
214 ****************************************************************************/
216 static struct node_status
*parse_node_status(TALLOC_CTX
*mem_ctx
, char *p
,
218 struct node_status_extra
*extra
)
220 struct node_status
*ret
;
223 *num_names
= CVAL(p
,0);
228 ret
= TALLOC_ARRAY(mem_ctx
, struct node_status
,*num_names
);
233 for (i
=0;i
< *num_names
;i
++) {
234 StrnCpy(ret
[i
].name
,p
,15);
235 trim_char(ret
[i
].name
,'\0',' ');
236 ret
[i
].type
= CVAL(p
,15);
237 ret
[i
].flags
= p
[16];
239 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret
[i
].name
,
240 ret
[i
].type
, ret
[i
].flags
));
243 * Also, pick up the MAC address ...
246 memcpy(&extra
->mac_addr
, p
, 6); /* Fill in the mac addr */
251 struct sock_packet_read_state
{
252 struct tevent_context
*ev
;
253 enum packet_type type
;
256 struct nb_packet_reader
*reader
;
257 struct tevent_req
*reader_req
;
260 struct tevent_req
*socket_req
;
262 struct sockaddr_storage addr
;
265 bool (*validator
)(struct packet_struct
*p
,
269 struct packet_struct
*packet
;
272 static int sock_packet_read_state_destructor(struct sock_packet_read_state
*s
);
273 static void sock_packet_read_got_packet(struct tevent_req
*subreq
);
274 static void sock_packet_read_got_socket(struct tevent_req
*subreq
);
276 static struct tevent_req
*sock_packet_read_send(
278 struct tevent_context
*ev
,
279 int sock
, /* dgram socket */
280 struct nb_packet_reader
*reader
,
281 enum packet_type type
,
283 bool (*validator
)(struct packet_struct
*p
, void *private_data
),
286 struct tevent_req
*req
;
287 struct sock_packet_read_state
*state
;
289 req
= tevent_req_create(mem_ctx
, &state
,
290 struct sock_packet_read_state
);
294 talloc_set_destructor(state
, sock_packet_read_state_destructor
);
296 state
->reader
= reader
;
299 state
->trn_id
= trn_id
;
300 state
->validator
= validator
;
301 state
->private_data
= private_data
;
303 if (reader
!= NULL
) {
304 state
->reader_req
= nb_packet_read_send(state
, ev
, reader
);
305 if (tevent_req_nomem(state
->reader_req
, req
)) {
306 return tevent_req_post(req
, ev
);
308 tevent_req_set_callback(
309 state
->reader_req
, sock_packet_read_got_packet
, req
);
312 state
->addr_len
= sizeof(state
->addr
);
313 state
->socket_req
= recvfrom_send(state
, ev
, sock
,
314 state
->buf
, sizeof(state
->buf
), 0,
315 &state
->addr
, &state
->addr_len
);
316 if (tevent_req_nomem(state
->socket_req
, req
)) {
317 return tevent_req_post(req
, ev
);
319 tevent_req_set_callback(state
->socket_req
, sock_packet_read_got_socket
,
325 static int sock_packet_read_state_destructor(struct sock_packet_read_state
*s
)
327 if (s
->packet
!= NULL
) {
328 free_packet(s
->packet
);
334 static void sock_packet_read_got_packet(struct tevent_req
*subreq
)
336 struct tevent_req
*req
= tevent_req_callback_data(
337 subreq
, struct tevent_req
);
338 struct sock_packet_read_state
*state
= tevent_req_data(
339 req
, struct sock_packet_read_state
);
342 status
= nb_packet_read_recv(subreq
, &state
->packet
);
344 TALLOC_FREE(state
->reader_req
);
346 if (!NT_STATUS_IS_OK(status
)) {
347 if (state
->socket_req
!= NULL
) {
349 * Still waiting for socket
354 * Both socket and packet reader failed
356 tevent_req_nterror(req
, status
);
360 if ((state
->validator
!= NULL
) &&
361 !state
->validator(state
->packet
, state
->private_data
)) {
362 DEBUG(10, ("validator failed\n"));
364 free_packet(state
->packet
);
365 state
->packet
= NULL
;
367 state
->reader_req
= nb_packet_read_send(state
, state
->ev
,
369 if (tevent_req_nomem(state
->reader_req
, req
)) {
372 tevent_req_set_callback(
373 state
->reader_req
, sock_packet_read_got_packet
, req
);
377 TALLOC_FREE(state
->socket_req
);
378 tevent_req_done(req
);
381 static void sock_packet_read_got_socket(struct tevent_req
*subreq
)
383 struct tevent_req
*req
= tevent_req_callback_data(
384 subreq
, struct tevent_req
);
385 struct sock_packet_read_state
*state
= tevent_req_data(
386 req
, struct sock_packet_read_state
);
387 struct sockaddr_in
*in_addr
;
391 received
= recvfrom_recv(subreq
, &err
);
393 TALLOC_FREE(state
->socket_req
);
395 if (received
== -1) {
396 if (state
->reader_req
!= NULL
) {
398 * Still waiting for reader
403 * Both socket and reader failed
405 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
408 if (state
->addr
.ss_family
!= AF_INET
) {
411 in_addr
= (struct sockaddr_in
*)(void *)&state
->addr
;
413 state
->packet
= parse_packet((char *)state
->buf
, received
, state
->type
,
414 in_addr
->sin_addr
, in_addr
->sin_port
);
415 if (state
->packet
== NULL
) {
416 DEBUG(10, ("parse_packet failed\n"));
419 if ((state
->trn_id
!= -1) &&
420 (state
->trn_id
!= packet_trn_id(state
->packet
))) {
421 DEBUG(10, ("Expected transaction id %d, got %d\n",
422 state
->trn_id
, packet_trn_id(state
->packet
)));
426 if ((state
->validator
!= NULL
) &&
427 !state
->validator(state
->packet
, state
->private_data
)) {
428 DEBUG(10, ("validator failed\n"));
432 tevent_req_done(req
);
436 if (state
->packet
!= NULL
) {
437 free_packet(state
->packet
);
438 state
->packet
= NULL
;
440 state
->socket_req
= recvfrom_send(state
, state
->ev
, state
->sock
,
441 state
->buf
, sizeof(state
->buf
), 0,
442 &state
->addr
, &state
->addr_len
);
443 if (tevent_req_nomem(state
->socket_req
, req
)) {
446 tevent_req_set_callback(state
->socket_req
, sock_packet_read_got_socket
,
450 static NTSTATUS
sock_packet_read_recv(struct tevent_req
*req
,
451 struct packet_struct
**ppacket
)
453 struct sock_packet_read_state
*state
= tevent_req_data(
454 req
, struct sock_packet_read_state
);
457 if (tevent_req_is_nterror(req
, &status
)) {
460 *ppacket
= state
->packet
;
461 state
->packet
= NULL
;
465 struct nb_trans_state
{
466 struct tevent_context
*ev
;
468 struct nb_packet_reader
*reader
;
470 const struct sockaddr_storage
*dst_addr
;
473 enum packet_type type
;
476 bool (*validator
)(struct packet_struct
*p
,
480 struct packet_struct
*packet
;
483 static int nb_trans_state_destructor(struct nb_trans_state
*s
);
484 static void nb_trans_got_reader(struct tevent_req
*subreq
);
485 static void nb_trans_done(struct tevent_req
*subreq
);
486 static void nb_trans_sent(struct tevent_req
*subreq
);
487 static void nb_trans_send_next(struct tevent_req
*subreq
);
489 static struct tevent_req
*nb_trans_send(
491 struct tevent_context
*ev
,
492 const struct sockaddr_storage
*my_addr
,
493 const struct sockaddr_storage
*dst_addr
,
495 uint8_t *buf
, size_t buflen
,
496 enum packet_type type
, int trn_id
,
497 bool (*validator
)(struct packet_struct
*p
,
501 struct tevent_req
*req
, *subreq
;
502 struct nb_trans_state
*state
;
504 req
= tevent_req_create(mem_ctx
, &state
, struct nb_trans_state
);
508 talloc_set_destructor(state
, nb_trans_state_destructor
);
510 state
->dst_addr
= dst_addr
;
512 state
->buflen
= buflen
;
514 state
->trn_id
= trn_id
;
515 state
->validator
= validator
;
516 state
->private_data
= private_data
;
518 state
->sock
= open_socket_in(SOCK_DGRAM
, 0, 3, my_addr
, True
);
519 if (state
->sock
== -1) {
520 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
521 DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno
)));
522 return tevent_req_post(req
, ev
);
526 set_socket_options(state
->sock
,"SO_BROADCAST");
529 subreq
= nb_packet_reader_send(state
, ev
, type
, state
->trn_id
, NULL
);
530 if (tevent_req_nomem(subreq
, req
)) {
531 return tevent_req_post(req
, ev
);
533 tevent_req_set_callback(subreq
, nb_trans_got_reader
, req
);
537 static int nb_trans_state_destructor(struct nb_trans_state
*s
)
543 if (s
->packet
!= NULL
) {
544 free_packet(s
->packet
);
550 static void nb_trans_got_reader(struct tevent_req
*subreq
)
552 struct tevent_req
*req
= tevent_req_callback_data(
553 subreq
, struct tevent_req
);
554 struct nb_trans_state
*state
= tevent_req_data(
555 req
, struct nb_trans_state
);
558 status
= nb_packet_reader_recv(subreq
, state
, &state
->reader
);
561 if (!NT_STATUS_IS_OK(status
)) {
562 DEBUG(10, ("nmbd not around\n"));
563 state
->reader
= NULL
;
566 subreq
= sock_packet_read_send(
567 state
, state
->ev
, state
->sock
,
568 state
->reader
, state
->type
, state
->trn_id
,
569 state
->validator
, state
->private_data
);
570 if (tevent_req_nomem(subreq
, req
)) {
573 tevent_req_set_callback(subreq
, nb_trans_done
, req
);
575 subreq
= sendto_send(state
, state
->ev
, state
->sock
,
576 state
->buf
, state
->buflen
, 0, state
->dst_addr
);
577 if (tevent_req_nomem(subreq
, req
)) {
580 tevent_req_set_callback(subreq
, nb_trans_sent
, req
);
583 static void nb_trans_sent(struct tevent_req
*subreq
)
585 struct tevent_req
*req
= tevent_req_callback_data(
586 subreq
, struct tevent_req
);
587 struct nb_trans_state
*state
= tevent_req_data(
588 req
, struct nb_trans_state
);
592 sent
= sendto_recv(subreq
, &err
);
595 DEBUG(10, ("sendto failed: %s\n", strerror(err
)));
596 tevent_req_nterror(req
, map_nt_error_from_unix(err
));
599 subreq
= tevent_wakeup_send(state
, state
->ev
,
600 timeval_current_ofs(1, 0));
601 if (tevent_req_nomem(subreq
, req
)) {
604 tevent_req_set_callback(subreq
, nb_trans_send_next
, req
);
607 static void nb_trans_send_next(struct tevent_req
*subreq
)
609 struct tevent_req
*req
= tevent_req_callback_data(
610 subreq
, struct tevent_req
);
611 struct nb_trans_state
*state
= tevent_req_data(
612 req
, struct nb_trans_state
);
615 ret
= tevent_wakeup_recv(subreq
);
618 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
621 subreq
= sendto_send(state
, state
->ev
, state
->sock
,
622 state
->buf
, state
->buflen
, 0, state
->dst_addr
);
623 if (tevent_req_nomem(subreq
, req
)) {
626 tevent_req_set_callback(subreq
, nb_trans_sent
, req
);
629 static void nb_trans_done(struct tevent_req
*subreq
)
631 struct tevent_req
*req
= tevent_req_callback_data(
632 subreq
, struct tevent_req
);
633 struct nb_trans_state
*state
= tevent_req_data(
634 req
, struct nb_trans_state
);
637 status
= sock_packet_read_recv(subreq
, &state
->packet
);
639 if (tevent_req_nterror(req
, status
)) {
642 tevent_req_done(req
);
645 static NTSTATUS
nb_trans_recv(struct tevent_req
*req
,
646 struct packet_struct
**ppacket
)
648 struct nb_trans_state
*state
= tevent_req_data(
649 req
, struct nb_trans_state
);
652 if (tevent_req_is_nterror(req
, &status
)) {
655 *ppacket
= state
->packet
;
656 state
->packet
= NULL
;
660 /****************************************************************************
661 Do a NBT node status query on an open socket and return an array of
662 structures holding the returned names or NULL if the query failed.
663 **************************************************************************/
665 struct node_status_query_state
{
666 struct sockaddr_storage my_addr
;
667 struct sockaddr_storage addr
;
670 struct packet_struct
*packet
;
673 static int node_status_query_state_destructor(
674 struct node_status_query_state
*s
);
675 static bool node_status_query_validator(struct packet_struct
*p
,
677 static void node_status_query_done(struct tevent_req
*subreq
);
679 struct tevent_req
*node_status_query_send(TALLOC_CTX
*mem_ctx
,
680 struct tevent_context
*ev
,
681 struct nmb_name
*name
,
682 const struct sockaddr_storage
*addr
)
684 struct tevent_req
*req
, *subreq
;
685 struct node_status_query_state
*state
;
686 struct packet_struct p
;
687 struct nmb_packet
*nmb
= &p
.packet
.nmb
;
688 struct sockaddr_in
*in_addr
;
690 req
= tevent_req_create(mem_ctx
, &state
,
691 struct node_status_query_state
);
695 talloc_set_destructor(state
, node_status_query_state_destructor
);
697 if (addr
->ss_family
!= AF_INET
) {
698 /* Can't do node status to IPv6 */
699 tevent_req_nterror(req
, NT_STATUS_INVALID_ADDRESS
);
700 return tevent_req_post(req
, ev
);
704 in_addr
= (struct sockaddr_in
*)(void *)&state
->addr
;
705 in_addr
->sin_port
= htons(NMB_PORT
);
707 if (!interpret_string_addr(&state
->my_addr
, lp_socket_address(),
708 AI_NUMERICHOST
|AI_PASSIVE
)) {
709 zero_sockaddr(&state
->my_addr
);
713 nmb
->header
.name_trn_id
= generate_trn_id();
714 nmb
->header
.opcode
= 0;
715 nmb
->header
.response
= false;
716 nmb
->header
.nm_flags
.bcast
= false;
717 nmb
->header
.nm_flags
.recursion_available
= false;
718 nmb
->header
.nm_flags
.recursion_desired
= false;
719 nmb
->header
.nm_flags
.trunc
= false;
720 nmb
->header
.nm_flags
.authoritative
= false;
721 nmb
->header
.rcode
= 0;
722 nmb
->header
.qdcount
= 1;
723 nmb
->header
.ancount
= 0;
724 nmb
->header
.nscount
= 0;
725 nmb
->header
.arcount
= 0;
726 nmb
->question
.question_name
= *name
;
727 nmb
->question
.question_type
= 0x21;
728 nmb
->question
.question_class
= 0x1;
730 state
->buflen
= build_packet((char *)state
->buf
, sizeof(state
->buf
),
732 if (state
->buflen
== 0) {
733 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
734 DEBUG(10, ("build_packet failed\n"));
735 return tevent_req_post(req
, ev
);
738 subreq
= nb_trans_send(state
, ev
, &state
->my_addr
, &state
->addr
, false,
739 state
->buf
, state
->buflen
,
740 NMB_PACKET
, nmb
->header
.name_trn_id
,
741 node_status_query_validator
, NULL
);
742 if (tevent_req_nomem(subreq
, req
)) {
743 DEBUG(10, ("nb_trans_send failed\n"));
744 return tevent_req_post(req
, ev
);
746 if (!tevent_req_set_endtime(req
, ev
, timeval_current_ofs(10, 0))) {
747 return tevent_req_post(req
, ev
);
749 tevent_req_set_callback(subreq
, node_status_query_done
, req
);
753 static bool node_status_query_validator(struct packet_struct
*p
,
756 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
759 if (nmb
->header
.opcode
!= 0 ||
760 nmb
->header
.nm_flags
.bcast
||
762 !nmb
->header
.ancount
||
763 nmb
->answers
->rr_type
!= 0x21) {
765 * XXXX what do we do with this? could be a redirect,
766 * but we'll discard it for the moment
773 static int node_status_query_state_destructor(
774 struct node_status_query_state
*s
)
776 if (s
->packet
!= NULL
) {
777 free_packet(s
->packet
);
783 static void node_status_query_done(struct tevent_req
*subreq
)
785 struct tevent_req
*req
= tevent_req_callback_data(
786 subreq
, struct tevent_req
);
787 struct node_status_query_state
*state
= tevent_req_data(
788 req
, struct node_status_query_state
);
791 status
= nb_trans_recv(subreq
, &state
->packet
);
793 if (tevent_req_nterror(req
, status
)) {
796 tevent_req_done(req
);
799 NTSTATUS
node_status_query_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
800 struct node_status
**pnode_status
,
802 struct node_status_extra
*extra
)
804 struct node_status_query_state
*state
= tevent_req_data(
805 req
, struct node_status_query_state
);
806 struct node_status
*node_status
;
810 if (tevent_req_is_nterror(req
, &status
)) {
813 node_status
= parse_node_status(
814 mem_ctx
, &state
->packet
->packet
.nmb
.answers
->rdata
[0],
816 if (node_status
== NULL
) {
817 return NT_STATUS_NO_MEMORY
;
819 *pnode_status
= node_status
;
820 *pnum_names
= num_names
;
824 NTSTATUS
node_status_query(TALLOC_CTX
*mem_ctx
, struct nmb_name
*name
,
825 const struct sockaddr_storage
*addr
,
826 struct node_status
**pnode_status
,
828 struct node_status_extra
*extra
)
830 TALLOC_CTX
*frame
= talloc_stackframe();
831 struct tevent_context
*ev
;
832 struct tevent_req
*req
;
833 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
835 ev
= tevent_context_init(frame
);
839 req
= node_status_query_send(ev
, ev
, name
, addr
);
843 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
846 status
= node_status_query_recv(req
, mem_ctx
, pnode_status
,
853 /****************************************************************************
854 Find the first type XX name in a node status reply - used for finding
855 a servers name given its IP. Return the matched name in *name.
856 **************************************************************************/
858 bool name_status_find(const char *q_name
,
861 const struct sockaddr_storage
*to_ss
,
864 char addr
[INET6_ADDRSTRLEN
];
865 struct sockaddr_storage ss
;
866 struct node_status
*addrs
= NULL
;
867 struct nmb_name nname
;
872 if (lp_disable_netbios()) {
873 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
878 print_sockaddr(addr
, sizeof(addr
), to_ss
);
880 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name
,
883 /* Check the cache first. */
885 if (namecache_status_fetch(q_name
, q_type
, type
, to_ss
, name
)) {
889 if (to_ss
->ss_family
!= AF_INET
) {
890 /* Can't do node status to IPv6 */
894 if (!interpret_string_addr(&ss
, lp_socket_address(),
895 AI_NUMERICHOST
|AI_PASSIVE
)) {
899 /* W2K PDC's seem not to respond to '*'#0. JRA */
900 make_nmb_name(&nname
, q_name
, q_type
);
901 status
= node_status_query(talloc_tos(), &nname
, to_ss
,
902 &addrs
, &count
, NULL
);
903 if (!NT_STATUS_IS_OK(status
)) {
907 for (i
=0;i
<count
;i
++) {
908 /* Find first one of the requested type that's not a GROUP. */
909 if (addrs
[i
].type
== type
&& ! (addrs
[i
].flags
& 0x80))
915 pull_ascii_nstring(name
, sizeof(fstring
), addrs
[i
].name
);
917 /* Store the result in the cache. */
918 /* but don't store an entry for 0x1c names here. Here we have
919 a single host and DOMAIN<0x1c> names should be a list of hosts */
921 if ( q_type
!= 0x1c ) {
922 namecache_status_store(q_name
, q_type
, type
, to_ss
, name
);
930 DEBUG(10, ("name_status_find: name %sfound", result
? "" : "not "));
933 DEBUGADD(10, (", name %s ip address is %s", name
, addr
));
941 comparison function used by sort_addr_list
944 static int addr_compare(const struct sockaddr_storage
*ss1
,
945 const struct sockaddr_storage
*ss2
)
947 int max_bits1
=0, max_bits2
=0;
948 int num_interfaces
= iface_count();
951 /* Sort IPv4 addresses first. */
952 if (ss1
->ss_family
!= ss2
->ss_family
) {
953 if (ss2
->ss_family
== AF_INET
) {
960 /* Here we know both addresses are of the same
963 for (i
=0;i
<num_interfaces
;i
++) {
964 const struct sockaddr_storage
*pss
= iface_n_bcast(i
);
965 unsigned char *p_ss1
= NULL
;
966 unsigned char *p_ss2
= NULL
;
967 unsigned char *p_if
= NULL
;
971 if (pss
->ss_family
!= ss1
->ss_family
) {
972 /* Ignore interfaces of the wrong type. */
975 if (pss
->ss_family
== AF_INET
) {
976 p_if
= (unsigned char *)
977 &((const struct sockaddr_in
*)pss
)->sin_addr
;
978 p_ss1
= (unsigned char *)
979 &((const struct sockaddr_in
*)ss1
)->sin_addr
;
980 p_ss2
= (unsigned char *)
981 &((const struct sockaddr_in
*)ss2
)->sin_addr
;
984 #if defined(HAVE_IPV6)
985 if (pss
->ss_family
== AF_INET6
) {
986 p_if
= (unsigned char *)
987 &((const struct sockaddr_in6
*)pss
)->sin6_addr
;
988 p_ss1
= (unsigned char *)
989 &((const struct sockaddr_in6
*)ss1
)->sin6_addr
;
990 p_ss2
= (unsigned char *)
991 &((const struct sockaddr_in6
*)ss2
)->sin6_addr
;
995 if (!p_ss1
|| !p_ss2
|| !p_if
|| len
== 0) {
998 bits1
= matching_len_bits(p_ss1
, p_if
, len
);
999 bits2
= matching_len_bits(p_ss2
, p_if
, len
);
1000 max_bits1
= MAX(bits1
, max_bits1
);
1001 max_bits2
= MAX(bits2
, max_bits2
);
1004 /* Bias towards directly reachable IPs */
1005 if (iface_local((struct sockaddr
*)ss1
)) {
1006 if (ss1
->ss_family
== AF_INET
) {
1012 if (iface_local((struct sockaddr
*)ss2
)) {
1013 if (ss2
->ss_family
== AF_INET
) {
1019 return max_bits2
- max_bits1
;
1022 /*******************************************************************
1023 compare 2 ldap IPs by nearness to our interfaces - used in qsort
1024 *******************************************************************/
1026 int ip_service_compare(struct ip_service
*ss1
, struct ip_service
*ss2
)
1030 if ((result
= addr_compare(&ss1
->ss
, &ss2
->ss
)) != 0) {
1034 if (ss1
->port
> ss2
->port
) {
1038 if (ss1
->port
< ss2
->port
) {
1046 sort an IP list so that names that are close to one of our interfaces
1047 are at the top. This prevents the problem where a WINS server returns an IP
1048 that is not reachable from our subnet as the first match
1051 static void sort_addr_list(struct sockaddr_storage
*sslist
, int count
)
1057 TYPESAFE_QSORT(sslist
, count
, addr_compare
);
1060 static void sort_service_list(struct ip_service
*servlist
, int count
)
1066 TYPESAFE_QSORT(servlist
, count
, ip_service_compare
);
1069 /**********************************************************************
1070 Remove any duplicate address/port pairs in the list
1071 *********************************************************************/
1073 static int remove_duplicate_addrs2(struct ip_service
*iplist
, int count
)
1077 DEBUG(10,("remove_duplicate_addrs2: "
1078 "looking for duplicate address/port pairs\n"));
1080 /* one loop to remove duplicates */
1081 for ( i
=0; i
<count
; i
++ ) {
1082 if ( is_zero_addr((struct sockaddr
*)&iplist
[i
].ss
)) {
1086 for ( j
=i
+1; j
<count
; j
++ ) {
1087 if (sockaddr_equal((struct sockaddr
*)&iplist
[i
].ss
, (struct sockaddr
*)&iplist
[j
].ss
) &&
1088 iplist
[i
].port
== iplist
[j
].port
) {
1089 zero_sockaddr(&iplist
[j
].ss
);
1094 /* one loop to clean up any holes we left */
1095 /* first ip should never be a zero_ip() */
1096 for (i
= 0; i
<count
; ) {
1097 if (is_zero_addr((struct sockaddr
*)&iplist
[i
].ss
) ) {
1099 memmove(&iplist
[i
], &iplist
[i
+1],
1100 (count
- i
- 1)*sizeof(iplist
[i
]));
1111 static bool prioritize_ipv4_list(struct ip_service
*iplist
, int count
)
1113 TALLOC_CTX
*frame
= talloc_stackframe();
1114 struct ip_service
*iplist_new
= TALLOC_ARRAY(frame
, struct ip_service
, count
);
1117 if (iplist_new
== NULL
) {
1124 /* Copy IPv4 first. */
1125 for (i
= 0; i
< count
; i
++) {
1126 if (iplist
[i
].ss
.ss_family
== AF_INET
) {
1127 iplist_new
[j
++] = iplist
[i
];
1132 for (i
= 0; i
< count
; i
++) {
1133 if (iplist
[i
].ss
.ss_family
!= AF_INET
) {
1134 iplist_new
[j
++] = iplist
[i
];
1138 memcpy(iplist
, iplist_new
, sizeof(struct ip_service
)*count
);
1143 /****************************************************************************
1144 Do a netbios name query to find someones IP.
1145 Returns an array of IP addresses or NULL if none.
1146 *count will be set to the number of addresses returned.
1147 *timed_out is set if we failed by timing out
1148 ****************************************************************************/
1150 struct name_query_state
{
1151 struct sockaddr_storage my_addr
;
1152 struct sockaddr_storage addr
;
1159 NTSTATUS validate_error
;
1162 struct sockaddr_storage
*addrs
;
1166 static bool name_query_validator(struct packet_struct
*p
, void *private_data
);
1167 static void name_query_done(struct tevent_req
*subreq
);
1169 struct tevent_req
*name_query_send(TALLOC_CTX
*mem_ctx
,
1170 struct tevent_context
*ev
,
1171 const char *name
, int name_type
,
1172 bool bcast
, bool recurse
,
1173 const struct sockaddr_storage
*addr
)
1175 struct tevent_req
*req
, *subreq
;
1176 struct name_query_state
*state
;
1177 struct packet_struct p
;
1178 struct nmb_packet
*nmb
= &p
.packet
.nmb
;
1179 struct sockaddr_in
*in_addr
;
1180 struct timeval timeout
;
1182 req
= tevent_req_create(mem_ctx
, &state
, struct name_query_state
);
1186 state
->bcast
= bcast
;
1188 if (addr
->ss_family
!= AF_INET
) {
1189 /* Can't do node status to IPv6 */
1190 tevent_req_nterror(req
, NT_STATUS_INVALID_ADDRESS
);
1191 return tevent_req_post(req
, ev
);
1194 if (lp_disable_netbios()) {
1195 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
1197 tevent_req_nterror(req
, NT_STATUS_NOT_SUPPORTED
);
1198 return tevent_req_post(req
, ev
);
1201 state
->addr
= *addr
;
1202 in_addr
= (struct sockaddr_in
*)(void *)&state
->addr
;
1203 in_addr
->sin_port
= htons(NMB_PORT
);
1205 if (!interpret_string_addr(&state
->my_addr
, lp_socket_address(),
1206 AI_NUMERICHOST
|AI_PASSIVE
)) {
1207 zero_sockaddr(&state
->my_addr
);
1211 nmb
->header
.name_trn_id
= generate_trn_id();
1212 nmb
->header
.opcode
= 0;
1213 nmb
->header
.response
= false;
1214 nmb
->header
.nm_flags
.bcast
= bcast
;
1215 nmb
->header
.nm_flags
.recursion_available
= false;
1216 nmb
->header
.nm_flags
.recursion_desired
= recurse
;
1217 nmb
->header
.nm_flags
.trunc
= false;
1218 nmb
->header
.nm_flags
.authoritative
= false;
1219 nmb
->header
.rcode
= 0;
1220 nmb
->header
.qdcount
= 1;
1221 nmb
->header
.ancount
= 0;
1222 nmb
->header
.nscount
= 0;
1223 nmb
->header
.arcount
= 0;
1225 make_nmb_name(&nmb
->question
.question_name
,name
,name_type
);
1227 nmb
->question
.question_type
= 0x20;
1228 nmb
->question
.question_class
= 0x1;
1230 state
->buflen
= build_packet((char *)state
->buf
, sizeof(state
->buf
),
1232 if (state
->buflen
== 0) {
1233 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
1234 DEBUG(10, ("build_packet failed\n"));
1235 return tevent_req_post(req
, ev
);
1238 subreq
= nb_trans_send(state
, ev
, &state
->my_addr
, &state
->addr
, bcast
,
1239 state
->buf
, state
->buflen
,
1240 NMB_PACKET
, nmb
->header
.name_trn_id
,
1241 name_query_validator
, state
);
1242 if (tevent_req_nomem(subreq
, req
)) {
1243 DEBUG(10, ("nb_trans_send failed\n"));
1244 return tevent_req_post(req
, ev
);
1247 timeout
= timeval_current_ofs(0, 250000);
1249 timeout
= timeval_current_ofs(2, 0);
1251 if (!tevent_req_set_endtime(req
, ev
, timeout
)) {
1252 return tevent_req_post(req
, ev
);
1254 tevent_req_set_callback(subreq
, name_query_done
, req
);
1258 static bool name_query_validator(struct packet_struct
*p
, void *private_data
)
1260 struct name_query_state
*state
= talloc_get_type_abort(
1261 private_data
, struct name_query_state
);
1262 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
1263 struct sockaddr_storage
*tmp_addrs
;
1266 debug_nmb_packet(p
);
1269 * If we get a Negative Name Query Response from a WINS
1270 * server, we should report it and give up.
1272 if( 0 == nmb
->header
.opcode
/* A query response */
1273 && !state
->bcast
/* from a WINS server */
1274 && nmb
->header
.rcode
/* Error returned */
1277 if( DEBUGLVL( 3 ) ) {
1278 /* Only executed if DEBUGLEVEL >= 3 */
1279 dbgtext( "Negative name query "
1280 "response, rcode 0x%02x: ",
1281 nmb
->header
.rcode
);
1282 switch( nmb
->header
.rcode
) {
1284 dbgtext("Request was invalidly formatted.\n");
1287 dbgtext("Problem with NBNS, cannot process "
1291 dbgtext("The name requested does not "
1295 dbgtext("Unsupported request error.\n");
1298 dbgtext("Query refused error.\n");
1301 dbgtext("Unrecognized error code.\n" );
1307 * We accept this packet as valid, but tell the upper
1308 * layers that it's a negative response.
1310 state
->validate_error
= NT_STATUS_NOT_FOUND
;
1314 if (nmb
->header
.opcode
!= 0 ||
1315 nmb
->header
.nm_flags
.bcast
||
1316 nmb
->header
.rcode
||
1317 !nmb
->header
.ancount
) {
1319 * XXXX what do we do with this? Could be a redirect,
1320 * but we'll discard it for the moment.
1325 tmp_addrs
= TALLOC_REALLOC_ARRAY(
1326 state
, state
->addrs
, struct sockaddr_storage
,
1327 state
->num_addrs
+ nmb
->answers
->rdlength
/6);
1328 if (tmp_addrs
== NULL
) {
1329 state
->validate_error
= NT_STATUS_NO_MEMORY
;
1332 state
->addrs
= tmp_addrs
;
1334 DEBUG(2,("Got a positive name query response "
1335 "from %s ( ", inet_ntoa(p
->ip
)));
1337 for (i
=0; i
<nmb
->answers
->rdlength
/6; i
++) {
1339 putip((char *)&ip
,&nmb
->answers
->rdata
[2+i
*6]);
1340 in_addr_to_sockaddr_storage(
1341 &state
->addrs
[state
->num_addrs
], ip
);
1342 DEBUGADD(2,("%s ",inet_ntoa(ip
)));
1343 state
->num_addrs
+= 1;
1345 DEBUGADD(2,(")\n"));
1347 /* We add the flags back ... */
1348 if (nmb
->header
.response
)
1349 state
->flags
|= NM_FLAGS_RS
;
1350 if (nmb
->header
.nm_flags
.authoritative
)
1351 state
->flags
|= NM_FLAGS_AA
;
1352 if (nmb
->header
.nm_flags
.trunc
)
1353 state
->flags
|= NM_FLAGS_TC
;
1354 if (nmb
->header
.nm_flags
.recursion_desired
)
1355 state
->flags
|= NM_FLAGS_RD
;
1356 if (nmb
->header
.nm_flags
.recursion_available
)
1357 state
->flags
|= NM_FLAGS_RA
;
1358 if (nmb
->header
.nm_flags
.bcast
)
1359 state
->flags
|= NM_FLAGS_B
;
1363 * We have to collect all entries coming in from
1369 * WINS responses are accepted when they are received
1374 static void name_query_done(struct tevent_req
*subreq
)
1376 struct tevent_req
*req
= tevent_req_callback_data(
1377 subreq
, struct tevent_req
);
1378 struct name_query_state
*state
= tevent_req_data(
1379 req
, struct name_query_state
);
1381 struct packet_struct
*p
= NULL
;
1383 status
= nb_trans_recv(subreq
, &p
);
1384 TALLOC_FREE(subreq
);
1385 if (tevent_req_nterror(req
, status
)) {
1388 if (!NT_STATUS_IS_OK(state
->validate_error
)) {
1389 tevent_req_nterror(req
, state
->validate_error
);
1394 * Free the packet here, we've collected the response in the
1399 tevent_req_done(req
);
1402 NTSTATUS
name_query_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
1403 struct sockaddr_storage
**addrs
, int *num_addrs
,
1406 struct name_query_state
*state
= tevent_req_data(
1407 req
, struct name_query_state
);
1410 if (tevent_req_is_nterror(req
, &status
)
1411 && !NT_STATUS_EQUAL(status
, NT_STATUS_IO_TIMEOUT
)) {
1414 if (state
->num_addrs
== 0) {
1415 return NT_STATUS_NOT_FOUND
;
1417 *addrs
= talloc_move(mem_ctx
, &state
->addrs
);
1418 sort_addr_list(*addrs
, state
->num_addrs
);
1419 *num_addrs
= state
->num_addrs
;
1420 if (flags
!= NULL
) {
1421 *flags
= state
->flags
;
1423 return NT_STATUS_OK
;
1426 NTSTATUS
name_query(const char *name
, int name_type
,
1427 bool bcast
, bool recurse
,
1428 const struct sockaddr_storage
*to_ss
,
1429 TALLOC_CTX
*mem_ctx
,
1430 struct sockaddr_storage
**addrs
,
1431 int *num_addrs
, uint8_t *flags
)
1433 TALLOC_CTX
*frame
= talloc_stackframe();
1434 struct tevent_context
*ev
;
1435 struct tevent_req
*req
;
1436 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1438 ev
= tevent_context_init(frame
);
1442 req
= name_query_send(ev
, ev
, name
, name_type
, bcast
, recurse
, to_ss
);
1446 if (!tevent_req_poll_ntstatus(req
, ev
, &status
)) {
1449 status
= name_query_recv(req
, mem_ctx
, addrs
, num_addrs
, flags
);
1455 /********************************************************
1456 convert an array if struct sockaddr_storage to struct ip_service
1457 return false on failure. Port is set to PORT_NONE;
1458 *********************************************************/
1460 static bool convert_ss2service(struct ip_service
**return_iplist
,
1461 const struct sockaddr_storage
*ss_list
,
1466 if ( count
==0 || !ss_list
)
1469 /* copy the ip address; port will be PORT_NONE */
1470 if ((*return_iplist
= SMB_MALLOC_ARRAY(struct ip_service
, count
)) ==
1472 DEBUG(0,("convert_ip2service: malloc failed "
1473 "for %d enetries!\n", count
));
1477 for ( i
=0; i
<count
; i
++ ) {
1478 (*return_iplist
)[i
].ss
= ss_list
[i
];
1479 (*return_iplist
)[i
].port
= PORT_NONE
;
1485 /********************************************************
1486 Resolve via "bcast" method.
1487 *********************************************************/
1489 NTSTATUS
name_resolve_bcast(const char *name
,
1491 struct ip_service
**return_iplist
,
1495 int num_interfaces
= iface_count();
1496 struct sockaddr_storage
*ss_list
;
1497 struct sockaddr_storage ss
;
1498 NTSTATUS status
= NT_STATUS_NOT_FOUND
;
1500 if (lp_disable_netbios()) {
1501 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
1503 return NT_STATUS_INVALID_PARAMETER
;
1506 *return_iplist
= NULL
;
1510 * "bcast" means do a broadcast lookup on all the local interfaces.
1513 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
1514 "for name %s<0x%x>\n", name
, name_type
));
1516 if (!interpret_string_addr(&ss
, lp_socket_address(),
1517 AI_NUMERICHOST
|AI_PASSIVE
)) {
1522 * Lookup the name on all the interfaces, return on
1523 * the first successful match.
1525 for( i
= num_interfaces
-1; i
>= 0; i
--) {
1526 const struct sockaddr_storage
*pss
= iface_n_bcast(i
);
1528 /* Done this way to fix compiler error on IRIX 5.x */
1532 status
= name_query(name
, name_type
, true, true, pss
,
1533 talloc_tos(), &ss_list
, return_count
,
1535 if (NT_STATUS_IS_OK(status
)) {
1540 /* failed - no response */
1546 if (!convert_ss2service(return_iplist
, ss_list
, *return_count
) )
1547 status
= NT_STATUS_NO_MEMORY
;
1549 TALLOC_FREE(ss_list
);
1553 /********************************************************
1554 Resolve via "wins" method.
1555 *********************************************************/
1557 NTSTATUS
resolve_wins(const char *name
,
1559 struct ip_service
**return_iplist
,
1564 struct sockaddr_storage src_ss
, *ss_list
= NULL
;
1565 struct in_addr src_ip
;
1568 if (lp_disable_netbios()) {
1569 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
1571 return NT_STATUS_INVALID_PARAMETER
;
1574 *return_iplist
= NULL
;
1577 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
1580 if (wins_srv_count() < 1) {
1581 DEBUG(3,("resolve_wins: WINS server resolution selected "
1582 "and no WINS servers listed.\n"));
1583 return NT_STATUS_INVALID_PARAMETER
;
1586 /* we try a lookup on each of the WINS tags in turn */
1587 wins_tags
= wins_srv_tags();
1590 /* huh? no tags?? give up in disgust */
1591 return NT_STATUS_INVALID_PARAMETER
;
1594 /* the address we will be sending from */
1595 if (!interpret_string_addr(&src_ss
, lp_socket_address(),
1596 AI_NUMERICHOST
|AI_PASSIVE
)) {
1597 zero_sockaddr(&src_ss
);
1600 if (src_ss
.ss_family
!= AF_INET
) {
1601 char addr
[INET6_ADDRSTRLEN
];
1602 print_sockaddr(addr
, sizeof(addr
), &src_ss
);
1603 DEBUG(3,("resolve_wins: cannot receive WINS replies "
1604 "on IPv6 address %s\n",
1606 wins_srv_tags_free(wins_tags
);
1607 return NT_STATUS_INVALID_PARAMETER
;
1610 src_ip
= ((struct sockaddr_in
*)&src_ss
)->sin_addr
;
1612 /* in the worst case we will try every wins server with every
1614 for (t
=0; wins_tags
&& wins_tags
[t
]; t
++) {
1615 int srv_count
= wins_srv_count_tag(wins_tags
[t
]);
1616 for (i
=0; i
<srv_count
; i
++) {
1617 struct sockaddr_storage wins_ss
;
1618 struct in_addr wins_ip
;
1620 wins_ip
= wins_srv_ip_tag(wins_tags
[t
], src_ip
);
1622 if (global_in_nmbd
&& ismyip_v4(wins_ip
)) {
1623 /* yikes! we'll loop forever */
1627 /* skip any that have been unresponsive lately */
1628 if (wins_srv_is_dead(wins_ip
, src_ip
)) {
1632 DEBUG(3,("resolve_wins: using WINS server %s "
1634 inet_ntoa(wins_ip
), wins_tags
[t
]));
1636 in_addr_to_sockaddr_storage(&wins_ss
, wins_ip
);
1637 status
= name_query(name
,
1647 /* exit loop if we got a list of addresses */
1649 if (NT_STATUS_IS_OK(status
)) {
1653 if (NT_STATUS_EQUAL(status
,
1654 NT_STATUS_IO_TIMEOUT
)) {
1655 /* Timed out waiting for WINS server to
1658 wins_srv_died(wins_ip
, src_ip
);
1660 /* The name definitely isn't in this
1661 group of WINS servers.
1662 goto the next group */
1668 wins_srv_tags_free(wins_tags
);
1669 return NT_STATUS_NO_LOGON_SERVERS
;
1673 status
= NT_STATUS_OK
;
1674 if (!convert_ss2service(return_iplist
, ss_list
, *return_count
))
1675 status
= NT_STATUS_INVALID_PARAMETER
;
1677 TALLOC_FREE(ss_list
);
1678 wins_srv_tags_free(wins_tags
);
1683 /********************************************************
1684 Resolve via "lmhosts" method.
1685 *********************************************************/
1687 static NTSTATUS
resolve_lmhosts(const char *name
, int name_type
,
1688 struct ip_service
**return_iplist
,
1692 * "lmhosts" means parse the local lmhosts file.
1694 struct sockaddr_storage
*ss_list
;
1695 NTSTATUS status
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1696 TALLOC_CTX
*ctx
= NULL
;
1698 *return_iplist
= NULL
;
1701 DEBUG(3,("resolve_lmhosts: "
1702 "Attempting lmhosts lookup for name %s<0x%x>\n",
1705 ctx
= talloc_init("resolve_lmhosts");
1707 return NT_STATUS_NO_MEMORY
;
1710 status
= resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(),
1715 if (NT_STATUS_IS_OK(status
)) {
1716 if (convert_ss2service(return_iplist
,
1720 return NT_STATUS_OK
;
1723 return NT_STATUS_NO_MEMORY
;
1731 /********************************************************
1732 Resolve via "hosts" method.
1733 *********************************************************/
1735 static NTSTATUS
resolve_hosts(const char *name
, int name_type
,
1736 struct ip_service
**return_iplist
,
1740 * "host" means do a localhost, or dns lookup.
1742 struct addrinfo hints
;
1743 struct addrinfo
*ailist
= NULL
;
1744 struct addrinfo
*res
= NULL
;
1748 if ( name_type
!= 0x20 && name_type
!= 0x0) {
1749 DEBUG(5, ("resolve_hosts: not appropriate "
1750 "for name type <0x%x>\n",
1752 return NT_STATUS_INVALID_PARAMETER
;
1755 *return_iplist
= NULL
;
1758 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
1762 /* By default make sure it supports TCP. */
1763 hints
.ai_socktype
= SOCK_STREAM
;
1764 hints
.ai_flags
= AI_ADDRCONFIG
;
1766 #if !defined(HAVE_IPV6)
1767 /* Unless we have IPv6, we really only want IPv4 addresses back. */
1768 hints
.ai_family
= AF_INET
;
1771 ret
= getaddrinfo(name
,
1776 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
1778 gai_strerror(ret
) ));
1781 for (res
= ailist
; res
; res
= res
->ai_next
) {
1782 struct sockaddr_storage ss
;
1784 if (!res
->ai_addr
|| res
->ai_addrlen
== 0) {
1789 memcpy(&ss
, res
->ai_addr
, res
->ai_addrlen
);
1793 *return_iplist
= SMB_REALLOC_ARRAY(*return_iplist
,
1796 if (!*return_iplist
) {
1797 DEBUG(3,("resolve_hosts: malloc fail !\n"));
1798 freeaddrinfo(ailist
);
1799 return NT_STATUS_NO_MEMORY
;
1801 (*return_iplist
)[i
].ss
= ss
;
1802 (*return_iplist
)[i
].port
= PORT_NONE
;
1806 freeaddrinfo(ailist
);
1808 if (*return_count
) {
1809 return NT_STATUS_OK
;
1811 return NT_STATUS_UNSUCCESSFUL
;
1814 /********************************************************
1815 Resolve via "ADS" method.
1816 *********************************************************/
1818 static NTSTATUS
resolve_ads(const char *name
,
1820 const char *sitename
,
1821 struct ip_service
**return_iplist
,
1827 struct dns_rr_srv
*dcs
= NULL
;
1831 if ((name_type
!= 0x1c) && (name_type
!= KDC_NAME_TYPE
) &&
1832 (name_type
!= 0x1b)) {
1833 return NT_STATUS_INVALID_PARAMETER
;
1836 if ( (ctx
= talloc_init("resolve_ads")) == NULL
) {
1837 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1838 return NT_STATUS_NO_MEMORY
;
1841 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
1843 switch (name_type
) {
1845 DEBUG(5,("resolve_ads: Attempting to resolve "
1846 "PDC for %s using DNS\n", name
));
1847 status
= ads_dns_query_pdc(ctx
, name
, &dcs
, &numdcs
);
1851 DEBUG(5,("resolve_ads: Attempting to resolve "
1852 "DCs for %s using DNS\n", name
));
1853 status
= ads_dns_query_dcs(ctx
, name
, sitename
, &dcs
,
1857 DEBUG(5,("resolve_ads: Attempting to resolve "
1858 "KDCs for %s using DNS\n", name
));
1859 status
= ads_dns_query_kdcs(ctx
, name
, sitename
, &dcs
,
1863 status
= NT_STATUS_INVALID_PARAMETER
;
1867 if ( !NT_STATUS_IS_OK( status
) ) {
1868 talloc_destroy(ctx
);
1872 for (i
=0;i
<numdcs
;i
++) {
1873 numaddrs
+= MAX(dcs
[i
].num_ips
,1);
1876 if ((*return_iplist
= SMB_MALLOC_ARRAY(struct ip_service
, numaddrs
)) ==
1878 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
1880 talloc_destroy(ctx
);
1881 return NT_STATUS_NO_MEMORY
;
1884 /* now unroll the list of IP addresses */
1889 while ( i
< numdcs
&& (*return_count
<numaddrs
) ) {
1890 struct ip_service
*r
= &(*return_iplist
)[*return_count
];
1892 r
->port
= dcs
[i
].port
;
1894 /* If we don't have an IP list for a name, lookup it up */
1897 interpret_string_addr(&r
->ss
, dcs
[i
].hostname
, 0);
1901 /* use the IP addresses from the SRV sresponse */
1903 if ( j
>= dcs
[i
].num_ips
) {
1909 r
->ss
= dcs
[i
].ss_s
[j
];
1913 /* make sure it is a valid IP. I considered checking the
1914 * negative connection cache, but this is the wrong place
1915 * for it. Maybe only as a hack. After think about it, if
1916 * all of the IP addresses returned from DNS are dead, what
1917 * hope does a netbios name lookup have ? The standard reason
1918 * for falling back to netbios lookups is that our DNS server
1919 * doesn't know anything about the DC's -- jerry */
1921 if (!is_zero_addr((struct sockaddr
*)&r
->ss
)) {
1926 talloc_destroy(ctx
);
1927 return NT_STATUS_OK
;
1930 /*******************************************************************
1931 Internal interface to resolve a name into an IP address.
1932 Use this function if the string is either an IP address, DNS
1933 or host name or NetBIOS name. This uses the name switch in the
1934 smb.conf to determine the order of name resolution.
1936 Added support for ip addr/port to support ADS ldap servers.
1937 the only place we currently care about the port is in the
1938 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1939 **********************************************************************/
1941 NTSTATUS
internal_resolve_name(const char *name
,
1943 const char *sitename
,
1944 struct ip_service
**return_iplist
,
1946 const char *resolve_order
)
1950 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
1952 TALLOC_CTX
*frame
= NULL
;
1954 *return_iplist
= NULL
;
1957 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1958 name
, name_type
, sitename
? sitename
: "(null)"));
1960 if (is_ipaddress(name
)) {
1961 if ((*return_iplist
= SMB_MALLOC_P(struct ip_service
)) ==
1963 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1964 return NT_STATUS_NO_MEMORY
;
1967 /* ignore the port here */
1968 (*return_iplist
)->port
= PORT_NONE
;
1970 /* if it's in the form of an IP address then get the lib to interpret it */
1971 if (!interpret_string_addr(&(*return_iplist
)->ss
,
1972 name
, AI_NUMERICHOST
)) {
1973 DEBUG(1,("internal_resolve_name: interpret_string_addr "
1976 SAFE_FREE(*return_iplist
);
1977 return NT_STATUS_INVALID_PARAMETER
;
1980 return NT_STATUS_OK
;
1983 /* Check name cache */
1985 if (namecache_fetch(name
, name_type
, return_iplist
, return_count
)) {
1986 /* This could be a negative response */
1987 if (*return_count
> 0) {
1988 return NT_STATUS_OK
;
1990 return NT_STATUS_UNSUCCESSFUL
;
1994 /* set the name resolution order */
1996 if (strcmp( resolve_order
, "NULL") == 0) {
1997 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1998 return NT_STATUS_INVALID_PARAMETER
;
2001 if (!resolve_order
[0]) {
2004 ptr
= resolve_order
;
2007 /* iterate through the name resolution backends */
2009 frame
= talloc_stackframe();
2010 while (next_token_talloc(frame
, &ptr
, &tok
, LIST_SEP
)) {
2011 if((strequal(tok
, "host") || strequal(tok
, "hosts"))) {
2012 status
= resolve_hosts(name
, name_type
, return_iplist
,
2014 if (NT_STATUS_IS_OK(status
)) {
2017 } else if(strequal( tok
, "kdc")) {
2018 /* deal with KDC_NAME_TYPE names here.
2019 * This will result in a SRV record lookup */
2020 status
= resolve_ads(name
, KDC_NAME_TYPE
, sitename
,
2021 return_iplist
, return_count
);
2022 if (NT_STATUS_IS_OK(status
)) {
2023 /* Ensure we don't namecache
2024 * this with the KDC port. */
2025 name_type
= KDC_NAME_TYPE
;
2028 } else if(strequal( tok
, "ads")) {
2029 /* deal with 0x1c and 0x1b names here.
2030 * This will result in a SRV record lookup */
2031 status
= resolve_ads(name
, name_type
, sitename
,
2032 return_iplist
, return_count
);
2033 if (NT_STATUS_IS_OK(status
)) {
2036 } else if(strequal( tok
, "lmhosts")) {
2037 status
= resolve_lmhosts(name
, name_type
,
2038 return_iplist
, return_count
);
2039 if (NT_STATUS_IS_OK(status
)) {
2042 } else if(strequal( tok
, "wins")) {
2043 /* don't resolve 1D via WINS */
2044 if (name_type
!= 0x1D) {
2045 status
= resolve_wins(name
, name_type
,
2048 if (NT_STATUS_IS_OK(status
)) {
2052 } else if(strequal( tok
, "bcast")) {
2053 status
= name_resolve_bcast(name
, name_type
,
2056 if (NT_STATUS_IS_OK(status
)) {
2060 DEBUG(0,("resolve_name: unknown name switch type %s\n",
2065 /* All of the resolve_* functions above have returned false. */
2068 SAFE_FREE(*return_iplist
);
2071 return NT_STATUS_UNSUCCESSFUL
;
2075 /* Remove duplicate entries. Some queries, notably #1c (domain
2076 controllers) return the PDC in iplist[0] and then all domain
2077 controllers including the PDC in iplist[1..n]. Iterating over
2078 the iplist when the PDC is down will cause two sets of timeouts. */
2080 if ( *return_count
) {
2081 *return_count
= remove_duplicate_addrs2(*return_iplist
,
2085 /* Save in name cache */
2086 if ( DEBUGLEVEL
>= 100 ) {
2087 for (i
= 0; i
< *return_count
&& DEBUGLEVEL
== 100; i
++) {
2088 char addr
[INET6_ADDRSTRLEN
];
2089 print_sockaddr(addr
, sizeof(addr
),
2090 &(*return_iplist
)[i
].ss
);
2091 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
2095 (*return_iplist
)[i
].port
));
2099 namecache_store(name
, name_type
, *return_count
, *return_iplist
);
2101 /* Display some debugging info */
2103 if ( DEBUGLEVEL
>= 10 ) {
2104 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
2107 for (i
= 0; i
< *return_count
; i
++) {
2108 char addr
[INET6_ADDRSTRLEN
];
2109 print_sockaddr(addr
, sizeof(addr
),
2110 &(*return_iplist
)[i
].ss
);
2111 DEBUGADD(10, ("%s:%d ",
2113 (*return_iplist
)[i
].port
));
2122 /********************************************************
2123 Internal interface to resolve a name into one IP address.
2124 Use this function if the string is either an IP address, DNS
2125 or host name or NetBIOS name. This uses the name switch in the
2126 smb.conf to determine the order of name resolution.
2127 *********************************************************/
2129 bool resolve_name(const char *name
,
2130 struct sockaddr_storage
*return_ss
,
2134 struct ip_service
*ss_list
= NULL
;
2135 char *sitename
= NULL
;
2138 if (is_ipaddress(name
)) {
2139 return interpret_string_addr(return_ss
, name
, AI_NUMERICHOST
);
2142 sitename
= sitename_fetch(lp_realm()); /* wild guess */
2144 if (NT_STATUS_IS_OK(internal_resolve_name(name
, name_type
, sitename
,
2146 lp_name_resolve_order()))) {
2150 for (i
=0; i
<count
; i
++) {
2151 if (!is_zero_addr((struct sockaddr
*)&ss_list
[i
].ss
) &&
2152 !is_broadcast_addr((struct sockaddr
*)&ss_list
[i
].ss
) &&
2153 (ss_list
[i
].ss
.ss_family
== AF_INET
)) {
2154 *return_ss
= ss_list
[i
].ss
;
2156 SAFE_FREE(sitename
);
2162 /* only return valid addresses for TCP connections */
2163 for (i
=0; i
<count
; i
++) {
2164 if (!is_zero_addr((struct sockaddr
*)&ss_list
[i
].ss
) &&
2165 !is_broadcast_addr((struct sockaddr
*)&ss_list
[i
].ss
)) {
2166 *return_ss
= ss_list
[i
].ss
;
2168 SAFE_FREE(sitename
);
2175 SAFE_FREE(sitename
);
2179 /********************************************************
2180 Internal interface to resolve a name into a list of IP addresses.
2181 Use this function if the string is either an IP address, DNS
2182 or host name or NetBIOS name. This uses the name switch in the
2183 smb.conf to determine the order of name resolution.
2184 *********************************************************/
2186 NTSTATUS
resolve_name_list(TALLOC_CTX
*ctx
,
2189 struct sockaddr_storage
**return_ss_arr
,
2190 unsigned int *p_num_entries
)
2192 struct ip_service
*ss_list
= NULL
;
2193 char *sitename
= NULL
;
2196 unsigned int num_entries
;
2200 *return_ss_arr
= NULL
;
2202 if (is_ipaddress(name
)) {
2203 *return_ss_arr
= TALLOC_P(ctx
, struct sockaddr_storage
);
2204 if (!*return_ss_arr
) {
2205 return NT_STATUS_NO_MEMORY
;
2207 if (!interpret_string_addr(*return_ss_arr
, name
, AI_NUMERICHOST
)) {
2208 TALLOC_FREE(*return_ss_arr
);
2209 return NT_STATUS_BAD_NETWORK_NAME
;
2212 return NT_STATUS_OK
;
2215 sitename
= sitename_fetch(lp_realm()); /* wild guess */
2217 status
= internal_resolve_name(name
, name_type
, sitename
,
2219 lp_name_resolve_order());
2220 SAFE_FREE(sitename
);
2222 if (!NT_STATUS_IS_OK(status
)) {
2226 /* only return valid addresses for TCP connections */
2227 for (i
=0, num_entries
= 0; i
<count
; i
++) {
2228 if (!is_zero_addr((struct sockaddr
*)&ss_list
[i
].ss
) &&
2229 !is_broadcast_addr((struct sockaddr
*)&ss_list
[i
].ss
)) {
2233 if (num_entries
== 0) {
2235 return NT_STATUS_BAD_NETWORK_NAME
;
2238 *return_ss_arr
= TALLOC_ARRAY(ctx
,
2239 struct sockaddr_storage
,
2241 if (!(*return_ss_arr
)) {
2243 return NT_STATUS_NO_MEMORY
;
2246 for (i
=0, num_entries
= 0; i
<count
; i
++) {
2247 if (!is_zero_addr((struct sockaddr
*)&ss_list
[i
].ss
) &&
2248 !is_broadcast_addr((struct sockaddr
*)&ss_list
[i
].ss
)) {
2249 (*return_ss_arr
)[num_entries
++] = ss_list
[i
].ss
;
2253 status
= NT_STATUS_OK
;
2254 *p_num_entries
= num_entries
;
2257 return NT_STATUS_OK
;
2260 /********************************************************
2261 Find the IP address of the master browser or DMB for a workgroup.
2262 *********************************************************/
2264 bool find_master_ip(const char *group
, struct sockaddr_storage
*master_ss
)
2266 struct ip_service
*ip_list
= NULL
;
2270 if (lp_disable_netbios()) {
2271 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group
));
2275 status
= internal_resolve_name(group
, 0x1D, NULL
, &ip_list
, &count
,
2276 lp_name_resolve_order());
2277 if (NT_STATUS_IS_OK(status
)) {
2278 *master_ss
= ip_list
[0].ss
;
2283 status
= internal_resolve_name(group
, 0x1B, NULL
, &ip_list
, &count
,
2284 lp_name_resolve_order());
2285 if (NT_STATUS_IS_OK(status
)) {
2286 *master_ss
= ip_list
[0].ss
;
2295 /********************************************************
2296 Get the IP address list of the primary domain controller
2298 *********************************************************/
2300 bool get_pdc_ip(const char *domain
, struct sockaddr_storage
*pss
)
2302 struct ip_service
*ip_list
= NULL
;
2304 NTSTATUS status
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
2306 /* Look up #1B name */
2308 if (lp_security() == SEC_ADS
) {
2309 status
= internal_resolve_name(domain
, 0x1b, NULL
, &ip_list
,
2313 if (!NT_STATUS_IS_OK(status
) || count
== 0) {
2314 status
= internal_resolve_name(domain
, 0x1b, NULL
, &ip_list
,
2316 lp_name_resolve_order());
2317 if (!NT_STATUS_IS_OK(status
)) {
2322 /* if we get more than 1 IP back we have to assume it is a
2323 multi-homed PDC and not a mess up */
2326 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count
));
2327 sort_service_list(ip_list
, count
);
2330 *pss
= ip_list
[0].ss
;
2335 /* Private enum type for lookups. */
2337 enum dc_lookup_type
{ DC_NORMAL_LOOKUP
, DC_ADS_ONLY
, DC_KDC_ONLY
};
2339 /********************************************************
2340 Get the IP address list of the domain controllers for
2342 *********************************************************/
2344 static NTSTATUS
get_dc_list(const char *domain
,
2345 const char *sitename
,
2346 struct ip_service
**ip_list
,
2348 enum dc_lookup_type lookup_type
,
2351 char *resolve_order
= NULL
;
2352 char *saf_servername
= NULL
;
2353 char *pserver
= NULL
;
2355 char *port_str
= NULL
;
2358 int num_addresses
= 0;
2359 int local_count
, i
, j
;
2360 struct ip_service
*return_iplist
= NULL
;
2361 struct ip_service
*auto_ip_list
= NULL
;
2362 bool done_auto_lookup
= false;
2365 TALLOC_CTX
*ctx
= talloc_init("get_dc_list");
2371 return NT_STATUS_NO_MEMORY
;
2376 /* if we are restricted to solely using DNS for looking
2377 up a domain controller, make sure that host lookups
2378 are enabled for the 'name resolve order'. If host lookups
2379 are disabled and ads_only is True, then set the string to
2382 resolve_order
= talloc_strdup(ctx
, lp_name_resolve_order());
2383 if (!resolve_order
) {
2384 status
= NT_STATUS_NO_MEMORY
;
2387 strlower_m(resolve_order
);
2388 if (lookup_type
== DC_ADS_ONLY
) {
2389 if (strstr( resolve_order
, "host")) {
2390 resolve_order
= talloc_strdup(ctx
, "ads");
2392 /* DNS SRV lookups used by the ads resolver
2393 are already sorted by priority and weight */
2396 resolve_order
= talloc_strdup(ctx
, "NULL");
2398 } else if (lookup_type
== DC_KDC_ONLY
) {
2399 /* DNS SRV lookups used by the ads/kdc resolver
2400 are already sorted by priority and weight */
2402 resolve_order
= talloc_strdup(ctx
, "kdc");
2404 if (!resolve_order
) {
2405 status
= NT_STATUS_NO_MEMORY
;
2409 /* fetch the server we have affinity for. Add the
2410 'password server' list to a search for our domain controllers */
2412 saf_servername
= saf_fetch( domain
);
2414 if (strequal(domain
, lp_workgroup()) || strequal(domain
, lp_realm())) {
2415 pserver
= talloc_asprintf(ctx
, "%s, %s",
2416 saf_servername
? saf_servername
: "",
2417 lp_passwordserver());
2419 pserver
= talloc_asprintf(ctx
, "%s, *",
2420 saf_servername
? saf_servername
: "");
2423 SAFE_FREE(saf_servername
);
2425 status
= NT_STATUS_NO_MEMORY
;
2429 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
2432 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
2433 status
= internal_resolve_name(domain
, 0x1C, sitename
, ip_list
,
2434 count
, resolve_order
);
2438 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver
));
2441 * if '*' appears in the "password server" list then add
2442 * an auto lookup to the list of manually configured
2443 * DC's. If any DC is listed by name, then the list should be
2444 * considered to be ordered
2448 while (next_token_talloc(ctx
, &p
, &name
, LIST_SEP
)) {
2449 if (!done_auto_lookup
&& strequal(name
, "*")) {
2450 status
= internal_resolve_name(domain
, 0x1C, sitename
,
2454 if (NT_STATUS_IS_OK(status
)) {
2455 num_addresses
+= auto_count
;
2457 done_auto_lookup
= true;
2458 DEBUG(8,("Adding %d DC's from auto lookup\n",
2465 /* if we have no addresses and haven't done the auto lookup, then
2466 just return the list of DC's. Or maybe we just failed. */
2468 if ((num_addresses
== 0)) {
2469 if (done_auto_lookup
) {
2470 DEBUG(4,("get_dc_list: no servers found\n"));
2471 status
= NT_STATUS_NO_LOGON_SERVERS
;
2474 status
= internal_resolve_name(domain
, 0x1C, sitename
, ip_list
,
2475 count
, resolve_order
);
2479 if ((return_iplist
= SMB_MALLOC_ARRAY(struct ip_service
,
2480 num_addresses
)) == NULL
) {
2481 DEBUG(3,("get_dc_list: malloc fail !\n"));
2482 status
= NT_STATUS_NO_MEMORY
;
2489 /* fill in the return list now with real IP's */
2491 while ((local_count
<num_addresses
) &&
2492 next_token_talloc(ctx
, &p
, &name
, LIST_SEP
)) {
2493 struct sockaddr_storage name_ss
;
2495 /* copy any addersses from the auto lookup */
2497 if (strequal(name
, "*")) {
2498 for (j
=0; j
<auto_count
; j
++) {
2499 char addr
[INET6_ADDRSTRLEN
];
2500 print_sockaddr(addr
,
2502 &auto_ip_list
[j
].ss
);
2503 /* Check for and don't copy any
2504 * known bad DC IP's. */
2505 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
2508 DEBUG(5,("get_dc_list: "
2509 "negative entry %s removed "
2514 return_iplist
[local_count
].ss
=
2516 return_iplist
[local_count
].port
=
2517 auto_ip_list
[j
].port
;
2523 /* added support for address:port syntax for ads
2524 * (not that I think anyone will ever run the LDAP
2525 * server in an AD domain on something other than
2528 port
= (lp_security() == SEC_ADS
) ? LDAP_PORT
: PORT_NONE
;
2529 if ((port_str
=strchr(name
, ':')) != NULL
) {
2532 port
= atoi(port_str
);
2535 /* explicit lookup; resolve_name() will
2536 * handle names & IP addresses */
2537 if (resolve_name( name
, &name_ss
, 0x20, true )) {
2538 char addr
[INET6_ADDRSTRLEN
];
2539 print_sockaddr(addr
,
2543 /* Check for and don't copy any known bad DC IP's. */
2544 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain
,
2546 DEBUG(5,("get_dc_list: negative entry %s "
2547 "removed from DC list\n",
2552 return_iplist
[local_count
].ss
= name_ss
;
2553 return_iplist
[local_count
].port
= port
;
2559 /* need to remove duplicates in the list if we have any
2560 explicit password servers */
2563 local_count
= remove_duplicate_addrs2(return_iplist
,
2567 /* For DC's we always prioritize IPv4 due to W2K3 not
2568 * supporting LDAP, KRB5 or CLDAP over IPv6. */
2570 if (local_count
&& return_iplist
) {
2571 prioritize_ipv4_list(return_iplist
, local_count
);
2574 if ( DEBUGLEVEL
>= 4 ) {
2575 DEBUG(4,("get_dc_list: returning %d ip addresses "
2576 "in an %sordered list\n",
2578 *ordered
? "":"un"));
2579 DEBUG(4,("get_dc_list: "));
2580 for ( i
=0; i
<local_count
; i
++ ) {
2581 char addr
[INET6_ADDRSTRLEN
];
2582 print_sockaddr(addr
,
2584 &return_iplist
[i
].ss
);
2585 DEBUGADD(4,("%s:%d ", addr
, return_iplist
[i
].port
));
2590 *ip_list
= return_iplist
;
2591 *count
= local_count
;
2593 status
= ( *count
!= 0 ? NT_STATUS_OK
: NT_STATUS_NO_LOGON_SERVERS
);
2597 if (!NT_STATUS_IS_OK(status
)) {
2598 SAFE_FREE(return_iplist
);
2603 SAFE_FREE(auto_ip_list
);
2608 /*********************************************************************
2609 Small wrapper function to get the DC list and sort it if neccessary.
2610 *********************************************************************/
2612 NTSTATUS
get_sorted_dc_list( const char *domain
,
2613 const char *sitename
,
2614 struct ip_service
**ip_list
,
2618 bool ordered
= false;
2620 enum dc_lookup_type lookup_type
= DC_NORMAL_LOOKUP
;
2625 DEBUG(8,("get_sorted_dc_list: attempting lookup "
2626 "for name %s (sitename %s) using [%s]\n",
2628 sitename
? sitename
: "NULL",
2629 (ads_only
? "ads" : lp_name_resolve_order())));
2632 lookup_type
= DC_ADS_ONLY
;
2635 status
= get_dc_list(domain
, sitename
, ip_list
,
2636 count
, lookup_type
, &ordered
);
2637 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_LOGON_SERVERS
)
2639 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
2640 " in site %s, fallback to all servers\n",
2642 status
= get_dc_list(domain
, NULL
, ip_list
,
2643 count
, lookup_type
, &ordered
);
2646 if (!NT_STATUS_IS_OK(status
)) {
2647 SAFE_FREE(*ip_list
);
2652 /* only sort if we don't already have an ordered list */
2654 sort_service_list(*ip_list
, *count
);
2657 return NT_STATUS_OK
;
2660 /*********************************************************************
2661 Get the KDC list - re-use all the logic in get_dc_list.
2662 *********************************************************************/
2664 NTSTATUS
get_kdc_list( const char *realm
,
2665 const char *sitename
,
2666 struct ip_service
**ip_list
,
2675 status
= get_dc_list(realm
, sitename
, ip_list
,
2676 count
, DC_KDC_ONLY
, &ordered
);
2678 if (!NT_STATUS_IS_OK(status
)) {
2679 SAFE_FREE(*ip_list
);
2684 /* only sort if we don't already have an ordered list */
2686 sort_service_list(*ip_list
, *count
);
2689 return NT_STATUS_OK
;