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.h"
25 #include "librpc/gen_ndr/messaging.h"
27 /* nmbd.c sets this to True. */
28 bool global_in_nmbd = False;
30 /****************************
31 * SERVER AFFINITY ROUTINES *
32 ****************************/
34 /* Server affinity is the concept of preferring the last domain
35 controller with whom you had a successful conversation */
37 /****************************************************************************
38 ****************************************************************************/
39 #define SAFKEY_FMT "SAF/DOMAIN/%s"
41 #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
42 #define SAFJOIN_TTL 3600
44 static char *saf_key(const char *domain)
48 asprintf_strupper_m(&keystr, SAFKEY_FMT, domain);
53 static char *saf_join_key(const char *domain)
57 asprintf_strupper_m(&keystr, SAFJOINKEY_FMT, domain);
62 /****************************************************************************
63 ****************************************************************************/
65 bool saf_store( const char *domain, const char *servername )
71 if ( !domain || !servername ) {
72 DEBUG(2,("saf_store: "
73 "Refusing to store empty domain or servername!\n"));
77 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
78 DEBUG(0,("saf_store: "
79 "refusing to store 0 length domain or servername!\n"));
83 key = saf_key( domain );
84 expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
86 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
87 domain, servername, (unsigned int)expire ));
89 ret = gencache_set( key, servername, expire );
96 bool saf_join_store( const char *domain, const char *servername )
102 if ( !domain || !servername ) {
103 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
107 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
108 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
112 key = saf_join_key( domain );
113 expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
115 DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
116 domain, servername, (unsigned int)expire ));
118 ret = gencache_set( key, servername, expire );
125 bool saf_delete( const char *domain )
131 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
135 key = saf_join_key(domain);
136 ret = gencache_del(key);
140 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
143 key = saf_key(domain);
144 ret = gencache_del(key);
148 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
154 /****************************************************************************
155 ****************************************************************************/
157 char *saf_fetch( const char *domain )
164 if ( !domain || strlen(domain) == 0) {
165 DEBUG(2,("saf_fetch: Empty domain name!\n"));
169 key = saf_join_key( domain );
171 ret = gencache_get( key, &server, &timeout );
176 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
181 key = saf_key( domain );
183 ret = gencache_get( key, &server, &timeout );
188 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
191 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
198 /****************************************************************************
199 Generate a random trn_id.
200 ****************************************************************************/
202 static int generate_trn_id(void)
206 generate_random_buffer((uint8 *)&id, sizeof(id));
208 return id % (unsigned)0x7FFF;
211 /****************************************************************************
212 Parse a node status response into an array of structures.
213 ****************************************************************************/
215 static NODE_STATUS_STRUCT *parse_node_status(char *p,
217 struct node_status_extra *extra)
219 NODE_STATUS_STRUCT *ret;
222 *num_names = CVAL(p,0);
227 ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
232 for (i=0;i< *num_names;i++) {
233 StrnCpy(ret[i].name,p,15);
234 trim_char(ret[i].name,'\0',' ');
235 ret[i].type = CVAL(p,15);
236 ret[i].flags = p[16];
238 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
239 ret[i].type, ret[i].flags));
242 * Also, pick up the MAC address ...
245 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
250 /****************************************************************************
251 Try and send a request to nmbd to send a packet_struct packet first.
252 If this fails, use send_packet().
253 **************************************************************************/
255 static bool send_packet_request(struct packet_struct *p)
257 struct messaging_context *msg_ctx = server_messaging_context();
259 pid_t nmbd_pid = pidfile_pid("nmbd");
263 if (NT_STATUS_IS_OK(messaging_send_buf(msg_ctx,
264 pid_to_procid(nmbd_pid),
267 sizeof(struct packet_struct)))) {
273 return send_packet(p);
276 /****************************************************************************
277 Do a NBT node status query on an open socket and return an array of
278 structures holding the returned names or NULL if the query failed.
279 **************************************************************************/
281 NODE_STATUS_STRUCT *node_status_query(int fd,
282 struct nmb_name *name,
283 const struct sockaddr_storage *to_ss,
285 struct node_status_extra *extra)
289 int retry_time = 2000;
291 struct packet_struct p;
292 struct packet_struct *p2;
293 struct nmb_packet *nmb = &p.packet.nmb;
294 NODE_STATUS_STRUCT *ret;
298 if (to_ss->ss_family != AF_INET) {
299 /* Can't do node status to IPv6 */
302 nmb->header.name_trn_id = generate_trn_id();
303 nmb->header.opcode = 0;
304 nmb->header.response = false;
305 nmb->header.nm_flags.bcast = false;
306 nmb->header.nm_flags.recursion_available = false;
307 nmb->header.nm_flags.recursion_desired = false;
308 nmb->header.nm_flags.trunc = false;
309 nmb->header.nm_flags.authoritative = false;
310 nmb->header.rcode = 0;
311 nmb->header.qdcount = 1;
312 nmb->header.ancount = 0;
313 nmb->header.nscount = 0;
314 nmb->header.arcount = 0;
315 nmb->question.question_name = *name;
316 nmb->question.question_type = 0x21;
317 nmb->question.question_class = 0x1;
319 p.ip = ((const struct sockaddr_in *)to_ss)->sin_addr;
323 p.timestamp = time(NULL);
324 p.packet_type = NMB_PACKET;
326 clock_gettime_mono(&tp);
328 if (!send_packet_request(&p))
335 clock_gettime_mono(&tp2);
336 if (nsec_time_diff(&tp2,&tp)/1000000 > retry_time) {
339 if (!found && !send_packet_request(&p))
341 clock_gettime_mono(&tp);
345 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
346 struct nmb_packet *nmb2 = &p2->packet.nmb;
347 debug_nmb_packet(p2);
349 if (nmb2->header.opcode != 0 ||
350 nmb2->header.nm_flags.bcast ||
351 nmb2->header.rcode ||
352 !nmb2->header.ancount ||
353 nmb2->answers->rr_type != 0x21) {
354 /* XXXX what do we do with this? could be a
355 redirect, but we'll discard it for the
361 ret = parse_node_status(&nmb2->answers->rdata[0],
371 /****************************************************************************
372 Find the first type XX name in a node status reply - used for finding
373 a servers name given its IP. Return the matched name in *name.
374 **************************************************************************/
376 bool name_status_find(const char *q_name,
379 const struct sockaddr_storage *to_ss,
382 char addr[INET6_ADDRSTRLEN];
383 struct sockaddr_storage ss;
384 NODE_STATUS_STRUCT *status = NULL;
385 struct nmb_name nname;
390 if (lp_disable_netbios()) {
391 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
396 print_sockaddr(addr, sizeof(addr), to_ss);
398 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
401 /* Check the cache first. */
403 if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
407 if (to_ss->ss_family != AF_INET) {
408 /* Can't do node status to IPv6 */
412 if (!interpret_string_addr(&ss, lp_socket_address(),
413 AI_NUMERICHOST|AI_PASSIVE)) {
417 sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);
421 /* W2K PDC's seem not to respond to '*'#0. JRA */
422 make_nmb_name(&nname, q_name, q_type);
423 status = node_status_query(sock, &nname, to_ss, &count, NULL);
428 for (i=0;i<count;i++) {
429 /* Find first one of the requested type that's not a GROUP. */
430 if (status[i].type == type && ! (status[i].flags & 0x80))
436 pull_ascii_nstring(name, sizeof(fstring), status[i].name);
438 /* Store the result in the cache. */
439 /* but don't store an entry for 0x1c names here. Here we have
440 a single host and DOMAIN<0x1c> names should be a list of hosts */
442 if ( q_type != 0x1c ) {
443 namecache_status_store(q_name, q_type, type, to_ss, name);
451 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
454 DEBUGADD(10, (", name %s ip address is %s", name, addr));
462 comparison function used by sort_addr_list
465 static int addr_compare(const struct sockaddr_storage *ss1,
466 const struct sockaddr_storage *ss2)
468 int max_bits1=0, max_bits2=0;
469 int num_interfaces = iface_count();
472 /* Sort IPv4 addresses first. */
473 if (ss1->ss_family != ss2->ss_family) {
474 if (ss2->ss_family == AF_INET) {
481 /* Here we know both addresses are of the same
484 for (i=0;i<num_interfaces;i++) {
485 const struct sockaddr_storage *pss = iface_n_bcast(i);
486 unsigned char *p_ss1 = NULL;
487 unsigned char *p_ss2 = NULL;
488 unsigned char *p_if = NULL;
492 if (pss->ss_family != ss1->ss_family) {
493 /* Ignore interfaces of the wrong type. */
496 if (pss->ss_family == AF_INET) {
497 p_if = (unsigned char *)
498 &((const struct sockaddr_in *)pss)->sin_addr;
499 p_ss1 = (unsigned char *)
500 &((const struct sockaddr_in *)ss1)->sin_addr;
501 p_ss2 = (unsigned char *)
502 &((const struct sockaddr_in *)ss2)->sin_addr;
505 #if defined(HAVE_IPV6)
506 if (pss->ss_family == AF_INET6) {
507 p_if = (unsigned char *)
508 &((const struct sockaddr_in6 *)pss)->sin6_addr;
509 p_ss1 = (unsigned char *)
510 &((const struct sockaddr_in6 *)ss1)->sin6_addr;
511 p_ss2 = (unsigned char *)
512 &((const struct sockaddr_in6 *)ss2)->sin6_addr;
516 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
519 bits1 = matching_len_bits(p_ss1, p_if, len);
520 bits2 = matching_len_bits(p_ss2, p_if, len);
521 max_bits1 = MAX(bits1, max_bits1);
522 max_bits2 = MAX(bits2, max_bits2);
525 /* Bias towards directly reachable IPs */
526 if (iface_local((struct sockaddr *)ss1)) {
527 if (ss1->ss_family == AF_INET) {
533 if (iface_local((struct sockaddr *)ss2)) {
534 if (ss2->ss_family == AF_INET) {
540 return max_bits2 - max_bits1;
543 /*******************************************************************
544 compare 2 ldap IPs by nearness to our interfaces - used in qsort
545 *******************************************************************/
547 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
551 if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) {
555 if (ss1->port > ss2->port) {
559 if (ss1->port < ss2->port) {
567 sort an IP list so that names that are close to one of our interfaces
568 are at the top. This prevents the problem where a WINS server returns an IP
569 that is not reachable from our subnet as the first match
572 static void sort_addr_list(struct sockaddr_storage *sslist, int count)
578 TYPESAFE_QSORT(sslist, count, addr_compare);
581 static void sort_service_list(struct ip_service *servlist, int count)
587 TYPESAFE_QSORT(servlist, count, ip_service_compare);
590 /**********************************************************************
591 Remove any duplicate address/port pairs in the list
592 *********************************************************************/
594 static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
598 DEBUG(10,("remove_duplicate_addrs2: "
599 "looking for duplicate address/port pairs\n"));
601 /* one loop to remove duplicates */
602 for ( i=0; i<count; i++ ) {
603 if ( is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
607 for ( j=i+1; j<count; j++ ) {
608 if (sockaddr_equal((struct sockaddr *)&iplist[i].ss, (struct sockaddr *)&iplist[j].ss) &&
609 iplist[i].port == iplist[j].port) {
610 zero_sockaddr(&iplist[j].ss);
615 /* one loop to clean up any holes we left */
616 /* first ip should never be a zero_ip() */
617 for (i = 0; i<count; ) {
618 if (is_zero_addr((struct sockaddr *)&iplist[i].ss) ) {
620 memmove(&iplist[i], &iplist[i+1],
621 (count - i - 1)*sizeof(iplist[i]));
632 static bool prioritize_ipv4_list(struct ip_service *iplist, int count)
634 TALLOC_CTX *frame = talloc_stackframe();
635 struct ip_service *iplist_new = TALLOC_ARRAY(frame, struct ip_service, count);
638 if (iplist_new == NULL) {
645 /* Copy IPv4 first. */
646 for (i = 0; i < count; i++) {
647 if (iplist[i].ss.ss_family == AF_INET) {
648 iplist_new[j++] = iplist[i];
653 for (i = 0; i < count; i++) {
654 if (iplist[i].ss.ss_family != AF_INET) {
655 iplist_new[j++] = iplist[i];
659 memcpy(iplist, iplist_new, sizeof(struct ip_service)*count);
664 /****************************************************************************
665 Do a netbios name query to find someones IP.
666 Returns an array of IP addresses or NULL if none.
667 *count will be set to the number of addresses returned.
668 *timed_out is set if we failed by timing out
669 ****************************************************************************/
671 struct sockaddr_storage *name_query(int fd,
676 const struct sockaddr_storage *to_ss,
683 int retry_time = bcast?250:2000;
685 struct packet_struct p;
686 struct packet_struct *p2;
687 struct nmb_packet *nmb = &p.packet.nmb;
688 struct sockaddr_storage *ss_list = NULL;
690 if (lp_disable_netbios()) {
691 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
696 if (to_ss->ss_family != AF_INET) {
704 memset((char *)&p,'\0',sizeof(p));
708 nmb->header.name_trn_id = generate_trn_id();
709 nmb->header.opcode = 0;
710 nmb->header.response = false;
711 nmb->header.nm_flags.bcast = bcast;
712 nmb->header.nm_flags.recursion_available = false;
713 nmb->header.nm_flags.recursion_desired = recurse;
714 nmb->header.nm_flags.trunc = false;
715 nmb->header.nm_flags.authoritative = false;
716 nmb->header.rcode = 0;
717 nmb->header.qdcount = 1;
718 nmb->header.ancount = 0;
719 nmb->header.nscount = 0;
720 nmb->header.arcount = 0;
722 make_nmb_name(&nmb->question.question_name,name,name_type);
724 nmb->question.question_type = 0x20;
725 nmb->question.question_class = 0x1;
727 p.ip = ((struct sockaddr_in *)to_ss)->sin_addr;
731 p.timestamp = time(NULL);
732 p.packet_type = NMB_PACKET;
734 clock_gettime_mono(&tp);
736 if (!send_packet_request(&p))
744 clock_gettime_mono(&tp2);
745 if (nsec_time_diff(&tp2,&tp)/1000000 > retry_time) {
748 if (!found && !send_packet_request(&p))
750 clock_gettime_mono(&tp);
753 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
754 struct nmb_packet *nmb2 = &p2->packet.nmb;
755 debug_nmb_packet(p2);
757 /* If we get a Negative Name Query Response from a WINS
758 * server, we should report it and give up.
760 if( 0 == nmb2->header.opcode /* A query response */
761 && !(bcast) /* from a WINS server */
762 && nmb2->header.rcode /* Error returned */
765 if( DEBUGLVL( 3 ) ) {
766 /* Only executed if DEBUGLEVEL >= 3 */
767 dbgtext( "Negative name query "
768 "response, rcode 0x%02x: ",
769 nmb2->header.rcode );
770 switch( nmb2->header.rcode ) {
773 "was invalidly formatted.\n" );
776 dbgtext( "Problem with NBNS, "
777 "cannot process name.\n");
780 dbgtext( "The name requested "
781 "does not exist.\n" );
784 dbgtext( "Unsupported request "
788 dbgtext( "Query refused "
792 dbgtext( "Unrecognized error "
801 if (nmb2->header.opcode != 0 ||
802 nmb2->header.nm_flags.bcast ||
803 nmb2->header.rcode ||
804 !nmb2->header.ancount) {
806 * XXXX what do we do with this? Could be a
807 * redirect, but we'll discard it for the
814 ss_list = SMB_REALLOC_ARRAY(ss_list,
815 struct sockaddr_storage,
817 nmb2->answers->rdlength/6);
820 DEBUG(0,("name_query: Realloc failed.\n"));
825 DEBUG(2,("Got a positive name query response "
829 for (i=0;i<nmb2->answers->rdlength/6;i++) {
831 putip((char *)&ip,&nmb2->answers->rdata[2+i*6]);
832 in_addr_to_sockaddr_storage(&ss_list[(*count)],
834 DEBUGADD(2,("%s ",inet_ntoa(ip)));
841 /* We add the flags back ... */
842 if (nmb2->header.response)
843 (*flags) |= NM_FLAGS_RS;
844 if (nmb2->header.nm_flags.authoritative)
845 (*flags) |= NM_FLAGS_AA;
846 if (nmb2->header.nm_flags.trunc)
847 (*flags) |= NM_FLAGS_TC;
848 if (nmb2->header.nm_flags.recursion_desired)
849 (*flags) |= NM_FLAGS_RD;
850 if (nmb2->header.nm_flags.recursion_available)
851 (*flags) |= NM_FLAGS_RA;
852 if (nmb2->header.nm_flags.bcast)
853 (*flags) |= NM_FLAGS_B;
856 * If we're doing a unicast lookup we only
857 * expect one reply. Don't wait the full 2
858 * seconds if we got one. JRA.
865 /* only set timed_out if we didn't fund what we where looking for*/
867 if ( !found && timed_out ) {
871 /* sort the ip list so we choose close servers first if possible */
872 sort_addr_list(ss_list, *count);
877 /********************************************************
878 convert an array if struct sockaddr_storage to struct ip_service
879 return false on failure. Port is set to PORT_NONE;
880 *********************************************************/
882 static bool convert_ss2service(struct ip_service **return_iplist,
883 const struct sockaddr_storage *ss_list,
888 if ( count==0 || !ss_list )
891 /* copy the ip address; port will be PORT_NONE */
892 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
894 DEBUG(0,("convert_ip2service: malloc failed "
895 "for %d enetries!\n", count ));
899 for ( i=0; i<count; i++ ) {
900 (*return_iplist)[i].ss = ss_list[i];
901 (*return_iplist)[i].port = PORT_NONE;
907 /********************************************************
908 Resolve via "bcast" method.
909 *********************************************************/
911 NTSTATUS name_resolve_bcast(const char *name,
913 struct ip_service **return_iplist,
917 int num_interfaces = iface_count();
918 struct sockaddr_storage *ss_list;
919 struct sockaddr_storage ss;
922 if (lp_disable_netbios()) {
923 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
925 return NT_STATUS_INVALID_PARAMETER;
928 *return_iplist = NULL;
932 * "bcast" means do a broadcast lookup on all the local interfaces.
935 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
936 "for name %s<0x%x>\n", name, name_type));
938 if (!interpret_string_addr(&ss, lp_socket_address(),
939 AI_NUMERICHOST|AI_PASSIVE)) {
943 sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
945 return NT_STATUS_UNSUCCESSFUL;
948 set_socket_options(sock,"SO_BROADCAST");
950 * Lookup the name on all the interfaces, return on
951 * the first successful match.
953 for( i = num_interfaces-1; i >= 0; i--) {
954 const struct sockaddr_storage *pss = iface_n_bcast(i);
957 /* Done this way to fix compiler error on IRIX 5.x */
961 ss_list = name_query(sock, name, name_type, true,
962 true, pss, return_count, &flags, NULL);
968 /* failed - no response */
971 return NT_STATUS_UNSUCCESSFUL;
975 status = NT_STATUS_OK;
976 if (!convert_ss2service(return_iplist, ss_list, *return_count) )
977 status = NT_STATUS_INVALID_PARAMETER;
984 /********************************************************
985 Resolve via "wins" method.
986 *********************************************************/
988 NTSTATUS resolve_wins(const char *name,
990 struct ip_service **return_iplist,
995 struct sockaddr_storage src_ss, *ss_list = NULL;
996 struct in_addr src_ip;
999 if (lp_disable_netbios()) {
1000 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
1002 return NT_STATUS_INVALID_PARAMETER;
1005 *return_iplist = NULL;
1008 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
1011 if (wins_srv_count() < 1) {
1012 DEBUG(3,("resolve_wins: WINS server resolution selected "
1013 "and no WINS servers listed.\n"));
1014 return NT_STATUS_INVALID_PARAMETER;
1017 /* we try a lookup on each of the WINS tags in turn */
1018 wins_tags = wins_srv_tags();
1021 /* huh? no tags?? give up in disgust */
1022 return NT_STATUS_INVALID_PARAMETER;
1025 /* the address we will be sending from */
1026 if (!interpret_string_addr(&src_ss, lp_socket_address(),
1027 AI_NUMERICHOST|AI_PASSIVE)) {
1028 zero_sockaddr(&src_ss);
1031 if (src_ss.ss_family != AF_INET) {
1032 char addr[INET6_ADDRSTRLEN];
1033 print_sockaddr(addr, sizeof(addr), &src_ss);
1034 DEBUG(3,("resolve_wins: cannot receive WINS replies "
1035 "on IPv6 address %s\n",
1037 wins_srv_tags_free(wins_tags);
1038 return NT_STATUS_INVALID_PARAMETER;
1041 src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
1043 /* in the worst case we will try every wins server with every
1045 for (t=0; wins_tags && wins_tags[t]; t++) {
1046 int srv_count = wins_srv_count_tag(wins_tags[t]);
1047 for (i=0; i<srv_count; i++) {
1048 struct sockaddr_storage wins_ss;
1049 struct in_addr wins_ip;
1053 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
1055 if (global_in_nmbd && ismyip_v4(wins_ip)) {
1056 /* yikes! we'll loop forever */
1060 /* skip any that have been unresponsive lately */
1061 if (wins_srv_is_dead(wins_ip, src_ip)) {
1065 DEBUG(3,("resolve_wins: using WINS server %s "
1067 inet_ntoa(wins_ip), wins_tags[t]));
1069 sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
1074 in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
1075 ss_list = name_query(sock,
1085 /* exit loop if we got a list of addresses */
1093 /* Timed out waiting for WINS server to
1096 wins_srv_died(wins_ip, src_ip);
1098 /* The name definitely isn't in this
1099 group of WINS servers.
1100 goto the next group */
1106 wins_srv_tags_free(wins_tags);
1107 return NT_STATUS_NO_LOGON_SERVERS;
1111 status = NT_STATUS_OK;
1112 if (!convert_ss2service(return_iplist, ss_list, *return_count))
1113 status = NT_STATUS_INVALID_PARAMETER;
1116 wins_srv_tags_free(wins_tags);
1122 /********************************************************
1123 Resolve via "lmhosts" method.
1124 *********************************************************/
1126 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
1127 struct ip_service **return_iplist,
1131 * "lmhosts" means parse the local lmhosts file.
1133 struct sockaddr_storage *ss_list;
1134 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1135 TALLOC_CTX *ctx = NULL;
1137 *return_iplist = NULL;
1140 DEBUG(3,("resolve_lmhosts: "
1141 "Attempting lmhosts lookup for name %s<0x%x>\n",
1144 ctx = talloc_init("resolve_lmhosts");
1146 return NT_STATUS_NO_MEMORY;
1149 status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(),
1154 if (NT_STATUS_IS_OK(status)) {
1155 if (convert_ss2service(return_iplist,
1159 return NT_STATUS_OK;
1162 return NT_STATUS_NO_MEMORY;
1170 /********************************************************
1171 Resolve via "hosts" method.
1172 *********************************************************/
1174 static NTSTATUS resolve_hosts(const char *name, int name_type,
1175 struct ip_service **return_iplist,
1179 * "host" means do a localhost, or dns lookup.
1181 struct addrinfo hints;
1182 struct addrinfo *ailist = NULL;
1183 struct addrinfo *res = NULL;
1187 if ( name_type != 0x20 && name_type != 0x0) {
1188 DEBUG(5, ("resolve_hosts: not appropriate "
1189 "for name type <0x%x>\n",
1191 return NT_STATUS_INVALID_PARAMETER;
1194 *return_iplist = NULL;
1197 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
1201 /* By default make sure it supports TCP. */
1202 hints.ai_socktype = SOCK_STREAM;
1203 hints.ai_flags = AI_ADDRCONFIG;
1205 #if !defined(HAVE_IPV6)
1206 /* Unless we have IPv6, we really only want IPv4 addresses back. */
1207 hints.ai_family = AF_INET;
1210 ret = getaddrinfo(name,
1215 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
1217 gai_strerror(ret) ));
1220 for (res = ailist; res; res = res->ai_next) {
1221 struct sockaddr_storage ss;
1223 if (!res->ai_addr || res->ai_addrlen == 0) {
1228 memcpy(&ss, res->ai_addr, res->ai_addrlen);
1232 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
1235 if (!*return_iplist) {
1236 DEBUG(3,("resolve_hosts: malloc fail !\n"));
1237 freeaddrinfo(ailist);
1238 return NT_STATUS_NO_MEMORY;
1240 (*return_iplist)[i].ss = ss;
1241 (*return_iplist)[i].port = PORT_NONE;
1245 freeaddrinfo(ailist);
1247 if (*return_count) {
1248 return NT_STATUS_OK;
1250 return NT_STATUS_UNSUCCESSFUL;
1253 /********************************************************
1254 Resolve via "ADS" method.
1255 *********************************************************/
1257 static NTSTATUS resolve_ads(const char *name,
1259 const char *sitename,
1260 struct ip_service **return_iplist,
1266 struct dns_rr_srv *dcs = NULL;
1270 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
1271 (name_type != 0x1b)) {
1272 return NT_STATUS_INVALID_PARAMETER;
1275 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1276 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1277 return NT_STATUS_NO_MEMORY;
1280 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
1282 switch (name_type) {
1284 DEBUG(5,("resolve_ads: Attempting to resolve "
1285 "PDC for %s using DNS\n", name));
1286 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
1290 DEBUG(5,("resolve_ads: Attempting to resolve "
1291 "DCs for %s using DNS\n", name));
1292 status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1296 DEBUG(5,("resolve_ads: Attempting to resolve "
1297 "KDCs for %s using DNS\n", name));
1298 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1302 status = NT_STATUS_INVALID_PARAMETER;
1306 if ( !NT_STATUS_IS_OK( status ) ) {
1307 talloc_destroy(ctx);
1311 for (i=0;i<numdcs;i++) {
1312 numaddrs += MAX(dcs[i].num_ips,1);
1315 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
1317 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
1319 talloc_destroy(ctx);
1320 return NT_STATUS_NO_MEMORY;
1323 /* now unroll the list of IP addresses */
1328 while ( i < numdcs && (*return_count<numaddrs) ) {
1329 struct ip_service *r = &(*return_iplist)[*return_count];
1331 r->port = dcs[i].port;
1333 /* If we don't have an IP list for a name, lookup it up */
1336 interpret_string_addr(&r->ss, dcs[i].hostname, 0);
1340 /* use the IP addresses from the SRV sresponse */
1342 if ( j >= dcs[i].num_ips ) {
1348 r->ss = dcs[i].ss_s[j];
1352 /* make sure it is a valid IP. I considered checking the
1353 * negative connection cache, but this is the wrong place
1354 * for it. Maybe only as a hack. After think about it, if
1355 * all of the IP addresses returned from DNS are dead, what
1356 * hope does a netbios name lookup have ? The standard reason
1357 * for falling back to netbios lookups is that our DNS server
1358 * doesn't know anything about the DC's -- jerry */
1360 if (!is_zero_addr((struct sockaddr *)&r->ss)) {
1365 talloc_destroy(ctx);
1366 return NT_STATUS_OK;
1369 /*******************************************************************
1370 Internal interface to resolve a name into an IP address.
1371 Use this function if the string is either an IP address, DNS
1372 or host name or NetBIOS name. This uses the name switch in the
1373 smb.conf to determine the order of name resolution.
1375 Added support for ip addr/port to support ADS ldap servers.
1376 the only place we currently care about the port is in the
1377 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1378 **********************************************************************/
1380 NTSTATUS internal_resolve_name(const char *name,
1382 const char *sitename,
1383 struct ip_service **return_iplist,
1385 const char *resolve_order)
1389 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1391 TALLOC_CTX *frame = NULL;
1393 *return_iplist = NULL;
1396 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1397 name, name_type, sitename ? sitename : "(null)"));
1399 if (is_ipaddress(name)) {
1400 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
1402 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1403 return NT_STATUS_NO_MEMORY;
1406 /* ignore the port here */
1407 (*return_iplist)->port = PORT_NONE;
1409 /* if it's in the form of an IP address then get the lib to interpret it */
1410 if (!interpret_string_addr(&(*return_iplist)->ss,
1411 name, AI_NUMERICHOST)) {
1412 DEBUG(1,("internal_resolve_name: interpret_string_addr "
1415 SAFE_FREE(*return_iplist);
1416 return NT_STATUS_INVALID_PARAMETER;
1419 return NT_STATUS_OK;
1422 /* Check name cache */
1424 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1425 /* This could be a negative response */
1426 if (*return_count > 0) {
1427 return NT_STATUS_OK;
1429 return NT_STATUS_UNSUCCESSFUL;
1433 /* set the name resolution order */
1435 if (strcmp( resolve_order, "NULL") == 0) {
1436 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1437 return NT_STATUS_INVALID_PARAMETER;
1440 if (!resolve_order[0]) {
1443 ptr = resolve_order;
1446 /* iterate through the name resolution backends */
1448 frame = talloc_stackframe();
1449 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
1450 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1451 status = resolve_hosts(name, name_type, return_iplist,
1453 if (NT_STATUS_IS_OK(status)) {
1456 } else if(strequal( tok, "kdc")) {
1457 /* deal with KDC_NAME_TYPE names here.
1458 * This will result in a SRV record lookup */
1459 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1460 return_iplist, return_count);
1461 if (NT_STATUS_IS_OK(status)) {
1462 /* Ensure we don't namecache
1463 * this with the KDC port. */
1464 name_type = KDC_NAME_TYPE;
1467 } else if(strequal( tok, "ads")) {
1468 /* deal with 0x1c and 0x1b names here.
1469 * This will result in a SRV record lookup */
1470 status = resolve_ads(name, name_type, sitename,
1471 return_iplist, return_count);
1472 if (NT_STATUS_IS_OK(status)) {
1475 } else if(strequal( tok, "lmhosts")) {
1476 status = resolve_lmhosts(name, name_type,
1477 return_iplist, return_count);
1478 if (NT_STATUS_IS_OK(status)) {
1481 } else if(strequal( tok, "wins")) {
1482 /* don't resolve 1D via WINS */
1483 if (name_type != 0x1D) {
1484 status = resolve_wins(name, name_type,
1487 if (NT_STATUS_IS_OK(status)) {
1491 } else if(strequal( tok, "bcast")) {
1492 status = name_resolve_bcast(name, name_type,
1495 if (NT_STATUS_IS_OK(status)) {
1499 DEBUG(0,("resolve_name: unknown name switch type %s\n",
1504 /* All of the resolve_* functions above have returned false. */
1507 SAFE_FREE(*return_iplist);
1510 return NT_STATUS_UNSUCCESSFUL;
1514 /* Remove duplicate entries. Some queries, notably #1c (domain
1515 controllers) return the PDC in iplist[0] and then all domain
1516 controllers including the PDC in iplist[1..n]. Iterating over
1517 the iplist when the PDC is down will cause two sets of timeouts. */
1519 if ( *return_count ) {
1520 *return_count = remove_duplicate_addrs2(*return_iplist,
1524 /* Save in name cache */
1525 if ( DEBUGLEVEL >= 100 ) {
1526 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
1527 char addr[INET6_ADDRSTRLEN];
1528 print_sockaddr(addr, sizeof(addr),
1529 &(*return_iplist)[i].ss);
1530 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
1534 (*return_iplist)[i].port));
1538 namecache_store(name, name_type, *return_count, *return_iplist);
1540 /* Display some debugging info */
1542 if ( DEBUGLEVEL >= 10 ) {
1543 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1546 for (i = 0; i < *return_count; i++) {
1547 char addr[INET6_ADDRSTRLEN];
1548 print_sockaddr(addr, sizeof(addr),
1549 &(*return_iplist)[i].ss);
1550 DEBUGADD(10, ("%s:%d ",
1552 (*return_iplist)[i].port));
1561 /********************************************************
1562 Internal interface to resolve a name into one IP address.
1563 Use this function if the string is either an IP address, DNS
1564 or host name or NetBIOS name. This uses the name switch in the
1565 smb.conf to determine the order of name resolution.
1566 *********************************************************/
1568 bool resolve_name(const char *name,
1569 struct sockaddr_storage *return_ss,
1573 struct ip_service *ss_list = NULL;
1574 char *sitename = NULL;
1577 if (is_ipaddress(name)) {
1578 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
1581 sitename = sitename_fetch(lp_realm()); /* wild guess */
1583 if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1585 lp_name_resolve_order()))) {
1589 for (i=0; i<count; i++) {
1590 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1591 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) &&
1592 (ss_list[i].ss.ss_family == AF_INET)) {
1593 *return_ss = ss_list[i].ss;
1595 SAFE_FREE(sitename);
1601 /* only return valid addresses for TCP connections */
1602 for (i=0; i<count; i++) {
1603 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1604 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1605 *return_ss = ss_list[i].ss;
1607 SAFE_FREE(sitename);
1614 SAFE_FREE(sitename);
1618 /********************************************************
1619 Internal interface to resolve a name into a list of IP addresses.
1620 Use this function if the string is either an IP address, DNS
1621 or host name or NetBIOS name. This uses the name switch in the
1622 smb.conf to determine the order of name resolution.
1623 *********************************************************/
1625 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
1628 struct sockaddr_storage **return_ss_arr,
1629 unsigned int *p_num_entries)
1631 struct ip_service *ss_list = NULL;
1632 char *sitename = NULL;
1635 unsigned int num_entries;
1639 *return_ss_arr = NULL;
1641 if (is_ipaddress(name)) {
1642 *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);
1643 if (!*return_ss_arr) {
1644 return NT_STATUS_NO_MEMORY;
1646 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
1647 TALLOC_FREE(*return_ss_arr);
1648 return NT_STATUS_BAD_NETWORK_NAME;
1651 return NT_STATUS_OK;
1654 sitename = sitename_fetch(lp_realm()); /* wild guess */
1656 status = internal_resolve_name(name, name_type, sitename,
1658 lp_name_resolve_order());
1659 SAFE_FREE(sitename);
1661 if (!NT_STATUS_IS_OK(status)) {
1665 /* only return valid addresses for TCP connections */
1666 for (i=0, num_entries = 0; i<count; i++) {
1667 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1668 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1672 if (num_entries == 0) {
1674 return NT_STATUS_BAD_NETWORK_NAME;
1677 *return_ss_arr = TALLOC_ARRAY(ctx,
1678 struct sockaddr_storage,
1680 if (!(*return_ss_arr)) {
1682 return NT_STATUS_NO_MEMORY;
1685 for (i=0, num_entries = 0; i<count; i++) {
1686 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1687 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1688 (*return_ss_arr)[num_entries++] = ss_list[i].ss;
1692 status = NT_STATUS_OK;
1693 *p_num_entries = num_entries;
1696 return NT_STATUS_OK;
1699 /********************************************************
1700 Find the IP address of the master browser or DMB for a workgroup.
1701 *********************************************************/
1703 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
1705 struct ip_service *ip_list = NULL;
1709 if (lp_disable_netbios()) {
1710 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1714 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1715 lp_name_resolve_order());
1716 if (NT_STATUS_IS_OK(status)) {
1717 *master_ss = ip_list[0].ss;
1722 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1723 lp_name_resolve_order());
1724 if (NT_STATUS_IS_OK(status)) {
1725 *master_ss = ip_list[0].ss;
1734 /********************************************************
1735 Get the IP address list of the primary domain controller
1737 *********************************************************/
1739 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
1741 struct ip_service *ip_list = NULL;
1743 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1745 /* Look up #1B name */
1747 if (lp_security() == SEC_ADS) {
1748 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1752 if (!NT_STATUS_IS_OK(status) || count == 0) {
1753 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1755 lp_name_resolve_order());
1756 if (!NT_STATUS_IS_OK(status)) {
1761 /* if we get more than 1 IP back we have to assume it is a
1762 multi-homed PDC and not a mess up */
1765 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1766 sort_service_list(ip_list, count);
1769 *pss = ip_list[0].ss;
1774 /* Private enum type for lookups. */
1776 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1778 /********************************************************
1779 Get the IP address list of the domain controllers for
1781 *********************************************************/
1783 static NTSTATUS get_dc_list(const char *domain,
1784 const char *sitename,
1785 struct ip_service **ip_list,
1787 enum dc_lookup_type lookup_type,
1790 char *resolve_order = NULL;
1791 char *saf_servername = NULL;
1792 char *pserver = NULL;
1794 char *port_str = NULL;
1797 int num_addresses = 0;
1798 int local_count, i, j;
1799 struct ip_service *return_iplist = NULL;
1800 struct ip_service *auto_ip_list = NULL;
1801 bool done_auto_lookup = false;
1804 TALLOC_CTX *ctx = talloc_init("get_dc_list");
1810 return NT_STATUS_NO_MEMORY;
1815 /* if we are restricted to solely using DNS for looking
1816 up a domain controller, make sure that host lookups
1817 are enabled for the 'name resolve order'. If host lookups
1818 are disabled and ads_only is True, then set the string to
1821 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
1822 if (!resolve_order) {
1823 status = NT_STATUS_NO_MEMORY;
1826 strlower_m(resolve_order);
1827 if (lookup_type == DC_ADS_ONLY) {
1828 if (strstr( resolve_order, "host")) {
1829 resolve_order = talloc_strdup(ctx, "ads");
1831 /* DNS SRV lookups used by the ads resolver
1832 are already sorted by priority and weight */
1835 resolve_order = talloc_strdup(ctx, "NULL");
1837 } else if (lookup_type == DC_KDC_ONLY) {
1838 /* DNS SRV lookups used by the ads/kdc resolver
1839 are already sorted by priority and weight */
1841 resolve_order = talloc_strdup(ctx, "kdc");
1843 if (!resolve_order) {
1844 status = NT_STATUS_NO_MEMORY;
1848 /* fetch the server we have affinity for. Add the
1849 'password server' list to a search for our domain controllers */
1851 saf_servername = saf_fetch( domain);
1853 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
1854 pserver = talloc_asprintf(ctx, "%s, %s",
1855 saf_servername ? saf_servername : "",
1856 lp_passwordserver());
1858 pserver = talloc_asprintf(ctx, "%s, *",
1859 saf_servername ? saf_servername : "");
1862 SAFE_FREE(saf_servername);
1864 status = NT_STATUS_NO_MEMORY;
1868 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1871 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1872 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1873 count, resolve_order);
1877 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1880 * if '*' appears in the "password server" list then add
1881 * an auto lookup to the list of manually configured
1882 * DC's. If any DC is listed by name, then the list should be
1883 * considered to be ordered
1887 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1888 if (!done_auto_lookup && strequal(name, "*")) {
1889 status = internal_resolve_name(domain, 0x1C, sitename,
1893 if (NT_STATUS_IS_OK(status)) {
1894 num_addresses += auto_count;
1896 done_auto_lookup = true;
1897 DEBUG(8,("Adding %d DC's from auto lookup\n",
1904 /* if we have no addresses and haven't done the auto lookup, then
1905 just return the list of DC's. Or maybe we just failed. */
1907 if ((num_addresses == 0)) {
1908 if (done_auto_lookup) {
1909 DEBUG(4,("get_dc_list: no servers found\n"));
1910 status = NT_STATUS_NO_LOGON_SERVERS;
1913 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1914 count, resolve_order);
1918 if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
1919 num_addresses)) == NULL) {
1920 DEBUG(3,("get_dc_list: malloc fail !\n"));
1921 status = NT_STATUS_NO_MEMORY;
1928 /* fill in the return list now with real IP's */
1930 while ((local_count<num_addresses) &&
1931 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1932 struct sockaddr_storage name_ss;
1934 /* copy any addersses from the auto lookup */
1936 if (strequal(name, "*")) {
1937 for (j=0; j<auto_count; j++) {
1938 char addr[INET6_ADDRSTRLEN];
1939 print_sockaddr(addr,
1941 &auto_ip_list[j].ss);
1942 /* Check for and don't copy any
1943 * known bad DC IP's. */
1944 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
1947 DEBUG(5,("get_dc_list: "
1948 "negative entry %s removed "
1953 return_iplist[local_count].ss =
1955 return_iplist[local_count].port =
1956 auto_ip_list[j].port;
1962 /* added support for address:port syntax for ads
1963 * (not that I think anyone will ever run the LDAP
1964 * server in an AD domain on something other than
1967 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1968 if ((port_str=strchr(name, ':')) != NULL) {
1971 port = atoi(port_str);
1974 /* explicit lookup; resolve_name() will
1975 * handle names & IP addresses */
1976 if (resolve_name( name, &name_ss, 0x20, true )) {
1977 char addr[INET6_ADDRSTRLEN];
1978 print_sockaddr(addr,
1982 /* Check for and don't copy any known bad DC IP's. */
1983 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
1985 DEBUG(5,("get_dc_list: negative entry %s "
1986 "removed from DC list\n",
1991 return_iplist[local_count].ss = name_ss;
1992 return_iplist[local_count].port = port;
1998 /* need to remove duplicates in the list if we have any
1999 explicit password servers */
2002 local_count = remove_duplicate_addrs2(return_iplist,
2006 /* For DC's we always prioritize IPv4 due to W2K3 not
2007 * supporting LDAP, KRB5 or CLDAP over IPv6. */
2009 if (local_count && return_iplist) {
2010 prioritize_ipv4_list(return_iplist, local_count);
2013 if ( DEBUGLEVEL >= 4 ) {
2014 DEBUG(4,("get_dc_list: returning %d ip addresses "
2015 "in an %sordered list\n",
2017 *ordered ? "":"un"));
2018 DEBUG(4,("get_dc_list: "));
2019 for ( i=0; i<local_count; i++ ) {
2020 char addr[INET6_ADDRSTRLEN];
2021 print_sockaddr(addr,
2023 &return_iplist[i].ss);
2024 DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
2029 *ip_list = return_iplist;
2030 *count = local_count;
2032 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
2036 if (!NT_STATUS_IS_OK(status)) {
2037 SAFE_FREE(return_iplist);
2042 SAFE_FREE(auto_ip_list);
2047 /*********************************************************************
2048 Small wrapper function to get the DC list and sort it if neccessary.
2049 *********************************************************************/
2051 NTSTATUS get_sorted_dc_list( const char *domain,
2052 const char *sitename,
2053 struct ip_service **ip_list,
2057 bool ordered = false;
2059 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
2064 DEBUG(8,("get_sorted_dc_list: attempting lookup "
2065 "for name %s (sitename %s) using [%s]\n",
2067 sitename ? sitename : "NULL",
2068 (ads_only ? "ads" : lp_name_resolve_order())));
2071 lookup_type = DC_ADS_ONLY;
2074 status = get_dc_list(domain, sitename, ip_list,
2075 count, lookup_type, &ordered);
2076 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
2078 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
2079 " in site %s, fallback to all servers\n",
2081 status = get_dc_list(domain, NULL, ip_list,
2082 count, lookup_type, &ordered);
2085 if (!NT_STATUS_IS_OK(status)) {
2086 SAFE_FREE(*ip_list);
2091 /* only sort if we don't already have an ordered list */
2093 sort_service_list(*ip_list, *count);
2096 return NT_STATUS_OK;
2099 /*********************************************************************
2100 Get the KDC list - re-use all the logic in get_dc_list.
2101 *********************************************************************/
2103 NTSTATUS get_kdc_list( const char *realm,
2104 const char *sitename,
2105 struct ip_service **ip_list,
2114 status = get_dc_list(realm, sitename, ip_list,
2115 count, DC_KDC_ONLY, &ordered);
2117 if (!NT_STATUS_IS_OK(status)) {
2118 SAFE_FREE(*ip_list);
2123 /* only sort if we don't already have an ordered list */
2125 sort_service_list(*ip_list, *count);
2128 return NT_STATUS_OK;