r248: Add support for printing out the MAC address on nmblookup.
[Samba/gebeck_regimport.git] / source3 / libsmb / namequery.c
blob2bb7359e742e2cbf779fa65936d9d1cfa8217ee9
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;
27 /****************************************************************************
28 Generate a random trn_id.
29 ****************************************************************************/
31 static int generate_trn_id(void)
33 static int trn_id;
35 if (trn_id == 0) {
36 sys_srandom(sys_getpid());
39 trn_id = sys_random();
41 return trn_id % (unsigned)0x7FFF;
44 /****************************************************************************
45 Parse a node status response into an array of structures.
46 ****************************************************************************/
48 static struct node_status *parse_node_status(char *p, int *num_names, struct node_status_extra *extra)
50 struct node_status *ret;
51 int i;
53 *num_names = CVAL(p,0);
55 if (*num_names == 0)
56 return NULL;
58 ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
59 if (!ret) return NULL;
61 p++;
62 for (i=0;i< *num_names;i++) {
63 StrnCpy(ret[i].name,p,15);
64 trim_char(ret[i].name,'\0',' ');
65 ret[i].type = CVAL(p,15);
66 ret[i].flags = p[16];
67 p += 18;
68 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
69 ret[i].type, ret[i].flags));
72 * Also, pick up the MAC address ...
74 if (extra) {
75 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
77 return ret;
81 /****************************************************************************
82 Do a NBT node status query on an open socket and return an array of
83 structures holding the returned names or NULL if the query failed.
84 **************************************************************************/
86 struct node_status *node_status_query(int fd,struct nmb_name *name,
87 struct in_addr to_ip, int *num_names,
88 struct node_status_extra *extra)
90 BOOL found=False;
91 int retries = 2;
92 int retry_time = 2000;
93 struct timeval tval;
94 struct packet_struct p;
95 struct packet_struct *p2;
96 struct nmb_packet *nmb = &p.packet.nmb;
97 struct node_status *ret;
99 ZERO_STRUCT(p);
101 nmb->header.name_trn_id = generate_trn_id();
102 nmb->header.opcode = 0;
103 nmb->header.response = False;
104 nmb->header.nm_flags.bcast = False;
105 nmb->header.nm_flags.recursion_available = False;
106 nmb->header.nm_flags.recursion_desired = False;
107 nmb->header.nm_flags.trunc = False;
108 nmb->header.nm_flags.authoritative = False;
109 nmb->header.rcode = 0;
110 nmb->header.qdcount = 1;
111 nmb->header.ancount = 0;
112 nmb->header.nscount = 0;
113 nmb->header.arcount = 0;
114 nmb->question.question_name = *name;
115 nmb->question.question_type = 0x21;
116 nmb->question.question_class = 0x1;
118 p.ip = to_ip;
119 p.port = NMB_PORT;
120 p.fd = fd;
121 p.timestamp = time(NULL);
122 p.packet_type = NMB_PACKET;
124 GetTimeOfDay(&tval);
126 if (!send_packet(&p))
127 return NULL;
129 retries--;
131 while (1) {
132 struct timeval tval2;
133 GetTimeOfDay(&tval2);
134 if (TvalDiff(&tval,&tval2) > retry_time) {
135 if (!retries)
136 break;
137 if (!found && !send_packet(&p))
138 return NULL;
139 GetTimeOfDay(&tval);
140 retries--;
143 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
144 struct nmb_packet *nmb2 = &p2->packet.nmb;
145 debug_nmb_packet(p2);
147 if (nmb2->header.opcode != 0 ||
148 nmb2->header.nm_flags.bcast ||
149 nmb2->header.rcode ||
150 !nmb2->header.ancount ||
151 nmb2->answers->rr_type != 0x21) {
152 /* XXXX what do we do with this? could be a
153 redirect, but we'll discard it for the
154 moment */
155 free_packet(p2);
156 continue;
159 ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra);
160 free_packet(p2);
161 return ret;
165 return NULL;
168 /****************************************************************************
169 Find the first type XX name in a node status reply - used for finding
170 a servers name given its IP. Return the matched name in *name.
171 **************************************************************************/
173 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
175 struct node_status *status = NULL;
176 struct nmb_name nname;
177 int count, i;
178 int sock;
179 BOOL result = False;
181 if (lp_disable_netbios()) {
182 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
183 return False;
186 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
187 q_type, inet_ntoa(to_ip)));
189 /* Check the cache first. */
191 if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
192 return True;
194 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
195 if (sock == -1)
196 goto done;
198 /* W2K PDC's seem not to respond to '*'#0. JRA */
199 make_nmb_name(&nname, q_name, q_type);
200 status = node_status_query(sock, &nname, to_ip, &count, NULL);
201 close(sock);
202 if (!status)
203 goto done;
205 for (i=0;i<count;i++) {
206 if (status[i].type == type)
207 break;
209 if (i == count)
210 goto done;
212 pull_ascii_nstring(name, sizeof(fstring), status[i].name);
214 /* Store the result in the cache. */
215 /* but don't store an entry for 0x1c names here. Here we have
216 a single host and DOMAIN<0x1c> names should be a list of hosts */
218 if ( q_type != 0x1c )
219 namecache_status_store(q_name, q_type, type, to_ip, name);
221 result = True;
223 done:
224 SAFE_FREE(status);
226 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
228 if (result)
229 DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
231 DEBUG(10, ("\n"));
233 return result;
237 comparison function used by sort_ip_list
240 static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
242 int max_bits1=0, max_bits2=0;
243 int num_interfaces = iface_count();
244 int i;
246 for (i=0;i<num_interfaces;i++) {
247 struct in_addr ip;
248 int bits1, bits2;
249 ip = *iface_n_bcast(i);
250 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
251 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
252 max_bits1 = MAX(bits1, max_bits1);
253 max_bits2 = MAX(bits2, max_bits2);
256 /* bias towards directly reachable IPs */
257 if (iface_local(*ip1)) {
258 max_bits1 += 32;
260 if (iface_local(*ip2)) {
261 max_bits2 += 32;
264 return max_bits2 - max_bits1;
267 /*******************************************************************
268 compare 2 ldap IPs by nearness to our interfaces - used in qsort
269 *******************************************************************/
271 static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
273 int result;
275 if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
276 return result;
278 if ( ip1->port > ip2->port )
279 return 1;
281 if ( ip1->port < ip2->port )
282 return -1;
284 return 0;
288 sort an IP list so that names that are close to one of our interfaces
289 are at the top. This prevents the problem where a WINS server returns an IP that
290 is not reachable from our subnet as the first match
293 static void sort_ip_list(struct in_addr *iplist, int count)
295 if (count <= 1) {
296 return;
299 qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
302 static void sort_ip_list2(struct ip_service *iplist, int count)
304 if (count <= 1) {
305 return;
308 qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare);
311 /**********************************************************************
312 Remove any duplicate address/port pairs in the list
313 *********************************************************************/
315 static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
317 int i, j;
319 DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
321 /* one loop to remove duplicates */
322 for ( i=0; i<count; i++ ) {
323 if ( is_zero_ip(iplist[i].ip) )
324 continue;
326 for ( j=i+1; j<count; j++ ) {
327 if ( ip_service_equal(iplist[i], iplist[j]) )
328 zero_ip(&iplist[j].ip);
332 /* one loop to clean up any holes we left */
333 /* first ip should never be a zero_ip() */
334 for (i = 0; i<count; ) {
335 if ( is_zero_ip(iplist[i].ip) ) {
336 if (i != count-1 )
337 memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
338 count--;
339 continue;
341 i++;
344 return count;
347 /****************************************************************************
348 Do a netbios name query to find someones IP.
349 Returns an array of IP addresses or NULL if none.
350 *count will be set to the number of addresses returned.
351 *timed_out is set if we failed by timing out
352 ****************************************************************************/
354 struct in_addr *name_query(int fd,const char *name,int name_type,
355 BOOL bcast,BOOL recurse,
356 struct in_addr to_ip, int *count, int *flags,
357 BOOL *timed_out)
359 BOOL found=False;
360 int i, retries = 3;
361 int retry_time = bcast?250:2000;
362 struct timeval tval;
363 struct packet_struct p;
364 struct packet_struct *p2;
365 struct nmb_packet *nmb = &p.packet.nmb;
366 struct in_addr *ip_list = NULL;
368 if (lp_disable_netbios()) {
369 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
370 return NULL;
373 if (timed_out) {
374 *timed_out = False;
377 memset((char *)&p,'\0',sizeof(p));
378 (*count) = 0;
379 (*flags) = 0;
381 nmb->header.name_trn_id = generate_trn_id();
382 nmb->header.opcode = 0;
383 nmb->header.response = False;
384 nmb->header.nm_flags.bcast = bcast;
385 nmb->header.nm_flags.recursion_available = False;
386 nmb->header.nm_flags.recursion_desired = recurse;
387 nmb->header.nm_flags.trunc = False;
388 nmb->header.nm_flags.authoritative = False;
389 nmb->header.rcode = 0;
390 nmb->header.qdcount = 1;
391 nmb->header.ancount = 0;
392 nmb->header.nscount = 0;
393 nmb->header.arcount = 0;
395 make_nmb_name(&nmb->question.question_name,name,name_type);
397 nmb->question.question_type = 0x20;
398 nmb->question.question_class = 0x1;
400 p.ip = to_ip;
401 p.port = NMB_PORT;
402 p.fd = fd;
403 p.timestamp = time(NULL);
404 p.packet_type = NMB_PACKET;
406 GetTimeOfDay(&tval);
408 if (!send_packet(&p))
409 return NULL;
411 retries--;
413 while (1) {
414 struct timeval tval2;
415 struct in_addr *tmp_ip_list;
417 GetTimeOfDay(&tval2);
418 if (TvalDiff(&tval,&tval2) > retry_time) {
419 if (!retries)
420 break;
421 if (!found && !send_packet(&p))
422 return NULL;
423 GetTimeOfDay(&tval);
424 retries--;
427 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
428 struct nmb_packet *nmb2 = &p2->packet.nmb;
429 debug_nmb_packet(p2);
431 /* If we get a Negative Name Query Response from a WINS
432 * server, we should report it and give up.
434 if( 0 == nmb2->header.opcode /* A query response */
435 && !(bcast) /* from a WINS server */
436 && nmb2->header.rcode /* Error returned */
439 if( DEBUGLVL( 3 ) ) {
440 /* Only executed if DEBUGLEVEL >= 3 */
441 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
442 switch( nmb2->header.rcode ) {
443 case 0x01:
444 dbgtext( "Request was invalidly formatted.\n" );
445 break;
446 case 0x02:
447 dbgtext( "Problem with NBNS, cannot process name.\n");
448 break;
449 case 0x03:
450 dbgtext( "The name requested does not exist.\n" );
451 break;
452 case 0x04:
453 dbgtext( "Unsupported request error.\n" );
454 break;
455 case 0x05:
456 dbgtext( "Query refused error.\n" );
457 break;
458 default:
459 dbgtext( "Unrecognized error code.\n" );
460 break;
463 free_packet(p2);
464 return( NULL );
467 if (nmb2->header.opcode != 0 ||
468 nmb2->header.nm_flags.bcast ||
469 nmb2->header.rcode ||
470 !nmb2->header.ancount) {
472 * XXXX what do we do with this? Could be a
473 * redirect, but we'll discard it for the
474 * moment.
476 free_packet(p2);
477 continue;
480 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
481 * ( (*count) + nmb2->answers->rdlength/6 ) );
483 if (!tmp_ip_list) {
484 DEBUG(0,("name_query: Realloc failed.\n"));
485 SAFE_FREE(ip_list);
488 ip_list = tmp_ip_list;
490 if (ip_list) {
491 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
492 for (i=0;i<nmb2->answers->rdlength/6;i++) {
493 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
494 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
495 (*count)++;
497 DEBUGADD(2,(")\n"));
500 found=True;
501 retries=0;
502 /* We add the flags back ... */
503 if (nmb2->header.response)
504 (*flags) |= NM_FLAGS_RS;
505 if (nmb2->header.nm_flags.authoritative)
506 (*flags) |= NM_FLAGS_AA;
507 if (nmb2->header.nm_flags.trunc)
508 (*flags) |= NM_FLAGS_TC;
509 if (nmb2->header.nm_flags.recursion_desired)
510 (*flags) |= NM_FLAGS_RD;
511 if (nmb2->header.nm_flags.recursion_available)
512 (*flags) |= NM_FLAGS_RA;
513 if (nmb2->header.nm_flags.bcast)
514 (*flags) |= NM_FLAGS_B;
515 free_packet(p2);
517 * If we're doing a unicast lookup we only
518 * expect one reply. Don't wait the full 2
519 * seconds if we got one. JRA.
521 if(!bcast && found)
522 break;
526 /* only set timed_out if we didn't fund what we where looking for*/
528 if ( !found && timed_out ) {
529 *timed_out = True;
532 /* sort the ip list so we choose close servers first if possible */
533 sort_ip_list(ip_list, *count);
535 return ip_list;
538 /********************************************************
539 Start parsing the lmhosts file.
540 *********************************************************/
542 XFILE *startlmhosts(char *fname)
544 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
545 if (!fp) {
546 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
547 fname, strerror(errno)));
548 return NULL;
550 return fp;
553 /********************************************************
554 Parse the next line in the lmhosts file.
555 *********************************************************/
557 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
559 pstring line;
561 while(!x_feof(fp) && !x_ferror(fp)) {
562 pstring ip,flags,extra;
563 const char *ptr;
564 char *ptr1;
565 int count = 0;
567 *name_type = -1;
569 if (!fgets_slash(line,sizeof(pstring),fp))
570 continue;
572 if (*line == '#')
573 continue;
575 pstrcpy(ip,"");
576 pstrcpy(name,"");
577 pstrcpy(flags,"");
579 ptr = line;
581 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
582 ++count;
583 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
584 ++count;
585 if (next_token(&ptr,flags,NULL, sizeof(flags)))
586 ++count;
587 if (next_token(&ptr,extra,NULL, sizeof(extra)))
588 ++count;
590 if (count <= 0)
591 continue;
593 if (count > 0 && count < 2)
595 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
596 continue;
599 if (count >= 4)
601 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
602 continue;
605 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
607 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
609 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
610 continue;
613 *ipaddr = *interpret_addr2(ip);
615 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
616 then only add that name type. */
617 if((ptr1 = strchr_m(name, '#')) != NULL)
619 char *endptr;
621 ptr1++;
622 *name_type = (int)strtol(ptr1, &endptr, 16);
624 if(!*ptr1 || (endptr == ptr1))
626 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
627 continue;
630 *(--ptr1) = '\0'; /* Truncate at the '#' */
633 return True;
636 return False;
639 /********************************************************
640 Finish parsing the lmhosts file.
641 *********************************************************/
643 void endlmhosts(XFILE *fp)
645 x_fclose(fp);
648 /********************************************************
649 convert an array if struct in_addrs to struct ip_service
650 return False on failure. Port is set to PORT_NONE;
651 *********************************************************/
653 static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
655 int i;
657 if ( count==0 || !ip_list )
658 return False;
660 /* copy the ip address; port will be PORT_NONE */
661 if ( (*return_iplist = (struct ip_service*)malloc(count*sizeof(struct ip_service))) == NULL ) {
662 DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
663 return False;
666 for ( i=0; i<count; i++ ) {
667 (*return_iplist)[i].ip = ip_list[i];
668 (*return_iplist)[i].port = PORT_NONE;
671 return True;
673 /********************************************************
674 Resolve via "bcast" method.
675 *********************************************************/
677 BOOL name_resolve_bcast(const char *name, int name_type,
678 struct ip_service **return_iplist, int *return_count)
680 int sock, i;
681 int num_interfaces = iface_count();
682 struct in_addr *ip_list;
683 BOOL ret;
685 if (lp_disable_netbios()) {
686 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
687 return False;
690 *return_iplist = NULL;
691 *return_count = 0;
694 * "bcast" means do a broadcast lookup on all the local interfaces.
697 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
699 sock = open_socket_in( SOCK_DGRAM, 0, 3,
700 interpret_addr(lp_socket_address()), True );
702 if (sock == -1) return False;
704 set_socket_options(sock,"SO_BROADCAST");
706 * Lookup the name on all the interfaces, return on
707 * the first successful match.
709 for( i = num_interfaces-1; i >= 0; i--) {
710 struct in_addr sendto_ip;
711 int flags;
712 /* Done this way to fix compiler error on IRIX 5.x */
713 sendto_ip = *iface_n_bcast(i);
714 ip_list = name_query(sock, name, name_type, True,
715 True, sendto_ip, return_count, &flags, NULL);
716 if( ip_list )
717 goto success;
720 /* failed - no response */
722 close(sock);
723 return False;
725 success:
726 ret = True;
727 if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
728 ret = False;
730 SAFE_FREE( ip_list );
731 close(sock);
732 return ret;
735 /********************************************************
736 Resolve via "wins" method.
737 *********************************************************/
739 BOOL resolve_wins(const char *name, int name_type,
740 struct ip_service **return_iplist, int *return_count)
742 int sock, t, i;
743 char **wins_tags;
744 struct in_addr src_ip, *ip_list = NULL;
745 BOOL ret;
747 if (lp_disable_netbios()) {
748 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
749 return False;
752 *return_iplist = NULL;
753 *return_count = 0;
755 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
757 if (wins_srv_count() < 1) {
758 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
759 return False;
762 /* we try a lookup on each of the WINS tags in turn */
763 wins_tags = wins_srv_tags();
765 if (!wins_tags) {
766 /* huh? no tags?? give up in disgust */
767 return False;
770 /* the address we will be sending from */
771 src_ip = *interpret_addr2(lp_socket_address());
773 /* in the worst case we will try every wins server with every
774 tag! */
775 for (t=0; wins_tags && wins_tags[t]; t++) {
776 int srv_count = wins_srv_count_tag(wins_tags[t]);
777 for (i=0; i<srv_count; i++) {
778 struct in_addr wins_ip;
779 int flags;
780 BOOL timed_out;
782 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
784 if (global_in_nmbd && ismyip(wins_ip)) {
785 /* yikes! we'll loop forever */
786 continue;
789 /* skip any that have been unresponsive lately */
790 if (wins_srv_is_dead(wins_ip, src_ip)) {
791 continue;
794 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
796 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
797 if (sock == -1) {
798 continue;
801 ip_list = name_query(sock,name,name_type, False,
802 True, wins_ip, return_count, &flags,
803 &timed_out);
805 /* exit loop if we got a list of addresses */
807 if ( ip_list )
808 goto success;
810 close(sock);
812 if (timed_out) {
813 /* Timed out wating for WINS server to respond. Mark it dead. */
814 wins_srv_died(wins_ip, src_ip);
815 } else {
816 /* The name definately isn't in this
817 group of WINS servers. goto the next group */
818 break;
823 wins_srv_tags_free(wins_tags);
824 return False;
826 success:
827 ret = True;
828 if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
829 ret = False;
831 SAFE_FREE( ip_list );
832 wins_srv_tags_free(wins_tags);
833 close(sock);
835 return ret;
838 /********************************************************
839 Resolve via "lmhosts" method.
840 *********************************************************/
842 static BOOL resolve_lmhosts(const char *name, int name_type,
843 struct ip_service **return_iplist, int *return_count)
846 * "lmhosts" means parse the local lmhosts file.
849 XFILE *fp;
850 pstring lmhost_name;
851 int name_type2;
852 struct in_addr return_ip;
854 *return_iplist = NULL;
855 *return_count = 0;
857 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
859 fp = startlmhosts(dyn_LMHOSTSFILE);
860 if(fp) {
861 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
862 if (strequal(name, lmhost_name) &&
863 ((name_type2 == -1) || (name_type == name_type2))
865 endlmhosts(fp);
866 if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
867 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
868 return False;
870 (*return_iplist)[0].ip = return_ip;
871 (*return_iplist)[0].port = PORT_NONE;
872 *return_count = 1;
873 return True;
876 endlmhosts(fp);
878 return False;
882 /********************************************************
883 Resolve via "hosts" method.
884 *********************************************************/
886 static BOOL resolve_hosts(const char *name, int name_type,
887 struct ip_service **return_iplist, int *return_count)
890 * "host" means do a localhost, or dns lookup.
892 struct hostent *hp;
894 if ( name_type != 0x20 && name_type != 0x0) {
895 DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
896 return False;
899 *return_iplist = NULL;
900 *return_count = 0;
902 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
904 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
905 struct in_addr return_ip;
906 putip((char *)&return_ip,(char *)hp->h_addr);
907 *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service));
908 if(*return_iplist == NULL) {
909 DEBUG(3,("resolve_hosts: malloc fail !\n"));
910 return False;
912 (*return_iplist)->ip = return_ip;
913 (*return_iplist)->port = PORT_NONE;
914 *return_count = 1;
915 return True;
917 return False;
920 /********************************************************
921 Resolve via "ADS" method.
922 *********************************************************/
924 static BOOL resolve_ads(const char *name, int name_type,
925 struct ip_service **return_iplist, int *return_count)
928 #ifdef HAVE_ADS
929 if ( name_type == 0x1c ) {
930 int count, i = 0;
931 char *list = NULL;
932 const char *ptr;
933 pstring tok;
935 /* try to lookup the _ldap._tcp.<domain> if we are using ADS */
936 if ( lp_security() != SEC_ADS )
937 return False;
939 DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n",
940 name));
942 if (ldap_domain2hostlist(name, &list) != LDAP_SUCCESS)
943 return False;
945 count = count_chars(list, ' ') + 1;
946 if ( (*return_iplist = malloc(count * sizeof(struct ip_service))) == NULL ) {
947 DEBUG(0,("resolve_hosts: malloc failed for %d entries\n", count ));
948 return False;
951 ptr = list;
952 while (next_token(&ptr, tok, " ", sizeof(tok))) {
953 unsigned port = LDAP_PORT;
954 char *p = strchr(tok, ':');
955 if (p) {
956 *p = 0;
957 port = atoi(p+1);
959 (*return_iplist)[i].ip = *interpret_addr2(tok);
960 (*return_iplist)[i].port = port;
962 /* make sure it is a valid IP. I considered checking the negative
963 connection cache, but this is the wrong place for it. Maybe only
964 as a hac. After think about it, if all of the IP addresses retuend
965 from DNS are dead, what hope does a netbios name lookup have?
966 The standard reason for falling back to netbios lookups is that
967 our DNS server doesn't know anything about the DC's -- jerry */
969 if ( is_zero_ip((*return_iplist)[i].ip) )
970 continue;
972 i++;
974 SAFE_FREE(list);
976 *return_count = i;
978 return True;
979 } else
980 #endif /* HAVE_ADS */
982 return False;
986 /*******************************************************************
987 Internal interface to resolve a name into an IP address.
988 Use this function if the string is either an IP address, DNS
989 or host name or NetBIOS name. This uses the name switch in the
990 smb.conf to determine the order of name resolution.
992 Added support for ip addr/port to support ADS ldap servers.
993 the only place we currently care about the port is in the
994 resolve_hosts() when looking up DC's via SRV RR entries in DNS
995 **********************************************************************/
997 static BOOL internal_resolve_name(const char *name, int name_type,
998 struct ip_service **return_iplist,
999 int *return_count, const char *resolve_order)
1001 pstring name_resolve_list;
1002 fstring tok;
1003 const char *ptr;
1004 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
1005 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
1006 BOOL is_address = is_ipaddress(name);
1007 BOOL result = False;
1008 int i;
1010 *return_iplist = NULL;
1011 *return_count = 0;
1013 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
1015 if (allzeros || allones || is_address) {
1017 if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
1018 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1019 return False;
1022 if(is_address) {
1023 /* ignore the port here */
1024 (*return_iplist)->port = PORT_NONE;
1026 /* if it's in the form of an IP address then get the lib to interpret it */
1027 if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1028 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1029 return False;
1031 } else {
1032 (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1034 *return_count = 1;
1035 return True;
1038 /* Check name cache */
1040 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1041 /* This could be a negative response */
1042 return (*return_count > 0);
1045 /* set the name resolution order */
1047 if ( strcmp( resolve_order, "NULL") == 0 ) {
1048 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1049 return False;
1052 if ( !resolve_order )
1053 pstrcpy(name_resolve_list, lp_name_resolve_order());
1054 else
1055 pstrcpy(name_resolve_list, resolve_order);
1057 if ( !name_resolve_list[0] )
1058 ptr = "host";
1059 else
1060 ptr = name_resolve_list;
1062 /* iterate through the name resolution backends */
1064 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1065 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1066 if (resolve_hosts(name, name_type, return_iplist, return_count)) {
1067 result = True;
1068 goto done;
1070 } else if(strequal( tok, "ads")) {
1071 /* deal with 0x1c names here. This will result in a
1072 SRV record lookup for _ldap._tcp.<domain> if we
1073 are using 'security = ads' */
1074 if (resolve_ads(name, name_type, return_iplist, return_count)) {
1075 result = True;
1076 goto done;
1078 } else if(strequal( tok, "lmhosts")) {
1079 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
1080 result = True;
1081 goto done;
1083 } else if(strequal( tok, "wins")) {
1084 /* don't resolve 1D via WINS */
1085 if (name_type != 0x1D &&
1086 resolve_wins(name, name_type, return_iplist, return_count)) {
1087 result = True;
1088 goto done;
1090 } else if(strequal( tok, "bcast")) {
1091 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
1092 result = True;
1093 goto done;
1095 } else {
1096 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
1100 /* All of the resolve_* functions above have returned false. */
1102 SAFE_FREE(*return_iplist);
1103 *return_count = 0;
1105 return False;
1107 done:
1109 /* Remove duplicate entries. Some queries, notably #1c (domain
1110 controllers) return the PDC in iplist[0] and then all domain
1111 controllers including the PDC in iplist[1..n]. Iterating over
1112 the iplist when the PDC is down will cause two sets of timeouts. */
1114 if ( *return_count ) {
1115 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1118 /* Save in name cache */
1119 if ( DEBUGLEVEL >= 100 ) {
1120 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1121 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1122 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1125 namecache_store(name, name_type, *return_count, *return_iplist);
1127 /* Display some debugging info */
1129 if ( DEBUGLEVEL >= 10 ) {
1130 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1131 *return_count));
1133 for (i = 0; i < *return_count; i++)
1134 DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1136 DEBUG(10, ("\n"));
1139 return result;
1142 /********************************************************
1143 Internal interface to resolve a name into one IP address.
1144 Use this function if the string is either an IP address, DNS
1145 or host name or NetBIOS name. This uses the name switch in the
1146 smb.conf to determine the order of name resolution.
1147 *********************************************************/
1149 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1151 struct ip_service *ip_list = NULL;
1152 int count = 0;
1154 if (is_ipaddress(name)) {
1155 *return_ip = *interpret_addr2(name);
1156 return True;
1159 if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
1160 int i;
1162 /* only return valid addresses for TCP connections */
1163 for (i=0; i<count; i++) {
1164 char *ip_str = inet_ntoa(ip_list[i].ip);
1165 if (ip_str &&
1166 strcmp(ip_str, "255.255.255.255") != 0 &&
1167 strcmp(ip_str, "0.0.0.0") != 0)
1169 *return_ip = ip_list[i].ip;
1170 SAFE_FREE(ip_list);
1171 return True;
1176 SAFE_FREE(ip_list);
1177 return False;
1180 /********************************************************
1181 Find the IP address of the master browser or DMB for a workgroup.
1182 *********************************************************/
1184 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
1186 struct ip_service *ip_list = NULL;
1187 int count = 0;
1189 if (lp_disable_netbios()) {
1190 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1191 return False;
1194 if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
1195 *master_ip = ip_list[0].ip;
1196 SAFE_FREE(ip_list);
1197 return True;
1199 if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
1200 *master_ip = ip_list[0].ip;
1201 SAFE_FREE(ip_list);
1202 return True;
1205 SAFE_FREE(ip_list);
1206 return False;
1209 /********************************************************
1210 Get the IP address list of the primary domain controller
1211 for a domain.
1212 *********************************************************/
1214 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1216 struct ip_service *ip_list;
1217 int count;
1219 /* Look up #1B name */
1221 if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order()))
1222 return False;
1224 /* if we get more than 1 IP back we have to assume it is a
1225 multi-homed PDC and not a mess up */
1227 if ( count > 1 ) {
1228 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1229 sort_ip_list2( ip_list, count );
1232 *ip = ip_list[0].ip;
1234 SAFE_FREE(ip_list);
1236 return True;
1239 /********************************************************
1240 Get the IP address list of the domain controllers for
1241 a domain.
1242 *********************************************************/
1244 static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
1245 int *count, BOOL ads_only, int *ordered)
1247 fstring resolve_order;
1249 /* if we are restricted to solely using DNS for looking
1250 up a domain controller, make sure that host lookups
1251 are enabled for the 'name resolve order'. If host lookups
1252 are disabled and ads_only is True, then set the string to
1253 NULL. */
1255 fstrcpy( resolve_order, lp_name_resolve_order() );
1256 strlower_m( resolve_order );
1257 if ( ads_only ) {
1258 if ( strstr( resolve_order, "host" ) )
1259 fstrcpy( resolve_order, "ads" );
1260 else
1261 fstrcpy( resolve_order, "NULL" );
1265 *ordered = False;
1267 /* If it's our domain then use the 'password server' parameter. */
1269 if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1270 const char *p;
1271 char *pserver = lp_passwordserver(); /* UNIX charset. */
1272 char *port_str;
1273 int port;
1274 fstring name;
1275 int num_addresses = 0;
1276 int local_count, i, j;
1277 struct ip_service *return_iplist = NULL;
1278 struct ip_service *auto_ip_list = NULL;
1279 BOOL done_auto_lookup = False;
1280 int auto_count = 0;
1283 if (!*pserver)
1284 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1286 p = pserver;
1289 * if '*' appears in the "password server" list then add
1290 * an auto lookup to the list of manually configured
1291 * DC's. If any DC is listed by name, then the list should be
1292 * considered to be ordered
1295 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1296 if (strequal(name, "*")) {
1297 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) )
1298 num_addresses += auto_count;
1299 done_auto_lookup = True;
1300 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1302 else
1303 num_addresses++;
1306 /* if we have no addresses and haven't done the auto lookup, then
1307 just return the list of DC's */
1309 if ( (num_addresses == 0) && !done_auto_lookup )
1310 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1312 /* maybe we just failed? */
1314 if ( num_addresses == 0 ) {
1315 DEBUG(4,("get_dc_list: no servers found\n"));
1316 return False;
1319 if ( (return_iplist = (struct ip_service *)
1320 malloc(num_addresses * sizeof(struct ip_service))) == NULL )
1322 DEBUG(3,("get_dc_list: malloc fail !\n"));
1323 return False;
1326 p = pserver;
1327 local_count = 0;
1329 /* fill in the return list now with real IP's */
1331 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1332 struct in_addr name_ip;
1334 /* copy any addersses from the auto lookup */
1336 if ( strequal(name, "*") ) {
1337 for ( j=0; j<auto_count; j++ ) {
1338 return_iplist[local_count].ip = auto_ip_list[j].ip;
1339 return_iplist[local_count].port = auto_ip_list[j].port;
1340 local_count++;
1342 continue;
1346 /* added support for address:port syntax for ads (not that I think
1347 anyone will ever run the LDAP server in an AD domain on something
1348 other than port 389 */
1350 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1351 if ( (port_str=strchr(name, ':')) != NULL ) {
1352 *port_str = '\0';
1353 port_str++;
1354 port = atoi( port_str );
1357 /* explicit lookup; resolve_name() will handle names & IP addresses */
1358 if ( resolve_name( name, &name_ip, 0x20 ) ) {
1359 return_iplist[local_count].ip = name_ip;
1360 return_iplist[local_count].port = port;
1361 local_count++;
1362 *ordered = True;
1366 SAFE_FREE(auto_ip_list);
1368 /* need to remove duplicates in the list if we have any
1369 explicit password servers */
1371 if ( local_count )
1372 local_count = remove_duplicate_addrs2( return_iplist, local_count );
1374 if ( DEBUGLEVEL >= 4 ) {
1375 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
1376 *ordered ? "":"un"));
1377 DEBUG(4,("get_dc_list: "));
1378 for ( i=0; i<local_count; i++ )
1379 DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1380 DEBUGADD(4,("\n"));
1383 *ip_list = return_iplist;
1384 *count = local_count;
1386 return (*count != 0);
1389 DEBUG(10,("get_dc_list: defaulting to internal auto lookup for domain %s\n", domain));
1391 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1394 /*********************************************************************
1395 small wrapper function to get the DC list and sort it if neccessary
1396 *********************************************************************/
1397 BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only )
1399 BOOL ordered;
1401 DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
1402 (ads_only ? "ads" : lp_name_resolve_order())));
1404 if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) )
1405 return False;
1407 /* only sort if we don't already have an ordered list */
1408 if ( !ordered )
1409 sort_ip_list2( *ip_list, *count );
1411 return True;