Fix the loop unrolling inside resolve_ads().
[Samba.git] / source3 / libsmb / namequery.c
blobaf76f3f85db08c63cff2e3e13400ae0839ad9339
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 if (is_zero_addr((struct sockaddr *)&ss)) {
1254 continue;
1257 *return_count += 1;
1259 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
1260 struct ip_service,
1261 *return_count);
1262 if (!*return_iplist) {
1263 DEBUG(3,("resolve_hosts: malloc fail !\n"));
1264 freeaddrinfo(ailist);
1265 return NT_STATUS_NO_MEMORY;
1267 (*return_iplist)[i].ss = ss;
1268 (*return_iplist)[i].port = PORT_NONE;
1269 i++;
1271 if (ailist) {
1272 freeaddrinfo(ailist);
1274 if (*return_count) {
1275 return NT_STATUS_OK;
1277 return NT_STATUS_UNSUCCESSFUL;
1280 /********************************************************
1281 Resolve via "ADS" method.
1282 *********************************************************/
1284 static NTSTATUS resolve_ads(const char *name,
1285 int name_type,
1286 const char *sitename,
1287 struct ip_service **return_iplist,
1288 int *return_count)
1290 int i;
1291 NTSTATUS status;
1292 TALLOC_CTX *ctx;
1293 struct dns_rr_srv *dcs = NULL;
1294 int numdcs = 0;
1295 int numaddrs = 0;
1297 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
1298 (name_type != 0x1b)) {
1299 return NT_STATUS_INVALID_PARAMETER;
1302 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1303 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1304 return NT_STATUS_NO_MEMORY;
1307 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
1309 switch (name_type) {
1310 case 0x1b:
1311 DEBUG(5,("resolve_ads: Attempting to resolve "
1312 "PDC for %s using DNS\n", name));
1313 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
1314 break;
1316 case 0x1c:
1317 DEBUG(5,("resolve_ads: Attempting to resolve "
1318 "DCs for %s using DNS\n", name));
1319 status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1320 &numdcs);
1321 break;
1322 case KDC_NAME_TYPE:
1323 DEBUG(5,("resolve_ads: Attempting to resolve "
1324 "KDCs for %s using DNS\n", name));
1325 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1326 &numdcs);
1327 break;
1328 default:
1329 status = NT_STATUS_INVALID_PARAMETER;
1330 break;
1333 if ( !NT_STATUS_IS_OK( status ) ) {
1334 talloc_destroy(ctx);
1335 return status;
1338 for (i=0;i<numdcs;i++) {
1339 if (!dcs[i].ss_s) {
1340 numaddrs += 1;
1341 } else {
1342 numaddrs += dcs[i].num_ips;
1346 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
1347 NULL ) {
1348 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
1349 numaddrs ));
1350 talloc_destroy(ctx);
1351 return NT_STATUS_NO_MEMORY;
1354 /* now unroll the list of IP addresses */
1356 *return_count = 0;
1358 for (i = 0; i < numdcs; i++) {
1359 /* If we don't have an IP list for a name, look it up */
1360 if (!dcs[i].ss_s) {
1361 /* We need to get all IP addresses here. */
1362 struct addrinfo *res = NULL;
1363 struct addrinfo *p;
1364 int extra_addrs = 0;
1366 if (!interpret_string_addr_internal(&res,
1367 dcs[i].hostname,
1368 0)) {
1369 continue;
1371 /* Add in every IP from the lookup. How
1372 many is that ? */
1373 for (p = res; p; p = p->ai_next) {
1374 if (is_zero_addr((struct sockaddr *)p->ai_addr)) {
1375 continue;
1377 extra_addrs++;
1379 if (extra_addrs > 1) {
1380 /* We need to expand the return_iplist array
1381 as we only budgeted for one address. */
1382 numaddrs += (extra_addrs-1);
1383 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
1384 struct ip_service,
1385 numaddrs);
1386 if (*return_iplist == NULL) {
1387 if (res) {
1388 freeaddrinfo(res);
1390 talloc_destroy(ctx);
1391 return NT_STATUS_NO_MEMORY;
1394 for (p = res; p; p = p->ai_next) {
1395 (*return_iplist)[*return_count].port = dcs[i].port;
1396 memcpy(&(*return_iplist)[*return_count].ss,
1397 p->ai_addr,
1398 p->ai_addrlen);
1399 if (is_zero_addr((struct sockaddr *)&(*return_iplist)[*return_count].ss)) {
1400 continue;
1402 (*return_count)++;
1403 /* Should never happen, but still... */
1404 if (*return_count>=numaddrs) {
1405 break;
1408 if (res) {
1409 freeaddrinfo(res);
1411 } else {
1412 /* use all the IP addresses from the SRV sresponse */
1413 int j;
1414 for (j = 0; j < dcs[i].num_ips; j++) {
1415 (*return_iplist)[*return_count].port = dcs[i].port;
1416 (*return_iplist)[*return_count].ss = dcs[i].ss_s[j];
1417 if (is_zero_addr((struct sockaddr *)&(*return_iplist)[*return_count].ss)) {
1418 continue;
1420 (*return_count)++;
1421 /* Should never happen, but still... */
1422 if (*return_count>=numaddrs) {
1423 break;
1429 talloc_destroy(ctx);
1430 return NT_STATUS_OK;
1433 /*******************************************************************
1434 Internal interface to resolve a name into an IP address.
1435 Use this function if the string is either an IP address, DNS
1436 or host name or NetBIOS name. This uses the name switch in the
1437 smb.conf to determine the order of name resolution.
1439 Added support for ip addr/port to support ADS ldap servers.
1440 the only place we currently care about the port is in the
1441 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1442 **********************************************************************/
1444 NTSTATUS internal_resolve_name(const char *name,
1445 int name_type,
1446 const char *sitename,
1447 struct ip_service **return_iplist,
1448 int *return_count,
1449 const char *resolve_order)
1451 char *tok;
1452 const char *ptr;
1453 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1454 int i;
1455 TALLOC_CTX *frame = NULL;
1457 *return_iplist = NULL;
1458 *return_count = 0;
1460 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1461 name, name_type, sitename ? sitename : "(null)"));
1463 if (is_ipaddress(name)) {
1464 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
1465 NULL) {
1466 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1467 return NT_STATUS_NO_MEMORY;
1470 /* ignore the port here */
1471 (*return_iplist)->port = PORT_NONE;
1473 /* if it's in the form of an IP address then get the lib to interpret it */
1474 if (!interpret_string_addr(&(*return_iplist)->ss,
1475 name, AI_NUMERICHOST)) {
1476 DEBUG(1,("internal_resolve_name: interpret_string_addr "
1477 "failed on %s\n",
1478 name));
1479 SAFE_FREE(*return_iplist);
1480 return NT_STATUS_INVALID_PARAMETER;
1482 if (is_zero_addr((struct sockaddr *)&(*return_iplist)->ss)) {
1483 SAFE_FREE(*return_iplist);
1484 return NT_STATUS_UNSUCCESSFUL;
1486 *return_count = 1;
1487 return NT_STATUS_OK;
1490 /* Check name cache */
1492 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1493 *return_count = remove_duplicate_addrs2(*return_iplist,
1494 *return_count );
1495 /* This could be a negative response */
1496 if (*return_count > 0) {
1497 return NT_STATUS_OK;
1498 } else {
1499 return NT_STATUS_UNSUCCESSFUL;
1503 /* set the name resolution order */
1505 if (strcmp( resolve_order, "NULL") == 0) {
1506 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1507 return NT_STATUS_INVALID_PARAMETER;
1510 if (!resolve_order[0]) {
1511 ptr = "host";
1512 } else {
1513 ptr = resolve_order;
1516 /* iterate through the name resolution backends */
1518 frame = talloc_stackframe();
1519 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
1520 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1521 status = resolve_hosts(name, name_type, return_iplist,
1522 return_count);
1523 if (NT_STATUS_IS_OK(status)) {
1524 goto done;
1526 } else if(strequal( tok, "kdc")) {
1527 /* deal with KDC_NAME_TYPE names here.
1528 * This will result in a SRV record lookup */
1529 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1530 return_iplist, return_count);
1531 if (NT_STATUS_IS_OK(status)) {
1532 /* Ensure we don't namecache
1533 * this with the KDC port. */
1534 name_type = KDC_NAME_TYPE;
1535 goto done;
1537 } else if(strequal( tok, "ads")) {
1538 /* deal with 0x1c and 0x1b names here.
1539 * This will result in a SRV record lookup */
1540 status = resolve_ads(name, name_type, sitename,
1541 return_iplist, return_count);
1542 if (NT_STATUS_IS_OK(status)) {
1543 goto done;
1545 } else if(strequal( tok, "lmhosts")) {
1546 status = resolve_lmhosts(name, name_type,
1547 return_iplist, return_count);
1548 if (NT_STATUS_IS_OK(status)) {
1549 goto done;
1551 } else if(strequal( tok, "wins")) {
1552 /* don't resolve 1D via WINS */
1553 if (name_type != 0x1D) {
1554 status = resolve_wins(name, name_type,
1555 return_iplist,
1556 return_count);
1557 if (NT_STATUS_IS_OK(status)) {
1558 goto done;
1561 } else if(strequal( tok, "bcast")) {
1562 status = name_resolve_bcast(name, name_type,
1563 return_iplist,
1564 return_count);
1565 if (NT_STATUS_IS_OK(status)) {
1566 goto done;
1568 } else {
1569 DEBUG(0,("resolve_name: unknown name switch type %s\n",
1570 tok));
1574 /* All of the resolve_* functions above have returned false. */
1576 TALLOC_FREE(frame);
1577 SAFE_FREE(*return_iplist);
1578 *return_count = 0;
1580 return NT_STATUS_UNSUCCESSFUL;
1582 done:
1584 /* Remove duplicate entries. Some queries, notably #1c (domain
1585 controllers) return the PDC in iplist[0] and then all domain
1586 controllers including the PDC in iplist[1..n]. Iterating over
1587 the iplist when the PDC is down will cause two sets of timeouts. */
1589 *return_count = remove_duplicate_addrs2(*return_iplist, *return_count );
1591 /* Save in name cache */
1592 if ( DEBUGLEVEL >= 100 ) {
1593 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
1594 char addr[INET6_ADDRSTRLEN];
1595 print_sockaddr(addr, sizeof(addr),
1596 &(*return_iplist)[i].ss);
1597 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
1598 name,
1599 name_type,
1600 addr,
1601 (*return_iplist)[i].port));
1605 if (*return_count) {
1606 namecache_store(name, name_type, *return_count, *return_iplist);
1609 /* Display some debugging info */
1611 if ( DEBUGLEVEL >= 10 ) {
1612 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1613 *return_count));
1615 for (i = 0; i < *return_count; i++) {
1616 char addr[INET6_ADDRSTRLEN];
1617 print_sockaddr(addr, sizeof(addr),
1618 &(*return_iplist)[i].ss);
1619 DEBUGADD(10, ("%s:%d ",
1620 addr,
1621 (*return_iplist)[i].port));
1623 DEBUG(10, ("\n"));
1626 TALLOC_FREE(frame);
1627 return status;
1630 /********************************************************
1631 Internal interface to resolve a name into one IP address.
1632 Use this function if the string is either an IP address, DNS
1633 or host name or NetBIOS name. This uses the name switch in the
1634 smb.conf to determine the order of name resolution.
1635 *********************************************************/
1637 bool resolve_name(const char *name,
1638 struct sockaddr_storage *return_ss,
1639 int name_type,
1640 bool prefer_ipv4)
1642 struct ip_service *ss_list = NULL;
1643 char *sitename = NULL;
1644 int count = 0;
1646 if (is_ipaddress(name)) {
1647 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
1650 sitename = sitename_fetch(lp_realm()); /* wild guess */
1652 if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1653 &ss_list, &count,
1654 lp_name_resolve_order()))) {
1655 int i;
1657 if (prefer_ipv4) {
1658 for (i=0; i<count; i++) {
1659 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1660 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) &&
1661 (ss_list[i].ss.ss_family == AF_INET)) {
1662 *return_ss = ss_list[i].ss;
1663 SAFE_FREE(ss_list);
1664 SAFE_FREE(sitename);
1665 return True;
1670 /* only return valid addresses for TCP connections */
1671 for (i=0; i<count; i++) {
1672 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1673 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1674 *return_ss = ss_list[i].ss;
1675 SAFE_FREE(ss_list);
1676 SAFE_FREE(sitename);
1677 return True;
1682 SAFE_FREE(ss_list);
1683 SAFE_FREE(sitename);
1684 return False;
1687 /********************************************************
1688 Internal interface to resolve a name into a list of IP addresses.
1689 Use this function if the string is either an IP address, DNS
1690 or host name or NetBIOS name. This uses the name switch in the
1691 smb.conf to determine the order of name resolution.
1692 *********************************************************/
1694 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
1695 const char *name,
1696 int name_type,
1697 struct sockaddr_storage **return_ss_arr,
1698 unsigned int *p_num_entries)
1700 struct ip_service *ss_list = NULL;
1701 char *sitename = NULL;
1702 int count = 0;
1703 int i;
1704 unsigned int num_entries;
1705 NTSTATUS status;
1707 *p_num_entries = 0;
1708 *return_ss_arr = NULL;
1710 if (is_ipaddress(name)) {
1711 *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);
1712 if (!*return_ss_arr) {
1713 return NT_STATUS_NO_MEMORY;
1715 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
1716 TALLOC_FREE(*return_ss_arr);
1717 return NT_STATUS_BAD_NETWORK_NAME;
1719 *p_num_entries = 1;
1720 return NT_STATUS_OK;
1723 sitename = sitename_fetch(lp_realm()); /* wild guess */
1725 status = internal_resolve_name(name, name_type, sitename,
1726 &ss_list, &count,
1727 lp_name_resolve_order());
1728 SAFE_FREE(sitename);
1730 if (!NT_STATUS_IS_OK(status)) {
1731 return status;
1734 /* only return valid addresses for TCP connections */
1735 for (i=0, num_entries = 0; i<count; i++) {
1736 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1737 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1738 num_entries++;
1741 if (num_entries == 0) {
1742 SAFE_FREE(ss_list);
1743 return NT_STATUS_BAD_NETWORK_NAME;
1746 *return_ss_arr = TALLOC_ARRAY(ctx,
1747 struct sockaddr_storage,
1748 num_entries);
1749 if (!(*return_ss_arr)) {
1750 SAFE_FREE(ss_list);
1751 return NT_STATUS_NO_MEMORY;
1754 for (i=0, num_entries = 0; i<count; i++) {
1755 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1756 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1757 (*return_ss_arr)[num_entries++] = ss_list[i].ss;
1761 status = NT_STATUS_OK;
1762 *p_num_entries = num_entries;
1764 SAFE_FREE(ss_list);
1765 return NT_STATUS_OK;
1768 /********************************************************
1769 Find the IP address of the master browser or DMB for a workgroup.
1770 *********************************************************/
1772 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
1774 struct ip_service *ip_list = NULL;
1775 int count = 0;
1776 NTSTATUS status;
1778 if (lp_disable_netbios()) {
1779 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1780 return false;
1783 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1784 lp_name_resolve_order());
1785 if (NT_STATUS_IS_OK(status)) {
1786 *master_ss = ip_list[0].ss;
1787 SAFE_FREE(ip_list);
1788 return true;
1791 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1792 lp_name_resolve_order());
1793 if (NT_STATUS_IS_OK(status)) {
1794 *master_ss = ip_list[0].ss;
1795 SAFE_FREE(ip_list);
1796 return true;
1799 SAFE_FREE(ip_list);
1800 return false;
1803 /********************************************************
1804 Get the IP address list of the primary domain controller
1805 for a domain.
1806 *********************************************************/
1808 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
1810 struct ip_service *ip_list = NULL;
1811 int count = 0;
1812 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1814 /* Look up #1B name */
1816 if (lp_security() == SEC_ADS) {
1817 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1818 &count, "ads");
1821 if (!NT_STATUS_IS_OK(status) || count == 0) {
1822 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1823 &count,
1824 lp_name_resolve_order());
1825 if (!NT_STATUS_IS_OK(status)) {
1826 return false;
1830 /* if we get more than 1 IP back we have to assume it is a
1831 multi-homed PDC and not a mess up */
1833 if ( count > 1 ) {
1834 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1835 sort_service_list(ip_list, count);
1838 *pss = ip_list[0].ss;
1839 SAFE_FREE(ip_list);
1840 return true;
1843 /* Private enum type for lookups. */
1845 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1847 /********************************************************
1848 Get the IP address list of the domain controllers for
1849 a domain.
1850 *********************************************************/
1852 static NTSTATUS get_dc_list(const char *domain,
1853 const char *sitename,
1854 struct ip_service **ip_list,
1855 int *count,
1856 enum dc_lookup_type lookup_type,
1857 bool *ordered)
1859 char *resolve_order = NULL;
1860 char *saf_servername = NULL;
1861 char *pserver = NULL;
1862 const char *p;
1863 char *port_str = NULL;
1864 int port;
1865 char *name;
1866 int num_addresses = 0;
1867 int local_count, i, j;
1868 struct ip_service *return_iplist = NULL;
1869 struct ip_service *auto_ip_list = NULL;
1870 bool done_auto_lookup = false;
1871 int auto_count = 0;
1872 NTSTATUS status;
1873 TALLOC_CTX *ctx = talloc_init("get_dc_list");
1875 *ip_list = NULL;
1876 *count = 0;
1878 if (!ctx) {
1879 return NT_STATUS_NO_MEMORY;
1882 *ordered = False;
1884 /* if we are restricted to solely using DNS for looking
1885 up a domain controller, make sure that host lookups
1886 are enabled for the 'name resolve order'. If host lookups
1887 are disabled and ads_only is True, then set the string to
1888 NULL. */
1890 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
1891 if (!resolve_order) {
1892 status = NT_STATUS_NO_MEMORY;
1893 goto out;
1895 strlower_m(resolve_order);
1896 if (lookup_type == DC_ADS_ONLY) {
1897 if (strstr( resolve_order, "host")) {
1898 resolve_order = talloc_strdup(ctx, "ads");
1900 /* DNS SRV lookups used by the ads resolver
1901 are already sorted by priority and weight */
1902 *ordered = true;
1903 } else {
1904 resolve_order = talloc_strdup(ctx, "NULL");
1906 } else if (lookup_type == DC_KDC_ONLY) {
1907 /* DNS SRV lookups used by the ads/kdc resolver
1908 are already sorted by priority and weight */
1909 *ordered = true;
1910 resolve_order = talloc_strdup(ctx, "kdc");
1912 if (!resolve_order) {
1913 status = NT_STATUS_NO_MEMORY;
1914 goto out;
1917 /* fetch the server we have affinity for. Add the
1918 'password server' list to a search for our domain controllers */
1920 saf_servername = saf_fetch( domain);
1922 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
1923 pserver = talloc_asprintf(NULL, "%s, %s",
1924 saf_servername ? saf_servername : "",
1925 lp_passwordserver());
1926 } else {
1927 pserver = talloc_asprintf(NULL, "%s, *",
1928 saf_servername ? saf_servername : "");
1931 SAFE_FREE(saf_servername);
1932 if (!pserver) {
1933 status = NT_STATUS_NO_MEMORY;
1934 goto out;
1937 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1939 if (!*pserver ) {
1940 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1941 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1942 count, resolve_order);
1943 goto out;
1946 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1949 * if '*' appears in the "password server" list then add
1950 * an auto lookup to the list of manually configured
1951 * DC's. If any DC is listed by name, then the list should be
1952 * considered to be ordered
1955 p = pserver;
1956 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1957 if (!done_auto_lookup && strequal(name, "*")) {
1958 status = internal_resolve_name(domain, 0x1C, sitename,
1959 &auto_ip_list,
1960 &auto_count,
1961 resolve_order);
1962 if (NT_STATUS_IS_OK(status)) {
1963 num_addresses += auto_count;
1965 done_auto_lookup = true;
1966 DEBUG(8,("Adding %d DC's from auto lookup\n",
1967 auto_count));
1968 } else {
1969 num_addresses++;
1973 /* if we have no addresses and haven't done the auto lookup, then
1974 just return the list of DC's. Or maybe we just failed. */
1976 if ((num_addresses == 0)) {
1977 if (done_auto_lookup) {
1978 DEBUG(4,("get_dc_list: no servers found\n"));
1979 status = NT_STATUS_NO_LOGON_SERVERS;
1980 goto out;
1982 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1983 count, resolve_order);
1984 goto out;
1987 if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
1988 num_addresses)) == NULL) {
1989 DEBUG(3,("get_dc_list: malloc fail !\n"));
1990 status = NT_STATUS_NO_MEMORY;
1991 goto out;
1994 p = pserver;
1995 local_count = 0;
1997 /* fill in the return list now with real IP's */
1999 while ((local_count<num_addresses) &&
2000 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
2001 struct sockaddr_storage name_ss;
2003 /* copy any addersses from the auto lookup */
2005 if (strequal(name, "*")) {
2006 for (j=0; j<auto_count; j++) {
2007 char addr[INET6_ADDRSTRLEN];
2008 print_sockaddr(addr,
2009 sizeof(addr),
2010 &auto_ip_list[j].ss);
2011 /* Check for and don't copy any
2012 * known bad DC IP's. */
2013 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
2014 domain,
2015 addr))) {
2016 DEBUG(5,("get_dc_list: "
2017 "negative entry %s removed "
2018 "from DC list\n",
2019 addr));
2020 continue;
2022 return_iplist[local_count].ss =
2023 auto_ip_list[j].ss;
2024 return_iplist[local_count].port =
2025 auto_ip_list[j].port;
2026 local_count++;
2028 continue;
2031 /* added support for address:port syntax for ads
2032 * (not that I think anyone will ever run the LDAP
2033 * server in an AD domain on something other than
2034 * port 389 */
2036 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
2037 if ((port_str=strchr(name, ':')) != NULL) {
2038 *port_str = '\0';
2039 port_str++;
2040 port = atoi(port_str);
2043 /* explicit lookup; resolve_name() will
2044 * handle names & IP addresses */
2045 if (resolve_name( name, &name_ss, 0x20, true )) {
2046 char addr[INET6_ADDRSTRLEN];
2047 print_sockaddr(addr,
2048 sizeof(addr),
2049 &name_ss);
2051 /* Check for and don't copy any known bad DC IP's. */
2052 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
2053 addr)) ) {
2054 DEBUG(5,("get_dc_list: negative entry %s "
2055 "removed from DC list\n",
2056 name ));
2057 continue;
2060 return_iplist[local_count].ss = name_ss;
2061 return_iplist[local_count].port = port;
2062 local_count++;
2063 *ordered = true;
2067 /* need to remove duplicates in the list if we have any
2068 explicit password servers */
2070 local_count = remove_duplicate_addrs2(return_iplist, local_count );
2072 /* For DC's we always prioritize IPv4 due to W2K3 not
2073 * supporting LDAP, KRB5 or CLDAP over IPv6. */
2075 if (local_count && return_iplist) {
2076 prioritize_ipv4_list(return_iplist, local_count);
2079 if ( DEBUGLEVEL >= 4 ) {
2080 DEBUG(4,("get_dc_list: returning %d ip addresses "
2081 "in an %sordered list\n",
2082 local_count,
2083 *ordered ? "":"un"));
2084 DEBUG(4,("get_dc_list: "));
2085 for ( i=0; i<local_count; i++ ) {
2086 char addr[INET6_ADDRSTRLEN];
2087 print_sockaddr(addr,
2088 sizeof(addr),
2089 &return_iplist[i].ss);
2090 DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
2092 DEBUGADD(4,("\n"));
2095 *ip_list = return_iplist;
2096 *count = local_count;
2098 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
2100 out:
2102 if (!NT_STATUS_IS_OK(status)) {
2103 SAFE_FREE(return_iplist);
2104 *ip_list = NULL;
2105 *count = 0;
2108 SAFE_FREE(auto_ip_list);
2109 TALLOC_FREE(ctx);
2110 return status;
2113 /*********************************************************************
2114 Small wrapper function to get the DC list and sort it if neccessary.
2115 *********************************************************************/
2117 NTSTATUS get_sorted_dc_list( const char *domain,
2118 const char *sitename,
2119 struct ip_service **ip_list,
2120 int *count,
2121 bool ads_only )
2123 bool ordered = false;
2124 NTSTATUS status;
2125 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
2127 *ip_list = NULL;
2128 *count = 0;
2130 DEBUG(8,("get_sorted_dc_list: attempting lookup "
2131 "for name %s (sitename %s) using [%s]\n",
2132 domain,
2133 sitename ? sitename : "NULL",
2134 (ads_only ? "ads" : lp_name_resolve_order())));
2136 if (ads_only) {
2137 lookup_type = DC_ADS_ONLY;
2140 status = get_dc_list(domain, sitename, ip_list,
2141 count, lookup_type, &ordered);
2142 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
2143 && sitename) {
2144 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
2145 " in site %s, fallback to all servers\n",
2146 domain, sitename));
2147 status = get_dc_list(domain, NULL, ip_list,
2148 count, lookup_type, &ordered);
2151 if (!NT_STATUS_IS_OK(status)) {
2152 SAFE_FREE(*ip_list);
2153 *count = 0;
2154 return status;
2157 /* only sort if we don't already have an ordered list */
2158 if (!ordered) {
2159 sort_service_list(*ip_list, *count);
2162 return NT_STATUS_OK;
2165 /*********************************************************************
2166 Get the KDC list - re-use all the logic in get_dc_list.
2167 *********************************************************************/
2169 NTSTATUS get_kdc_list( const char *realm,
2170 const char *sitename,
2171 struct ip_service **ip_list,
2172 int *count)
2174 bool ordered;
2175 NTSTATUS status;
2177 *count = 0;
2178 *ip_list = NULL;
2180 status = get_dc_list(realm, sitename, ip_list,
2181 count, DC_KDC_ONLY, &ordered);
2183 if (!NT_STATUS_IS_OK(status)) {
2184 SAFE_FREE(*ip_list);
2185 *count = 0;
2186 return status;
2189 /* only sort if we don't already have an ordered list */
2190 if ( !ordered ) {
2191 sort_service_list(*ip_list, *count);
2194 return NT_STATUS_OK;