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/>.
23 /* nmbd.c sets this to True. */
24 bool global_in_nmbd = False;
26 /****************************
27 * SERVER AFFINITY ROUTINES *
28 ****************************/
30 /* Server affinity is the concept of preferring the last domain
31 controller with whom you had a successful conversation */
33 /****************************************************************************
34 ****************************************************************************/
35 #define SAFKEY_FMT "SAF/DOMAIN/%s"
37 #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
38 #define SAFJOIN_TTL 3600
40 static char *saf_key(const char *domain)
44 asprintf_strupper_m(&keystr, SAFKEY_FMT, domain);
49 static char *saf_join_key(const char *domain)
53 asprintf_strupper_m(&keystr, SAFJOINKEY_FMT, domain);
58 /****************************************************************************
59 ****************************************************************************/
61 bool saf_store( const char *domain, const char *servername )
67 if ( !domain || !servername ) {
68 DEBUG(2,("saf_store: "
69 "Refusing to store empty domain or servername!\n"));
73 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
74 DEBUG(0,("saf_store: "
75 "refusing to store 0 length domain or servername!\n"));
79 key = saf_key( domain );
80 expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
82 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
83 domain, servername, (unsigned int)expire ));
85 ret = gencache_set( key, servername, expire );
92 bool saf_join_store( const char *domain, const char *servername )
98 if ( !domain || !servername ) {
99 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
103 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
104 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
108 key = saf_join_key( domain );
109 expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
111 DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
112 domain, servername, (unsigned int)expire ));
114 ret = gencache_set( key, servername, expire );
121 bool saf_delete( const char *domain )
127 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
131 key = saf_join_key(domain);
132 ret = gencache_del(key);
136 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
139 key = saf_key(domain);
140 ret = gencache_del(key);
144 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
150 /****************************************************************************
151 ****************************************************************************/
153 char *saf_fetch( const char *domain )
160 if ( !domain || strlen(domain) == 0) {
161 DEBUG(2,("saf_fetch: Empty domain name!\n"));
165 key = saf_join_key( domain );
167 ret = gencache_get( key, &server, &timeout );
172 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
177 key = saf_key( domain );
179 ret = gencache_get( key, &server, &timeout );
184 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
187 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
194 /****************************************************************************
195 Generate a random trn_id.
196 ****************************************************************************/
198 static int generate_trn_id(void)
202 generate_random_buffer((uint8 *)&id, sizeof(id));
204 return id % (unsigned)0x7FFF;
207 /****************************************************************************
208 Parse a node status response into an array of structures.
209 ****************************************************************************/
211 static NODE_STATUS_STRUCT *parse_node_status(char *p,
213 struct node_status_extra *extra)
215 NODE_STATUS_STRUCT *ret;
218 *num_names = CVAL(p,0);
223 ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
228 for (i=0;i< *num_names;i++) {
229 StrnCpy(ret[i].name,p,15);
230 trim_char(ret[i].name,'\0',' ');
231 ret[i].type = CVAL(p,15);
232 ret[i].flags = p[16];
234 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
235 ret[i].type, ret[i].flags));
238 * Also, pick up the MAC address ...
241 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
247 /****************************************************************************
248 Do a NBT node status query on an open socket and return an array of
249 structures holding the returned names or NULL if the query failed.
250 **************************************************************************/
252 NODE_STATUS_STRUCT *node_status_query(int fd,
253 struct nmb_name *name,
254 const struct sockaddr_storage *to_ss,
256 struct node_status_extra *extra)
260 int retry_time = 2000;
262 struct packet_struct p;
263 struct packet_struct *p2;
264 struct nmb_packet *nmb = &p.packet.nmb;
265 NODE_STATUS_STRUCT *ret;
269 if (to_ss->ss_family != AF_INET) {
270 /* Can't do node status to IPv6 */
273 nmb->header.name_trn_id = generate_trn_id();
274 nmb->header.opcode = 0;
275 nmb->header.response = false;
276 nmb->header.nm_flags.bcast = false;
277 nmb->header.nm_flags.recursion_available = false;
278 nmb->header.nm_flags.recursion_desired = false;
279 nmb->header.nm_flags.trunc = false;
280 nmb->header.nm_flags.authoritative = false;
281 nmb->header.rcode = 0;
282 nmb->header.qdcount = 1;
283 nmb->header.ancount = 0;
284 nmb->header.nscount = 0;
285 nmb->header.arcount = 0;
286 nmb->question.question_name = *name;
287 nmb->question.question_type = 0x21;
288 nmb->question.question_class = 0x1;
290 p.ip = ((const struct sockaddr_in *)to_ss)->sin_addr;
294 p.timestamp = time(NULL);
295 p.packet_type = NMB_PACKET;
299 if (!send_packet(&p))
305 struct timeval tval2;
306 GetTimeOfDay(&tval2);
307 if (TvalDiff(&tval,&tval2) > retry_time) {
310 if (!found && !send_packet(&p))
316 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
317 struct nmb_packet *nmb2 = &p2->packet.nmb;
318 debug_nmb_packet(p2);
320 if (nmb2->header.opcode != 0 ||
321 nmb2->header.nm_flags.bcast ||
322 nmb2->header.rcode ||
323 !nmb2->header.ancount ||
324 nmb2->answers->rr_type != 0x21) {
325 /* XXXX what do we do with this? could be a
326 redirect, but we'll discard it for the
332 ret = parse_node_status(&nmb2->answers->rdata[0],
342 /****************************************************************************
343 Find the first type XX name in a node status reply - used for finding
344 a servers name given its IP. Return the matched name in *name.
345 **************************************************************************/
347 bool name_status_find(const char *q_name,
350 const struct sockaddr_storage *to_ss,
353 char addr[INET6_ADDRSTRLEN];
354 struct sockaddr_storage ss;
355 NODE_STATUS_STRUCT *status = NULL;
356 struct nmb_name nname;
361 if (lp_disable_netbios()) {
362 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
367 print_sockaddr(addr, sizeof(addr), to_ss);
369 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
372 /* Check the cache first. */
374 if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
378 if (to_ss->ss_family != AF_INET) {
379 /* Can't do node status to IPv6 */
383 if (!interpret_string_addr(&ss, lp_socket_address(),
384 AI_NUMERICHOST|AI_PASSIVE)) {
388 sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);
392 /* W2K PDC's seem not to respond to '*'#0. JRA */
393 make_nmb_name(&nname, q_name, q_type);
394 status = node_status_query(sock, &nname, to_ss, &count, NULL);
399 for (i=0;i<count;i++) {
400 /* Find first one of the requested type that's not a GROUP. */
401 if (status[i].type == type && ! (status[i].flags & 0x80))
407 pull_ascii_nstring(name, sizeof(fstring), status[i].name);
409 /* Store the result in the cache. */
410 /* but don't store an entry for 0x1c names here. Here we have
411 a single host and DOMAIN<0x1c> names should be a list of hosts */
413 if ( q_type != 0x1c ) {
414 namecache_status_store(q_name, q_type, type, to_ss, name);
422 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
425 DEBUGADD(10, (", name %s ip address is %s", name, addr));
433 comparison function used by sort_addr_list
436 static int addr_compare(const struct sockaddr *ss1,
437 const struct sockaddr *ss2)
439 int max_bits1=0, max_bits2=0;
440 int num_interfaces = iface_count();
443 /* Sort IPv4 addresses first. */
444 if (ss1->sa_family != ss2->sa_family) {
445 if (ss2->sa_family == AF_INET) {
452 /* Here we know both addresses are of the same
455 for (i=0;i<num_interfaces;i++) {
456 const struct sockaddr_storage *pss = iface_n_bcast(i);
457 unsigned char *p_ss1 = NULL;
458 unsigned char *p_ss2 = NULL;
459 unsigned char *p_if = NULL;
463 if (pss->ss_family != ss1->sa_family) {
464 /* Ignore interfaces of the wrong type. */
467 if (pss->ss_family == AF_INET) {
468 p_if = (unsigned char *)
469 &((const struct sockaddr_in *)pss)->sin_addr;
470 p_ss1 = (unsigned char *)
471 &((const struct sockaddr_in *)ss1)->sin_addr;
472 p_ss2 = (unsigned char *)
473 &((const struct sockaddr_in *)ss2)->sin_addr;
476 #if defined(HAVE_IPV6)
477 if (pss->ss_family == AF_INET6) {
478 p_if = (unsigned char *)
479 &((const struct sockaddr_in6 *)pss)->sin6_addr;
480 p_ss1 = (unsigned char *)
481 &((const struct sockaddr_in6 *)ss1)->sin6_addr;
482 p_ss2 = (unsigned char *)
483 &((const struct sockaddr_in6 *)ss2)->sin6_addr;
487 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
490 bits1 = matching_len_bits(p_ss1, p_if, len);
491 bits2 = matching_len_bits(p_ss2, p_if, len);
492 max_bits1 = MAX(bits1, max_bits1);
493 max_bits2 = MAX(bits2, max_bits2);
496 /* Bias towards directly reachable IPs */
497 if (iface_local(ss1)) {
498 if (ss1->sa_family == AF_INET) {
504 if (iface_local(ss2)) {
505 if (ss2->sa_family == AF_INET) {
511 return max_bits2 - max_bits1;
514 /*******************************************************************
515 compare 2 ldap IPs by nearness to our interfaces - used in qsort
516 *******************************************************************/
518 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
522 if ((result = addr_compare((struct sockaddr *)&ss1->ss, (struct sockaddr *)&ss2->ss)) != 0) {
526 if (ss1->port > ss2->port) {
530 if (ss1->port < ss2->port) {
538 sort an IP list so that names that are close to one of our interfaces
539 are at the top. This prevents the problem where a WINS server returns an IP
540 that is not reachable from our subnet as the first match
543 static void sort_addr_list(struct sockaddr_storage *sslist, int count)
549 qsort(sslist, count, sizeof(struct sockaddr_storage),
550 QSORT_CAST addr_compare);
553 static void sort_service_list(struct ip_service *servlist, int count)
559 qsort(servlist, count, sizeof(struct ip_service),
560 QSORT_CAST ip_service_compare);
563 /**********************************************************************
564 Remove any duplicate address/port pairs in the list
565 *********************************************************************/
567 static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
571 DEBUG(10,("remove_duplicate_addrs2: "
572 "looking for duplicate address/port pairs\n"));
574 /* One loop to set duplicates to a zero addr. */
575 for ( i=0; i<count; i++ ) {
576 if ( is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
580 for ( j=i+1; j<count; j++ ) {
581 if (sockaddr_equal((struct sockaddr *)&iplist[i].ss, (struct sockaddr *)&iplist[j].ss) &&
582 iplist[i].port == iplist[j].port) {
583 zero_sockaddr(&iplist[j].ss);
588 /* Now remove any addresses set to zero above. */
589 for (i = 0; i < count; i++) {
591 is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
595 (count-i-1)*sizeof(struct ip_service));
604 static bool prioritize_ipv4_list(struct ip_service *iplist, int count)
606 TALLOC_CTX *frame = talloc_stackframe();
607 struct ip_service *iplist_new = TALLOC_ARRAY(frame, struct ip_service, count);
610 if (iplist_new == NULL) {
617 /* Copy IPv4 first. */
618 for (i = 0; i < count; i++) {
619 if (iplist[i].ss.ss_family == AF_INET) {
620 iplist_new[j++] = iplist[i];
625 for (i = 0; i < count; i++) {
626 if (iplist[i].ss.ss_family != AF_INET) {
627 iplist_new[j++] = iplist[i];
631 memcpy(iplist, iplist_new, sizeof(struct ip_service)*count);
636 /****************************************************************************
637 Do a netbios name query to find someones IP.
638 Returns an array of IP addresses or NULL if none.
639 *count will be set to the number of addresses returned.
640 *timed_out is set if we failed by timing out
641 ****************************************************************************/
643 struct sockaddr_storage *name_query(int fd,
648 const struct sockaddr_storage *to_ss,
655 int retry_time = bcast?250:2000;
657 struct packet_struct p;
658 struct packet_struct *p2;
659 struct nmb_packet *nmb = &p.packet.nmb;
660 struct sockaddr_storage *ss_list = NULL;
662 if (lp_disable_netbios()) {
663 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
668 if (to_ss->ss_family != AF_INET) {
676 memset((char *)&p,'\0',sizeof(p));
680 nmb->header.name_trn_id = generate_trn_id();
681 nmb->header.opcode = 0;
682 nmb->header.response = false;
683 nmb->header.nm_flags.bcast = bcast;
684 nmb->header.nm_flags.recursion_available = false;
685 nmb->header.nm_flags.recursion_desired = recurse;
686 nmb->header.nm_flags.trunc = false;
687 nmb->header.nm_flags.authoritative = false;
688 nmb->header.rcode = 0;
689 nmb->header.qdcount = 1;
690 nmb->header.ancount = 0;
691 nmb->header.nscount = 0;
692 nmb->header.arcount = 0;
694 make_nmb_name(&nmb->question.question_name,name,name_type);
696 nmb->question.question_type = 0x20;
697 nmb->question.question_class = 0x1;
699 p.ip = ((struct sockaddr_in *)to_ss)->sin_addr;
703 p.timestamp = time(NULL);
704 p.packet_type = NMB_PACKET;
708 if (!send_packet(&p))
714 struct timeval tval2;
716 GetTimeOfDay(&tval2);
717 if (TvalDiff(&tval,&tval2) > retry_time) {
720 if (!found && !send_packet(&p))
726 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
727 struct nmb_packet *nmb2 = &p2->packet.nmb;
728 debug_nmb_packet(p2);
730 /* If we get a Negative Name Query Response from a WINS
731 * server, we should report it and give up.
733 if( 0 == nmb2->header.opcode /* A query response */
734 && !(bcast) /* from a WINS server */
735 && nmb2->header.rcode /* Error returned */
738 if( DEBUGLVL( 3 ) ) {
739 /* Only executed if DEBUGLEVEL >= 3 */
740 dbgtext( "Negative name query "
741 "response, rcode 0x%02x: ",
742 nmb2->header.rcode );
743 switch( nmb2->header.rcode ) {
746 "was invalidly formatted.\n" );
749 dbgtext( "Problem with NBNS, "
750 "cannot process name.\n");
753 dbgtext( "The name requested "
754 "does not exist.\n" );
757 dbgtext( "Unsupported request "
761 dbgtext( "Query refused "
765 dbgtext( "Unrecognized error "
774 if (nmb2->header.opcode != 0 ||
775 nmb2->header.nm_flags.bcast ||
776 nmb2->header.rcode ||
777 !nmb2->header.ancount) {
779 * XXXX what do we do with this? Could be a
780 * redirect, but we'll discard it for the
787 ss_list = SMB_REALLOC_ARRAY(ss_list,
788 struct sockaddr_storage,
790 nmb2->answers->rdlength/6);
793 DEBUG(0,("name_query: Realloc failed.\n"));
798 DEBUG(2,("Got a positive name query response "
802 for (i=0;i<nmb2->answers->rdlength/6;i++) {
804 putip((char *)&ip,&nmb2->answers->rdata[2+i*6]);
805 in_addr_to_sockaddr_storage(&ss_list[(*count)],
807 DEBUGADD(2,("%s ",inet_ntoa(ip)));
814 /* We add the flags back ... */
815 if (nmb2->header.response)
816 (*flags) |= NM_FLAGS_RS;
817 if (nmb2->header.nm_flags.authoritative)
818 (*flags) |= NM_FLAGS_AA;
819 if (nmb2->header.nm_flags.trunc)
820 (*flags) |= NM_FLAGS_TC;
821 if (nmb2->header.nm_flags.recursion_desired)
822 (*flags) |= NM_FLAGS_RD;
823 if (nmb2->header.nm_flags.recursion_available)
824 (*flags) |= NM_FLAGS_RA;
825 if (nmb2->header.nm_flags.bcast)
826 (*flags) |= NM_FLAGS_B;
829 * If we're doing a unicast lookup we only
830 * expect one reply. Don't wait the full 2
831 * seconds if we got one. JRA.
838 /* only set timed_out if we didn't fund what we where looking for*/
840 if ( !found && timed_out ) {
844 /* sort the ip list so we choose close servers first if possible */
845 sort_addr_list(ss_list, *count);
850 /********************************************************
851 convert an array if struct sockaddr_storage to struct ip_service
852 return false on failure. Port is set to PORT_NONE;
853 *********************************************************/
855 static bool convert_ss2service(struct ip_service **return_iplist,
856 const struct sockaddr_storage *ss_list,
861 if ( count==0 || !ss_list )
864 /* copy the ip address; port will be PORT_NONE */
865 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
867 DEBUG(0,("convert_ip2service: malloc failed "
868 "for %d enetries!\n", count ));
872 for ( i=0; i<count; i++ ) {
873 (*return_iplist)[i].ss = ss_list[i];
874 (*return_iplist)[i].port = PORT_NONE;
880 /********************************************************
881 Resolve via "bcast" method.
882 *********************************************************/
884 NTSTATUS name_resolve_bcast(const char *name,
886 struct ip_service **return_iplist,
890 int num_interfaces = iface_count();
891 struct sockaddr_storage *ss_list;
892 struct sockaddr_storage ss;
895 if (lp_disable_netbios()) {
896 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
898 return NT_STATUS_INVALID_PARAMETER;
901 *return_iplist = NULL;
905 * "bcast" means do a broadcast lookup on all the local interfaces.
908 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
909 "for name %s<0x%x>\n", name, name_type));
911 if (!interpret_string_addr(&ss, lp_socket_address(),
912 AI_NUMERICHOST|AI_PASSIVE)) {
916 sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
918 return NT_STATUS_UNSUCCESSFUL;
921 set_socket_options(sock,"SO_BROADCAST");
923 * Lookup the name on all the interfaces, return on
924 * the first successful match.
926 for( i = num_interfaces-1; i >= 0; i--) {
927 const struct sockaddr_storage *pss = iface_n_bcast(i);
930 /* Done this way to fix compiler error on IRIX 5.x */
934 ss_list = name_query(sock, name, name_type, true,
935 true, pss, return_count, &flags, NULL);
941 /* failed - no response */
944 return NT_STATUS_UNSUCCESSFUL;
948 status = NT_STATUS_OK;
949 if (!convert_ss2service(return_iplist, ss_list, *return_count) )
950 status = NT_STATUS_INVALID_PARAMETER;
957 /********************************************************
958 Resolve via "wins" method.
959 *********************************************************/
961 NTSTATUS resolve_wins(const char *name,
963 struct ip_service **return_iplist,
968 struct sockaddr_storage src_ss, *ss_list = NULL;
969 struct in_addr src_ip;
972 if (lp_disable_netbios()) {
973 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
975 return NT_STATUS_INVALID_PARAMETER;
978 *return_iplist = NULL;
981 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
984 if (wins_srv_count() < 1) {
985 DEBUG(3,("resolve_wins: WINS server resolution selected "
986 "and no WINS servers listed.\n"));
987 return NT_STATUS_INVALID_PARAMETER;
990 /* we try a lookup on each of the WINS tags in turn */
991 wins_tags = wins_srv_tags();
994 /* huh? no tags?? give up in disgust */
995 return NT_STATUS_INVALID_PARAMETER;
998 /* the address we will be sending from */
999 if (!interpret_string_addr(&src_ss, lp_socket_address(),
1000 AI_NUMERICHOST|AI_PASSIVE)) {
1001 zero_sockaddr(&src_ss);
1004 if (src_ss.ss_family != AF_INET) {
1005 char addr[INET6_ADDRSTRLEN];
1006 print_sockaddr(addr, sizeof(addr), &src_ss);
1007 DEBUG(3,("resolve_wins: cannot receive WINS replies "
1008 "on IPv6 address %s\n",
1010 wins_srv_tags_free(wins_tags);
1011 return NT_STATUS_INVALID_PARAMETER;
1014 src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
1016 /* in the worst case we will try every wins server with every
1018 for (t=0; wins_tags && wins_tags[t]; t++) {
1019 int srv_count = wins_srv_count_tag(wins_tags[t]);
1020 for (i=0; i<srv_count; i++) {
1021 struct sockaddr_storage wins_ss;
1022 struct in_addr wins_ip;
1026 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
1028 if (global_in_nmbd && ismyip_v4(wins_ip)) {
1029 /* yikes! we'll loop forever */
1033 /* skip any that have been unresponsive lately */
1034 if (wins_srv_is_dead(wins_ip, src_ip)) {
1038 DEBUG(3,("resolve_wins: using WINS server %s "
1040 inet_ntoa(wins_ip), wins_tags[t]));
1042 sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
1047 in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
1048 ss_list = name_query(sock,
1058 /* exit loop if we got a list of addresses */
1066 /* Timed out wating for WINS server to respond.
1068 wins_srv_died(wins_ip, src_ip);
1070 /* The name definately isn't in this
1071 group of WINS servers.
1072 goto the next group */
1078 wins_srv_tags_free(wins_tags);
1079 return NT_STATUS_NO_LOGON_SERVERS;
1083 status = NT_STATUS_OK;
1084 if (!convert_ss2service(return_iplist, ss_list, *return_count))
1085 status = NT_STATUS_INVALID_PARAMETER;
1088 wins_srv_tags_free(wins_tags);
1094 /********************************************************
1095 Resolve via "lmhosts" method.
1096 *********************************************************/
1098 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
1099 struct ip_service **return_iplist,
1103 * "lmhosts" means parse the local lmhosts file.
1107 char *lmhost_name = NULL;
1109 struct sockaddr_storage return_ss;
1110 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1111 TALLOC_CTX *ctx = NULL;
1113 *return_iplist = NULL;
1116 DEBUG(3,("resolve_lmhosts: "
1117 "Attempting lmhosts lookup for name %s<0x%x>\n",
1120 fp = startlmhosts(get_dyn_LMHOSTSFILE());
1123 return NT_STATUS_NO_SUCH_FILE;
1125 ctx = talloc_init("resolve_lmhosts");
1128 return NT_STATUS_NO_MEMORY;
1131 while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) {
1133 if (!strequal(name, lmhost_name)) {
1134 TALLOC_FREE(lmhost_name);
1138 if ((name_type2 != -1) && (name_type != name_type2)) {
1139 TALLOC_FREE(lmhost_name);
1143 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist),
1147 if ((*return_iplist) == NULL) {
1150 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
1151 return NT_STATUS_NO_MEMORY;
1154 (*return_iplist)[*return_count].ss = return_ss;
1155 (*return_iplist)[*return_count].port = PORT_NONE;
1158 /* we found something */
1159 status = NT_STATUS_OK;
1161 /* Multiple names only for DC lookup */
1162 if (name_type != 0x1c)
1172 /********************************************************
1173 Resolve via "hosts" method.
1174 *********************************************************/
1176 static NTSTATUS resolve_hosts(const char *name, int name_type,
1177 struct ip_service **return_iplist,
1181 * "host" means do a localhost, or dns lookup.
1183 struct addrinfo hints;
1184 struct addrinfo *ailist = NULL;
1185 struct addrinfo *res = NULL;
1189 if ( name_type != 0x20 && name_type != 0x0) {
1190 DEBUG(5, ("resolve_hosts: not appropriate "
1191 "for name type <0x%x>\n",
1193 return NT_STATUS_INVALID_PARAMETER;
1196 *return_iplist = NULL;
1199 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
1203 /* By default make sure it supports TCP. */
1204 hints.ai_socktype = SOCK_STREAM;
1205 hints.ai_flags = AI_ADDRCONFIG;
1207 #if !defined(HAVE_IPV6)
1208 /* Unless we have IPv6, we really only want IPv4 addresses back. */
1209 hints.ai_family = AF_INET;
1212 ret = getaddrinfo(name,
1217 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
1219 gai_strerror(ret) ));
1222 for (res = ailist; res; res = res->ai_next) {
1223 struct sockaddr_storage ss;
1225 if (!res->ai_addr || res->ai_addrlen == 0) {
1230 memcpy(&ss, res->ai_addr, res->ai_addrlen);
1234 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
1237 if (!*return_iplist) {
1238 DEBUG(3,("resolve_hosts: malloc fail !\n"));
1239 freeaddrinfo(ailist);
1240 return NT_STATUS_NO_MEMORY;
1242 (*return_iplist)[i].ss = ss;
1243 (*return_iplist)[i].port = PORT_NONE;
1247 freeaddrinfo(ailist);
1249 if (*return_count) {
1250 return NT_STATUS_OK;
1252 return NT_STATUS_UNSUCCESSFUL;
1255 /********************************************************
1256 Resolve via "ADS" method.
1257 *********************************************************/
1259 static NTSTATUS resolve_ads(const char *name,
1261 const char *sitename,
1262 struct ip_service **return_iplist,
1268 struct dns_rr_srv *dcs = NULL;
1272 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
1273 (name_type != 0x1b)) {
1274 return NT_STATUS_INVALID_PARAMETER;
1277 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1278 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1279 return NT_STATUS_NO_MEMORY;
1282 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
1284 switch (name_type) {
1286 DEBUG(5,("resolve_ads: Attempting to resolve "
1287 "PDC for %s using DNS\n", name));
1288 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
1292 DEBUG(5,("resolve_ads: Attempting to resolve "
1293 "DCs for %s using DNS\n", name));
1294 status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1298 DEBUG(5,("resolve_ads: Attempting to resolve "
1299 "KDCs for %s using DNS\n", name));
1300 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1304 status = NT_STATUS_INVALID_PARAMETER;
1308 if ( !NT_STATUS_IS_OK( status ) ) {
1309 talloc_destroy(ctx);
1313 for (i=0;i<numdcs;i++) {
1314 numaddrs += MAX(dcs[i].num_ips,1);
1317 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
1319 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
1321 talloc_destroy(ctx);
1322 return NT_STATUS_NO_MEMORY;
1325 /* now unroll the list of IP addresses */
1330 while ( i < numdcs && (*return_count<numaddrs) ) {
1331 struct ip_service *r = &(*return_iplist)[*return_count];
1333 r->port = dcs[i].port;
1335 /* If we don't have an IP list for a name, lookup it up */
1338 interpret_string_addr(&r->ss, dcs[i].hostname, 0);
1342 /* use the IP addresses from the SRV sresponse */
1344 if ( j >= dcs[i].num_ips ) {
1350 r->ss = dcs[i].ss_s[j];
1354 /* make sure it is a valid IP. I considered checking the
1355 * negative connection cache, but this is the wrong place
1356 * for it. Maybe only as a hack. After think about it, if
1357 * all of the IP addresses returned from DNS are dead, what
1358 * hope does a netbios name lookup have ? The standard reason
1359 * for falling back to netbios lookups is that our DNS server
1360 * doesn't know anything about the DC's -- jerry */
1362 if (!is_zero_addr((struct sockaddr *)&r->ss)) {
1367 talloc_destroy(ctx);
1368 return NT_STATUS_OK;
1371 /*******************************************************************
1372 Internal interface to resolve a name into an IP address.
1373 Use this function if the string is either an IP address, DNS
1374 or host name or NetBIOS name. This uses the name switch in the
1375 smb.conf to determine the order of name resolution.
1377 Added support for ip addr/port to support ADS ldap servers.
1378 the only place we currently care about the port is in the
1379 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1380 **********************************************************************/
1382 NTSTATUS internal_resolve_name(const char *name,
1384 const char *sitename,
1385 struct ip_service **return_iplist,
1387 const char *resolve_order)
1391 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1393 TALLOC_CTX *frame = NULL;
1395 *return_iplist = NULL;
1398 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1399 name, name_type, sitename ? sitename : "(null)"));
1401 if (is_ipaddress(name)) {
1402 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
1404 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1405 return NT_STATUS_NO_MEMORY;
1408 /* ignore the port here */
1409 (*return_iplist)->port = PORT_NONE;
1411 /* if it's in the form of an IP address then get the lib to interpret it */
1412 if (!interpret_string_addr(&(*return_iplist)->ss,
1413 name, AI_NUMERICHOST)) {
1414 DEBUG(1,("internal_resolve_name: interpret_string_addr "
1417 SAFE_FREE(*return_iplist);
1418 return NT_STATUS_INVALID_PARAMETER;
1421 return NT_STATUS_OK;
1424 /* Check name cache */
1426 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1427 /* This could be a negative response */
1428 if (*return_count > 0) {
1429 return NT_STATUS_OK;
1431 return NT_STATUS_UNSUCCESSFUL;
1435 /* set the name resolution order */
1437 if (strcmp( resolve_order, "NULL") == 0) {
1438 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1439 return NT_STATUS_INVALID_PARAMETER;
1442 if (!resolve_order[0]) {
1445 ptr = resolve_order;
1448 /* iterate through the name resolution backends */
1450 frame = talloc_stackframe();
1451 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
1452 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1453 status = resolve_hosts(name, name_type, return_iplist,
1455 if (NT_STATUS_IS_OK(status)) {
1458 } else if(strequal( tok, "kdc")) {
1459 /* deal with KDC_NAME_TYPE names here.
1460 * This will result in a SRV record lookup */
1461 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1462 return_iplist, return_count);
1463 if (NT_STATUS_IS_OK(status)) {
1464 /* Ensure we don't namecache
1465 * this with the KDC port. */
1466 name_type = KDC_NAME_TYPE;
1469 } else if(strequal( tok, "ads")) {
1470 /* deal with 0x1c and 0x1b names here.
1471 * This will result in a SRV record lookup */
1472 status = resolve_ads(name, name_type, sitename,
1473 return_iplist, return_count);
1474 if (NT_STATUS_IS_OK(status)) {
1477 } else if(strequal( tok, "lmhosts")) {
1478 status = resolve_lmhosts(name, name_type,
1479 return_iplist, return_count);
1480 if (NT_STATUS_IS_OK(status)) {
1483 } else if(strequal( tok, "wins")) {
1484 /* don't resolve 1D via WINS */
1485 if (name_type != 0x1D) {
1486 status = resolve_wins(name, name_type,
1489 if (NT_STATUS_IS_OK(status)) {
1493 } else if(strequal( tok, "bcast")) {
1494 status = name_resolve_bcast(name, name_type,
1497 if (NT_STATUS_IS_OK(status)) {
1501 DEBUG(0,("resolve_name: unknown name switch type %s\n",
1506 /* All of the resolve_* functions above have returned false. */
1509 SAFE_FREE(*return_iplist);
1512 return NT_STATUS_UNSUCCESSFUL;
1516 /* Remove duplicate entries. Some queries, notably #1c (domain
1517 controllers) return the PDC in iplist[0] and then all domain
1518 controllers including the PDC in iplist[1..n]. Iterating over
1519 the iplist when the PDC is down will cause two sets of timeouts. */
1521 if ( *return_count ) {
1522 *return_count = remove_duplicate_addrs2(*return_iplist,
1526 /* Save in name cache */
1527 if ( DEBUGLEVEL >= 100 ) {
1528 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
1529 char addr[INET6_ADDRSTRLEN];
1530 print_sockaddr(addr, sizeof(addr),
1531 &(*return_iplist)[i].ss);
1532 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
1536 (*return_iplist)[i].port));
1540 namecache_store(name, name_type, *return_count, *return_iplist);
1542 /* Display some debugging info */
1544 if ( DEBUGLEVEL >= 10 ) {
1545 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1548 for (i = 0; i < *return_count; i++) {
1549 char addr[INET6_ADDRSTRLEN];
1550 print_sockaddr(addr, sizeof(addr),
1551 &(*return_iplist)[i].ss);
1552 DEBUGADD(10, ("%s:%d ",
1554 (*return_iplist)[i].port));
1563 /********************************************************
1564 Internal interface to resolve a name into one IP address.
1565 Use this function if the string is either an IP address, DNS
1566 or host name or NetBIOS name. This uses the name switch in the
1567 smb.conf to determine the order of name resolution.
1568 *********************************************************/
1570 bool resolve_name(const char *name,
1571 struct sockaddr_storage *return_ss,
1575 struct ip_service *ss_list = NULL;
1576 char *sitename = NULL;
1579 if (is_ipaddress(name)) {
1580 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
1583 sitename = sitename_fetch(lp_realm()); /* wild guess */
1585 if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1587 lp_name_resolve_order()))) {
1591 for (i=0; i<count; i++) {
1592 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1593 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) &&
1594 (ss_list[i].ss.ss_family == AF_INET)) {
1595 *return_ss = ss_list[i].ss;
1597 SAFE_FREE(sitename);
1603 /* only return valid addresses for TCP connections */
1604 for (i=0; i<count; i++) {
1605 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1606 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1607 *return_ss = ss_list[i].ss;
1609 SAFE_FREE(sitename);
1616 SAFE_FREE(sitename);
1620 /********************************************************
1621 Internal interface to resolve a name into a list of IP addresses.
1622 Use this function if the string is either an IP address, DNS
1623 or host name or NetBIOS name. This uses the name switch in the
1624 smb.conf to determine the order of name resolution.
1625 *********************************************************/
1627 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
1630 struct sockaddr_storage **return_ss_arr,
1631 unsigned int *p_num_entries)
1633 struct ip_service *ss_list = NULL;
1634 char *sitename = NULL;
1637 unsigned int num_entries;
1641 *return_ss_arr = NULL;
1643 if (is_ipaddress(name)) {
1644 *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);
1645 if (!*return_ss_arr) {
1646 return NT_STATUS_NO_MEMORY;
1648 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
1649 TALLOC_FREE(*return_ss_arr);
1650 return NT_STATUS_BAD_NETWORK_NAME;
1653 return NT_STATUS_OK;
1656 sitename = sitename_fetch(lp_realm()); /* wild guess */
1658 status = internal_resolve_name(name, name_type, sitename,
1660 lp_name_resolve_order());
1661 SAFE_FREE(sitename);
1663 if (!NT_STATUS_IS_OK(status)) {
1667 /* only return valid addresses for TCP connections */
1668 for (i=0, num_entries = 0; i<count; i++) {
1669 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1670 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1674 if (num_entries == 0) {
1676 return NT_STATUS_BAD_NETWORK_NAME;
1679 *return_ss_arr = TALLOC_ARRAY(ctx,
1680 struct sockaddr_storage,
1682 if (!(*return_ss_arr)) {
1684 return NT_STATUS_NO_MEMORY;
1687 for (i=0, num_entries = 0; i<count; i++) {
1688 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1689 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1690 (*return_ss_arr)[num_entries++] = ss_list[i].ss;
1694 status = NT_STATUS_OK;
1695 *p_num_entries = num_entries;
1698 return NT_STATUS_OK;
1701 /********************************************************
1702 Find the IP address of the master browser or DMB for a workgroup.
1703 *********************************************************/
1705 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
1707 struct ip_service *ip_list = NULL;
1711 if (lp_disable_netbios()) {
1712 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1716 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1717 lp_name_resolve_order());
1718 if (NT_STATUS_IS_OK(status)) {
1719 *master_ss = ip_list[0].ss;
1724 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1725 lp_name_resolve_order());
1726 if (NT_STATUS_IS_OK(status)) {
1727 *master_ss = ip_list[0].ss;
1736 /********************************************************
1737 Get the IP address list of the primary domain controller
1739 *********************************************************/
1741 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
1743 struct ip_service *ip_list = NULL;
1745 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1747 /* Look up #1B name */
1749 if (lp_security() == SEC_ADS) {
1750 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1754 if (!NT_STATUS_IS_OK(status) || count == 0) {
1755 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1757 lp_name_resolve_order());
1758 if (!NT_STATUS_IS_OK(status)) {
1763 /* if we get more than 1 IP back we have to assume it is a
1764 multi-homed PDC and not a mess up */
1767 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1768 sort_service_list(ip_list, count);
1771 *pss = ip_list[0].ss;
1776 /* Private enum type for lookups. */
1778 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1780 /********************************************************
1781 Get the IP address list of the domain controllers for
1783 *********************************************************/
1785 static NTSTATUS get_dc_list(const char *domain,
1786 const char *sitename,
1787 struct ip_service **ip_list,
1789 enum dc_lookup_type lookup_type,
1792 char *resolve_order = NULL;
1793 char *saf_servername = NULL;
1794 char *pserver = NULL;
1796 char *port_str = NULL;
1799 int num_addresses = 0;
1800 int local_count, i, j;
1801 struct ip_service *return_iplist = NULL;
1802 struct ip_service *auto_ip_list = NULL;
1803 bool done_auto_lookup = false;
1806 TALLOC_CTX *ctx = talloc_init("get_dc_list");
1812 return NT_STATUS_NO_MEMORY;
1817 /* if we are restricted to solely using DNS for looking
1818 up a domain controller, make sure that host lookups
1819 are enabled for the 'name resolve order'. If host lookups
1820 are disabled and ads_only is True, then set the string to
1823 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
1824 if (!resolve_order) {
1825 status = NT_STATUS_NO_MEMORY;
1828 strlower_m(resolve_order);
1829 if (lookup_type == DC_ADS_ONLY) {
1830 if (strstr( resolve_order, "host")) {
1831 resolve_order = talloc_strdup(ctx, "ads");
1833 /* DNS SRV lookups used by the ads resolver
1834 are already sorted by priority and weight */
1837 resolve_order = talloc_strdup(ctx, "NULL");
1839 } else if (lookup_type == DC_KDC_ONLY) {
1840 /* DNS SRV lookups used by the ads/kdc resolver
1841 are already sorted by priority and weight */
1843 resolve_order = talloc_strdup(ctx, "kdc");
1845 if (!resolve_order) {
1846 status = NT_STATUS_NO_MEMORY;
1850 /* fetch the server we have affinity for. Add the
1851 'password server' list to a search for our domain controllers */
1853 saf_servername = saf_fetch( domain);
1855 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
1856 pserver = talloc_asprintf(NULL, "%s, %s",
1857 saf_servername ? saf_servername : "",
1858 lp_passwordserver());
1860 pserver = talloc_asprintf(NULL, "%s, *",
1861 saf_servername ? saf_servername : "");
1864 SAFE_FREE(saf_servername);
1866 status = NT_STATUS_NO_MEMORY;
1870 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1873 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1874 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1875 count, resolve_order);
1879 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1882 * if '*' appears in the "password server" list then add
1883 * an auto lookup to the list of manually configured
1884 * DC's. If any DC is listed by name, then the list should be
1885 * considered to be ordered
1889 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1890 if (!done_auto_lookup && strequal(name, "*")) {
1891 status = internal_resolve_name(domain, 0x1C, sitename,
1895 if (NT_STATUS_IS_OK(status)) {
1896 num_addresses += auto_count;
1898 done_auto_lookup = true;
1899 DEBUG(8,("Adding %d DC's from auto lookup\n",
1906 /* if we have no addresses and haven't done the auto lookup, then
1907 just return the list of DC's. Or maybe we just failed. */
1909 if ((num_addresses == 0)) {
1910 if (done_auto_lookup) {
1911 DEBUG(4,("get_dc_list: no servers found\n"));
1912 status = NT_STATUS_NO_LOGON_SERVERS;
1915 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1916 count, resolve_order);
1920 if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
1921 num_addresses)) == NULL) {
1922 DEBUG(3,("get_dc_list: malloc fail !\n"));
1923 status = NT_STATUS_NO_MEMORY;
1930 /* fill in the return list now with real IP's */
1932 while ((local_count<num_addresses) &&
1933 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1934 struct sockaddr_storage name_ss;
1936 /* copy any addersses from the auto lookup */
1938 if (strequal(name, "*")) {
1939 for (j=0; j<auto_count; j++) {
1940 char addr[INET6_ADDRSTRLEN];
1941 print_sockaddr(addr,
1943 &auto_ip_list[j].ss);
1944 /* Check for and don't copy any
1945 * known bad DC IP's. */
1946 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
1949 DEBUG(5,("get_dc_list: "
1950 "negative entry %s removed "
1955 return_iplist[local_count].ss =
1957 return_iplist[local_count].port =
1958 auto_ip_list[j].port;
1964 /* added support for address:port syntax for ads
1965 * (not that I think anyone will ever run the LDAP
1966 * server in an AD domain on something other than
1969 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1970 if ((port_str=strchr(name, ':')) != NULL) {
1973 port = atoi(port_str);
1976 /* explicit lookup; resolve_name() will
1977 * handle names & IP addresses */
1978 if (resolve_name( name, &name_ss, 0x20, true )) {
1979 char addr[INET6_ADDRSTRLEN];
1980 print_sockaddr(addr,
1984 /* Check for and don't copy any known bad DC IP's. */
1985 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
1987 DEBUG(5,("get_dc_list: negative entry %s "
1988 "removed from DC list\n",
1993 return_iplist[local_count].ss = name_ss;
1994 return_iplist[local_count].port = port;
2000 /* need to remove duplicates in the list if we have any
2001 explicit password servers */
2004 local_count = remove_duplicate_addrs2(return_iplist,
2008 /* For DC's we always prioritize IPv4 due to W2K3 not
2009 * supporting LDAP, KRB5 or CLDAP over IPv6. */
2011 if (local_count && return_iplist) {
2012 prioritize_ipv4_list(return_iplist, local_count);
2015 if ( DEBUGLEVEL >= 4 ) {
2016 DEBUG(4,("get_dc_list: returning %d ip addresses "
2017 "in an %sordered list\n",
2019 *ordered ? "":"un"));
2020 DEBUG(4,("get_dc_list: "));
2021 for ( i=0; i<local_count; i++ ) {
2022 char addr[INET6_ADDRSTRLEN];
2023 print_sockaddr(addr,
2025 &return_iplist[i].ss);
2026 DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
2031 *ip_list = return_iplist;
2032 *count = local_count;
2034 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
2038 if (!NT_STATUS_IS_OK(status)) {
2039 SAFE_FREE(return_iplist);
2044 SAFE_FREE(auto_ip_list);
2049 /*********************************************************************
2050 Small wrapper function to get the DC list and sort it if neccessary.
2051 *********************************************************************/
2053 NTSTATUS get_sorted_dc_list( const char *domain,
2054 const char *sitename,
2055 struct ip_service **ip_list,
2059 bool ordered = false;
2061 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
2066 DEBUG(8,("get_sorted_dc_list: attempting lookup "
2067 "for name %s (sitename %s) using [%s]\n",
2069 sitename ? sitename : "NULL",
2070 (ads_only ? "ads" : lp_name_resolve_order())));
2073 lookup_type = DC_ADS_ONLY;
2076 status = get_dc_list(domain, sitename, ip_list,
2077 count, lookup_type, &ordered);
2078 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
2080 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
2081 " in site %s, fallback to all servers\n",
2083 status = get_dc_list(domain, NULL, ip_list,
2084 count, lookup_type, &ordered);
2087 if (!NT_STATUS_IS_OK(status)) {
2088 SAFE_FREE(*ip_list);
2093 /* only sort if we don't already have an ordered list */
2095 sort_service_list(*ip_list, *count);
2098 return NT_STATUS_OK;
2101 /*********************************************************************
2102 Get the KDC list - re-use all the logic in get_dc_list.
2103 *********************************************************************/
2105 NTSTATUS get_kdc_list( const char *realm,
2106 const char *sitename,
2107 struct ip_service **ip_list,
2116 status = get_dc_list(realm, sitename, ip_list,
2117 count, DC_KDC_ONLY, &ordered);
2119 if (!NT_STATUS_IS_OK(status)) {
2120 SAFE_FREE(*ip_list);
2125 /* only sort if we don't already have an ordered list */
2127 sort_service_list(*ip_list, *count);
2130 return NT_STATUS_OK;