Modified fix for bugid #784. Based on a patch from moriyama@miraclelinux.com (MORIYAM...
[Samba/gebeck_regimport.git] / source / libsmb / namequery.c
blobb9bc4e11664da2b06f8eb8f7a6b6fe996a0cbf4a
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)
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));
71 return ret;
75 /****************************************************************************
76 Do a NBT node status query on an open socket and return an array of
77 structures holding the returned names or NULL if the query failed.
78 **************************************************************************/
80 struct node_status *node_status_query(int fd,struct nmb_name *name,
81 struct in_addr to_ip, int *num_names)
83 BOOL found=False;
84 int retries = 2;
85 int retry_time = 2000;
86 struct timeval tval;
87 struct packet_struct p;
88 struct packet_struct *p2;
89 struct nmb_packet *nmb = &p.packet.nmb;
90 struct node_status *ret;
92 ZERO_STRUCT(p);
94 nmb->header.name_trn_id = generate_trn_id();
95 nmb->header.opcode = 0;
96 nmb->header.response = False;
97 nmb->header.nm_flags.bcast = False;
98 nmb->header.nm_flags.recursion_available = False;
99 nmb->header.nm_flags.recursion_desired = False;
100 nmb->header.nm_flags.trunc = False;
101 nmb->header.nm_flags.authoritative = False;
102 nmb->header.rcode = 0;
103 nmb->header.qdcount = 1;
104 nmb->header.ancount = 0;
105 nmb->header.nscount = 0;
106 nmb->header.arcount = 0;
107 nmb->question.question_name = *name;
108 nmb->question.question_type = 0x21;
109 nmb->question.question_class = 0x1;
111 p.ip = to_ip;
112 p.port = NMB_PORT;
113 p.fd = fd;
114 p.timestamp = time(NULL);
115 p.packet_type = NMB_PACKET;
117 GetTimeOfDay(&tval);
119 if (!send_packet(&p))
120 return NULL;
122 retries--;
124 while (1) {
125 struct timeval tval2;
126 GetTimeOfDay(&tval2);
127 if (TvalDiff(&tval,&tval2) > retry_time) {
128 if (!retries)
129 break;
130 if (!found && !send_packet(&p))
131 return NULL;
132 GetTimeOfDay(&tval);
133 retries--;
136 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
137 struct nmb_packet *nmb2 = &p2->packet.nmb;
138 debug_nmb_packet(p2);
140 if (nmb2->header.opcode != 0 ||
141 nmb2->header.nm_flags.bcast ||
142 nmb2->header.rcode ||
143 !nmb2->header.ancount ||
144 nmb2->answers->rr_type != 0x21) {
145 /* XXXX what do we do with this? could be a
146 redirect, but we'll discard it for the
147 moment */
148 free_packet(p2);
149 continue;
152 ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
153 free_packet(p2);
154 return ret;
158 return NULL;
161 /****************************************************************************
162 Find the first type XX name in a node status reply - used for finding
163 a servers name given its IP. Return the matched name in *name.
164 **************************************************************************/
166 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
168 struct node_status *status = NULL;
169 struct nmb_name nname;
170 int count, i;
171 int sock;
172 BOOL result = False;
174 if (lp_disable_netbios()) {
175 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
176 return False;
179 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
180 q_type, inet_ntoa(to_ip)));
182 /* Check the cache first. */
184 if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
185 return True;
187 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
188 if (sock == -1)
189 goto done;
191 /* W2K PDC's seem not to respond to '*'#0. JRA */
192 make_nmb_name(&nname, q_name, q_type);
193 status = node_status_query(sock, &nname, to_ip, &count);
194 close(sock);
195 if (!status)
196 goto done;
198 for (i=0;i<count;i++) {
199 if (status[i].type == type)
200 break;
202 if (i == count)
203 goto done;
205 pull_ascii_nstring(name, sizeof(fstring), status[i].name);
207 /* Store the result in the cache. */
208 /* but don't store an entry for 0x1c names here. Here we have
209 a single host and DOMAIN<0x1c> names should be a list of hosts */
211 if ( q_type != 0x1c )
212 namecache_status_store(q_name, q_type, type, to_ip, name);
214 result = True;
216 done:
217 SAFE_FREE(status);
219 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
221 if (result)
222 DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
224 DEBUG(10, ("\n"));
226 return result;
230 comparison function used by sort_ip_list
233 static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
235 int max_bits1=0, max_bits2=0;
236 int num_interfaces = iface_count();
237 int i;
239 for (i=0;i<num_interfaces;i++) {
240 struct in_addr ip;
241 int bits1, bits2;
242 ip = *iface_n_bcast(i);
243 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
244 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
245 max_bits1 = MAX(bits1, max_bits1);
246 max_bits2 = MAX(bits2, max_bits2);
249 /* bias towards directly reachable IPs */
250 if (iface_local(*ip1)) {
251 max_bits1 += 32;
253 if (iface_local(*ip2)) {
254 max_bits2 += 32;
257 return max_bits2 - max_bits1;
260 /*******************************************************************
261 compare 2 ldap IPs by nearness to our interfaces - used in qsort
262 *******************************************************************/
264 static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
266 int result;
268 if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
269 return result;
271 if ( ip1->port > ip2->port )
272 return 1;
274 if ( ip1->port < ip2->port )
275 return -1;
277 return 0;
281 sort an IP list so that names that are close to one of our interfaces
282 are at the top. This prevents the problem where a WINS server returns an IP that
283 is not reachable from our subnet as the first match
286 static void sort_ip_list(struct in_addr *iplist, int count)
288 if (count <= 1) {
289 return;
292 qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
295 static void sort_ip_list2(struct ip_service *iplist, int count)
297 if (count <= 1) {
298 return;
301 qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare);
304 /**********************************************************************
305 Remove any duplicate address/port pairs in the list
306 *********************************************************************/
308 static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
310 int i, j;
312 DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
314 /* one loop to remove duplicates */
315 for ( i=0; i<count; i++ ) {
316 if ( is_zero_ip(iplist[i].ip) )
317 continue;
319 for ( j=i+1; j<count; j++ ) {
320 if ( ip_service_equal(iplist[i], iplist[j]) )
321 zero_ip(&iplist[j].ip);
325 /* one loop to clean up any holes we left */
326 /* first ip should never be a zero_ip() */
327 for (i = 0; i<count; ) {
328 if ( is_zero_ip(iplist[i].ip) ) {
329 if (i != count-1 )
330 memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
331 count--;
332 continue;
334 i++;
337 return count;
340 /****************************************************************************
341 Do a netbios name query to find someones IP.
342 Returns an array of IP addresses or NULL if none.
343 *count will be set to the number of addresses returned.
344 *timed_out is set if we failed by timing out
345 ****************************************************************************/
347 struct in_addr *name_query(int fd,const char *name,int name_type,
348 BOOL bcast,BOOL recurse,
349 struct in_addr to_ip, int *count, int *flags,
350 BOOL *timed_out)
352 BOOL found=False;
353 int i, retries = 3;
354 int retry_time = bcast?250:2000;
355 struct timeval tval;
356 struct packet_struct p;
357 struct packet_struct *p2;
358 struct nmb_packet *nmb = &p.packet.nmb;
359 struct in_addr *ip_list = NULL;
361 if (lp_disable_netbios()) {
362 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
363 return NULL;
366 if (timed_out) {
367 *timed_out = False;
370 memset((char *)&p,'\0',sizeof(p));
371 (*count) = 0;
372 (*flags) = 0;
374 nmb->header.name_trn_id = generate_trn_id();
375 nmb->header.opcode = 0;
376 nmb->header.response = False;
377 nmb->header.nm_flags.bcast = bcast;
378 nmb->header.nm_flags.recursion_available = False;
379 nmb->header.nm_flags.recursion_desired = recurse;
380 nmb->header.nm_flags.trunc = False;
381 nmb->header.nm_flags.authoritative = False;
382 nmb->header.rcode = 0;
383 nmb->header.qdcount = 1;
384 nmb->header.ancount = 0;
385 nmb->header.nscount = 0;
386 nmb->header.arcount = 0;
388 make_nmb_name(&nmb->question.question_name,name,name_type);
390 nmb->question.question_type = 0x20;
391 nmb->question.question_class = 0x1;
393 p.ip = to_ip;
394 p.port = NMB_PORT;
395 p.fd = fd;
396 p.timestamp = time(NULL);
397 p.packet_type = NMB_PACKET;
399 GetTimeOfDay(&tval);
401 if (!send_packet(&p))
402 return NULL;
404 retries--;
406 while (1) {
407 struct timeval tval2;
408 struct in_addr *tmp_ip_list;
410 GetTimeOfDay(&tval2);
411 if (TvalDiff(&tval,&tval2) > retry_time) {
412 if (!retries)
413 break;
414 if (!found && !send_packet(&p))
415 return NULL;
416 GetTimeOfDay(&tval);
417 retries--;
420 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
421 struct nmb_packet *nmb2 = &p2->packet.nmb;
422 debug_nmb_packet(p2);
424 /* If we get a Negative Name Query Response from a WINS
425 * server, we should report it and give up.
427 if( 0 == nmb2->header.opcode /* A query response */
428 && !(bcast) /* from a WINS server */
429 && nmb2->header.rcode /* Error returned */
432 if( DEBUGLVL( 3 ) ) {
433 /* Only executed if DEBUGLEVEL >= 3 */
434 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
435 switch( nmb2->header.rcode ) {
436 case 0x01:
437 dbgtext( "Request was invalidly formatted.\n" );
438 break;
439 case 0x02:
440 dbgtext( "Problem with NBNS, cannot process name.\n");
441 break;
442 case 0x03:
443 dbgtext( "The name requested does not exist.\n" );
444 break;
445 case 0x04:
446 dbgtext( "Unsupported request error.\n" );
447 break;
448 case 0x05:
449 dbgtext( "Query refused error.\n" );
450 break;
451 default:
452 dbgtext( "Unrecognized error code.\n" );
453 break;
456 free_packet(p2);
457 return( NULL );
460 if (nmb2->header.opcode != 0 ||
461 nmb2->header.nm_flags.bcast ||
462 nmb2->header.rcode ||
463 !nmb2->header.ancount) {
465 * XXXX what do we do with this? Could be a
466 * redirect, but we'll discard it for the
467 * moment.
469 free_packet(p2);
470 continue;
473 tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
474 * ( (*count) + nmb2->answers->rdlength/6 ) );
476 if (!tmp_ip_list) {
477 DEBUG(0,("name_query: Realloc failed.\n"));
478 SAFE_FREE(ip_list);
481 ip_list = tmp_ip_list;
483 if (ip_list) {
484 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
485 for (i=0;i<nmb2->answers->rdlength/6;i++) {
486 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
487 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
488 (*count)++;
490 DEBUGADD(2,(")\n"));
493 found=True;
494 retries=0;
495 /* We add the flags back ... */
496 if (nmb2->header.response)
497 (*flags) |= NM_FLAGS_RS;
498 if (nmb2->header.nm_flags.authoritative)
499 (*flags) |= NM_FLAGS_AA;
500 if (nmb2->header.nm_flags.trunc)
501 (*flags) |= NM_FLAGS_TC;
502 if (nmb2->header.nm_flags.recursion_desired)
503 (*flags) |= NM_FLAGS_RD;
504 if (nmb2->header.nm_flags.recursion_available)
505 (*flags) |= NM_FLAGS_RA;
506 if (nmb2->header.nm_flags.bcast)
507 (*flags) |= NM_FLAGS_B;
508 free_packet(p2);
510 * If we're doing a unicast lookup we only
511 * expect one reply. Don't wait the full 2
512 * seconds if we got one. JRA.
514 if(!bcast && found)
515 break;
519 /* only set timed_out if we didn't fund what we where looking for*/
521 if ( !found && timed_out ) {
522 *timed_out = True;
525 /* sort the ip list so we choose close servers first if possible */
526 sort_ip_list(ip_list, *count);
528 return ip_list;
531 /********************************************************
532 Start parsing the lmhosts file.
533 *********************************************************/
535 XFILE *startlmhosts(char *fname)
537 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
538 if (!fp) {
539 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
540 fname, strerror(errno)));
541 return NULL;
543 return fp;
546 /********************************************************
547 Parse the next line in the lmhosts file.
548 *********************************************************/
550 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
552 pstring line;
554 while(!x_feof(fp) && !x_ferror(fp)) {
555 pstring ip,flags,extra;
556 const char *ptr;
557 char *ptr1;
558 int count = 0;
560 *name_type = -1;
562 if (!fgets_slash(line,sizeof(pstring),fp))
563 continue;
565 if (*line == '#')
566 continue;
568 pstrcpy(ip,"");
569 pstrcpy(name,"");
570 pstrcpy(flags,"");
572 ptr = line;
574 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
575 ++count;
576 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
577 ++count;
578 if (next_token(&ptr,flags,NULL, sizeof(flags)))
579 ++count;
580 if (next_token(&ptr,extra,NULL, sizeof(extra)))
581 ++count;
583 if (count <= 0)
584 continue;
586 if (count > 0 && count < 2)
588 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
589 continue;
592 if (count >= 4)
594 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
595 continue;
598 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
600 if (strchr_m(flags,'G') || strchr_m(flags,'S'))
602 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
603 continue;
606 *ipaddr = *interpret_addr2(ip);
608 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
609 then only add that name type. */
610 if((ptr1 = strchr_m(name, '#')) != NULL)
612 char *endptr;
614 ptr1++;
615 *name_type = (int)strtol(ptr1, &endptr, 16);
617 if(!*ptr1 || (endptr == ptr1))
619 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
620 continue;
623 *(--ptr1) = '\0'; /* Truncate at the '#' */
626 return True;
629 return False;
632 /********************************************************
633 Finish parsing the lmhosts file.
634 *********************************************************/
636 void endlmhosts(XFILE *fp)
638 x_fclose(fp);
641 /********************************************************
642 convert an array if struct in_addrs to struct ip_service
643 return False on failure. Port is set to PORT_NONE;
644 *********************************************************/
646 static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
648 int i;
650 if ( count==0 || !ip_list )
651 return False;
653 /* copy the ip address; port will be PORT_NONE */
654 if ( (*return_iplist = (struct ip_service*)malloc(count*sizeof(struct ip_service))) == NULL ) {
655 DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
656 return False;
659 for ( i=0; i<count; i++ ) {
660 (*return_iplist)[i].ip = ip_list[i];
661 (*return_iplist)[i].port = PORT_NONE;
664 return True;
666 /********************************************************
667 Resolve via "bcast" method.
668 *********************************************************/
670 BOOL name_resolve_bcast(const char *name, int name_type,
671 struct ip_service **return_iplist, int *return_count)
673 int sock, i;
674 int num_interfaces = iface_count();
675 struct in_addr *ip_list;
676 BOOL ret;
678 if (lp_disable_netbios()) {
679 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
680 return False;
683 *return_iplist = NULL;
684 *return_count = 0;
687 * "bcast" means do a broadcast lookup on all the local interfaces.
690 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
692 sock = open_socket_in( SOCK_DGRAM, 0, 3,
693 interpret_addr(lp_socket_address()), True );
695 if (sock == -1) return False;
697 set_socket_options(sock,"SO_BROADCAST");
699 * Lookup the name on all the interfaces, return on
700 * the first successful match.
702 for( i = num_interfaces-1; i >= 0; i--) {
703 struct in_addr sendto_ip;
704 int flags;
705 /* Done this way to fix compiler error on IRIX 5.x */
706 sendto_ip = *iface_n_bcast(i);
707 ip_list = name_query(sock, name, name_type, True,
708 True, sendto_ip, return_count, &flags, NULL);
709 if( ip_list )
710 goto success;
713 /* failed - no response */
715 close(sock);
716 return False;
718 success:
719 ret = True;
720 if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
721 ret = False;
723 SAFE_FREE( ip_list );
724 close(sock);
725 return ret;
728 /********************************************************
729 Resolve via "wins" method.
730 *********************************************************/
732 BOOL resolve_wins(const char *name, int name_type,
733 struct ip_service **return_iplist, int *return_count)
735 int sock, t, i;
736 char **wins_tags;
737 struct in_addr src_ip, *ip_list = NULL;
738 BOOL ret;
740 if (lp_disable_netbios()) {
741 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
742 return False;
745 *return_iplist = NULL;
746 *return_count = 0;
748 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
750 if (wins_srv_count() < 1) {
751 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
752 return False;
755 /* we try a lookup on each of the WINS tags in turn */
756 wins_tags = wins_srv_tags();
758 if (!wins_tags) {
759 /* huh? no tags?? give up in disgust */
760 return False;
763 /* the address we will be sending from */
764 src_ip = *interpret_addr2(lp_socket_address());
766 /* in the worst case we will try every wins server with every
767 tag! */
768 for (t=0; wins_tags && wins_tags[t]; t++) {
769 int srv_count = wins_srv_count_tag(wins_tags[t]);
770 for (i=0; i<srv_count; i++) {
771 struct in_addr wins_ip;
772 int flags;
773 BOOL timed_out;
775 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
777 if (global_in_nmbd && ismyip(wins_ip)) {
778 /* yikes! we'll loop forever */
779 continue;
782 /* skip any that have been unresponsive lately */
783 if (wins_srv_is_dead(wins_ip, src_ip)) {
784 continue;
787 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
789 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
790 if (sock == -1) {
791 continue;
794 ip_list = name_query(sock,name,name_type, False,
795 True, wins_ip, return_count, &flags,
796 &timed_out);
798 /* exit loop if we got a list of addresses */
800 if ( ip_list )
801 goto success;
803 close(sock);
805 if (timed_out) {
806 /* Timed out wating for WINS server to respond. Mark it dead. */
807 wins_srv_died(wins_ip, src_ip);
808 } else {
809 /* The name definately isn't in this
810 group of WINS servers. goto the next group */
811 break;
816 wins_srv_tags_free(wins_tags);
817 return False;
819 success:
820 ret = True;
821 if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
822 ret = False;
824 SAFE_FREE( ip_list );
825 wins_srv_tags_free(wins_tags);
826 close(sock);
828 return ret;
831 /********************************************************
832 Resolve via "lmhosts" method.
833 *********************************************************/
835 static BOOL resolve_lmhosts(const char *name, int name_type,
836 struct ip_service **return_iplist, int *return_count)
839 * "lmhosts" means parse the local lmhosts file.
842 XFILE *fp;
843 pstring lmhost_name;
844 int name_type2;
845 struct in_addr return_ip;
847 *return_iplist = NULL;
848 *return_count = 0;
850 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
852 fp = startlmhosts(dyn_LMHOSTSFILE);
853 if(fp) {
854 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
855 if (strequal(name, lmhost_name) &&
856 ((name_type2 == -1) || (name_type == name_type2))
858 endlmhosts(fp);
859 if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
860 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
861 return False;
863 (*return_iplist)[0].ip = return_ip;
864 (*return_iplist)[0].port = PORT_NONE;
865 *return_count = 1;
866 return True;
869 endlmhosts(fp);
871 return False;
875 /********************************************************
876 Resolve via "hosts" method.
877 *********************************************************/
879 static BOOL resolve_hosts(const char *name, int name_type,
880 struct ip_service **return_iplist, int *return_count)
883 * "host" means do a localhost, or dns lookup.
885 struct hostent *hp;
887 if ( name_type != 0x20 && name_type != 0x0) {
888 DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
889 return False;
892 *return_iplist = NULL;
893 *return_count = 0;
895 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
897 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
898 struct in_addr return_ip;
899 putip((char *)&return_ip,(char *)hp->h_addr);
900 *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service));
901 if(*return_iplist == NULL) {
902 DEBUG(3,("resolve_hosts: malloc fail !\n"));
903 return False;
905 (*return_iplist)->ip = return_ip;
906 (*return_iplist)->port = PORT_NONE;
907 *return_count = 1;
908 return True;
910 return False;
913 /********************************************************
914 Resolve via "ADS" method.
915 *********************************************************/
917 static BOOL resolve_ads(const char *name, int name_type,
918 struct ip_service **return_iplist, int *return_count)
921 #ifdef HAVE_ADS
922 if ( name_type == 0x1c ) {
923 int count, i = 0;
924 char *list = NULL;
925 const char *ptr;
926 pstring tok;
928 /* try to lookup the _ldap._tcp.<domain> if we are using ADS */
929 if ( lp_security() != SEC_ADS )
930 return False;
932 DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n",
933 name));
935 if (ldap_domain2hostlist(name, &list) != LDAP_SUCCESS)
936 return False;
938 count = count_chars(list, ' ') + 1;
939 if ( (*return_iplist = malloc(count * sizeof(struct ip_service))) == NULL ) {
940 DEBUG(0,("resolve_hosts: malloc failed for %d entries\n", count ));
941 return False;
944 ptr = list;
945 while (next_token(&ptr, tok, " ", sizeof(tok))) {
946 unsigned port = LDAP_PORT;
947 char *p = strchr(tok, ':');
948 if (p) {
949 *p = 0;
950 port = atoi(p+1);
952 (*return_iplist)[i].ip = *interpret_addr2(tok);
953 (*return_iplist)[i].port = port;
955 /* make sure it is a valid IP. I considered checking the negative
956 connection cache, but this is the wrong place for it. Maybe only
957 as a hac. After think about it, if all of the IP addresses retuend
958 from DNS are dead, what hope does a netbios name lookup have?
959 The standard reason for falling back to netbios lookups is that
960 our DNS server doesn't know anything about the DC's -- jerry */
962 if ( is_zero_ip((*return_iplist)[i].ip) )
963 continue;
965 i++;
967 SAFE_FREE(list);
969 *return_count = i;
971 return True;
972 } else
973 #endif /* HAVE_ADS */
975 return False;
979 /*******************************************************************
980 Internal interface to resolve a name into an IP address.
981 Use this function if the string is either an IP address, DNS
982 or host name or NetBIOS name. This uses the name switch in the
983 smb.conf to determine the order of name resolution.
985 Added support for ip addr/port to support ADS ldap servers.
986 the only place we currently care about the port is in the
987 resolve_hosts() when looking up DC's via SRV RR entries in DNS
988 **********************************************************************/
990 static BOOL internal_resolve_name(const char *name, int name_type,
991 struct ip_service **return_iplist,
992 int *return_count, const char *resolve_order)
994 pstring name_resolve_list;
995 fstring tok;
996 const char *ptr;
997 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
998 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
999 BOOL is_address = is_ipaddress(name);
1000 BOOL result = False;
1001 int i;
1003 *return_iplist = NULL;
1004 *return_count = 0;
1006 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
1008 if (allzeros || allones || is_address) {
1010 if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
1011 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1012 return False;
1015 if(is_address) {
1016 /* ignore the port here */
1017 (*return_iplist)->port = PORT_NONE;
1019 /* if it's in the form of an IP address then get the lib to interpret it */
1020 if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1021 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1022 return False;
1024 } else {
1025 (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1027 *return_count = 1;
1028 return True;
1031 /* Check name cache */
1033 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1034 /* This could be a negative response */
1035 return (*return_count > 0);
1038 /* set the name resolution order */
1040 if ( strcmp( resolve_order, "NULL") == 0 ) {
1041 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1042 return False;
1045 if ( !resolve_order )
1046 pstrcpy(name_resolve_list, lp_name_resolve_order());
1047 else
1048 pstrcpy(name_resolve_list, resolve_order);
1050 if ( !name_resolve_list[0] )
1051 ptr = "host";
1052 else
1053 ptr = name_resolve_list;
1055 /* iterate through the name resolution backends */
1057 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1058 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1059 if (resolve_hosts(name, name_type, return_iplist, return_count)) {
1060 result = True;
1061 goto done;
1063 } else if(strequal( tok, "ads")) {
1064 /* deal with 0x1c names here. This will result in a
1065 SRV record lookup for _ldap._tcp.<domain> if we
1066 are using 'security = ads' */
1067 if (resolve_ads(name, name_type, return_iplist, return_count)) {
1068 result = True;
1069 goto done;
1071 } else if(strequal( tok, "lmhosts")) {
1072 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
1073 result = True;
1074 goto done;
1076 } else if(strequal( tok, "wins")) {
1077 /* don't resolve 1D via WINS */
1078 if (name_type != 0x1D &&
1079 resolve_wins(name, name_type, return_iplist, return_count)) {
1080 result = True;
1081 goto done;
1083 } else if(strequal( tok, "bcast")) {
1084 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
1085 result = True;
1086 goto done;
1088 } else {
1089 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
1093 /* All of the resolve_* functions above have returned false. */
1095 SAFE_FREE(*return_iplist);
1096 *return_count = 0;
1098 return False;
1100 done:
1102 /* Remove duplicate entries. Some queries, notably #1c (domain
1103 controllers) return the PDC in iplist[0] and then all domain
1104 controllers including the PDC in iplist[1..n]. Iterating over
1105 the iplist when the PDC is down will cause two sets of timeouts. */
1107 if ( *return_count ) {
1108 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1111 /* Save in name cache */
1112 if ( DEBUGLEVEL >= 100 ) {
1113 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1114 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1115 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1118 namecache_store(name, name_type, *return_count, *return_iplist);
1120 /* Display some debugging info */
1122 if ( DEBUGLEVEL >= 10 ) {
1123 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1124 *return_count));
1126 for (i = 0; i < *return_count; i++)
1127 DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1129 DEBUG(10, ("\n"));
1132 return result;
1135 /********************************************************
1136 Internal interface to resolve a name into one IP address.
1137 Use this function if the string is either an IP address, DNS
1138 or host name or NetBIOS name. This uses the name switch in the
1139 smb.conf to determine the order of name resolution.
1140 *********************************************************/
1142 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1144 struct ip_service *ip_list = NULL;
1145 int count = 0;
1147 if (is_ipaddress(name)) {
1148 *return_ip = *interpret_addr2(name);
1149 return True;
1152 if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
1153 int i;
1155 /* only return valid addresses for TCP connections */
1156 for (i=0; i<count; i++) {
1157 char *ip_str = inet_ntoa(ip_list[i].ip);
1158 if (ip_str &&
1159 strcmp(ip_str, "255.255.255.255") != 0 &&
1160 strcmp(ip_str, "0.0.0.0") != 0)
1162 *return_ip = ip_list[i].ip;
1163 SAFE_FREE(ip_list);
1164 return True;
1169 SAFE_FREE(ip_list);
1170 return False;
1173 /********************************************************
1174 Find the IP address of the master browser or DMB for a workgroup.
1175 *********************************************************/
1177 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
1179 struct ip_service *ip_list = NULL;
1180 int count = 0;
1182 if (lp_disable_netbios()) {
1183 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1184 return False;
1187 if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
1188 *master_ip = ip_list[0].ip;
1189 SAFE_FREE(ip_list);
1190 return True;
1192 if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
1193 *master_ip = ip_list[0].ip;
1194 SAFE_FREE(ip_list);
1195 return True;
1198 SAFE_FREE(ip_list);
1199 return False;
1202 /********************************************************
1203 Get the IP address list of the primary domain controller
1204 for a domain.
1205 *********************************************************/
1207 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1209 struct ip_service *ip_list;
1210 int count;
1212 /* Look up #1B name */
1214 if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order()))
1215 return False;
1217 /* if we get more than 1 IP back we have to assume it is a
1218 multi-homed PDC and not a mess up */
1220 if ( count > 1 ) {
1221 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1222 sort_ip_list2( ip_list, count );
1225 *ip = ip_list[0].ip;
1227 SAFE_FREE(ip_list);
1229 return True;
1232 /********************************************************
1233 Get the IP address list of the domain controllers for
1234 a domain.
1235 *********************************************************/
1237 static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
1238 int *count, BOOL ads_only, int *ordered)
1240 fstring resolve_order;
1242 /* if we are restricted to solely using DNS for looking
1243 up a domain controller, make sure that host lookups
1244 are enabled for the 'name resolve order'. If host lookups
1245 are disabled and ads_only is True, then set the string to
1246 NULL. */
1248 fstrcpy( resolve_order, lp_name_resolve_order() );
1249 strlower_m( resolve_order );
1250 if ( ads_only ) {
1251 if ( strstr( resolve_order, "host" ) )
1252 fstrcpy( resolve_order, "ads" );
1253 else
1254 fstrcpy( resolve_order, "NULL" );
1258 *ordered = False;
1260 /* If it's our domain then use the 'password server' parameter. */
1262 if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1263 const char *p;
1264 char *pserver = lp_passwordserver(); /* UNIX charset. */
1265 char *port_str;
1266 int port;
1267 fstring name;
1268 int num_addresses = 0;
1269 int local_count, i, j;
1270 struct ip_service *return_iplist = NULL;
1271 struct ip_service *auto_ip_list = NULL;
1272 BOOL done_auto_lookup = False;
1273 int auto_count = 0;
1276 if (!*pserver)
1277 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1279 p = pserver;
1282 * if '*' appears in the "password server" list then add
1283 * an auto lookup to the list of manually configured
1284 * DC's. If any DC is listed by name, then the list should be
1285 * considered to be ordered
1288 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1289 if (strequal(name, "*")) {
1290 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) )
1291 num_addresses += auto_count;
1292 done_auto_lookup = True;
1293 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1295 else
1296 num_addresses++;
1299 /* if we have no addresses and haven't done the auto lookup, then
1300 just return the list of DC's */
1302 if ( (num_addresses == 0) && !done_auto_lookup )
1303 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1305 /* maybe we just failed? */
1307 if ( num_addresses == 0 ) {
1308 DEBUG(4,("get_dc_list: no servers found\n"));
1309 return False;
1312 if ( (return_iplist = (struct ip_service *)
1313 malloc(num_addresses * sizeof(struct ip_service))) == NULL )
1315 DEBUG(3,("get_dc_list: malloc fail !\n"));
1316 return False;
1319 p = pserver;
1320 local_count = 0;
1322 /* fill in the return list now with real IP's */
1324 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1325 struct in_addr name_ip;
1327 /* copy any addersses from the auto lookup */
1329 if ( strequal(name, "*") ) {
1330 for ( j=0; j<auto_count; j++ ) {
1331 return_iplist[local_count].ip = auto_ip_list[j].ip;
1332 return_iplist[local_count].port = auto_ip_list[j].port;
1333 local_count++;
1335 continue;
1339 /* added support for address:port syntax for ads (not that I think
1340 anyone will ever run the LDAP server in an AD domain on something
1341 other than port 389 */
1343 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1344 if ( (port_str=strchr(name, ':')) != NULL ) {
1345 *port_str = '\0';
1346 port_str++;
1347 port = atoi( port_str );
1350 /* explicit lookup; resolve_name() will handle names & IP addresses */
1351 if ( resolve_name( name, &name_ip, 0x20 ) ) {
1352 return_iplist[local_count].ip = name_ip;
1353 return_iplist[local_count].port = port;
1354 local_count++;
1355 *ordered = True;
1359 SAFE_FREE(auto_ip_list);
1361 /* need to remove duplicates in the list if we have any
1362 explicit password servers */
1364 if ( local_count )
1365 local_count = remove_duplicate_addrs2( return_iplist, local_count );
1367 if ( DEBUGLEVEL >= 4 ) {
1368 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
1369 *ordered ? "":"un"));
1370 DEBUG(4,("get_dc_list: "));
1371 for ( i=0; i<local_count; i++ )
1372 DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1373 DEBUGADD(4,("\n"));
1376 *ip_list = return_iplist;
1377 *count = local_count;
1379 return (*count != 0);
1382 DEBUG(10,("get_dc_list: defaulting to internal auto lookup for domain %s\n", domain));
1384 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1387 /*********************************************************************
1388 small wrapper function to get the DC list and sort it if neccessary
1389 *********************************************************************/
1390 BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only )
1392 BOOL ordered;
1394 DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
1395 (ads_only ? "ads" : lp_name_resolve_order())));
1397 if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) )
1398 return False;
1400 /* only sort if we don't already have an ordered list */
1401 if ( !ordered )
1402 sort_ip_list2( *ip_list, *count );
1404 return True;