r17143: svn merge -r17091:17138 ../SAMBA_3_0_23/
[Samba.git] / source / libsmb / namequery.c
blobf6dbe3c548347d3c5f4b0616df0f5e632fa8c20d
1 /*
2 Unix SMB/CIFS implementation.
3 name query routines
4 Copyright (C) Andrew Tridgell 1994-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 /* nmbd.c sets this to True. */
25 BOOL global_in_nmbd = False;
28 /****************************
29 * SERVER AFFINITY ROUTINES *
30 ****************************/
32 /* Server affinity is the concept of preferring the last domain
33 controller with whom you had a successful conversation */
35 /****************************************************************************
36 ****************************************************************************/
37 #define SAFKEY_FMT "SAF/DOMAIN/%s"
38 #define SAF_TTL 900
40 static char *saf_key(const char *domain)
42 char *keystr;
44 asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) );
46 return keystr;
49 /****************************************************************************
50 ****************************************************************************/
52 BOOL saf_store( const char *domain, const char *servername )
54 char *key;
55 time_t expire;
56 BOOL ret = False;
58 if ( !domain || !servername ) {
59 DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n"));
60 return False;
63 if ( !gencache_init() )
64 return False;
66 key = saf_key( domain );
67 expire = time( NULL ) + SAF_TTL;
70 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
71 domain, servername, (unsigned int)expire ));
73 ret = gencache_set( key, servername, expire );
75 SAFE_FREE( key );
77 return ret;
80 /****************************************************************************
81 ****************************************************************************/
83 char *saf_fetch( const char *domain )
85 char *server = NULL;
86 time_t timeout;
87 BOOL ret = False;
88 char *key = NULL;
90 if ( !domain ) {
91 DEBUG(2,("saf_fetch: Empty domain name!\n"));
92 return NULL;
95 if ( !gencache_init() )
96 return False;
98 key = saf_key( domain );
100 ret = gencache_get( key, &server, &timeout );
102 SAFE_FREE( key );
104 if ( !ret ) {
105 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain ));
106 } else {
107 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
108 server, domain ));
111 return server;
115 /****************************************************************************
116 Generate a random trn_id.
117 ****************************************************************************/
119 static int generate_trn_id(void)
121 static int trn_id;
123 if (trn_id == 0) {
124 sys_srandom(sys_getpid());
127 trn_id = sys_random();
129 return trn_id % (unsigned)0x7FFF;
132 /****************************************************************************
133 Parse a node status response into an array of structures.
134 ****************************************************************************/
136 static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra)
138 NODE_STATUS_STRUCT *ret;
139 int i;
141 *num_names = CVAL(p,0);
143 if (*num_names == 0)
144 return NULL;
146 ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
147 if (!ret)
148 return NULL;
150 p++;
151 for (i=0;i< *num_names;i++) {
152 StrnCpy(ret[i].name,p,15);
153 trim_char(ret[i].name,'\0',' ');
154 ret[i].type = CVAL(p,15);
155 ret[i].flags = p[16];
156 p += 18;
157 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
158 ret[i].type, ret[i].flags));
161 * Also, pick up the MAC address ...
163 if (extra) {
164 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
166 return ret;
170 /****************************************************************************
171 Do a NBT node status query on an open socket and return an array of
172 structures holding the returned names or NULL if the query failed.
173 **************************************************************************/
175 NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
176 struct in_addr to_ip, int *num_names,
177 struct node_status_extra *extra)
179 BOOL found=False;
180 int retries = 2;
181 int retry_time = 2000;
182 struct timeval tval;
183 struct packet_struct p;
184 struct packet_struct *p2;
185 struct nmb_packet *nmb = &p.packet.nmb;
186 NODE_STATUS_STRUCT *ret;
188 ZERO_STRUCT(p);
190 nmb->header.name_trn_id = generate_trn_id();
191 nmb->header.opcode = 0;
192 nmb->header.response = False;
193 nmb->header.nm_flags.bcast = False;
194 nmb->header.nm_flags.recursion_available = False;
195 nmb->header.nm_flags.recursion_desired = False;
196 nmb->header.nm_flags.trunc = False;
197 nmb->header.nm_flags.authoritative = False;
198 nmb->header.rcode = 0;
199 nmb->header.qdcount = 1;
200 nmb->header.ancount = 0;
201 nmb->header.nscount = 0;
202 nmb->header.arcount = 0;
203 nmb->question.question_name = *name;
204 nmb->question.question_type = 0x21;
205 nmb->question.question_class = 0x1;
207 p.ip = to_ip;
208 p.port = NMB_PORT;
209 p.fd = fd;
210 p.timestamp = time(NULL);
211 p.packet_type = NMB_PACKET;
213 GetTimeOfDay(&tval);
215 if (!send_packet(&p))
216 return NULL;
218 retries--;
220 while (1) {
221 struct timeval tval2;
222 GetTimeOfDay(&tval2);
223 if (TvalDiff(&tval,&tval2) > retry_time) {
224 if (!retries)
225 break;
226 if (!found && !send_packet(&p))
227 return NULL;
228 GetTimeOfDay(&tval);
229 retries--;
232 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
233 struct nmb_packet *nmb2 = &p2->packet.nmb;
234 debug_nmb_packet(p2);
236 if (nmb2->header.opcode != 0 ||
237 nmb2->header.nm_flags.bcast ||
238 nmb2->header.rcode ||
239 !nmb2->header.ancount ||
240 nmb2->answers->rr_type != 0x21) {
241 /* XXXX what do we do with this? could be a
242 redirect, but we'll discard it for the
243 moment */
244 free_packet(p2);
245 continue;
248 ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra);
249 free_packet(p2);
250 return ret;
254 return NULL;
257 /****************************************************************************
258 Find the first type XX name in a node status reply - used for finding
259 a servers name given its IP. Return the matched name in *name.
260 **************************************************************************/
262 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
264 NODE_STATUS_STRUCT *status = NULL;
265 struct nmb_name nname;
266 int count, i;
267 int sock;
268 BOOL result = False;
270 if (lp_disable_netbios()) {
271 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
272 return False;
275 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
276 q_type, inet_ntoa(to_ip)));
278 /* Check the cache first. */
280 if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
281 return True;
283 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
284 if (sock == -1)
285 goto done;
287 /* W2K PDC's seem not to respond to '*'#0. JRA */
288 make_nmb_name(&nname, q_name, q_type);
289 status = node_status_query(sock, &nname, to_ip, &count, NULL);
290 close(sock);
291 if (!status)
292 goto done;
294 for (i=0;i<count;i++) {
295 if (status[i].type == type)
296 break;
298 if (i == count)
299 goto done;
301 pull_ascii_nstring(name, sizeof(fstring), status[i].name);
303 /* Store the result in the cache. */
304 /* but don't store an entry for 0x1c names here. Here we have
305 a single host and DOMAIN<0x1c> names should be a list of hosts */
307 if ( q_type != 0x1c )
308 namecache_status_store(q_name, q_type, type, to_ip, name);
310 result = True;
312 done:
313 SAFE_FREE(status);
315 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
317 if (result)
318 DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
320 DEBUG(10, ("\n"));
322 return result;
326 comparison function used by sort_ip_list
329 static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
331 int max_bits1=0, max_bits2=0;
332 int num_interfaces = iface_count();
333 int i;
335 for (i=0;i<num_interfaces;i++) {
336 struct in_addr ip;
337 int bits1, bits2;
338 ip = *iface_n_bcast(i);
339 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
340 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
341 max_bits1 = MAX(bits1, max_bits1);
342 max_bits2 = MAX(bits2, max_bits2);
345 /* bias towards directly reachable IPs */
346 if (iface_local(*ip1)) {
347 max_bits1 += 32;
349 if (iface_local(*ip2)) {
350 max_bits2 += 32;
353 return max_bits2 - max_bits1;
356 /*******************************************************************
357 compare 2 ldap IPs by nearness to our interfaces - used in qsort
358 *******************************************************************/
360 static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
362 int result;
364 if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
365 return result;
367 if ( ip1->port > ip2->port )
368 return 1;
370 if ( ip1->port < ip2->port )
371 return -1;
373 return 0;
377 sort an IP list so that names that are close to one of our interfaces
378 are at the top. This prevents the problem where a WINS server returns an IP that
379 is not reachable from our subnet as the first match
382 static void sort_ip_list(struct in_addr *iplist, int count)
384 if (count <= 1) {
385 return;
388 qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
391 static void sort_ip_list2(struct ip_service *iplist, int count)
393 if (count <= 1) {
394 return;
397 qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare);
400 /**********************************************************************
401 Remove any duplicate address/port pairs in the list
402 *********************************************************************/
404 static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
406 int i, j;
408 DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
410 /* one loop to remove duplicates */
411 for ( i=0; i<count; i++ ) {
412 if ( is_zero_ip(iplist[i].ip) )
413 continue;
415 for ( j=i+1; j<count; j++ ) {
416 if ( ip_service_equal(iplist[i], iplist[j]) )
417 zero_ip(&iplist[j].ip);
421 /* one loop to clean up any holes we left */
422 /* first ip should never be a zero_ip() */
423 for (i = 0; i<count; ) {
424 if ( is_zero_ip(iplist[i].ip) ) {
425 if (i != count-1 )
426 memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
427 count--;
428 continue;
430 i++;
433 return count;
436 /****************************************************************************
437 Do a netbios name query to find someones IP.
438 Returns an array of IP addresses or NULL if none.
439 *count will be set to the number of addresses returned.
440 *timed_out is set if we failed by timing out
441 ****************************************************************************/
443 struct in_addr *name_query(int fd,const char *name,int name_type,
444 BOOL bcast,BOOL recurse,
445 struct in_addr to_ip, int *count, int *flags,
446 BOOL *timed_out)
448 BOOL found=False;
449 int i, retries = 3;
450 int retry_time = bcast?250:2000;
451 struct timeval tval;
452 struct packet_struct p;
453 struct packet_struct *p2;
454 struct nmb_packet *nmb = &p.packet.nmb;
455 struct in_addr *ip_list = NULL;
457 if (lp_disable_netbios()) {
458 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
459 return NULL;
462 if (timed_out) {
463 *timed_out = False;
466 memset((char *)&p,'\0',sizeof(p));
467 (*count) = 0;
468 (*flags) = 0;
470 nmb->header.name_trn_id = generate_trn_id();
471 nmb->header.opcode = 0;
472 nmb->header.response = False;
473 nmb->header.nm_flags.bcast = bcast;
474 nmb->header.nm_flags.recursion_available = False;
475 nmb->header.nm_flags.recursion_desired = recurse;
476 nmb->header.nm_flags.trunc = False;
477 nmb->header.nm_flags.authoritative = False;
478 nmb->header.rcode = 0;
479 nmb->header.qdcount = 1;
480 nmb->header.ancount = 0;
481 nmb->header.nscount = 0;
482 nmb->header.arcount = 0;
484 make_nmb_name(&nmb->question.question_name,name,name_type);
486 nmb->question.question_type = 0x20;
487 nmb->question.question_class = 0x1;
489 p.ip = to_ip;
490 p.port = NMB_PORT;
491 p.fd = fd;
492 p.timestamp = time(NULL);
493 p.packet_type = NMB_PACKET;
495 GetTimeOfDay(&tval);
497 if (!send_packet(&p))
498 return NULL;
500 retries--;
502 while (1) {
503 struct timeval tval2;
505 GetTimeOfDay(&tval2);
506 if (TvalDiff(&tval,&tval2) > retry_time) {
507 if (!retries)
508 break;
509 if (!found && !send_packet(&p))
510 return NULL;
511 GetTimeOfDay(&tval);
512 retries--;
515 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
516 struct nmb_packet *nmb2 = &p2->packet.nmb;
517 debug_nmb_packet(p2);
519 /* If we get a Negative Name Query Response from a WINS
520 * server, we should report it and give up.
522 if( 0 == nmb2->header.opcode /* A query response */
523 && !(bcast) /* from a WINS server */
524 && nmb2->header.rcode /* Error returned */
527 if( DEBUGLVL( 3 ) ) {
528 /* Only executed if DEBUGLEVEL >= 3 */
529 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
530 switch( nmb2->header.rcode ) {
531 case 0x01:
532 dbgtext( "Request was invalidly formatted.\n" );
533 break;
534 case 0x02:
535 dbgtext( "Problem with NBNS, cannot process name.\n");
536 break;
537 case 0x03:
538 dbgtext( "The name requested does not exist.\n" );
539 break;
540 case 0x04:
541 dbgtext( "Unsupported request error.\n" );
542 break;
543 case 0x05:
544 dbgtext( "Query refused error.\n" );
545 break;
546 default:
547 dbgtext( "Unrecognized error code.\n" );
548 break;
551 free_packet(p2);
552 return( NULL );
555 if (nmb2->header.opcode != 0 ||
556 nmb2->header.nm_flags.bcast ||
557 nmb2->header.rcode ||
558 !nmb2->header.ancount) {
560 * XXXX what do we do with this? Could be a
561 * redirect, but we'll discard it for the
562 * moment.
564 free_packet(p2);
565 continue;
568 ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr,
569 (*count) + nmb2->answers->rdlength/6 );
571 if (!ip_list) {
572 DEBUG(0,("name_query: Realloc failed.\n"));
573 free_packet(p2);
574 return( NULL );
577 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
578 for (i=0;i<nmb2->answers->rdlength/6;i++) {
579 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
580 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
581 (*count)++;
583 DEBUGADD(2,(")\n"));
585 found=True;
586 retries=0;
587 /* We add the flags back ... */
588 if (nmb2->header.response)
589 (*flags) |= NM_FLAGS_RS;
590 if (nmb2->header.nm_flags.authoritative)
591 (*flags) |= NM_FLAGS_AA;
592 if (nmb2->header.nm_flags.trunc)
593 (*flags) |= NM_FLAGS_TC;
594 if (nmb2->header.nm_flags.recursion_desired)
595 (*flags) |= NM_FLAGS_RD;
596 if (nmb2->header.nm_flags.recursion_available)
597 (*flags) |= NM_FLAGS_RA;
598 if (nmb2->header.nm_flags.bcast)
599 (*flags) |= NM_FLAGS_B;
600 free_packet(p2);
602 * If we're doing a unicast lookup we only
603 * expect one reply. Don't wait the full 2
604 * seconds if we got one. JRA.
606 if(!bcast && found)
607 break;
611 /* only set timed_out if we didn't fund what we where looking for*/
613 if ( !found && timed_out ) {
614 *timed_out = True;
617 /* sort the ip list so we choose close servers first if possible */
618 sort_ip_list(ip_list, *count);
620 return ip_list;
623 /********************************************************
624 Start parsing the lmhosts file.
625 *********************************************************/
627 XFILE *startlmhosts(char *fname)
629 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
630 if (!fp) {
631 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
632 fname, strerror(errno)));
633 return NULL;
635 return fp;
638 /********************************************************
639 Parse the next line in the lmhosts file.
640 *********************************************************/
642 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
644 pstring line;
646 while(!x_feof(fp) && !x_ferror(fp)) {
647 pstring ip,flags,extra;
648 const char *ptr;
649 char *ptr1;
650 int count = 0;
652 *name_type = -1;
654 if (!fgets_slash(line,sizeof(pstring),fp)) {
655 continue;
658 if (*line == '#') {
659 continue;
662 pstrcpy(ip,"");
663 pstrcpy(name,"");
664 pstrcpy(flags,"");
666 ptr = line;
668 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
669 ++count;
670 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
671 ++count;
672 if (next_token(&ptr,flags,NULL, sizeof(flags)))
673 ++count;
674 if (next_token(&ptr,extra,NULL, sizeof(extra)))
675 ++count;
677 if (count <= 0)
678 continue;
680 if (count > 0 && count < 2) {
681 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
682 continue;
685 if (count >= 4) {
686 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
687 continue;
690 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
692 if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
693 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
694 continue;
697 *ipaddr = *interpret_addr2(ip);
699 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
700 then only add that name type. */
701 if((ptr1 = strchr_m(name, '#')) != NULL) {
702 char *endptr;
703 ptr1++;
705 *name_type = (int)strtol(ptr1, &endptr, 16);
706 if(!*ptr1 || (endptr == ptr1)) {
707 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
708 continue;
711 *(--ptr1) = '\0'; /* Truncate at the '#' */
714 return True;
717 return False;
720 /********************************************************
721 Finish parsing the lmhosts file.
722 *********************************************************/
724 void endlmhosts(XFILE *fp)
726 x_fclose(fp);
729 /********************************************************
730 convert an array if struct in_addrs to struct ip_service
731 return False on failure. Port is set to PORT_NONE;
732 *********************************************************/
734 static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
736 int i;
738 if ( count==0 || !ip_list )
739 return False;
741 /* copy the ip address; port will be PORT_NONE */
742 if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
743 DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
744 return False;
747 for ( i=0; i<count; i++ ) {
748 (*return_iplist)[i].ip = ip_list[i];
749 (*return_iplist)[i].port = PORT_NONE;
752 return True;
754 /********************************************************
755 Resolve via "bcast" method.
756 *********************************************************/
758 BOOL name_resolve_bcast(const char *name, int name_type,
759 struct ip_service **return_iplist, int *return_count)
761 int sock, i;
762 int num_interfaces = iface_count();
763 struct in_addr *ip_list;
764 BOOL ret;
766 if (lp_disable_netbios()) {
767 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
768 return False;
771 *return_iplist = NULL;
772 *return_count = 0;
775 * "bcast" means do a broadcast lookup on all the local interfaces.
778 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
780 sock = open_socket_in( SOCK_DGRAM, 0, 3,
781 interpret_addr(lp_socket_address()), True );
783 if (sock == -1) return False;
785 set_socket_options(sock,"SO_BROADCAST");
787 * Lookup the name on all the interfaces, return on
788 * the first successful match.
790 for( i = num_interfaces-1; i >= 0; i--) {
791 struct in_addr sendto_ip;
792 int flags;
793 /* Done this way to fix compiler error on IRIX 5.x */
794 sendto_ip = *iface_n_bcast(i);
795 ip_list = name_query(sock, name, name_type, True,
796 True, sendto_ip, return_count, &flags, NULL);
797 if( ip_list )
798 goto success;
801 /* failed - no response */
803 close(sock);
804 return False;
806 success:
807 ret = True;
808 if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
809 ret = False;
811 SAFE_FREE( ip_list );
812 close(sock);
813 return ret;
816 /********************************************************
817 Resolve via "wins" method.
818 *********************************************************/
820 BOOL resolve_wins(const char *name, int name_type,
821 struct ip_service **return_iplist, int *return_count)
823 int sock, t, i;
824 char **wins_tags;
825 struct in_addr src_ip, *ip_list = NULL;
826 BOOL ret;
828 if (lp_disable_netbios()) {
829 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
830 return False;
833 *return_iplist = NULL;
834 *return_count = 0;
836 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
838 if (wins_srv_count() < 1) {
839 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
840 return False;
843 /* we try a lookup on each of the WINS tags in turn */
844 wins_tags = wins_srv_tags();
846 if (!wins_tags) {
847 /* huh? no tags?? give up in disgust */
848 return False;
851 /* the address we will be sending from */
852 src_ip = *interpret_addr2(lp_socket_address());
854 /* in the worst case we will try every wins server with every
855 tag! */
856 for (t=0; wins_tags && wins_tags[t]; t++) {
857 int srv_count = wins_srv_count_tag(wins_tags[t]);
858 for (i=0; i<srv_count; i++) {
859 struct in_addr wins_ip;
860 int flags;
861 BOOL timed_out;
863 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
865 if (global_in_nmbd && ismyip(wins_ip)) {
866 /* yikes! we'll loop forever */
867 continue;
870 /* skip any that have been unresponsive lately */
871 if (wins_srv_is_dead(wins_ip, src_ip)) {
872 continue;
875 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
877 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
878 if (sock == -1) {
879 continue;
882 ip_list = name_query(sock,name,name_type, False,
883 True, wins_ip, return_count, &flags,
884 &timed_out);
886 /* exit loop if we got a list of addresses */
888 if ( ip_list )
889 goto success;
891 close(sock);
893 if (timed_out) {
894 /* Timed out wating for WINS server to respond. Mark it dead. */
895 wins_srv_died(wins_ip, src_ip);
896 } else {
897 /* The name definately isn't in this
898 group of WINS servers. goto the next group */
899 break;
904 wins_srv_tags_free(wins_tags);
905 return False;
907 success:
908 ret = True;
909 if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
910 ret = False;
912 SAFE_FREE( ip_list );
913 wins_srv_tags_free(wins_tags);
914 close(sock);
916 return ret;
919 /********************************************************
920 Resolve via "lmhosts" method.
921 *********************************************************/
923 static BOOL resolve_lmhosts(const char *name, int name_type,
924 struct ip_service **return_iplist, int *return_count)
927 * "lmhosts" means parse the local lmhosts file.
930 XFILE *fp;
931 pstring lmhost_name;
932 int name_type2;
933 struct in_addr return_ip;
934 BOOL result = False;
936 *return_iplist = NULL;
937 *return_count = 0;
939 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
941 fp = startlmhosts(dyn_LMHOSTSFILE);
943 if ( fp == NULL )
944 return False;
946 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip))
949 if (!strequal(name, lmhost_name))
950 continue;
952 if ((name_type2 != -1) && (name_type != name_type2))
953 continue;
955 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service,
956 (*return_count)+1);
958 if ((*return_iplist) == NULL) {
959 endlmhosts(fp);
960 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
961 return False;
964 (*return_iplist)[*return_count].ip = return_ip;
965 (*return_iplist)[*return_count].port = PORT_NONE;
966 *return_count += 1;
968 /* we found something */
969 result = True;
971 /* Multiple names only for DC lookup */
972 if (name_type != 0x1c)
973 break;
976 endlmhosts(fp);
978 return result;
982 /********************************************************
983 Resolve via "hosts" method.
984 *********************************************************/
986 static BOOL resolve_hosts(const char *name, int name_type,
987 struct ip_service **return_iplist, int *return_count)
990 * "host" means do a localhost, or dns lookup.
992 struct hostent *hp;
994 if ( name_type != 0x20 && name_type != 0x0) {
995 DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
996 return False;
999 *return_iplist = NULL;
1000 *return_count = 0;
1002 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
1004 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
1005 struct in_addr return_ip;
1006 putip((char *)&return_ip,(char *)hp->h_addr);
1007 *return_iplist = SMB_MALLOC_P(struct ip_service);
1008 if(*return_iplist == NULL) {
1009 DEBUG(3,("resolve_hosts: malloc fail !\n"));
1010 return False;
1012 (*return_iplist)->ip = return_ip;
1013 (*return_iplist)->port = PORT_NONE;
1014 *return_count = 1;
1015 return True;
1017 return False;
1020 /********************************************************
1021 Resolve via "ADS" method.
1022 *********************************************************/
1024 static BOOL resolve_ads(const char *name, int name_type,
1025 struct ip_service **return_iplist, int *return_count)
1027 int i = 0;
1028 NTSTATUS status;
1029 TALLOC_CTX *ctx;
1030 struct dns_rr_srv *dcs = NULL;
1031 int numdcs = 0;
1033 if ( name_type != 0x1c )
1034 return False;
1036 DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n",
1037 name));
1039 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1040 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1041 return False;
1044 status = ads_dns_query_dcs( ctx, name, &dcs, &numdcs );
1045 if ( !NT_STATUS_IS_OK( status ) ) {
1046 return False;
1049 if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numdcs)) == NULL ) {
1050 DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numdcs ));
1051 return False;
1054 *return_count = 0;
1056 for (i=0;i<numdcs;i++) {
1057 struct ip_service *r = &(*return_iplist)[*return_count];
1059 /* use the IP address from the SRV structure if we have one */
1060 if ( is_zero_ip( dcs[i].ip ) )
1061 r->ip = *interpret_addr2(dcs[i].hostname);
1062 else
1063 r->ip = dcs[i].ip;
1065 r->port = dcs[i].port;
1067 /* make sure it is a valid IP. I considered checking the negative
1068 connection cache, but this is the wrong place for it. Maybe only
1069 as a hac. After think about it, if all of the IP addresses retuend
1070 from DNS are dead, what hope does a netbios name lookup have?
1071 The standard reason for falling back to netbios lookups is that
1072 our DNS server doesn't know anything about the DC's -- jerry */
1074 if ( ! is_zero_ip(r->ip) )
1075 (*return_count)++;
1078 TALLOC_FREE( dcs );
1080 return True;
1083 /*******************************************************************
1084 Internal interface to resolve a name into an IP address.
1085 Use this function if the string is either an IP address, DNS
1086 or host name or NetBIOS name. This uses the name switch in the
1087 smb.conf to determine the order of name resolution.
1089 Added support for ip addr/port to support ADS ldap servers.
1090 the only place we currently care about the port is in the
1091 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1092 **********************************************************************/
1094 BOOL internal_resolve_name(const char *name, int name_type,
1095 struct ip_service **return_iplist,
1096 int *return_count, const char *resolve_order)
1098 pstring name_resolve_list;
1099 fstring tok;
1100 const char *ptr;
1101 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
1102 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
1103 BOOL is_address = is_ipaddress(name);
1104 BOOL result = False;
1105 int i;
1107 *return_iplist = NULL;
1108 *return_count = 0;
1110 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
1112 if (allzeros || allones || is_address) {
1114 if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
1115 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1116 return False;
1119 if(is_address) {
1120 /* ignore the port here */
1121 (*return_iplist)->port = PORT_NONE;
1123 /* if it's in the form of an IP address then get the lib to interpret it */
1124 if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1125 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1126 SAFE_FREE(*return_iplist);
1127 return False;
1129 } else {
1130 (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1132 *return_count = 1;
1133 return True;
1136 /* Check name cache */
1138 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1139 /* This could be a negative response */
1140 return (*return_count > 0);
1143 /* set the name resolution order */
1145 if ( strcmp( resolve_order, "NULL") == 0 ) {
1146 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1147 return False;
1150 if ( !resolve_order ) {
1151 pstrcpy(name_resolve_list, lp_name_resolve_order());
1152 } else {
1153 pstrcpy(name_resolve_list, resolve_order);
1155 if ( !name_resolve_list[0] ) {
1156 ptr = "host";
1157 } else {
1158 ptr = name_resolve_list;
1161 /* iterate through the name resolution backends */
1163 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1164 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1165 if (resolve_hosts(name, name_type, return_iplist, return_count)) {
1166 result = True;
1167 goto done;
1169 } else if(strequal( tok, "ads")) {
1170 /* deal with 0x1c names here. This will result in a
1171 SRV record lookup */
1172 if (resolve_ads(name, name_type, return_iplist, return_count)) {
1173 result = True;
1174 goto done;
1176 } else if(strequal( tok, "lmhosts")) {
1177 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
1178 result = True;
1179 goto done;
1181 } else if(strequal( tok, "wins")) {
1182 /* don't resolve 1D via WINS */
1183 if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) {
1184 result = True;
1185 goto done;
1187 } else if(strequal( tok, "bcast")) {
1188 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
1189 result = True;
1190 goto done;
1192 } else {
1193 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
1197 /* All of the resolve_* functions above have returned false. */
1199 SAFE_FREE(*return_iplist);
1200 *return_count = 0;
1202 return False;
1204 done:
1206 /* Remove duplicate entries. Some queries, notably #1c (domain
1207 controllers) return the PDC in iplist[0] and then all domain
1208 controllers including the PDC in iplist[1..n]. Iterating over
1209 the iplist when the PDC is down will cause two sets of timeouts. */
1211 if ( *return_count ) {
1212 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1215 /* Save in name cache */
1216 if ( DEBUGLEVEL >= 100 ) {
1217 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1218 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1219 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1222 namecache_store(name, name_type, *return_count, *return_iplist);
1224 /* Display some debugging info */
1226 if ( DEBUGLEVEL >= 10 ) {
1227 DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
1229 for (i = 0; i < *return_count; i++) {
1230 DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1232 DEBUG(10, ("\n"));
1236 return result;
1239 /********************************************************
1240 Internal interface to resolve a name into one IP address.
1241 Use this function if the string is either an IP address, DNS
1242 or host name or NetBIOS name. This uses the name switch in the
1243 smb.conf to determine the order of name resolution.
1244 *********************************************************/
1246 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1248 struct ip_service *ip_list = NULL;
1249 int count = 0;
1251 if (is_ipaddress(name)) {
1252 *return_ip = *interpret_addr2(name);
1253 return True;
1256 if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
1257 int i;
1259 /* only return valid addresses for TCP connections */
1260 for (i=0; i<count; i++) {
1261 char *ip_str = inet_ntoa(ip_list[i].ip);
1262 if (ip_str &&
1263 strcmp(ip_str, "255.255.255.255") != 0 &&
1264 strcmp(ip_str, "0.0.0.0") != 0)
1266 *return_ip = ip_list[i].ip;
1267 SAFE_FREE(ip_list);
1268 return True;
1273 SAFE_FREE(ip_list);
1274 return False;
1277 /********************************************************
1278 Find the IP address of the master browser or DMB for a workgroup.
1279 *********************************************************/
1281 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
1283 struct ip_service *ip_list = NULL;
1284 int count = 0;
1286 if (lp_disable_netbios()) {
1287 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1288 return False;
1291 if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
1292 *master_ip = ip_list[0].ip;
1293 SAFE_FREE(ip_list);
1294 return True;
1296 if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
1297 *master_ip = ip_list[0].ip;
1298 SAFE_FREE(ip_list);
1299 return True;
1302 SAFE_FREE(ip_list);
1303 return False;
1306 /********************************************************
1307 Get the IP address list of the primary domain controller
1308 for a domain.
1309 *********************************************************/
1311 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1313 struct ip_service *ip_list;
1314 int count;
1316 /* Look up #1B name */
1318 if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order())) {
1319 return False;
1322 /* if we get more than 1 IP back we have to assume it is a
1323 multi-homed PDC and not a mess up */
1325 if ( count > 1 ) {
1326 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1327 sort_ip_list2( ip_list, count );
1330 *ip = ip_list[0].ip;
1332 SAFE_FREE(ip_list);
1334 return True;
1337 /********************************************************
1338 Get the IP address list of the domain controllers for
1339 a domain.
1340 *********************************************************/
1342 static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
1343 int *count, BOOL ads_only, int *ordered)
1345 fstring resolve_order;
1346 char *saf_servername;
1347 pstring pserver;
1348 const char *p;
1349 char *port_str;
1350 int port;
1351 fstring name;
1352 int num_addresses = 0;
1353 int local_count, i, j;
1354 struct ip_service *return_iplist = NULL;
1355 struct ip_service *auto_ip_list = NULL;
1356 BOOL done_auto_lookup = False;
1357 int auto_count = 0;
1359 /* if we are restricted to solely using DNS for looking
1360 up a domain controller, make sure that host lookups
1361 are enabled for the 'name resolve order'. If host lookups
1362 are disabled and ads_only is True, then set the string to
1363 NULL. */
1365 fstrcpy( resolve_order, lp_name_resolve_order() );
1366 strlower_m( resolve_order );
1367 if ( ads_only ) {
1368 if ( strstr( resolve_order, "host" ) )
1369 fstrcpy( resolve_order, "ads" );
1370 else
1371 fstrcpy( resolve_order, "NULL" );
1374 *ordered = False;
1376 /* fetch the server we have affinity for. Add the
1377 'password server' list to a search for our domain controllers */
1379 saf_servername = saf_fetch( domain );
1381 if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1382 pstr_sprintf( pserver, "%s, %s",
1383 saf_servername ? saf_servername : "",
1384 lp_passwordserver() );
1385 } else {
1386 pstr_sprintf( pserver, "%s, *",
1387 saf_servername ? saf_servername : "" );
1390 SAFE_FREE( saf_servername );
1392 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1394 if ( !*pserver ) {
1395 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1396 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1399 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1402 * if '*' appears in the "password server" list then add
1403 * an auto lookup to the list of manually configured
1404 * DC's. If any DC is listed by name, then the list should be
1405 * considered to be ordered
1408 p = pserver;
1409 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1410 if (strequal(name, "*")) {
1411 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) )
1412 num_addresses += auto_count;
1413 done_auto_lookup = True;
1414 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1415 } else {
1416 num_addresses++;
1420 /* if we have no addresses and haven't done the auto lookup, then
1421 just return the list of DC's. Or maybe we just failed. */
1423 if ( (num_addresses == 0) ) {
1424 if ( !done_auto_lookup ) {
1425 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1426 } else {
1427 DEBUG(4,("get_dc_list: no servers found\n"));
1428 return False;
1432 if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
1433 DEBUG(3,("get_dc_list: malloc fail !\n"));
1434 return False;
1437 p = pserver;
1438 local_count = 0;
1440 /* fill in the return list now with real IP's */
1442 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1443 struct in_addr name_ip;
1445 /* copy any addersses from the auto lookup */
1447 if ( strequal(name, "*") ) {
1448 for ( j=0; j<auto_count; j++ ) {
1449 /* Check for and don't copy any known bad DC IP's. */
1450 if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain,
1451 inet_ntoa(auto_ip_list[j].ip)))) {
1452 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
1453 inet_ntoa(auto_ip_list[j].ip) ));
1454 continue;
1456 return_iplist[local_count].ip = auto_ip_list[j].ip;
1457 return_iplist[local_count].port = auto_ip_list[j].port;
1458 local_count++;
1460 continue;
1464 /* added support for address:port syntax for ads (not that I think
1465 anyone will ever run the LDAP server in an AD domain on something
1466 other than port 389 */
1468 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1469 if ( (port_str=strchr(name, ':')) != NULL ) {
1470 *port_str = '\0';
1471 port_str++;
1472 port = atoi( port_str );
1475 /* explicit lookup; resolve_name() will handle names & IP addresses */
1476 if ( resolve_name( name, &name_ip, 0x20 ) ) {
1478 /* Check for and don't copy any known bad DC IP's. */
1479 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
1480 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
1481 continue;
1484 return_iplist[local_count].ip = name_ip;
1485 return_iplist[local_count].port = port;
1486 local_count++;
1487 *ordered = True;
1491 SAFE_FREE(auto_ip_list);
1493 /* need to remove duplicates in the list if we have any
1494 explicit password servers */
1496 if ( local_count ) {
1497 local_count = remove_duplicate_addrs2( return_iplist, local_count );
1500 if ( DEBUGLEVEL >= 4 ) {
1501 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
1502 *ordered ? "":"un"));
1503 DEBUG(4,("get_dc_list: "));
1504 for ( i=0; i<local_count; i++ )
1505 DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1506 DEBUGADD(4,("\n"));
1509 *ip_list = return_iplist;
1510 *count = local_count;
1512 return (*count != 0);
1515 /*********************************************************************
1516 Small wrapper function to get the DC list and sort it if neccessary.
1517 *********************************************************************/
1519 BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only )
1521 BOOL ordered;
1523 DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
1524 (ads_only ? "ads" : lp_name_resolve_order())));
1526 if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) {
1527 return False;
1530 /* only sort if we don't already have an ordered list */
1531 if ( !ordered ) {
1532 sort_ip_list2( *ip_list, *count );
1535 return True;