s3:registry: add an extra check for dsize==0 to regdb_fetch_keys_internal()
[Samba/fernandojvsilva.git] / source3 / libsmb / namequery.c
blob930f0a54f4cffab1986736fa9aa3f9046229d856
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.fd = fd;
293 p.timestamp = time(NULL);
294 p.packet_type = NMB_PACKET;
296 GetTimeOfDay(&tval);
298 if (!send_packet(&p))
299 return NULL;
301 retries--;
303 while (1) {
304 struct timeval tval2;
305 GetTimeOfDay(&tval2);
306 if (TvalDiff(&tval,&tval2) > retry_time) {
307 if (!retries)
308 break;
309 if (!found && !send_packet(&p))
310 return NULL;
311 GetTimeOfDay(&tval);
312 retries--;
315 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
316 struct nmb_packet *nmb2 = &p2->packet.nmb;
317 debug_nmb_packet(p2);
319 if (nmb2->header.opcode != 0 ||
320 nmb2->header.nm_flags.bcast ||
321 nmb2->header.rcode ||
322 !nmb2->header.ancount ||
323 nmb2->answers->rr_type != 0x21) {
324 /* XXXX what do we do with this? could be a
325 redirect, but we'll discard it for the
326 moment */
327 free_packet(p2);
328 continue;
331 ret = parse_node_status(&nmb2->answers->rdata[0],
332 num_names, extra);
333 free_packet(p2);
334 return ret;
338 return NULL;
341 /****************************************************************************
342 Find the first type XX name in a node status reply - used for finding
343 a servers name given its IP. Return the matched name in *name.
344 **************************************************************************/
346 bool name_status_find(const char *q_name,
347 int q_type,
348 int type,
349 const struct sockaddr_storage *to_ss,
350 fstring name)
352 char addr[INET6_ADDRSTRLEN];
353 struct sockaddr_storage ss;
354 NODE_STATUS_STRUCT *status = NULL;
355 struct nmb_name nname;
356 int count, i;
357 int sock;
358 bool result = false;
360 if (lp_disable_netbios()) {
361 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
362 q_name, q_type));
363 return False;
366 print_sockaddr(addr, sizeof(addr), to_ss);
368 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
369 q_type, addr));
371 /* Check the cache first. */
373 if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) {
374 return True;
377 if (to_ss->ss_family != AF_INET) {
378 /* Can't do node status to IPv6 */
379 return false;
382 if (!interpret_string_addr(&ss, lp_socket_address(),
383 AI_NUMERICHOST|AI_PASSIVE)) {
384 zero_sockaddr(&ss);
387 sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);
388 if (sock == -1)
389 goto done;
391 /* W2K PDC's seem not to respond to '*'#0. JRA */
392 make_nmb_name(&nname, q_name, q_type);
393 status = node_status_query(sock, &nname, to_ss, &count, NULL);
394 close(sock);
395 if (!status)
396 goto done;
398 for (i=0;i<count;i++) {
399 /* Find first one of the requested type that's not a GROUP. */
400 if (status[i].type == type && ! (status[i].flags & 0x80))
401 break;
403 if (i == count)
404 goto done;
406 pull_ascii_nstring(name, sizeof(fstring), status[i].name);
408 /* Store the result in the cache. */
409 /* but don't store an entry for 0x1c names here. Here we have
410 a single host and DOMAIN<0x1c> names should be a list of hosts */
412 if ( q_type != 0x1c ) {
413 namecache_status_store(q_name, q_type, type, to_ss, name);
416 result = true;
418 done:
419 SAFE_FREE(status);
421 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
423 if (result)
424 DEBUGADD(10, (", name %s ip address is %s", name, addr));
426 DEBUG(10, ("\n"));
428 return result;
432 comparison function used by sort_addr_list
435 static int addr_compare(const struct sockaddr *ss1,
436 const struct sockaddr *ss2)
438 int max_bits1=0, max_bits2=0;
439 int num_interfaces = iface_count();
440 int i;
442 /* Sort IPv4 addresses first. */
443 if (ss1->sa_family != ss2->sa_family) {
444 if (ss2->sa_family == AF_INET) {
445 return 1;
446 } else {
447 return -1;
451 /* Here we know both addresses are of the same
452 * family. */
454 for (i=0;i<num_interfaces;i++) {
455 const struct sockaddr_storage *pss = iface_n_bcast(i);
456 unsigned char *p_ss1 = NULL;
457 unsigned char *p_ss2 = NULL;
458 unsigned char *p_if = NULL;
459 size_t len = 0;
460 int bits1, bits2;
462 if (pss->ss_family != ss1->sa_family) {
463 /* Ignore interfaces of the wrong type. */
464 continue;
466 if (pss->ss_family == AF_INET) {
467 p_if = (unsigned char *)
468 &((const struct sockaddr_in *)pss)->sin_addr;
469 p_ss1 = (unsigned char *)
470 &((const struct sockaddr_in *)ss1)->sin_addr;
471 p_ss2 = (unsigned char *)
472 &((const struct sockaddr_in *)ss2)->sin_addr;
473 len = 4;
475 #if defined(HAVE_IPV6)
476 if (pss->ss_family == AF_INET6) {
477 p_if = (unsigned char *)
478 &((const struct sockaddr_in6 *)pss)->sin6_addr;
479 p_ss1 = (unsigned char *)
480 &((const struct sockaddr_in6 *)ss1)->sin6_addr;
481 p_ss2 = (unsigned char *)
482 &((const struct sockaddr_in6 *)ss2)->sin6_addr;
483 len = 16;
485 #endif
486 if (!p_ss1 || !p_ss2 || !p_if || len == 0) {
487 continue;
489 bits1 = matching_len_bits(p_ss1, p_if, len);
490 bits2 = matching_len_bits(p_ss2, p_if, len);
491 max_bits1 = MAX(bits1, max_bits1);
492 max_bits2 = MAX(bits2, max_bits2);
495 /* Bias towards directly reachable IPs */
496 if (iface_local(ss1)) {
497 if (ss1->sa_family == AF_INET) {
498 max_bits1 += 32;
499 } else {
500 max_bits1 += 128;
503 if (iface_local(ss2)) {
504 if (ss2->sa_family == AF_INET) {
505 max_bits2 += 32;
506 } else {
507 max_bits2 += 128;
510 return max_bits2 - max_bits1;
513 /*******************************************************************
514 compare 2 ldap IPs by nearness to our interfaces - used in qsort
515 *******************************************************************/
517 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)
519 int result;
521 if ((result = addr_compare((struct sockaddr *)&ss1->ss, (struct sockaddr *)&ss2->ss)) != 0) {
522 return result;
525 if (ss1->port > ss2->port) {
526 return 1;
529 if (ss1->port < ss2->port) {
530 return -1;
533 return 0;
537 sort an IP list so that names that are close to one of our interfaces
538 are at the top. This prevents the problem where a WINS server returns an IP
539 that is not reachable from our subnet as the first match
542 static void sort_addr_list(struct sockaddr_storage *sslist, int count)
544 if (count <= 1) {
545 return;
548 qsort(sslist, count, sizeof(struct sockaddr_storage),
549 QSORT_CAST addr_compare);
552 static void sort_service_list(struct ip_service *servlist, int count)
554 if (count <= 1) {
555 return;
558 qsort(servlist, count, sizeof(struct ip_service),
559 QSORT_CAST ip_service_compare);
562 /**********************************************************************
563 Remove any duplicate address/port pairs in the list
564 *********************************************************************/
566 static int remove_duplicate_addrs2(struct ip_service *iplist, int count )
568 int i, j;
570 DEBUG(10,("remove_duplicate_addrs2: "
571 "looking for duplicate address/port pairs\n"));
573 /* one loop to remove duplicates */
574 for ( i=0; i<count; i++ ) {
575 if ( is_zero_addr((struct sockaddr *)&iplist[i].ss)) {
576 continue;
579 for ( j=i+1; j<count; j++ ) {
580 if (sockaddr_equal((struct sockaddr *)&iplist[i].ss, (struct sockaddr *)&iplist[j].ss) &&
581 iplist[i].port == iplist[j].port) {
582 zero_sockaddr(&iplist[j].ss);
587 /* one loop to clean up any holes we left */
588 /* first ip should never be a zero_ip() */
589 for (i = 0; i<count; ) {
590 if (is_zero_addr((struct sockaddr *)&iplist[i].ss) ) {
591 if (i != count-1) {
592 memmove(&iplist[i], &iplist[i+1],
593 (count - i - 1)*sizeof(iplist[i]));
595 count--;
596 continue;
598 i++;
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.fd = fd;
702 p.timestamp = time(NULL);
703 p.packet_type = NMB_PACKET;
705 GetTimeOfDay(&tval);
707 if (!send_packet(&p))
708 return NULL;
710 retries--;
712 while (1) {
713 struct timeval tval2;
715 GetTimeOfDay(&tval2);
716 if (TvalDiff(&tval,&tval2) > retry_time) {
717 if (!retries)
718 break;
719 if (!found && !send_packet(&p))
720 return NULL;
721 GetTimeOfDay(&tval);
722 retries--;
725 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
726 struct nmb_packet *nmb2 = &p2->packet.nmb;
727 debug_nmb_packet(p2);
729 /* If we get a Negative Name Query Response from a WINS
730 * server, we should report it and give up.
732 if( 0 == nmb2->header.opcode /* A query response */
733 && !(bcast) /* from a WINS server */
734 && nmb2->header.rcode /* Error returned */
737 if( DEBUGLVL( 3 ) ) {
738 /* Only executed if DEBUGLEVEL >= 3 */
739 dbgtext( "Negative name query "
740 "response, rcode 0x%02x: ",
741 nmb2->header.rcode );
742 switch( nmb2->header.rcode ) {
743 case 0x01:
744 dbgtext( "Request "
745 "was invalidly formatted.\n" );
746 break;
747 case 0x02:
748 dbgtext( "Problem with NBNS, "
749 "cannot process name.\n");
750 break;
751 case 0x03:
752 dbgtext( "The name requested "
753 "does not exist.\n" );
754 break;
755 case 0x04:
756 dbgtext( "Unsupported request "
757 "error.\n" );
758 break;
759 case 0x05:
760 dbgtext( "Query refused "
761 "error.\n" );
762 break;
763 default:
764 dbgtext( "Unrecognized error "
765 "code.\n" );
766 break;
769 free_packet(p2);
770 return( NULL );
773 if (nmb2->header.opcode != 0 ||
774 nmb2->header.nm_flags.bcast ||
775 nmb2->header.rcode ||
776 !nmb2->header.ancount) {
778 * XXXX what do we do with this? Could be a
779 * redirect, but we'll discard it for the
780 * moment.
782 free_packet(p2);
783 continue;
786 ss_list = SMB_REALLOC_ARRAY(ss_list,
787 struct sockaddr_storage,
788 (*count) +
789 nmb2->answers->rdlength/6);
791 if (!ss_list) {
792 DEBUG(0,("name_query: Realloc failed.\n"));
793 free_packet(p2);
794 return NULL;
797 DEBUG(2,("Got a positive name query response "
798 "from %s ( ",
799 inet_ntoa(p2->ip)));
801 for (i=0;i<nmb2->answers->rdlength/6;i++) {
802 struct in_addr ip;
803 putip((char *)&ip,&nmb2->answers->rdata[2+i*6]);
804 in_addr_to_sockaddr_storage(&ss_list[(*count)],
805 ip);
806 DEBUGADD(2,("%s ",inet_ntoa(ip)));
807 (*count)++;
809 DEBUGADD(2,(")\n"));
811 found=true;
812 retries=0;
813 /* We add the flags back ... */
814 if (nmb2->header.response)
815 (*flags) |= NM_FLAGS_RS;
816 if (nmb2->header.nm_flags.authoritative)
817 (*flags) |= NM_FLAGS_AA;
818 if (nmb2->header.nm_flags.trunc)
819 (*flags) |= NM_FLAGS_TC;
820 if (nmb2->header.nm_flags.recursion_desired)
821 (*flags) |= NM_FLAGS_RD;
822 if (nmb2->header.nm_flags.recursion_available)
823 (*flags) |= NM_FLAGS_RA;
824 if (nmb2->header.nm_flags.bcast)
825 (*flags) |= NM_FLAGS_B;
826 free_packet(p2);
828 * If we're doing a unicast lookup we only
829 * expect one reply. Don't wait the full 2
830 * seconds if we got one. JRA.
832 if(!bcast && found)
833 break;
837 /* only set timed_out if we didn't fund what we where looking for*/
839 if ( !found && timed_out ) {
840 *timed_out = true;
843 /* sort the ip list so we choose close servers first if possible */
844 sort_addr_list(ss_list, *count);
846 return ss_list;
849 /********************************************************
850 convert an array if struct sockaddr_storage to struct ip_service
851 return false on failure. Port is set to PORT_NONE;
852 *********************************************************/
854 static bool convert_ss2service(struct ip_service **return_iplist,
855 const struct sockaddr_storage *ss_list,
856 int count)
858 int i;
860 if ( count==0 || !ss_list )
861 return False;
863 /* copy the ip address; port will be PORT_NONE */
864 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) ==
865 NULL) {
866 DEBUG(0,("convert_ip2service: malloc failed "
867 "for %d enetries!\n", count ));
868 return False;
871 for ( i=0; i<count; i++ ) {
872 (*return_iplist)[i].ss = ss_list[i];
873 (*return_iplist)[i].port = PORT_NONE;
876 return true;
879 /********************************************************
880 Resolve via "bcast" method.
881 *********************************************************/
883 NTSTATUS name_resolve_bcast(const char *name,
884 int name_type,
885 struct ip_service **return_iplist,
886 int *return_count)
888 int sock, i;
889 int num_interfaces = iface_count();
890 struct sockaddr_storage *ss_list;
891 struct sockaddr_storage ss;
892 NTSTATUS status;
894 if (lp_disable_netbios()) {
895 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
896 name, name_type));
897 return NT_STATUS_INVALID_PARAMETER;
900 *return_iplist = NULL;
901 *return_count = 0;
904 * "bcast" means do a broadcast lookup on all the local interfaces.
907 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
908 "for name %s<0x%x>\n", name, name_type));
910 if (!interpret_string_addr(&ss, lp_socket_address(),
911 AI_NUMERICHOST|AI_PASSIVE)) {
912 zero_sockaddr(&ss);
915 sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );
916 if (sock == -1) {
917 return NT_STATUS_UNSUCCESSFUL;
920 set_socket_options(sock,"SO_BROADCAST");
922 * Lookup the name on all the interfaces, return on
923 * the first successful match.
925 for( i = num_interfaces-1; i >= 0; i--) {
926 const struct sockaddr_storage *pss = iface_n_bcast(i);
927 int flags;
929 /* Done this way to fix compiler error on IRIX 5.x */
930 if (!pss) {
931 continue;
933 ss_list = name_query(sock, name, name_type, true,
934 true, pss, return_count, &flags, NULL);
935 if (ss_list) {
936 goto success;
940 /* failed - no response */
942 close(sock);
943 return NT_STATUS_UNSUCCESSFUL;
945 success:
947 status = NT_STATUS_OK;
948 if (!convert_ss2service(return_iplist, ss_list, *return_count) )
949 status = NT_STATUS_INVALID_PARAMETER;
951 SAFE_FREE(ss_list);
952 close(sock);
953 return status;
956 /********************************************************
957 Resolve via "wins" method.
958 *********************************************************/
960 NTSTATUS resolve_wins(const char *name,
961 int name_type,
962 struct ip_service **return_iplist,
963 int *return_count)
965 int sock, t, i;
966 char **wins_tags;
967 struct sockaddr_storage src_ss, *ss_list = NULL;
968 struct in_addr src_ip;
969 NTSTATUS status;
971 if (lp_disable_netbios()) {
972 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
973 name, name_type));
974 return NT_STATUS_INVALID_PARAMETER;
977 *return_iplist = NULL;
978 *return_count = 0;
980 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
981 name, name_type));
983 if (wins_srv_count() < 1) {
984 DEBUG(3,("resolve_wins: WINS server resolution selected "
985 "and no WINS servers listed.\n"));
986 return NT_STATUS_INVALID_PARAMETER;
989 /* we try a lookup on each of the WINS tags in turn */
990 wins_tags = wins_srv_tags();
992 if (!wins_tags) {
993 /* huh? no tags?? give up in disgust */
994 return NT_STATUS_INVALID_PARAMETER;
997 /* the address we will be sending from */
998 if (!interpret_string_addr(&src_ss, lp_socket_address(),
999 AI_NUMERICHOST|AI_PASSIVE)) {
1000 zero_sockaddr(&src_ss);
1003 if (src_ss.ss_family != AF_INET) {
1004 char addr[INET6_ADDRSTRLEN];
1005 print_sockaddr(addr, sizeof(addr), &src_ss);
1006 DEBUG(3,("resolve_wins: cannot receive WINS replies "
1007 "on IPv6 address %s\n",
1008 addr));
1009 wins_srv_tags_free(wins_tags);
1010 return NT_STATUS_INVALID_PARAMETER;
1013 src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
1015 /* in the worst case we will try every wins server with every
1016 tag! */
1017 for (t=0; wins_tags && wins_tags[t]; t++) {
1018 int srv_count = wins_srv_count_tag(wins_tags[t]);
1019 for (i=0; i<srv_count; i++) {
1020 struct sockaddr_storage wins_ss;
1021 struct in_addr wins_ip;
1022 int flags;
1023 bool timed_out;
1025 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
1027 if (global_in_nmbd && ismyip_v4(wins_ip)) {
1028 /* yikes! we'll loop forever */
1029 continue;
1032 /* skip any that have been unresponsive lately */
1033 if (wins_srv_is_dead(wins_ip, src_ip)) {
1034 continue;
1037 DEBUG(3,("resolve_wins: using WINS server %s "
1038 "and tag '%s'\n",
1039 inet_ntoa(wins_ip), wins_tags[t]));
1041 sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);
1042 if (sock == -1) {
1043 continue;
1046 in_addr_to_sockaddr_storage(&wins_ss, wins_ip);
1047 ss_list = name_query(sock,
1048 name,
1049 name_type,
1050 false,
1051 true,
1052 &wins_ss,
1053 return_count,
1054 &flags,
1055 &timed_out);
1057 /* exit loop if we got a list of addresses */
1059 if (ss_list)
1060 goto success;
1062 close(sock);
1064 if (timed_out) {
1065 /* Timed out wating for WINS server to respond.
1066 * Mark it dead. */
1067 wins_srv_died(wins_ip, src_ip);
1068 } else {
1069 /* The name definately isn't in this
1070 group of WINS servers.
1071 goto the next group */
1072 break;
1077 wins_srv_tags_free(wins_tags);
1078 return NT_STATUS_NO_LOGON_SERVERS;
1080 success:
1082 status = NT_STATUS_OK;
1083 if (!convert_ss2service(return_iplist, ss_list, *return_count))
1084 status = NT_STATUS_INVALID_PARAMETER;
1086 SAFE_FREE(ss_list);
1087 wins_srv_tags_free(wins_tags);
1088 close(sock);
1090 return status;
1093 /********************************************************
1094 Resolve via "lmhosts" method.
1095 *********************************************************/
1097 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
1098 struct ip_service **return_iplist,
1099 int *return_count)
1102 * "lmhosts" means parse the local lmhosts file.
1105 XFILE *fp;
1106 char *lmhost_name = NULL;
1107 int name_type2;
1108 struct sockaddr_storage return_ss;
1109 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1110 TALLOC_CTX *ctx = NULL;
1112 *return_iplist = NULL;
1113 *return_count = 0;
1115 DEBUG(3,("resolve_lmhosts: "
1116 "Attempting lmhosts lookup for name %s<0x%x>\n",
1117 name, name_type));
1119 fp = startlmhosts(get_dyn_LMHOSTSFILE());
1121 if ( fp == NULL )
1122 return NT_STATUS_NO_SUCH_FILE;
1124 ctx = talloc_init("resolve_lmhosts");
1125 if (!ctx) {
1126 endlmhosts(fp);
1127 return NT_STATUS_NO_MEMORY;
1130 while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) {
1132 if (!strequal(name, lmhost_name)) {
1133 TALLOC_FREE(lmhost_name);
1134 continue;
1137 if ((name_type2 != -1) && (name_type != name_type2)) {
1138 TALLOC_FREE(lmhost_name);
1139 continue;
1142 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist),
1143 struct ip_service,
1144 (*return_count)+1);
1146 if ((*return_iplist) == NULL) {
1147 TALLOC_FREE(ctx);
1148 endlmhosts(fp);
1149 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
1150 return NT_STATUS_NO_MEMORY;
1153 (*return_iplist)[*return_count].ss = return_ss;
1154 (*return_iplist)[*return_count].port = PORT_NONE;
1155 *return_count += 1;
1157 /* we found something */
1158 status = NT_STATUS_OK;
1160 /* Multiple names only for DC lookup */
1161 if (name_type != 0x1c)
1162 break;
1165 TALLOC_FREE(ctx);
1166 endlmhosts(fp);
1167 return status;
1171 /********************************************************
1172 Resolve via "hosts" method.
1173 *********************************************************/
1175 static NTSTATUS resolve_hosts(const char *name, int name_type,
1176 struct ip_service **return_iplist,
1177 int *return_count)
1180 * "host" means do a localhost, or dns lookup.
1182 struct addrinfo hints;
1183 struct addrinfo *ailist = NULL;
1184 struct addrinfo *res = NULL;
1185 int ret = -1;
1186 int i = 0;
1188 if ( name_type != 0x20 && name_type != 0x0) {
1189 DEBUG(5, ("resolve_hosts: not appropriate "
1190 "for name type <0x%x>\n",
1191 name_type));
1192 return NT_STATUS_INVALID_PARAMETER;
1195 *return_iplist = NULL;
1196 *return_count = 0;
1198 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
1199 name, name_type));
1201 ZERO_STRUCT(hints);
1202 /* By default make sure it supports TCP. */
1203 hints.ai_socktype = SOCK_STREAM;
1204 hints.ai_flags = AI_ADDRCONFIG;
1206 #if !defined(HAVE_IPV6)
1207 /* Unless we have IPv6, we really only want IPv4 addresses back. */
1208 hints.ai_family = AF_INET;
1209 #endif
1211 ret = getaddrinfo(name,
1212 NULL,
1213 &hints,
1214 &ailist);
1215 if (ret) {
1216 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
1217 name,
1218 gai_strerror(ret) ));
1221 for (res = ailist; res; res = res->ai_next) {
1222 struct sockaddr_storage ss;
1224 if (!res->ai_addr || res->ai_addrlen == 0) {
1225 continue;
1228 ZERO_STRUCT(ss);
1229 memcpy(&ss, res->ai_addr, res->ai_addrlen);
1231 *return_count += 1;
1233 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,
1234 struct ip_service,
1235 *return_count);
1236 if (!*return_iplist) {
1237 DEBUG(3,("resolve_hosts: malloc fail !\n"));
1238 freeaddrinfo(ailist);
1239 return NT_STATUS_NO_MEMORY;
1241 (*return_iplist)[i].ss = ss;
1242 (*return_iplist)[i].port = PORT_NONE;
1243 i++;
1245 if (ailist) {
1246 freeaddrinfo(ailist);
1248 if (*return_count) {
1249 return NT_STATUS_OK;
1251 return NT_STATUS_UNSUCCESSFUL;
1254 /********************************************************
1255 Resolve via "ADS" method.
1256 *********************************************************/
1258 static NTSTATUS resolve_ads(const char *name,
1259 int name_type,
1260 const char *sitename,
1261 struct ip_service **return_iplist,
1262 int *return_count)
1264 int i, j;
1265 NTSTATUS status;
1266 TALLOC_CTX *ctx;
1267 struct dns_rr_srv *dcs = NULL;
1268 int numdcs = 0;
1269 int numaddrs = 0;
1271 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
1272 (name_type != 0x1b)) {
1273 return NT_STATUS_INVALID_PARAMETER;
1276 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1277 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1278 return NT_STATUS_NO_MEMORY;
1281 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
1283 switch (name_type) {
1284 case 0x1b:
1285 DEBUG(5,("resolve_ads: Attempting to resolve "
1286 "PDC for %s using DNS\n", name));
1287 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
1288 break;
1290 case 0x1c:
1291 DEBUG(5,("resolve_ads: Attempting to resolve "
1292 "DCs for %s using DNS\n", name));
1293 status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1294 &numdcs);
1295 break;
1296 case KDC_NAME_TYPE:
1297 DEBUG(5,("resolve_ads: Attempting to resolve "
1298 "KDCs for %s using DNS\n", name));
1299 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1300 &numdcs);
1301 break;
1302 default:
1303 status = NT_STATUS_INVALID_PARAMETER;
1304 break;
1307 if ( !NT_STATUS_IS_OK( status ) ) {
1308 talloc_destroy(ctx);
1309 return status;
1312 for (i=0;i<numdcs;i++) {
1313 numaddrs += MAX(dcs[i].num_ips,1);
1316 if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) ==
1317 NULL ) {
1318 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
1319 numaddrs ));
1320 talloc_destroy(ctx);
1321 return NT_STATUS_NO_MEMORY;
1324 /* now unroll the list of IP addresses */
1326 *return_count = 0;
1327 i = 0;
1328 j = 0;
1329 while ( i < numdcs && (*return_count<numaddrs) ) {
1330 struct ip_service *r = &(*return_iplist)[*return_count];
1332 r->port = dcs[i].port;
1334 /* If we don't have an IP list for a name, lookup it up */
1336 if (!dcs[i].ss_s) {
1337 interpret_string_addr(&r->ss, dcs[i].hostname, 0);
1338 i++;
1339 j = 0;
1340 } else {
1341 /* use the IP addresses from the SRV sresponse */
1343 if ( j >= dcs[i].num_ips ) {
1344 i++;
1345 j = 0;
1346 continue;
1349 r->ss = dcs[i].ss_s[j];
1350 j++;
1353 /* make sure it is a valid IP. I considered checking the
1354 * negative connection cache, but this is the wrong place
1355 * for it. Maybe only as a hack. After think about it, if
1356 * all of the IP addresses returned from DNS are dead, what
1357 * hope does a netbios name lookup have ? The standard reason
1358 * for falling back to netbios lookups is that our DNS server
1359 * doesn't know anything about the DC's -- jerry */
1361 if (!is_zero_addr((struct sockaddr *)&r->ss)) {
1362 (*return_count)++;
1366 talloc_destroy(ctx);
1367 return NT_STATUS_OK;
1370 /*******************************************************************
1371 Internal interface to resolve a name into an IP address.
1372 Use this function if the string is either an IP address, DNS
1373 or host name or NetBIOS name. This uses the name switch in the
1374 smb.conf to determine the order of name resolution.
1376 Added support for ip addr/port to support ADS ldap servers.
1377 the only place we currently care about the port is in the
1378 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1379 **********************************************************************/
1381 NTSTATUS internal_resolve_name(const char *name,
1382 int name_type,
1383 const char *sitename,
1384 struct ip_service **return_iplist,
1385 int *return_count,
1386 const char *resolve_order)
1388 char *tok;
1389 const char *ptr;
1390 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1391 int i;
1392 TALLOC_CTX *frame = NULL;
1394 *return_iplist = NULL;
1395 *return_count = 0;
1397 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1398 name, name_type, sitename ? sitename : "(null)"));
1400 if (is_ipaddress(name)) {
1401 if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) ==
1402 NULL) {
1403 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1404 return NT_STATUS_NO_MEMORY;
1407 /* ignore the port here */
1408 (*return_iplist)->port = PORT_NONE;
1410 /* if it's in the form of an IP address then get the lib to interpret it */
1411 if (!interpret_string_addr(&(*return_iplist)->ss,
1412 name, AI_NUMERICHOST)) {
1413 DEBUG(1,("internal_resolve_name: interpret_string_addr "
1414 "failed on %s\n",
1415 name));
1416 SAFE_FREE(*return_iplist);
1417 return NT_STATUS_INVALID_PARAMETER;
1419 *return_count = 1;
1420 return NT_STATUS_OK;
1423 /* Check name cache */
1425 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1426 /* This could be a negative response */
1427 if (*return_count > 0) {
1428 return NT_STATUS_OK;
1429 } else {
1430 return NT_STATUS_UNSUCCESSFUL;
1434 /* set the name resolution order */
1436 if (strcmp( resolve_order, "NULL") == 0) {
1437 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1438 return NT_STATUS_INVALID_PARAMETER;
1441 if (!resolve_order[0]) {
1442 ptr = "host";
1443 } else {
1444 ptr = resolve_order;
1447 /* iterate through the name resolution backends */
1449 frame = talloc_stackframe();
1450 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) {
1451 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1452 status = resolve_hosts(name, name_type, return_iplist,
1453 return_count);
1454 if (NT_STATUS_IS_OK(status)) {
1455 goto done;
1457 } else if(strequal( tok, "kdc")) {
1458 /* deal with KDC_NAME_TYPE names here.
1459 * This will result in a SRV record lookup */
1460 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1461 return_iplist, return_count);
1462 if (NT_STATUS_IS_OK(status)) {
1463 /* Ensure we don't namecache
1464 * this with the KDC port. */
1465 name_type = KDC_NAME_TYPE;
1466 goto done;
1468 } else if(strequal( tok, "ads")) {
1469 /* deal with 0x1c and 0x1b names here.
1470 * This will result in a SRV record lookup */
1471 status = resolve_ads(name, name_type, sitename,
1472 return_iplist, return_count);
1473 if (NT_STATUS_IS_OK(status)) {
1474 goto done;
1476 } else if(strequal( tok, "lmhosts")) {
1477 status = resolve_lmhosts(name, name_type,
1478 return_iplist, return_count);
1479 if (NT_STATUS_IS_OK(status)) {
1480 goto done;
1482 } else if(strequal( tok, "wins")) {
1483 /* don't resolve 1D via WINS */
1484 if (name_type != 0x1D) {
1485 status = resolve_wins(name, name_type,
1486 return_iplist,
1487 return_count);
1488 if (NT_STATUS_IS_OK(status)) {
1489 goto done;
1492 } else if(strequal( tok, "bcast")) {
1493 status = name_resolve_bcast(name, name_type,
1494 return_iplist,
1495 return_count);
1496 if (NT_STATUS_IS_OK(status)) {
1497 goto done;
1499 } else {
1500 DEBUG(0,("resolve_name: unknown name switch type %s\n",
1501 tok));
1505 /* All of the resolve_* functions above have returned false. */
1507 TALLOC_FREE(frame);
1508 SAFE_FREE(*return_iplist);
1509 *return_count = 0;
1511 return NT_STATUS_UNSUCCESSFUL;
1513 done:
1515 /* Remove duplicate entries. Some queries, notably #1c (domain
1516 controllers) return the PDC in iplist[0] and then all domain
1517 controllers including the PDC in iplist[1..n]. Iterating over
1518 the iplist when the PDC is down will cause two sets of timeouts. */
1520 if ( *return_count ) {
1521 *return_count = remove_duplicate_addrs2(*return_iplist,
1522 *return_count );
1525 /* Save in name cache */
1526 if ( DEBUGLEVEL >= 100 ) {
1527 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) {
1528 char addr[INET6_ADDRSTRLEN];
1529 print_sockaddr(addr, sizeof(addr),
1530 &(*return_iplist)[i].ss);
1531 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
1532 name,
1533 name_type,
1534 addr,
1535 (*return_iplist)[i].port));
1539 namecache_store(name, name_type, *return_count, *return_iplist);
1541 /* Display some debugging info */
1543 if ( DEBUGLEVEL >= 10 ) {
1544 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1545 *return_count));
1547 for (i = 0; i < *return_count; i++) {
1548 char addr[INET6_ADDRSTRLEN];
1549 print_sockaddr(addr, sizeof(addr),
1550 &(*return_iplist)[i].ss);
1551 DEBUGADD(10, ("%s:%d ",
1552 addr,
1553 (*return_iplist)[i].port));
1555 DEBUG(10, ("\n"));
1558 TALLOC_FREE(frame);
1559 return status;
1562 /********************************************************
1563 Internal interface to resolve a name into one IP address.
1564 Use this function if the string is either an IP address, DNS
1565 or host name or NetBIOS name. This uses the name switch in the
1566 smb.conf to determine the order of name resolution.
1567 *********************************************************/
1569 bool resolve_name(const char *name,
1570 struct sockaddr_storage *return_ss,
1571 int name_type,
1572 bool prefer_ipv4)
1574 struct ip_service *ss_list = NULL;
1575 char *sitename = NULL;
1576 int count = 0;
1578 if (is_ipaddress(name)) {
1579 return interpret_string_addr(return_ss, name, AI_NUMERICHOST);
1582 sitename = sitename_fetch(lp_realm()); /* wild guess */
1584 if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1585 &ss_list, &count,
1586 lp_name_resolve_order()))) {
1587 int i;
1589 if (prefer_ipv4) {
1590 for (i=0; i<count; i++) {
1591 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1592 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) &&
1593 (ss_list[i].ss.ss_family == AF_INET)) {
1594 *return_ss = ss_list[i].ss;
1595 SAFE_FREE(ss_list);
1596 SAFE_FREE(sitename);
1597 return True;
1602 /* only return valid addresses for TCP connections */
1603 for (i=0; i<count; i++) {
1604 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1605 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1606 *return_ss = ss_list[i].ss;
1607 SAFE_FREE(ss_list);
1608 SAFE_FREE(sitename);
1609 return True;
1614 SAFE_FREE(ss_list);
1615 SAFE_FREE(sitename);
1616 return False;
1619 /********************************************************
1620 Internal interface to resolve a name into a list of IP addresses.
1621 Use this function if the string is either an IP address, DNS
1622 or host name or NetBIOS name. This uses the name switch in the
1623 smb.conf to determine the order of name resolution.
1624 *********************************************************/
1626 NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
1627 const char *name,
1628 int name_type,
1629 struct sockaddr_storage **return_ss_arr,
1630 unsigned int *p_num_entries)
1632 struct ip_service *ss_list = NULL;
1633 char *sitename = NULL;
1634 int count = 0;
1635 int i;
1636 unsigned int num_entries;
1637 NTSTATUS status;
1639 *p_num_entries = 0;
1640 *return_ss_arr = NULL;
1642 if (is_ipaddress(name)) {
1643 *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);
1644 if (!*return_ss_arr) {
1645 return NT_STATUS_NO_MEMORY;
1647 if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
1648 TALLOC_FREE(*return_ss_arr);
1649 return NT_STATUS_BAD_NETWORK_NAME;
1651 *p_num_entries = 1;
1652 return NT_STATUS_OK;
1655 sitename = sitename_fetch(lp_realm()); /* wild guess */
1657 status = internal_resolve_name(name, name_type, sitename,
1658 &ss_list, &count,
1659 lp_name_resolve_order());
1660 SAFE_FREE(sitename);
1662 if (!NT_STATUS_IS_OK(status)) {
1663 return status;
1666 /* only return valid addresses for TCP connections */
1667 for (i=0, num_entries = 0; i<count; i++) {
1668 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1669 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1670 num_entries++;
1673 if (num_entries == 0) {
1674 SAFE_FREE(ss_list);
1675 return NT_STATUS_BAD_NETWORK_NAME;
1678 *return_ss_arr = TALLOC_ARRAY(ctx,
1679 struct sockaddr_storage,
1680 num_entries);
1681 if (!(*return_ss_arr)) {
1682 SAFE_FREE(ss_list);
1683 return NT_STATUS_NO_MEMORY;
1686 for (i=0, num_entries = 0; i<count; i++) {
1687 if (!is_zero_addr((struct sockaddr *)&ss_list[i].ss) &&
1688 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) {
1689 (*return_ss_arr)[num_entries++] = ss_list[i].ss;
1693 status = NT_STATUS_OK;
1694 *p_num_entries = num_entries;
1696 SAFE_FREE(ss_list);
1697 return NT_STATUS_OK;
1700 /********************************************************
1701 Find the IP address of the master browser or DMB for a workgroup.
1702 *********************************************************/
1704 bool find_master_ip(const char *group, struct sockaddr_storage *master_ss)
1706 struct ip_service *ip_list = NULL;
1707 int count = 0;
1708 NTSTATUS status;
1710 if (lp_disable_netbios()) {
1711 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1712 return false;
1715 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1716 lp_name_resolve_order());
1717 if (NT_STATUS_IS_OK(status)) {
1718 *master_ss = ip_list[0].ss;
1719 SAFE_FREE(ip_list);
1720 return true;
1723 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1724 lp_name_resolve_order());
1725 if (NT_STATUS_IS_OK(status)) {
1726 *master_ss = ip_list[0].ss;
1727 SAFE_FREE(ip_list);
1728 return true;
1731 SAFE_FREE(ip_list);
1732 return false;
1735 /********************************************************
1736 Get the IP address list of the primary domain controller
1737 for a domain.
1738 *********************************************************/
1740 bool get_pdc_ip(const char *domain, struct sockaddr_storage *pss)
1742 struct ip_service *ip_list = NULL;
1743 int count = 0;
1744 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1746 /* Look up #1B name */
1748 if (lp_security() == SEC_ADS) {
1749 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1750 &count, "ads");
1753 if (!NT_STATUS_IS_OK(status) || count == 0) {
1754 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1755 &count,
1756 lp_name_resolve_order());
1757 if (!NT_STATUS_IS_OK(status)) {
1758 return false;
1762 /* if we get more than 1 IP back we have to assume it is a
1763 multi-homed PDC and not a mess up */
1765 if ( count > 1 ) {
1766 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1767 sort_service_list(ip_list, count);
1770 *pss = ip_list[0].ss;
1771 SAFE_FREE(ip_list);
1772 return true;
1775 /* Private enum type for lookups. */
1777 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1779 /********************************************************
1780 Get the IP address list of the domain controllers for
1781 a domain.
1782 *********************************************************/
1784 static NTSTATUS get_dc_list(const char *domain,
1785 const char *sitename,
1786 struct ip_service **ip_list,
1787 int *count,
1788 enum dc_lookup_type lookup_type,
1789 bool *ordered)
1791 char *resolve_order = NULL;
1792 char *saf_servername = NULL;
1793 char *pserver = NULL;
1794 const char *p;
1795 char *port_str = NULL;
1796 int port;
1797 char *name;
1798 int num_addresses = 0;
1799 int local_count, i, j;
1800 struct ip_service *return_iplist = NULL;
1801 struct ip_service *auto_ip_list = NULL;
1802 bool done_auto_lookup = false;
1803 int auto_count = 0;
1804 NTSTATUS status;
1805 TALLOC_CTX *ctx = talloc_init("get_dc_list");
1807 *ip_list = NULL;
1808 *count = 0;
1810 if (!ctx) {
1811 return NT_STATUS_NO_MEMORY;
1814 *ordered = False;
1816 /* if we are restricted to solely using DNS for looking
1817 up a domain controller, make sure that host lookups
1818 are enabled for the 'name resolve order'. If host lookups
1819 are disabled and ads_only is True, then set the string to
1820 NULL. */
1822 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());
1823 if (!resolve_order) {
1824 status = NT_STATUS_NO_MEMORY;
1825 goto out;
1827 strlower_m(resolve_order);
1828 if (lookup_type == DC_ADS_ONLY) {
1829 if (strstr( resolve_order, "host")) {
1830 resolve_order = talloc_strdup(ctx, "ads");
1832 /* DNS SRV lookups used by the ads resolver
1833 are already sorted by priority and weight */
1834 *ordered = true;
1835 } else {
1836 resolve_order = talloc_strdup(ctx, "NULL");
1838 } else if (lookup_type == DC_KDC_ONLY) {
1839 /* DNS SRV lookups used by the ads/kdc resolver
1840 are already sorted by priority and weight */
1841 *ordered = true;
1842 resolve_order = talloc_strdup(ctx, "kdc");
1844 if (!resolve_order) {
1845 status = NT_STATUS_NO_MEMORY;
1846 goto out;
1849 /* fetch the server we have affinity for. Add the
1850 'password server' list to a search for our domain controllers */
1852 saf_servername = saf_fetch( domain);
1854 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) {
1855 pserver = talloc_asprintf(NULL, "%s, %s",
1856 saf_servername ? saf_servername : "",
1857 lp_passwordserver());
1858 } else {
1859 pserver = talloc_asprintf(NULL, "%s, *",
1860 saf_servername ? saf_servername : "");
1863 SAFE_FREE(saf_servername);
1864 if (!pserver) {
1865 status = NT_STATUS_NO_MEMORY;
1866 goto out;
1869 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1871 if (!*pserver ) {
1872 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1873 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1874 count, resolve_order);
1875 goto out;
1878 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1881 * if '*' appears in the "password server" list then add
1882 * an auto lookup to the list of manually configured
1883 * DC's. If any DC is listed by name, then the list should be
1884 * considered to be ordered
1887 p = pserver;
1888 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1889 if (!done_auto_lookup && strequal(name, "*")) {
1890 status = internal_resolve_name(domain, 0x1C, sitename,
1891 &auto_ip_list,
1892 &auto_count,
1893 resolve_order);
1894 if (NT_STATUS_IS_OK(status)) {
1895 num_addresses += auto_count;
1897 done_auto_lookup = true;
1898 DEBUG(8,("Adding %d DC's from auto lookup\n",
1899 auto_count));
1900 } else {
1901 num_addresses++;
1905 /* if we have no addresses and haven't done the auto lookup, then
1906 just return the list of DC's. Or maybe we just failed. */
1908 if ((num_addresses == 0)) {
1909 if (done_auto_lookup) {
1910 DEBUG(4,("get_dc_list: no servers found\n"));
1911 status = NT_STATUS_NO_LOGON_SERVERS;
1912 goto out;
1914 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,
1915 count, resolve_order);
1916 goto out;
1919 if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service,
1920 num_addresses)) == NULL) {
1921 DEBUG(3,("get_dc_list: malloc fail !\n"));
1922 status = NT_STATUS_NO_MEMORY;
1923 goto out;
1926 p = pserver;
1927 local_count = 0;
1929 /* fill in the return list now with real IP's */
1931 while ((local_count<num_addresses) &&
1932 next_token_talloc(ctx, &p, &name, LIST_SEP)) {
1933 struct sockaddr_storage name_ss;
1935 /* copy any addersses from the auto lookup */
1937 if (strequal(name, "*")) {
1938 for (j=0; j<auto_count; j++) {
1939 char addr[INET6_ADDRSTRLEN];
1940 print_sockaddr(addr,
1941 sizeof(addr),
1942 &auto_ip_list[j].ss);
1943 /* Check for and don't copy any
1944 * known bad DC IP's. */
1945 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
1946 domain,
1947 addr))) {
1948 DEBUG(5,("get_dc_list: "
1949 "negative entry %s removed "
1950 "from DC list\n",
1951 addr));
1952 continue;
1954 return_iplist[local_count].ss =
1955 auto_ip_list[j].ss;
1956 return_iplist[local_count].port =
1957 auto_ip_list[j].port;
1958 local_count++;
1960 continue;
1963 /* added support for address:port syntax for ads
1964 * (not that I think anyone will ever run the LDAP
1965 * server in an AD domain on something other than
1966 * port 389 */
1968 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1969 if ((port_str=strchr(name, ':')) != NULL) {
1970 *port_str = '\0';
1971 port_str++;
1972 port = atoi(port_str);
1975 /* explicit lookup; resolve_name() will
1976 * handle names & IP addresses */
1977 if (resolve_name( name, &name_ss, 0x20, true )) {
1978 char addr[INET6_ADDRSTRLEN];
1979 print_sockaddr(addr,
1980 sizeof(addr),
1981 &name_ss);
1983 /* Check for and don't copy any known bad DC IP's. */
1984 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain,
1985 addr)) ) {
1986 DEBUG(5,("get_dc_list: negative entry %s "
1987 "removed from DC list\n",
1988 name ));
1989 continue;
1992 return_iplist[local_count].ss = name_ss;
1993 return_iplist[local_count].port = port;
1994 local_count++;
1995 *ordered = true;
1999 /* need to remove duplicates in the list if we have any
2000 explicit password servers */
2002 if (local_count) {
2003 local_count = remove_duplicate_addrs2(return_iplist,
2004 local_count );
2007 /* For DC's we always prioritize IPv4 due to W2K3 not
2008 * supporting LDAP, KRB5 or CLDAP over IPv6. */
2010 if (local_count && return_iplist) {
2011 prioritize_ipv4_list(return_iplist, local_count);
2014 if ( DEBUGLEVEL >= 4 ) {
2015 DEBUG(4,("get_dc_list: returning %d ip addresses "
2016 "in an %sordered list\n",
2017 local_count,
2018 *ordered ? "":"un"));
2019 DEBUG(4,("get_dc_list: "));
2020 for ( i=0; i<local_count; i++ ) {
2021 char addr[INET6_ADDRSTRLEN];
2022 print_sockaddr(addr,
2023 sizeof(addr),
2024 &return_iplist[i].ss);
2025 DEBUGADD(4,("%s:%d ", addr, return_iplist[i].port ));
2027 DEBUGADD(4,("\n"));
2030 *ip_list = return_iplist;
2031 *count = local_count;
2033 status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
2035 out:
2037 if (!NT_STATUS_IS_OK(status)) {
2038 SAFE_FREE(return_iplist);
2039 *ip_list = NULL;
2040 *count = 0;
2043 SAFE_FREE(auto_ip_list);
2044 TALLOC_FREE(ctx);
2045 return status;
2048 /*********************************************************************
2049 Small wrapper function to get the DC list and sort it if neccessary.
2050 *********************************************************************/
2052 NTSTATUS get_sorted_dc_list( const char *domain,
2053 const char *sitename,
2054 struct ip_service **ip_list,
2055 int *count,
2056 bool ads_only )
2058 bool ordered = false;
2059 NTSTATUS status;
2060 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
2062 *ip_list = NULL;
2063 *count = 0;
2065 DEBUG(8,("get_sorted_dc_list: attempting lookup "
2066 "for name %s (sitename %s) using [%s]\n",
2067 domain,
2068 sitename ? sitename : "NULL",
2069 (ads_only ? "ads" : lp_name_resolve_order())));
2071 if (ads_only) {
2072 lookup_type = DC_ADS_ONLY;
2075 status = get_dc_list(domain, sitename, ip_list,
2076 count, lookup_type, &ordered);
2077 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS)
2078 && sitename) {
2079 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
2080 " in site %s, fallback to all servers\n",
2081 domain, sitename));
2082 status = get_dc_list(domain, NULL, ip_list,
2083 count, lookup_type, &ordered);
2086 if (!NT_STATUS_IS_OK(status)) {
2087 SAFE_FREE(*ip_list);
2088 *count = 0;
2089 return status;
2092 /* only sort if we don't already have an ordered list */
2093 if (!ordered) {
2094 sort_service_list(*ip_list, *count);
2097 return NT_STATUS_OK;
2100 /*********************************************************************
2101 Get the KDC list - re-use all the logic in get_dc_list.
2102 *********************************************************************/
2104 NTSTATUS get_kdc_list( const char *realm,
2105 const char *sitename,
2106 struct ip_service **ip_list,
2107 int *count)
2109 bool ordered;
2110 NTSTATUS status;
2112 *count = 0;
2113 *ip_list = NULL;
2115 status = get_dc_list(realm, sitename, ip_list,
2116 count, DC_KDC_ONLY, &ordered);
2118 if (!NT_STATUS_IS_OK(status)) {
2119 SAFE_FREE(*ip_list);
2120 *count = 0;
2121 return status;
2124 /* only sort if we don't already have an ordered list */
2125 if ( !ordered ) {
2126 sort_service_list(*ip_list, *count);
2129 return NT_STATUS_OK;