Samba 3: added Samba 3.0.24 sources
[tomato.git] / release / src / router / samba3 / source / libsmb / namequery.c
blob718cf28d22e814c6d8efec0b3c585c4acf0fab3d
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_ads: 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 talloc_destroy(ctx);
1048 return False;
1051 for (i=0;i<numdcs;i++) {
1052 numaddrs += MAX(dcs[i].num_ips,1);
1055 if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
1056 DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
1057 talloc_destroy(ctx);
1058 return False;
1061 /* now unroll the list of IP addresses */
1063 *return_count = 0;
1064 i = 0;
1065 j = 0;
1066 while ( i < numdcs && (*return_count<numaddrs) ) {
1067 struct ip_service *r = &(*return_iplist)[*return_count];
1069 r->port = dcs[i].port;
1071 /* If we don't have an IP list for a name, lookup it up */
1073 if ( !dcs[i].ips ) {
1074 r->ip = *interpret_addr2(dcs[i].hostname);
1075 i++;
1076 j = 0;
1077 } else {
1078 /* use the IP addresses from the SRV sresponse */
1080 if ( j >= dcs[i].num_ips ) {
1081 i++;
1082 j = 0;
1083 continue;
1086 r->ip = dcs[i].ips[j];
1087 j++;
1090 /* make sure it is a valid IP. I considered checking the negative
1091 connection cache, but this is the wrong place for it. Maybe only
1092 as a hac. After think about it, if all of the IP addresses retuend
1093 from DNS are dead, what hope does a netbios name lookup have?
1094 The standard reason for falling back to netbios lookups is that
1095 our DNS server doesn't know anything about the DC's -- jerry */
1097 if ( ! is_zero_ip(r->ip) )
1098 (*return_count)++;
1101 talloc_destroy(ctx);
1102 return True;
1105 /*******************************************************************
1106 Internal interface to resolve a name into an IP address.
1107 Use this function if the string is either an IP address, DNS
1108 or host name or NetBIOS name. This uses the name switch in the
1109 smb.conf to determine the order of name resolution.
1111 Added support for ip addr/port to support ADS ldap servers.
1112 the only place we currently care about the port is in the
1113 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1114 **********************************************************************/
1116 BOOL internal_resolve_name(const char *name, int name_type,
1117 struct ip_service **return_iplist,
1118 int *return_count, const char *resolve_order)
1120 pstring name_resolve_list;
1121 fstring tok;
1122 const char *ptr;
1123 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
1124 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
1125 BOOL is_address = is_ipaddress(name);
1126 BOOL result = False;
1127 int i;
1129 *return_iplist = NULL;
1130 *return_count = 0;
1132 DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
1134 if (allzeros || allones || is_address) {
1136 if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
1137 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1138 return False;
1141 if(is_address) {
1142 /* ignore the port here */
1143 (*return_iplist)->port = PORT_NONE;
1145 /* if it's in the form of an IP address then get the lib to interpret it */
1146 if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1147 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1148 SAFE_FREE(*return_iplist);
1149 return False;
1151 } else {
1152 (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1154 *return_count = 1;
1155 return True;
1158 /* Check name cache */
1160 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1161 /* This could be a negative response */
1162 return (*return_count > 0);
1165 /* set the name resolution order */
1167 if ( strcmp( resolve_order, "NULL") == 0 ) {
1168 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1169 return False;
1172 if ( !resolve_order ) {
1173 pstrcpy(name_resolve_list, lp_name_resolve_order());
1174 } else {
1175 pstrcpy(name_resolve_list, resolve_order);
1178 if ( !name_resolve_list[0] ) {
1179 ptr = "host";
1180 } else {
1181 ptr = name_resolve_list;
1184 /* iterate through the name resolution backends */
1186 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1187 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1188 if (resolve_hosts(name, name_type, return_iplist, return_count)) {
1189 result = True;
1190 goto done;
1192 } else if(strequal( tok, "ads")) {
1193 /* deal with 0x1c names here. This will result in a
1194 SRV record lookup */
1195 if (resolve_ads(name, name_type, return_iplist, return_count)) {
1196 result = True;
1197 goto done;
1199 } else if(strequal( tok, "lmhosts")) {
1200 if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
1201 result = True;
1202 goto done;
1204 } else if(strequal( tok, "wins")) {
1205 /* don't resolve 1D via WINS */
1206 if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) {
1207 result = True;
1208 goto done;
1210 } else if(strequal( tok, "bcast")) {
1211 if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
1212 result = True;
1213 goto done;
1215 } else {
1216 DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
1220 /* All of the resolve_* functions above have returned false. */
1222 SAFE_FREE(*return_iplist);
1223 *return_count = 0;
1225 return False;
1227 done:
1229 /* Remove duplicate entries. Some queries, notably #1c (domain
1230 controllers) return the PDC in iplist[0] and then all domain
1231 controllers including the PDC in iplist[1..n]. Iterating over
1232 the iplist when the PDC is down will cause two sets of timeouts. */
1234 if ( *return_count ) {
1235 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1238 /* Save in name cache */
1239 if ( DEBUGLEVEL >= 100 ) {
1240 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1241 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1242 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1245 namecache_store(name, name_type, *return_count, *return_iplist);
1247 /* Display some debugging info */
1249 if ( DEBUGLEVEL >= 10 ) {
1250 DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
1252 for (i = 0; i < *return_count; i++) {
1253 DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1255 DEBUG(10, ("\n"));
1258 return result;
1261 /********************************************************
1262 Internal interface to resolve a name into one IP address.
1263 Use this function if the string is either an IP address, DNS
1264 or host name or NetBIOS name. This uses the name switch in the
1265 smb.conf to determine the order of name resolution.
1266 *********************************************************/
1268 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1270 struct ip_service *ip_list = NULL;
1271 int count = 0;
1273 if (is_ipaddress(name)) {
1274 *return_ip = *interpret_addr2(name);
1275 return True;
1278 if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
1279 int i;
1281 /* only return valid addresses for TCP connections */
1282 for (i=0; i<count; i++) {
1283 char *ip_str = inet_ntoa(ip_list[i].ip);
1284 if (ip_str &&
1285 strcmp(ip_str, "255.255.255.255") != 0 &&
1286 strcmp(ip_str, "0.0.0.0") != 0)
1288 *return_ip = ip_list[i].ip;
1289 SAFE_FREE(ip_list);
1290 return True;
1295 SAFE_FREE(ip_list);
1296 return False;
1299 /********************************************************
1300 Find the IP address of the master browser or DMB for a workgroup.
1301 *********************************************************/
1303 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
1305 struct ip_service *ip_list = NULL;
1306 int count = 0;
1308 if (lp_disable_netbios()) {
1309 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1310 return False;
1313 if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
1314 *master_ip = ip_list[0].ip;
1315 SAFE_FREE(ip_list);
1316 return True;
1318 if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
1319 *master_ip = ip_list[0].ip;
1320 SAFE_FREE(ip_list);
1321 return True;
1324 SAFE_FREE(ip_list);
1325 return False;
1328 /********************************************************
1329 Get the IP address list of the primary domain controller
1330 for a domain.
1331 *********************************************************/
1333 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1335 struct ip_service *ip_list;
1336 int count;
1338 /* Look up #1B name */
1340 if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order())) {
1341 return False;
1344 /* if we get more than 1 IP back we have to assume it is a
1345 multi-homed PDC and not a mess up */
1347 if ( count > 1 ) {
1348 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1349 sort_ip_list2( ip_list, count );
1352 *ip = ip_list[0].ip;
1354 SAFE_FREE(ip_list);
1356 return True;
1359 /********************************************************
1360 Get the IP address list of the domain controllers for
1361 a domain.
1362 *********************************************************/
1364 static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
1365 int *count, BOOL ads_only, int *ordered)
1367 fstring resolve_order;
1368 char *saf_servername;
1369 pstring pserver;
1370 const char *p;
1371 char *port_str;
1372 int port;
1373 fstring name;
1374 int num_addresses = 0;
1375 int local_count, i, j;
1376 struct ip_service *return_iplist = NULL;
1377 struct ip_service *auto_ip_list = NULL;
1378 BOOL done_auto_lookup = False;
1379 int auto_count = 0;
1381 *ordered = False;
1383 /* if we are restricted to solely using DNS for looking
1384 up a domain controller, make sure that host lookups
1385 are enabled for the 'name resolve order'. If host lookups
1386 are disabled and ads_only is True, then set the string to
1387 NULL. */
1389 fstrcpy( resolve_order, lp_name_resolve_order() );
1390 strlower_m( resolve_order );
1391 if ( ads_only ) {
1392 if ( strstr( resolve_order, "host" ) ) {
1393 fstrcpy( resolve_order, "ads" );
1395 /* DNS SRV lookups used by the ads resolver
1396 are already sorted by priority and weight */
1397 *ordered = True;
1398 } else {
1399 fstrcpy( resolve_order, "NULL" );
1403 /* fetch the server we have affinity for. Add the
1404 'password server' list to a search for our domain controllers */
1406 saf_servername = saf_fetch( domain );
1408 if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1409 pstr_sprintf( pserver, "%s, %s",
1410 saf_servername ? saf_servername : "",
1411 lp_passwordserver() );
1412 } else {
1413 pstr_sprintf( pserver, "%s, *",
1414 saf_servername ? saf_servername : "" );
1417 SAFE_FREE( saf_servername );
1419 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1421 if ( !*pserver ) {
1422 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1423 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1426 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1429 * if '*' appears in the "password server" list then add
1430 * an auto lookup to the list of manually configured
1431 * DC's. If any DC is listed by name, then the list should be
1432 * considered to be ordered
1435 p = pserver;
1436 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1437 if (strequal(name, "*")) {
1438 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) )
1439 num_addresses += auto_count;
1440 done_auto_lookup = True;
1441 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1442 } else {
1443 num_addresses++;
1447 /* if we have no addresses and haven't done the auto lookup, then
1448 just return the list of DC's. Or maybe we just failed. */
1450 if ( (num_addresses == 0) ) {
1451 if ( !done_auto_lookup ) {
1452 return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
1453 } else {
1454 DEBUG(4,("get_dc_list: no servers found\n"));
1455 return False;
1459 if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
1460 DEBUG(3,("get_dc_list: malloc fail !\n"));
1461 return False;
1464 p = pserver;
1465 local_count = 0;
1467 /* fill in the return list now with real IP's */
1469 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1470 struct in_addr name_ip;
1472 /* copy any addersses from the auto lookup */
1474 if ( strequal(name, "*") ) {
1475 for ( j=0; j<auto_count; j++ ) {
1476 /* Check for and don't copy any known bad DC IP's. */
1477 if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain,
1478 inet_ntoa(auto_ip_list[j].ip)))) {
1479 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
1480 inet_ntoa(auto_ip_list[j].ip) ));
1481 continue;
1483 return_iplist[local_count].ip = auto_ip_list[j].ip;
1484 return_iplist[local_count].port = auto_ip_list[j].port;
1485 local_count++;
1487 continue;
1491 /* added support for address:port syntax for ads (not that I think
1492 anyone will ever run the LDAP server in an AD domain on something
1493 other than port 389 */
1495 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1496 if ( (port_str=strchr(name, ':')) != NULL ) {
1497 *port_str = '\0';
1498 port_str++;
1499 port = atoi( port_str );
1502 /* explicit lookup; resolve_name() will handle names & IP addresses */
1503 if ( resolve_name( name, &name_ip, 0x20 ) ) {
1505 /* Check for and don't copy any known bad DC IP's. */
1506 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
1507 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
1508 continue;
1511 return_iplist[local_count].ip = name_ip;
1512 return_iplist[local_count].port = port;
1513 local_count++;
1514 *ordered = True;
1518 SAFE_FREE(auto_ip_list);
1520 /* need to remove duplicates in the list if we have any
1521 explicit password servers */
1523 if ( local_count ) {
1524 local_count = remove_duplicate_addrs2( return_iplist, local_count );
1527 if ( DEBUGLEVEL >= 4 ) {
1528 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
1529 *ordered ? "":"un"));
1530 DEBUG(4,("get_dc_list: "));
1531 for ( i=0; i<local_count; i++ )
1532 DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1533 DEBUGADD(4,("\n"));
1536 *ip_list = return_iplist;
1537 *count = local_count;
1539 return (*count != 0);
1542 /*********************************************************************
1543 Small wrapper function to get the DC list and sort it if neccessary.
1544 *********************************************************************/
1546 BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only )
1548 BOOL ordered;
1550 DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
1551 (ads_only ? "ads" : lp_name_resolve_order())));
1553 if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) {
1554 return False;
1557 /* only sort if we don't already have an ordered list */
1558 if ( !ordered ) {
1559 sort_ip_list2( *ip_list, *count );
1562 return True;