Fix convert_ss2service() to filter out zero addresses.
[Samba.git] / source3 / libsmb / namequery.c
blobb68448e16aedcd83cca86a71b59e785df9004188
1 /*
2 Unix SMB/CIFS implementation.
3 name query routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2007.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
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"
36 #define SAF_TTL 900
37 #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
38 #define SAFJOIN_TTL 3600
40 static char *saf_key(const char *domain)
42 char *keystr;
44 asprintf_strupper_m(&keystr, SAFKEY_FMT, domain);
46 return keystr;
49 static char *saf_join_key(const char *domain)
51 char *keystr;
53 asprintf_strupper_m(&keystr, SAFJOINKEY_FMT, domain);
55 return keystr;
58 /****************************************************************************
59 ****************************************************************************/
61 bool saf_store( const char *domain, const char *servername )
63 char *key;
64 time_t expire;
65 bool ret = False;
67 if ( !domain || !servername ) {
68 DEBUG(2,("saf_store: "
69 "Refusing to store empty domain or servername!\n"));
70 return False;
73 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
74 DEBUG(0,("saf_store: "
75 "refusing to store 0 length domain or servername!\n"));
76 return False;
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 );
87 SAFE_FREE( key );
89 return ret;
92 bool saf_join_store( const char *domain, const char *servername )
94 char *key;
95 time_t expire;
96 bool ret = False;
98 if ( !domain || !servername ) {
99 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
100 return False;
103 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
104 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
105 return False;
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 );
116 SAFE_FREE( key );
118 return ret;
121 bool saf_delete( const char *domain )
123 char *key;
124 bool ret = False;
126 if ( !domain ) {
127 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
128 return False;
131 key = saf_join_key(domain);
132 ret = gencache_del(key);
133 SAFE_FREE(key);
135 if (ret) {
136 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain ));
139 key = saf_key(domain);
140 ret = gencache_del(key);
141 SAFE_FREE(key);
143 if (ret) {
144 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
147 return ret;
150 /****************************************************************************
151 ****************************************************************************/
153 char *saf_fetch( const char *domain )
155 char *server = NULL;
156 time_t timeout;
157 bool ret = False;
158 char *key = NULL;
160 if ( !domain || strlen(domain) == 0) {
161 DEBUG(2,("saf_fetch: Empty domain name!\n"));
162 return NULL;
165 key = saf_join_key( domain );
167 ret = gencache_get( key, &server, &timeout );
169 SAFE_FREE( key );
171 if ( ret ) {
172 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
173 server, domain ));
174 return server;
177 key = saf_key( domain );
179 ret = gencache_get( key, &server, &timeout );
181 SAFE_FREE( key );
183 if ( !ret ) {
184 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
185 domain ));
186 } else {
187 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
188 server, domain ));
191 return server;
194 /****************************************************************************
195 Generate a random trn_id.
196 ****************************************************************************/
198 static int generate_trn_id(void)
200 uint16 id;
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,
212 int *num_names,
213 struct node_status_extra *extra)
215 NODE_STATUS_STRUCT *ret;
216 int i;
218 *num_names = CVAL(p,0);
220 if (*num_names == 0)
221 return NULL;
223 ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
224 if (!ret)
225 return NULL;
227 p++;
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];
233 p += 18;
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 ...
240 if (extra) {
241 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
243 return ret;
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,
255 int *num_names,
256 struct node_status_extra *extra)
258 bool found=False;
259 int retries = 2;
260 int retry_time = 2000;
261 struct timeval tval;
262 struct packet_struct p;
263 struct packet_struct *p2;
264 struct nmb_packet *nmb = &p.packet.nmb;
265 NODE_STATUS_STRUCT *ret;
267 ZERO_STRUCT(p);
269 if (to_ss->ss_family != AF_INET) {
270 /* Can't do node status to IPv6 */
271 return NULL;
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;
291 p.port = NMB_PORT;
292 p.recv_fd = -1;
293 p.send_fd = fd;
294 p.timestamp = time(NULL);
295 p.packet_type = NMB_PACKET;
297 GetTimeOfDay(&tval);
299 if (!send_packet(&p))
300 return NULL;
302 retries--;
304 while (1) {
305 struct timeval tval2;
306 GetTimeOfDay(&tval2);
307 if (TvalDiff(&tval,&tval2) > retry_time) {
308 if (!retries)
309 break;
310 if (!found && !send_packet(&p))
311 return NULL;
312 GetTimeOfDay(&tval);
313 retries--;
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
327 moment */
328 free_packet(p2);
329 continue;
332 ret = parse_node_status(&nmb2->answers->rdata[0],
333 num_names, extra);
334 free_packet(p2);
335 return ret;
339 return NULL;
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,
348 int q_type,
349 int type,
350 const struct sockaddr_storage *to_ss,
351 fstring name)
353 char addr[INET6_ADDRSTRLEN];
354 struct sockaddr_storage ss;
355 NODE_STATUS_STRUCT *status = NULL;
356 struct nmb_name nname;
357 int count, i;
358 int sock;
359 bool result = false;
361 if (lp_disable_netbios()) {
362 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
363 q_name, q_type));
364 return False;
367 print_sockaddr(addr, sizeof(addr), to_ss);
369 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
370 q_type, addr));
372 /* Check the cache first. */
374 if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
375 return True;
378 if (to_ss->ss_family != AF_INET) {
379 /* Can't do node status to IPv6 */
380 return false;
383 if (!interpret_string_addr(&ss, lp_socket_address(),
384 AI_NUMERICHOST|AI_PASSIVE)) {
385 zero_sockaddr(&ss);
388 sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);
389 if (sock == -1)
390 goto done;
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);
395 close(sock);
396 if (!status)
397 goto done;
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))
402 break;
404 if (i == count)
405 goto done;
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);
417 result = true;
419 done:
420 SAFE_FREE(status);
422 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
424 if (result)
425 DEBUGADD(10, (", name %s ip address is %s", name, addr));
427 DEBUG(10, ("\n"));
429 return result;
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();
441 int i;
443 /* Sort IPv4 addresses first. */
444 if (ss1->sa_family != ss2->sa_family) {
445 if (ss2->sa_family == AF_INET) {
446 return 1;
447 } else {
448 return -1;
452 /* Here we know both addresses are of the same
453 * family. */
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;
460 size_t len = 0;
461 int bits1, bits2;
463 if (pss->ss_family != ss1->sa_family) {
464 /* Ignore interfaces of the wrong type. */
465 continue;
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;
474 len = 4;
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;
484 len = 16;
486 #endif
487 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
488 continue;
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) {
499 max_bits1 += 32;
500 } else {
501 max_bits1 += 128;
504 if (iface_local(ss2)) {
505 if (ss2->sa_family == AF_INET) {
506 max_bits2 += 32;
507 } else {
508 max_bits2 += 128;
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)
520 int result;
522 if ((result = addr_compare((struct sockaddr *)&ss1->ss, (struct sockaddr *)&ss2->ss)) != 0) {
523 return result;
526 if (ss1->port > ss2->port) {
527 return 1;
530 if (ss1->port < ss2->port) {
531 return -1;
534 return 0;
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)
545 if (count <= 1) {
546 return;
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)
555 if (count <= 1) {
556 return;
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 )
569 int i, j;
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)) {
577 continue;
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++) {
590 while (i < count &&
591 is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
592 if (count-i-1>0) {
593 memmove(&iplist[i],
594 &iplist[i+1],
595 (count-i-1)*sizeof(struct ip_service));
597 count--;
601 return count;
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);
608 int i, j;
610 if (iplist_new == NULL) {
611 TALLOC_FREE(frame);
612 return false;
615 j = 0;
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];
624 /* Copy IPv6. */
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);
632 TALLOC_FREE(frame);
633 return true;
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,
644 const char *name,
645 int name_type,
646 bool bcast,
647 bool recurse,
648 const struct sockaddr_storage *to_ss,
649 int *count,
650 int *flags,
651 bool *timed_out)
653 bool found=false;
654 int i, retries = 3;
655 int retry_time = bcast?250:2000;
656 struct timeval tval;
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",
664 name, name_type));
665 return NULL;
668 if (to_ss->ss_family != AF_INET) {
669 return NULL;
672 if (timed_out) {
673 *timed_out = false;
676 memset((char *)&p,'\0',sizeof(p));
677 (*count) = 0;
678 (*flags) = 0;
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;
700 p.port = NMB_PORT;
701 p.recv_fd = -1;
702 p.send_fd = fd;
703 p.timestamp = time(NULL);
704 p.packet_type = NMB_PACKET;
706 GetTimeOfDay(&tval);
708 if (!send_packet(&p))
709 return NULL;
711 retries--;
713 while (1) {
714 struct timeval tval2;
716 GetTimeOfDay(&tval2);
717 if (TvalDiff(&tval,&tval2) > retry_time) {
718 if (!retries)
719 break;
720 if (!found && !send_packet(&p))
721 return NULL;
722 GetTimeOfDay(&tval);
723 retries--;
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 ) {
744 case 0x01:
745 dbgtext( "Request "
746 "was invalidly formatted.\n" );
747 break;
748 case 0x02:
749 dbgtext( "Problem with NBNS, "
750 "cannot process name.\n");
751 break;
752 case 0x03:
753 dbgtext( "The name requested "
754 "does not exist.\n" );
755 break;
756 case 0x04:
757 dbgtext( "Unsupported request "
758 "error.\n" );
759 break;
760 case 0x05:
761 dbgtext( "Query refused "
762 "error.\n" );
763 break;
764 default:
765 dbgtext( "Unrecognized error "
766 "code.\n" );
767 break;
770 free_packet(p2);
771 return( NULL );
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
781 * moment.
783 free_packet(p2);
784 continue;
787 ss_list = SMB_REALLOC_ARRAY(ss_list,
788 struct sockaddr_storage,
789 (*count) +
790 nmb2->answers->rdlength/6);
792 if (!ss_list) {
793 DEBUG(0,("name_query: Realloc failed.\n"));
794 free_packet(p2);
795 return NULL;
798 DEBUG(2,("Got a positive name query response "
799 "from %s ( ",
800 inet_ntoa(p2->ip)));
802 for (i=0;i<nmb2->answers->rdlength/6;i++) {
803 struct in_addr ip;
804 putip((char *)&ip,&nmb2->answers->rdata[2+i*6]);
805 in_addr_to_sockaddr_storage(&ss_list[(*count)],
806 ip);
807 DEBUGADD(2,("%s ",inet_ntoa(ip)));
808 (*count)++;
810 DEBUGADD(2,(")\n"));
812 found=true;
813 retries=0;
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;
827 free_packet(p2);
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.
833 if(!bcast && found)
834 break;
838 /* only set timed_out if we didn't fund what we where looking for*/
840 if ( !found && timed_out ) {
841 *timed_out = true;
844 /* sort the ip list so we choose close servers first if possible */
845 sort_addr_list(ss_list, *count);
847 return ss_list;
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 pcount is [in/out] - it is the length of ss_list on input,
854 and the length of return_iplist on output as we remove any
855 zero addresses from ss_list.
856 *********************************************************/
858 static bool convert_ss2service(struct ip_service **return_iplist,
859 const struct sockaddr_storage *ss_list,
860 int *pcount)
862 int i;
863 int orig_count = *pcount;
864 int real_count = 0;
866 if (orig_count==0 || !ss_list )
867 return False;
869 /* Filter out zero addrs. */
870 for ( i=0; i<orig_count; i++ ) {
871 if (is_zero_addr((struct sockaddr *)&ss_list[i])) {
872 continue;
874 real_count++;
876 if (real_count==0) {
877 return false;
880 /* copy the ip address; port will be PORT_NONE */
881 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, real_count)) ==
882 NULL) {
883 DEBUG(0,("convert_ip2service: malloc failed "
884 "for %d enetries!\n", real_count ));
885 return False;
888 for ( i=0, real_count = 0; i<orig_count; i++ ) {
889 if (is_zero_addr((struct sockaddr *)&ss_list[i])) {
890 continue;
892 (*return_iplist)[real_count].ss = ss_list[i];
893 (*return_iplist)[real_count].port = PORT_NONE;
894 real_count++;
897 *pcount = real_count;
898 return true;
901 /********************************************************
902 Resolve via "bcast" method.
903 *********************************************************/
905 NTSTATUS name_resolve_bcast(const char *name,
906 int name_type,
907 struct ip_service **return_iplist,
908 int *return_count)
910 int sock, i;
911 int num_interfaces = iface_count();
912 struct sockaddr_storage *ss_list;
913 struct sockaddr_storage ss;
914 NTSTATUS status;
916 if (lp_disable_netbios()) {
917 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
918 name, name_type));
919 return NT_STATUS_INVALID_PARAMETER;
922 *return_iplist = NULL;
923 *return_count = 0;
926 * "bcast" means do a broadcast lookup on all the local interfaces.
929 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
930 "for name %s<0x%x>\n", name, name_type));
932 if (!interpret_string_addr(&ss, lp_socket_address(),
933 AI_NUMERICHOST|AI_PASSIVE)) {
934 zero_sockaddr(&ss);
937 sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
938 if (sock == -1) {
939 return NT_STATUS_UNSUCCESSFUL;
942 set_socket_options(sock,"SO_BROADCAST");
944 * Lookup the name on all the interfaces, return on
945 * the first successful match.
947 for( i = num_interfaces-1; i >= 0; i--) {
948 const struct sockaddr_storage *pss = iface_n_bcast(i);
949 int flags;
951 /* Done this way to fix compiler error on IRIX 5.x */
952 if (!pss) {
953 continue;
955 ss_list = name_query(sock, name, name_type, true,
956 true, pss, return_count, &flags, NULL);
957 if (ss_list) {
958 goto success;
962 /* failed - no response */
964 close(sock);
965 return NT_STATUS_UNSUCCESSFUL;
967 success:
969 status = NT_STATUS_OK;
970 if (!convert_ss2service(return_iplist, ss_list, return_count) )
971 status = NT_STATUS_INVALID_PARAMETER;
973 SAFE_FREE(ss_list);
974 close(sock);
975 return status;
978 /********************************************************
979 Resolve via "wins" method.
980 *********************************************************/
982 NTSTATUS resolve_wins(const char *name,
983 int name_type,
984 struct ip_service **return_iplist,
985 int *return_count)
987 int sock, t, i;
988 char **wins_tags;
989 struct sockaddr_storage src_ss, *ss_list = NULL;
990 struct in_addr src_ip;
991 NTSTATUS status;
993 if (lp_disable_netbios()) {
994 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
995 name, name_type));
996 return NT_STATUS_INVALID_PARAMETER;
999 *return_iplist = NULL;
1000 *return_count = 0;
1002 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
1003 name, name_type));
1005 if (wins_srv_count() < 1) {
1006 DEBUG(3,("resolve_wins: WINS server resolution selected "
1007 "and no WINS servers listed.\n"));
1008 return NT_STATUS_INVALID_PARAMETER;
1011 /* we try a lookup on each of the WINS tags in turn */
1012 wins_tags = wins_srv_tags();
1014 if (!wins_tags) {
1015 /* huh? no tags?? give up in disgust */
1016 return NT_STATUS_INVALID_PARAMETER;
1019 /* the address we will be sending from */
1020 if (!interpret_string_addr(&src_ss, lp_socket_address(),
1021 AI_NUMERICHOST|AI_PASSIVE)) {
1022 zero_sockaddr(&src_ss);
1025 if (src_ss.ss_family != AF_INET) {
1026 char addr[INET6_ADDRSTRLEN];
1027 print_sockaddr(addr, sizeof(addr), &src_ss);
1028 DEBUG(3,("resolve_wins: cannot receive WINS replies "
1029 "on IPv6 address %s\n",
1030 addr));
1031 wins_srv_tags_free(wins_tags);
1032 return NT_STATUS_INVALID_PARAMETER;
1035 src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
1037 /* in the worst case we will try every wins server with every
1038 tag! */
1039 for (t=0; wins_tags && wins_tags[t]; t++) {
1040 int srv_count = wins_srv_count_tag(wins_tags[t]);
1041 for (i=0; i<srv_count; i++) {
1042 struct sockaddr_storage wins_ss;
1043 struct in_addr wins_ip;
1044 int flags;
1045 bool timed_out;
1047 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
1049 if (global_in_nmbd && ismyip_v4(wins_ip)) {
1050 /* yikes! we'll loop forever */
1051 continue;
1054 /* skip any that have been unresponsive lately */
1055 if (wins_srv_is_dead(wins_ip, src_ip)) {
1056 continue;
1059 DEBUG(3,("resolve_wins: using WINS server %s "
1060 "and tag '%s'\n",
1061 inet_ntoa(wins_ip), wins_tags[t]));
1063 sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
1064 if (sock == -1) {
1065 continue;
1068 in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
1069 ss_list = name_query(sock,
1070 name,
1071 name_type,
1072 false,
1073 true,
1074 &wins_ss,
1075 return_count,
1076 &flags,
1077 &timed_out);
1079 /* exit loop if we got a list of addresses */
1081 if (ss_list)
1082 goto success;
1084 close(sock);
1086 if (timed_out) {
1087 /* Timed out wating for WINS server to respond.
1088 * Mark it dead. */
1089 wins_srv_died(wins_ip, src_ip);
1090 } else {
1091 /* The name definately isn't in this
1092 group of WINS servers.
1093 goto the next group */
1094 break;
1099 wins_srv_tags_free(wins_tags);
1100 return NT_STATUS_NO_LOGON_SERVERS;
1102 success:
1104 status = NT_STATUS_OK;
1105 if (!convert_ss2service(return_iplist, ss_list, return_count))
1106 status = NT_STATUS_INVALID_PARAMETER;
1108 SAFE_FREE(ss_list);
1109 wins_srv_tags_free(wins_tags);
1110 close(sock);
1112 return status;
1115 /********************************************************
1116 Resolve via "lmhosts" method.
1117 *********************************************************/
1119 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
1120 struct ip_service **return_iplist,
1121 int *return_count)
1124 * "lmhosts" means parse the local lmhosts file.
1127 XFILE *fp;
1128 char *lmhost_name = NULL;
1129 int name_type2;
1130 struct sockaddr_storage return_ss;
1131 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1132 TALLOC_CTX *ctx = NULL;
1134 *return_iplist = NULL;
1135 *return_count = 0;
1137 DEBUG(3,("resolve_lmhosts: "
1138 "Attempting lmhosts lookup for name %s<0x%x>\n",
1139 name, name_type));
1141 fp = startlmhosts(get_dyn_LMHOSTSFILE());
1143 if ( fp == NULL )
1144 return NT_STATUS_NO_SUCH_FILE;
1146 ctx = talloc_init("resolve_lmhosts");
1147 if (!ctx) {
1148 endlmhosts(fp);
1149 return NT_STATUS_NO_MEMORY;
1152 while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) {
1154 if (!strequal(name, lmhost_name)) {
1155 TALLOC_FREE(lmhost_name);
1156 continue;
1159 if ((name_type2 != -1) && (name_type != name_type2)) {
1160 TALLOC_FREE(lmhost_name);
1161 continue;
1164 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist),
1165 struct ip_service,
1166 (*return_count)+1);
1168 if ((*return_iplist) == NULL) {
1169 TALLOC_FREE(ctx);
1170 endlmhosts(fp);
1171 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
1172 return NT_STATUS_NO_MEMORY;
1175 (*return_iplist)[*return_count].ss = return_ss;
1176 (*return_iplist)[*return_count].port = PORT_NONE;
1177 *return_count += 1;
1179 /* we found something */
1180 status = NT_STATUS_OK;
1182 /* Multiple names only for DC lookup */
1183 if (name_type != 0x1c)
1184 break;
1187 TALLOC_FREE(ctx);
1188 endlmhosts(fp);
1189 return status;
1193 /********************************************************
1194 Resolve via "hosts" method.
1195 *********************************************************/
1197 static NTSTATUS resolve_hosts(const char *name, int name_type,
1198 struct ip_service **return_iplist,
1199 int *return_count)
1202 * "host" means do a localhost, or dns lookup.
1204 struct addrinfo hints;
1205 struct addrinfo *ailist = NULL;
1206 struct addrinfo *res = NULL;
1207 int ret = -1;
1208 int i = 0;
1210 if ( name_type != 0x20 && name_type != 0x0) {
1211 DEBUG(5, ("resolve_hosts: not appropriate "
1212 "for name type <0x%x>\n",
1213 name_type));
1214 return NT_STATUS_INVALID_PARAMETER;
1217 *return_iplist = NULL;
1218 *return_count = 0;
1220 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
1221 name, name_type));
1223 ZERO_STRUCT(hints);
1224 /* By default make sure it supports TCP. */
1225 hints.ai_socktype = SOCK_STREAM;
1226 hints.ai_flags = AI_ADDRCONFIG;
1228 #if !defined(HAVE_IPV6)
1229 /* Unless we have IPv6, we really only want IPv4 addresses back. */
1230 hints.ai_family = AF_INET;
1231 #endif
1233 ret = getaddrinfo(name,
1234 NULL,
1235 &hints,
1236 &ailist);
1237 if (ret) {
1238 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
1239 name,
1240 gai_strerror(ret) ));
1243 for (res = ailist; res; res = res->ai_next) {
1244 struct sockaddr_storage ss;
1246 if (!res->ai_addr || res->ai_addrlen == 0) {
1247 continue;
1250 ZERO_STRUCT(ss);
1251 memcpy(&ss, res->ai_addr, res->ai_addrlen);
1253 *return_count += 1;
1255 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
1256 struct ip_service,
1257 *return_count);
1258 if (!*return_iplist) {
1259 DEBUG(3,("resolve_hosts: malloc fail !\n"));
1260 freeaddrinfo(ailist);
1261 return NT_STATUS_NO_MEMORY;
1263 (*return_iplist)[i].ss = ss;
1264 (*return_iplist)[i].port = PORT_NONE;
1265 i++;
1267 if (ailist) {
1268 freeaddrinfo(ailist);
1270 if (*return_count) {
1271 return NT_STATUS_OK;
1273 return NT_STATUS_UNSUCCESSFUL;
1276 /********************************************************
1277 Resolve via "ADS" method.
1278 *********************************************************/
1280 static NTSTATUS resolve_ads(const char *name,
1281 int name_type,
1282 const char *sitename,
1283 struct ip_service **return_iplist,
1284 int *return_count)
1286 int i, j;
1287 NTSTATUS status;
1288 TALLOC_CTX *ctx;
1289 struct dns_rr_srv *dcs = NULL;
1290 int numdcs = 0;
1291 int numaddrs = 0;
1293 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
1294 (name_type != 0x1b)) {
1295 return NT_STATUS_INVALID_PARAMETER;
1298 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1299 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1300 return NT_STATUS_NO_MEMORY;
1303 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
1305 switch (name_type) {
1306 case 0x1b:
1307 DEBUG(5,("resolve_ads: Attempting to resolve "
1308 "PDC for %s using DNS\n", name));
1309 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
1310 break;
1312 case 0x1c:
1313 DEBUG(5,("resolve_ads: Attempting to resolve "
1314 "DCs for %s using DNS\n", name));
1315 status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1316 &numdcs);
1317 break;
1318 case KDC_NAME_TYPE:
1319 DEBUG(5,("resolve_ads: Attempting to resolve "
1320 "KDCs for %s using DNS\n", name));
1321 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1322 &numdcs);
1323 break;
1324 default:
1325 status = NT_STATUS_INVALID_PARAMETER;
1326 break;
1329 if ( !NT_STATUS_IS_OK( status ) ) {
1330 talloc_destroy(ctx);
1331 return status;
1334 for (i=0;i<numdcs;i++) {
1335 numaddrs += MAX(dcs[i].num_ips,1);
1338 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
1339 NULL ) {
1340 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
1341 numaddrs ));
1342 talloc_destroy(ctx);
1343 return NT_STATUS_NO_MEMORY;
1346 /* now unroll the list of IP addresses */
1348 *return_count = 0;
1349 i = 0;
1350 j = 0;
1351 while ( i < numdcs && (*return_count<numaddrs) ) {
1352 struct ip_service *r = &(*return_iplist)[*return_count];
1354 r->port = dcs[i].port;
1356 /* If we don't have an IP list for a name, lookup it up */
1358 if (!dcs[i].ss_s) {
1359 interpret_string_addr(&r->ss, dcs[i].hostname, 0);
1360 i++;
1361 j = 0;
1362 } else {
1363 /* use the IP addresses from the SRV sresponse */
1365 if ( j >= dcs[i].num_ips ) {
1366 i++;
1367 j = 0;
1368 continue;
1371 r->ss = dcs[i].ss_s[j];
1372 j++;
1375 /* make sure it is a valid IP. I considered checking the
1376 * negative connection cache, but this is the wrong place
1377 * for it. Maybe only as a hack. After think about it, if
1378 * all of the IP addresses returned from DNS are dead, what
1379 * hope does a netbios name lookup have ? The standard reason
1380 * for falling back to netbios lookups is that our DNS server
1381 * doesn't know anything about the DC's -- jerry */
1383 if (!is_zero_addr((struct sockaddr *)&r->ss)) {
1384 (*return_count)++;
1388 talloc_destroy(ctx);
1389 return NT_STATUS_OK;
1392 /*******************************************************************
1393 Internal interface to resolve a name into an IP address.
1394 Use this function if the string is either an IP address, DNS
1395 or host name or NetBIOS name. This uses the name switch in the
1396 smb.conf to determine the order of name resolution.
1398 Added support for ip addr/port to support ADS ldap servers.
1399 the only place we currently care about the port is in the
1400 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1401 **********************************************************************/
1403 NTSTATUS internal_resolve_name(const char *name,
1404 int name_type,
1405 const char *sitename,
1406 struct ip_service **return_iplist,
1407 int *return_count,
1408 const char *resolve_order)
1410 char *tok;
1411 const char *ptr;
1412 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1413 int i;
1414 TALLOC_CTX *frame = NULL;
1416 *return_iplist = NULL;
1417 *return_count = 0;
1419 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1420 name, name_type, sitename ? sitename : "(null)"));
1422 if (is_ipaddress(name)) {
1423 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
1424 NULL) {
1425 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1426 return NT_STATUS_NO_MEMORY;
1429 /* ignore the port here */
1430 (*return_iplist)->port = PORT_NONE;
1432 /* if it's in the form of an IP address then get the lib to interpret it */
1433 if (!interpret_string_addr(&(*return_iplist)->ss,
1434 name, AI_NUMERICHOST)) {
1435 DEBUG(1,("internal_resolve_name: interpret_string_addr "
1436 "failed on %s\n",
1437 name));
1438 SAFE_FREE(*return_iplist);
1439 return NT_STATUS_INVALID_PARAMETER;
1441 *return_count = 1;
1442 return NT_STATUS_OK;
1445 /* Check name cache */
1447 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1448 /* This could be a negative response */
1449 if (*return_count > 0) {
1450 return NT_STATUS_OK;
1451 } else {
1452 return NT_STATUS_UNSUCCESSFUL;
1456 /* set the name resolution order */
1458 if (strcmp( resolve_order, "NULL") == 0) {
1459 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1460 return NT_STATUS_INVALID_PARAMETER;
1463 if (!resolve_order[0]) {
1464 ptr = "host";
1465 } else {
1466 ptr = resolve_order;
1469 /* iterate through the name resolution backends */
1471 frame = talloc_stackframe();
1472 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
1473 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1474 status = resolve_hosts(name, name_type, return_iplist,
1475 return_count);
1476 if (NT_STATUS_IS_OK(status)) {
1477 goto done;
1479 } else if(strequal( tok, "kdc")) {
1480 /* deal with KDC_NAME_TYPE names here.
1481 * This will result in a SRV record lookup */
1482 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1483 return_iplist, return_count);
1484 if (NT_STATUS_IS_OK(status)) {
1485 /* Ensure we don't namecache
1486 * this with the KDC port. */
1487 name_type = KDC_NAME_TYPE;
1488 goto done;
1490 } else if(strequal( tok, "ads")) {
1491 /* deal with 0x1c and 0x1b names here.
1492 * This will result in a SRV record lookup */
1493 status = resolve_ads(name, name_type, sitename,
1494 return_iplist, return_count);
1495 if (NT_STATUS_IS_OK(status)) {
1496 goto done;
1498 } else if(strequal( tok, "lmhosts")) {
1499 status = resolve_lmhosts(name, name_type,
1500 return_iplist, return_count);
1501 if (NT_STATUS_IS_OK(status)) {
1502 goto done;
1504 } else if(strequal( tok, "wins")) {
1505 /* don't resolve 1D via WINS */
1506 if (name_type != 0x1D) {
1507 status = resolve_wins(name, name_type,
1508 return_iplist,
1509 return_count);
1510 if (NT_STATUS_IS_OK(status)) {
1511 goto done;
1514 } else if(strequal( tok, "bcast")) {
1515 status = name_resolve_bcast(name, name_type,
1516 return_iplist,
1517 return_count);
1518 if (NT_STATUS_IS_OK(status)) {
1519 goto done;
1521 } else {
1522 DEBUG(0,("resolve_name: unknown name switch type %s\n",
1523 tok));
1527 /* All of the resolve_* functions above have returned false. */
1529 TALLOC_FREE(frame);
1530 SAFE_FREE(*return_iplist);
1531 *return_count = 0;
1533 return NT_STATUS_UNSUCCESSFUL;
1535 done:
1537 /* Remove duplicate entries. Some queries, notably #1c (domain
1538 controllers) return the PDC in iplist[0] and then all domain
1539 controllers including the PDC in iplist[1..n]. Iterating over
1540 the iplist when the PDC is down will cause two sets of timeouts. */
1542 if ( *return_count ) {
1543 *return_count = remove_duplicate_addrs2(*return_iplist,
1544 *return_count );
1547 /* Save in name cache */
1548 if ( DEBUGLEVEL >= 100 ) {
1549 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
1550 char addr[INET6_ADDRSTRLEN];
1551 print_sockaddr(addr, sizeof(addr),
1552 &(*return_iplist)[i].ss);
1553 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
1554 name,
1555 name_type,
1556 addr,
1557 (*return_iplist)[i].port));
1561 namecache_store(name, name_type, *return_count, *return_iplist);
1563 /* Display some debugging info */
1565 if ( DEBUGLEVEL >= 10 ) {
1566 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1567 *return_count));
1569 for (i = 0; i < *return_count; i++) {
1570 char addr[INET6_ADDRSTRLEN];
1571 print_sockaddr(addr, sizeof(addr),
1572 &(*return_iplist)[i].ss);
1573 DEBUGADD(10, ("%s:%d ",
1574 addr,
1575 (*return_iplist)[i].port));
1577 DEBUG(10, ("\n"));
1580 TALLOC_FREE(frame);
1581 return status;
1584 /********************************************************
1585 Internal interface to resolve a name into one IP address.
1586 Use this function if the string is either an IP address, DNS
1587 or host name or NetBIOS name. This uses the name switch in the
1588 smb.conf to determine the order of name resolution.
1589 *********************************************************/
1591 bool resolve_name(const char *name,
1592 struct sockaddr_storage *return_ss,
1593 int name_type,
1594 bool prefer_ipv4)
1596 struct ip_service *ss_list = NULL;
1597 char *sitename = NULL;
1598 int count = 0;
1600 if (is_ipaddress(name)) {
1601 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
1604 sitename = sitename_fetch(lp_realm()); /* wild guess */
1606 if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1607 &ss_list, &count,
1608 lp_name_resolve_order()))) {
1609 int i;
1611 if (prefer_ipv4) {
1612 for (i=0; i<count; i++) {
1613 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1614 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) &&
1615 (ss_list[i].ss.ss_family == AF_INET)) {
1616 *return_ss = ss_list[i].ss;
1617 SAFE_FREE(ss_list);
1618 SAFE_FREE(sitename);
1619 return True;
1624 /* only return valid addresses for TCP connections */
1625 for (i=0; i<count; i++) {
1626 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1627 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1628 *return_ss = ss_list[i].ss;
1629 SAFE_FREE(ss_list);
1630 SAFE_FREE(sitename);
1631 return True;
1636 SAFE_FREE(ss_list);
1637 SAFE_FREE(sitename);
1638 return False;
1641 /********************************************************
1642 Internal interface to resolve a name into a list of IP addresses.
1643 Use this function if the string is either an IP address, DNS
1644 or host name or NetBIOS name. This uses the name switch in the
1645 smb.conf to determine the order of name resolution.
1646 *********************************************************/
1648 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
1649 const char *name,
1650 int name_type,
1651 struct sockaddr_storage **return_ss_arr,
1652 unsigned int *p_num_entries)
1654 struct ip_service *ss_list = NULL;
1655 char *sitename = NULL;
1656 int count = 0;
1657 int i;
1658 unsigned int num_entries;
1659 NTSTATUS status;
1661 *p_num_entries = 0;
1662 *return_ss_arr = NULL;
1664 if (is_ipaddress(name)) {
1665 *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);
1666 if (!*return_ss_arr) {
1667 return NT_STATUS_NO_MEMORY;
1669 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
1670 TALLOC_FREE(*return_ss_arr);
1671 return NT_STATUS_BAD_NETWORK_NAME;
1673 *p_num_entries = 1;
1674 return NT_STATUS_OK;
1677 sitename = sitename_fetch(lp_realm()); /* wild guess */
1679 status = internal_resolve_name(name, name_type, sitename,
1680 &ss_list, &count,
1681 lp_name_resolve_order());
1682 SAFE_FREE(sitename);
1684 if (!NT_STATUS_IS_OK(status)) {
1685 return status;
1688 /* only return valid addresses for TCP connections */
1689 for (i=0, num_entries = 0; i<count; i++) {
1690 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1691 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1692 num_entries++;
1695 if (num_entries == 0) {
1696 SAFE_FREE(ss_list);
1697 return NT_STATUS_BAD_NETWORK_NAME;
1700 *return_ss_arr = TALLOC_ARRAY(ctx,
1701 struct sockaddr_storage,
1702 num_entries);
1703 if (!(*return_ss_arr)) {
1704 SAFE_FREE(ss_list);
1705 return NT_STATUS_NO_MEMORY;
1708 for (i=0, num_entries = 0; i<count; i++) {
1709 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1710 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1711 (*return_ss_arr)[num_entries++] = ss_list[i].ss;
1715 status = NT_STATUS_OK;
1716 *p_num_entries = num_entries;
1718 SAFE_FREE(ss_list);
1719 return NT_STATUS_OK;
1722 /********************************************************
1723 Find the IP address of the master browser or DMB for a workgroup.
1724 *********************************************************/
1726 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
1728 struct ip_service *ip_list = NULL;
1729 int count = 0;
1730 NTSTATUS status;
1732 if (lp_disable_netbios()) {
1733 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1734 return false;
1737 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1738 lp_name_resolve_order());
1739 if (NT_STATUS_IS_OK(status)) {
1740 *master_ss = ip_list[0].ss;
1741 SAFE_FREE(ip_list);
1742 return true;
1745 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1746 lp_name_resolve_order());
1747 if (NT_STATUS_IS_OK(status)) {
1748 *master_ss = ip_list[0].ss;
1749 SAFE_FREE(ip_list);
1750 return true;
1753 SAFE_FREE(ip_list);
1754 return false;
1757 /********************************************************
1758 Get the IP address list of the primary domain controller
1759 for a domain.
1760 *********************************************************/
1762 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
1764 struct ip_service *ip_list = NULL;
1765 int count = 0;
1766 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1768 /* Look up #1B name */
1770 if (lp_security() == SEC_ADS) {
1771 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1772 &count, "ads");
1775 if (!NT_STATUS_IS_OK(status) || count == 0) {
1776 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1777 &count,
1778 lp_name_resolve_order());
1779 if (!NT_STATUS_IS_OK(status)) {
1780 return false;
1784 /* if we get more than 1 IP back we have to assume it is a
1785 multi-homed PDC and not a mess up */
1787 if ( count > 1 ) {
1788 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1789 sort_service_list(ip_list, count);
1792 *pss = ip_list[0].ss;
1793 SAFE_FREE(ip_list);
1794 return true;
1797 /* Private enum type for lookups. */
1799 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1801 /********************************************************
1802 Get the IP address list of the domain controllers for
1803 a domain.
1804 *********************************************************/
1806 static NTSTATUS get_dc_list(const char *domain,
1807 const char *sitename,
1808 struct ip_service **ip_list,
1809 int *count,
1810 enum dc_lookup_type lookup_type,
1811 bool *ordered)
1813 char *resolve_order = NULL;
1814 char *saf_servername = NULL;
1815 char *pserver = NULL;
1816 const char *p;
1817 char *port_str = NULL;
1818 int port;
1819 char *name;
1820 int num_addresses = 0;
1821 int local_count, i, j;
1822 struct ip_service *return_iplist = NULL;
1823 struct ip_service *auto_ip_list = NULL;
1824 bool done_auto_lookup = false;
1825 int auto_count = 0;
1826 NTSTATUS status;
1827 TALLOC_CTX *ctx = talloc_init("get_dc_list");
1829 *ip_list = NULL;
1830 *count = 0;
1832 if (!ctx) {
1833 return NT_STATUS_NO_MEMORY;
1836 *ordered = False;
1838 /* if we are restricted to solely using DNS for looking
1839 up a domain controller, make sure that host lookups
1840 are enabled for the 'name resolve order'. If host lookups
1841 are disabled and ads_only is True, then set the string to
1842 NULL. */
1844 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
1845 if (!resolve_order) {
1846 status = NT_STATUS_NO_MEMORY;
1847 goto out;
1849 strlower_m(resolve_order);
1850 if (lookup_type == DC_ADS_ONLY) {
1851 if (strstr( resolve_order, "host")) {
1852 resolve_order = talloc_strdup(ctx, "ads");
1854 /* DNS SRV lookups used by the ads resolver
1855 are already sorted by priority and weight */
1856 *ordered = true;
1857 } else {
1858 resolve_order = talloc_strdup(ctx, "NULL");
1860 } else if (lookup_type == DC_KDC_ONLY) {
1861 /* DNS SRV lookups used by the ads/kdc resolver
1862 are already sorted by priority and weight */
1863 *ordered = true;
1864 resolve_order = talloc_strdup(ctx, "kdc");
1866 if (!resolve_order) {
1867 status = NT_STATUS_NO_MEMORY;
1868 goto out;
1871 /* fetch the server we have affinity for. Add the
1872 'password server' list to a search for our domain controllers */
1874 saf_servername = saf_fetch( domain);
1876 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
1877 pserver = talloc_asprintf(NULL, "%s, %s",
1878 saf_servername ? saf_servername : "",
1879 lp_passwordserver());
1880 } else {
1881 pserver = talloc_asprintf(NULL, "%s, *",
1882 saf_servername ? saf_servername : "");
1885 SAFE_FREE(saf_servername);
1886 if (!pserver) {
1887 status = NT_STATUS_NO_MEMORY;
1888 goto out;
1891 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1893 if (!*pserver ) {
1894 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1895 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1896 count, resolve_order);
1897 goto out;
1900 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1903 * if '*' appears in the "password server" list then add
1904 * an auto lookup to the list of manually configured
1905 * DC's. If any DC is listed by name, then the list should be
1906 * considered to be ordered
1909 p = pserver;
1910 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1911 if (!done_auto_lookup && strequal(name, "*")) {
1912 status = internal_resolve_name(domain, 0x1C, sitename,
1913 &auto_ip_list,
1914 &auto_count,
1915 resolve_order);
1916 if (NT_STATUS_IS_OK(status)) {
1917 num_addresses += auto_count;
1919 done_auto_lookup = true;
1920 DEBUG(8,("Adding %d DC's from auto lookup\n",
1921 auto_count));
1922 } else {
1923 num_addresses++;
1927 /* if we have no addresses and haven't done the auto lookup, then
1928 just return the list of DC's. Or maybe we just failed. */
1930 if ((num_addresses == 0)) {
1931 if (done_auto_lookup) {
1932 DEBUG(4,("get_dc_list: no servers found\n"));
1933 status = NT_STATUS_NO_LOGON_SERVERS;
1934 goto out;
1936 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1937 count, resolve_order);
1938 goto out;
1941 if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
1942 num_addresses)) == NULL) {
1943 DEBUG(3,("get_dc_list: malloc fail !\n"));
1944 status = NT_STATUS_NO_MEMORY;
1945 goto out;
1948 p = pserver;
1949 local_count = 0;
1951 /* fill in the return list now with real IP's */
1953 while ((local_count<num_addresses) &&
1954 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1955 struct sockaddr_storage name_ss;
1957 /* copy any addersses from the auto lookup */
1959 if (strequal(name, "*")) {
1960 for (j=0; j<auto_count; j++) {
1961 char addr[INET6_ADDRSTRLEN];
1962 print_sockaddr(addr,
1963 sizeof(addr),
1964 &auto_ip_list[j].ss);
1965 /* Check for and don't copy any
1966 * known bad DC IP's. */
1967 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
1968 domain,
1969 addr))) {
1970 DEBUG(5,("get_dc_list: "
1971 "negative entry %s removed "
1972 "from DC list\n",
1973 addr));
1974 continue;
1976 return_iplist[local_count].ss =
1977 auto_ip_list[j].ss;
1978 return_iplist[local_count].port =
1979 auto_ip_list[j].port;
1980 local_count++;
1982 continue;
1985 /* added support for address:port syntax for ads
1986 * (not that I think anyone will ever run the LDAP
1987 * server in an AD domain on something other than
1988 * port 389 */
1990 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1991 if ((port_str=strchr(name, ':')) != NULL) {
1992 *port_str = '\0';
1993 port_str++;
1994 port = atoi(port_str);
1997 /* explicit lookup; resolve_name() will
1998 * handle names & IP addresses */
1999 if (resolve_name( name, &name_ss, 0x20, true )) {
2000 char addr[INET6_ADDRSTRLEN];
2001 print_sockaddr(addr,
2002 sizeof(addr),
2003 &name_ss);
2005 /* Check for and don't copy any known bad DC IP's. */
2006 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
2007 addr)) ) {
2008 DEBUG(5,("get_dc_list: negative entry %s "
2009 "removed from DC list\n",
2010 name ));
2011 continue;
2014 return_iplist[local_count].ss = name_ss;
2015 return_iplist[local_count].port = port;
2016 local_count++;
2017 *ordered = true;
2021 /* need to remove duplicates in the list if we have any
2022 explicit password servers */
2024 if (local_count) {
2025 local_count = remove_duplicate_addrs2(return_iplist,
2026 local_count );
2029 /* For DC's we always prioritize IPv4 due to W2K3 not
2030 * supporting LDAP, KRB5 or CLDAP over IPv6. */
2032 if (local_count && return_iplist) {
2033 prioritize_ipv4_list(return_iplist, local_count);
2036 if ( DEBUGLEVEL >= 4 ) {
2037 DEBUG(4,("get_dc_list: returning %d ip addresses "
2038 "in an %sordered list\n",
2039 local_count,
2040 *ordered ? "":"un"));
2041 DEBUG(4,("get_dc_list: "));
2042 for ( i=0; i<local_count; i++ ) {
2043 char addr[INET6_ADDRSTRLEN];
2044 print_sockaddr(addr,
2045 sizeof(addr),
2046 &return_iplist[i].ss);
2047 DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
2049 DEBUGADD(4,("\n"));
2052 *ip_list = return_iplist;
2053 *count = local_count;
2055 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
2057 out:
2059 if (!NT_STATUS_IS_OK(status)) {
2060 SAFE_FREE(return_iplist);
2061 *ip_list = NULL;
2062 *count = 0;
2065 SAFE_FREE(auto_ip_list);
2066 TALLOC_FREE(ctx);
2067 return status;
2070 /*********************************************************************
2071 Small wrapper function to get the DC list and sort it if neccessary.
2072 *********************************************************************/
2074 NTSTATUS get_sorted_dc_list( const char *domain,
2075 const char *sitename,
2076 struct ip_service **ip_list,
2077 int *count,
2078 bool ads_only )
2080 bool ordered = false;
2081 NTSTATUS status;
2082 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
2084 *ip_list = NULL;
2085 *count = 0;
2087 DEBUG(8,("get_sorted_dc_list: attempting lookup "
2088 "for name %s (sitename %s) using [%s]\n",
2089 domain,
2090 sitename ? sitename : "NULL",
2091 (ads_only ? "ads" : lp_name_resolve_order())));
2093 if (ads_only) {
2094 lookup_type = DC_ADS_ONLY;
2097 status = get_dc_list(domain, sitename, ip_list,
2098 count, lookup_type, &ordered);
2099 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
2100 && sitename) {
2101 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
2102 " in site %s, fallback to all servers\n",
2103 domain, sitename));
2104 status = get_dc_list(domain, NULL, ip_list,
2105 count, lookup_type, &ordered);
2108 if (!NT_STATUS_IS_OK(status)) {
2109 SAFE_FREE(*ip_list);
2110 *count = 0;
2111 return status;
2114 /* only sort if we don't already have an ordered list */
2115 if (!ordered) {
2116 sort_service_list(*ip_list, *count);
2119 return NT_STATUS_OK;
2122 /*********************************************************************
2123 Get the KDC list - re-use all the logic in get_dc_list.
2124 *********************************************************************/
2126 NTSTATUS get_kdc_list( const char *realm,
2127 const char *sitename,
2128 struct ip_service **ip_list,
2129 int *count)
2131 bool ordered;
2132 NTSTATUS status;
2134 *count = 0;
2135 *ip_list = NULL;
2137 status = get_dc_list(realm, sitename, ip_list,
2138 count, DC_KDC_ONLY, &ordered);
2140 if (!NT_STATUS_IS_OK(status)) {
2141 SAFE_FREE(*ip_list);
2142 *count = 0;
2143 return status;
2146 /* only sort if we don't already have an ordered list */
2147 if ( !ordered ) {
2148 sort_service_list(*ip_list, *count);
2151 return NT_STATUS_OK;