r17915: Saturn fixes
[Samba/gbeck.git] / source / libsmb / namequery.c
blob57a74ea3c3e0eb2c40e699259385b523913c2c96
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, j;
1028 NTSTATUS status;
1029 TALLOC_CTX *ctx;
1030 struct dns_rr_srv *dcs = NULL;
1031 int numdcs = 0;
1032 int numaddrs = 0;
1034 if ( name_type != 0x1c )
1035 return False;
1037 DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n",
1038 name));
1040 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1041 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1042 return False;
1045 status = ads_dns_query_dcs( ctx, name, &dcs, &numdcs );
1046 if ( !NT_STATUS_IS_OK( status ) ) {
1047 return False;
1050 for (i=0;i<numdcs;i++) {
1051 numaddrs += MAX(dcs[i].num_ips,1);
1054 if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
1055 DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
1056 return False;
1059 /* now unroll the list of IP addresses */
1061 *return_count = 0;
1062 i = 0;
1063 j = 0;
1064 while ( i < numdcs && (*return_count<numaddrs) ) {
1065 struct ip_service *r = &(*return_iplist)[*return_count];
1067 r->port = dcs[i].port;
1069 /* If we don't have an IP list for a name, lookup it up */
1071 if ( !dcs[i].ips ) {
1072 r->ip = *interpret_addr2(dcs[i].hostname);
1073 i++;
1074 j = 0;
1075 } else {
1076 /* use the IP addresses from the SRV sresponse */
1078 if ( j >= dcs[i].num_ips ) {
1079 i++;
1080 j = 0;
1081 continue;
1084 r->ip = dcs[i].ips[j];
1085 j++;
1088 /* make sure it is a valid IP. I considered checking the negative
1089 connection cache, but this is the wrong place for it. Maybe only
1090 as a hac. After think about it, if all of the IP addresses retuend
1091 from DNS are dead, what hope does a netbios name lookup have?
1092 The standard reason for falling back to netbios lookups is that
1093 our DNS server doesn't know anything about the DC's -- jerry */
1095 if ( ! is_zero_ip(r->ip) )
1096 (*return_count)++;
1099 TALLOC_FREE( dcs );
1101 return True;
1104 /*******************************************************************
1105 Internal interface to resolve a name into an IP address.
1106 Use this function if the string is either an IP address, DNS
1107 or host name or NetBIOS name. This uses the name switch in the
1108 smb.conf to determine the order of name resolution.
1110 Added support for ip addr/port to support ADS ldap servers.
1111 the only place we currently care about the port is in the
1112 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1113 **********************************************************************/
1115 BOOL internal_resolve_name(const char *name, int name_type,
1116 struct ip_service **return_iplist,
1117 int *return_count, const char *resolve_order)
1119 pstring name_resolve_list;
1120 fstring tok;
1121 const char *ptr;
1122 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
1123 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
1124 BOOL is_address = is_ipaddress(name);
1125 BOOL result = False;
1126 int i;
1128 *return_iplist = NULL;
1129 *return_count = 0;
1131 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
1133 if (allzeros || allones || is_address) {
1135 if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
1136 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1137 return False;
1140 if(is_address) {
1141 /* ignore the port here */
1142 (*return_iplist)->port = PORT_NONE;
1144 /* if it's in the form of an IP address then get the lib to interpret it */
1145 if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1146 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1147 SAFE_FREE(*return_iplist);
1148 return False;
1150 } else {
1151 (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1153 *return_count = 1;
1154 return True;
1157 /* Check name cache */
1159 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1160 /* This could be a negative response */
1161 return (*return_count > 0);
1164 /* set the name resolution order */
1166 if ( strcmp( resolve_order, "NULL") == 0 ) {
1167 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1168 return False;
1171 if ( !resolve_order ) {
1172 pstrcpy(name_resolve_list, lp_name_resolve_order());
1173 } else {
1174 pstrcpy(name_resolve_list, resolve_order);
1177 if ( !name_resolve_list[0] ) {
1178 ptr = "host";
1179 } else {
1180 ptr = name_resolve_list;
1183 /* iterate through the name resolution backends */
1185 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1186 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1187 if (resolve_hosts(name, name_type, return_iplist, return_count)) {
1188 result = True;
1189 goto done;
1191 } else if(strequal( tok, "ads")) {
1192 /* deal with 0x1c names here. This will result in a
1193 SRV record lookup */
1194 if (resolve_ads(name, name_type, return_iplist, return_count)) {
1195 result = True;
1196 goto done;
1198 } else if(strequal( tok, "lmhosts")) {
1199 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
1200 result = True;
1201 goto done;
1203 } else if(strequal( tok, "wins")) {
1204 /* don't resolve 1D via WINS */
1205 if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) {
1206 result = True;
1207 goto done;
1209 } else if(strequal( tok, "bcast")) {
1210 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
1211 result = True;
1212 goto done;
1214 } else {
1215 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
1219 /* All of the resolve_* functions above have returned false. */
1221 SAFE_FREE(*return_iplist);
1222 *return_count = 0;
1224 return False;
1226 done:
1228 /* Remove duplicate entries. Some queries, notably #1c (domain
1229 controllers) return the PDC in iplist[0] and then all domain
1230 controllers including the PDC in iplist[1..n]. Iterating over
1231 the iplist when the PDC is down will cause two sets of timeouts. */
1233 if ( *return_count ) {
1234 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1237 /* Save in name cache */
1238 if ( DEBUGLEVEL >= 100 ) {
1239 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1240 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1241 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1244 namecache_store(name, name_type, *return_count, *return_iplist);
1246 /* Display some debugging info */
1248 if ( DEBUGLEVEL >= 10 ) {
1249 DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
1251 for (i = 0; i < *return_count; i++) {
1252 DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1254 DEBUG(10, ("\n"));
1257 return result;
1260 /********************************************************
1261 Internal interface to resolve a name into one IP address.
1262 Use this function if the string is either an IP address, DNS
1263 or host name or NetBIOS name. This uses the name switch in the
1264 smb.conf to determine the order of name resolution.
1265 *********************************************************/
1267 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1269 struct ip_service *ip_list = NULL;
1270 int count = 0;
1272 if (is_ipaddress(name)) {
1273 *return_ip = *interpret_addr2(name);
1274 return True;
1277 if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
1278 int i;
1280 /* only return valid addresses for TCP connections */
1281 for (i=0; i<count; i++) {
1282 char *ip_str = inet_ntoa(ip_list[i].ip);
1283 if (ip_str &&
1284 strcmp(ip_str, "255.255.255.255") != 0 &&
1285 strcmp(ip_str, "0.0.0.0") != 0)
1287 *return_ip = ip_list[i].ip;
1288 SAFE_FREE(ip_list);
1289 return True;
1294 SAFE_FREE(ip_list);
1295 return False;
1298 /********************************************************
1299 Find the IP address of the master browser or DMB for a workgroup.
1300 *********************************************************/
1302 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
1304 struct ip_service *ip_list = NULL;
1305 int count = 0;
1307 if (lp_disable_netbios()) {
1308 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1309 return False;
1312 if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
1313 *master_ip = ip_list[0].ip;
1314 SAFE_FREE(ip_list);
1315 return True;
1317 if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
1318 *master_ip = ip_list[0].ip;
1319 SAFE_FREE(ip_list);
1320 return True;
1323 SAFE_FREE(ip_list);
1324 return False;
1327 /********************************************************
1328 Get the IP address list of the primary domain controller
1329 for a domain.
1330 *********************************************************/
1332 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1334 struct ip_service *ip_list;
1335 int count;
1337 /* Look up #1B name */
1339 if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order())) {
1340 return False;
1343 /* if we get more than 1 IP back we have to assume it is a
1344 multi-homed PDC and not a mess up */
1346 if ( count > 1 ) {
1347 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1348 sort_ip_list2( ip_list, count );
1351 *ip = ip_list[0].ip;
1353 SAFE_FREE(ip_list);
1355 return True;
1358 /********************************************************
1359 Get the IP address list of the domain controllers for
1360 a domain.
1361 *********************************************************/
1363 static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
1364 int *count, BOOL ads_only, int *ordered)
1366 fstring resolve_order;
1367 char *saf_servername;
1368 pstring pserver;
1369 const char *p;
1370 char *port_str;
1371 int port;
1372 fstring name;
1373 int num_addresses = 0;
1374 int local_count, i, j;
1375 struct ip_service *return_iplist = NULL;
1376 struct ip_service *auto_ip_list = NULL;
1377 BOOL done_auto_lookup = False;
1378 int auto_count = 0;
1380 *ordered = False;
1382 /* if we are restricted to solely using DNS for looking
1383 up a domain controller, make sure that host lookups
1384 are enabled for the 'name resolve order'. If host lookups
1385 are disabled and ads_only is True, then set the string to
1386 NULL. */
1388 fstrcpy( resolve_order, lp_name_resolve_order() );
1389 strlower_m( resolve_order );
1390 if ( ads_only ) {
1391 if ( strstr( resolve_order, "host" ) ) {
1392 fstrcpy( resolve_order, "ads" );
1394 /* DNS SRV lookups used by the ads resolver
1395 are already sorted by priority and weight */
1396 *ordered = True;
1397 } else {
1398 fstrcpy( resolve_order, "NULL" );
1402 /* fetch the server we have affinity for. Add the
1403 'password server' list to a search for our domain controllers */
1405 saf_servername = saf_fetch( domain );
1407 if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1408 pstr_sprintf( pserver, "%s, %s",
1409 saf_servername ? saf_servername : "",
1410 lp_passwordserver() );
1411 } else {
1412 pstr_sprintf( pserver, "%s, *",
1413 saf_servername ? saf_servername : "" );
1416 SAFE_FREE( saf_servername );
1418 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1420 if ( !*pserver ) {
1421 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1422 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1425 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1428 * if '*' appears in the "password server" list then add
1429 * an auto lookup to the list of manually configured
1430 * DC's. If any DC is listed by name, then the list should be
1431 * considered to be ordered
1434 p = pserver;
1435 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1436 if (strequal(name, "*")) {
1437 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) )
1438 num_addresses += auto_count;
1439 done_auto_lookup = True;
1440 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1441 } else {
1442 num_addresses++;
1446 /* if we have no addresses and haven't done the auto lookup, then
1447 just return the list of DC's. Or maybe we just failed. */
1449 if ( (num_addresses == 0) ) {
1450 if ( !done_auto_lookup ) {
1451 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1452 } else {
1453 DEBUG(4,("get_dc_list: no servers found\n"));
1454 return False;
1458 if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
1459 DEBUG(3,("get_dc_list: malloc fail !\n"));
1460 return False;
1463 p = pserver;
1464 local_count = 0;
1466 /* fill in the return list now with real IP's */
1468 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1469 struct in_addr name_ip;
1471 /* copy any addersses from the auto lookup */
1473 if ( strequal(name, "*") ) {
1474 for ( j=0; j<auto_count; j++ ) {
1475 /* Check for and don't copy any known bad DC IP's. */
1476 if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain,
1477 inet_ntoa(auto_ip_list[j].ip)))) {
1478 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
1479 inet_ntoa(auto_ip_list[j].ip) ));
1480 continue;
1482 return_iplist[local_count].ip = auto_ip_list[j].ip;
1483 return_iplist[local_count].port = auto_ip_list[j].port;
1484 local_count++;
1486 continue;
1490 /* added support for address:port syntax for ads (not that I think
1491 anyone will ever run the LDAP server in an AD domain on something
1492 other than port 389 */
1494 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1495 if ( (port_str=strchr(name, ':')) != NULL ) {
1496 *port_str = '\0';
1497 port_str++;
1498 port = atoi( port_str );
1501 /* explicit lookup; resolve_name() will handle names & IP addresses */
1502 if ( resolve_name( name, &name_ip, 0x20 ) ) {
1504 /* Check for and don't copy any known bad DC IP's. */
1505 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
1506 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
1507 continue;
1510 return_iplist[local_count].ip = name_ip;
1511 return_iplist[local_count].port = port;
1512 local_count++;
1513 *ordered = True;
1517 SAFE_FREE(auto_ip_list);
1519 /* need to remove duplicates in the list if we have any
1520 explicit password servers */
1522 if ( local_count ) {
1523 local_count = remove_duplicate_addrs2( return_iplist, local_count );
1526 if ( DEBUGLEVEL >= 4 ) {
1527 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
1528 *ordered ? "":"un"));
1529 DEBUG(4,("get_dc_list: "));
1530 for ( i=0; i<local_count; i++ )
1531 DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1532 DEBUGADD(4,("\n"));
1535 *ip_list = return_iplist;
1536 *count = local_count;
1538 return (*count != 0);
1541 /*********************************************************************
1542 Small wrapper function to get the DC list and sort it if neccessary.
1543 *********************************************************************/
1545 BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only )
1547 BOOL ordered;
1549 DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
1550 (ads_only ? "ads" : lp_name_resolve_order())));
1552 if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) {
1553 return False;
1556 /* only sort if we don't already have an ordered list */
1557 if ( !ordered ) {
1558 sort_ip_list2( *ip_list, *count );
1561 return True;