trying to get HEAD building again. If you want the code
[nivanova/samba-autobuild/.git] / source3 / libsmb / namequery.c
1 /* 
2    Unix SMB/CIFS implementation.
3    name query routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    
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.
10    
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.
15    
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.
19    
20 */
21
22 #include "includes.h"
23
24 /* nmbd.c sets this to True. */
25 BOOL global_in_nmbd = False;
26
27 /****************************************************************************
28  Generate a random trn_id.
29 ****************************************************************************/
30
31 static int generate_trn_id(void)
32 {
33         static int trn_id;
34
35         if (trn_id == 0) {
36                 sys_srandom(sys_getpid());
37         }
38
39         trn_id = sys_random();
40
41         return trn_id % (unsigned)0x7FFF;
42 }
43
44 /****************************************************************************
45  Parse a node status response into an array of structures.
46 ****************************************************************************/
47
48 static struct node_status *parse_node_status(char *p, int *num_names)
49 {
50         struct node_status *ret;
51         int i;
52
53         *num_names = CVAL(p,0);
54
55         if (*num_names == 0)
56                 return NULL;
57
58         ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
59         if (!ret) return NULL;
60
61         p++;
62         for (i=0;i< *num_names;i++) {
63                 StrnCpy(ret[i].name,p,15);
64                 trim_string(ret[i].name,NULL," ");
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));
70         }
71         return ret;
72 }
73
74
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 **************************************************************************/
79
80 struct node_status *node_status_query(int fd,struct nmb_name *name,
81                                       struct in_addr to_ip, int *num_names)
82 {
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;
91
92         ZERO_STRUCT(p);
93
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;
110
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;
116         
117         GetTimeOfDay(&tval);
118   
119         if (!send_packet(&p)) 
120                 return NULL;
121
122         retries--;
123
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--;
134                 }
135
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);
139                         
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;
150                         }
151
152                         ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
153                         free_packet(p2);
154                         return ret;
155                 }
156         }
157         
158         return NULL;
159 }
160
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 **************************************************************************/
165
166 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
167 {
168         struct node_status *status = NULL;
169         struct nmb_name nname;
170         int count, i;
171         int sock;
172         BOOL result = False;
173
174         if (lp_disable_netbios()) {
175                 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
176                 return False;
177         }
178
179         DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, 
180                    q_type, inet_ntoa(to_ip)));
181
182         /* Check the cache first. */
183
184         if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
185                 return True;
186
187         sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
188         if (sock == -1)
189                 goto done;
190
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;
197
198         for (i=0;i<count;i++) {
199                 if (status[i].type == type)
200                         break;
201         }
202         if (i == count)
203                 goto done;
204
205         pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
206
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 */
210            
211         if ( q_type != 0x1c )
212                 namecache_status_store(q_name, q_type, type, to_ip, name);
213
214         result = True;
215
216  done:
217         SAFE_FREE(status);
218
219         DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
220
221         if (result)
222                 DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
223
224         DEBUG(10, ("\n"));      
225
226         return result;
227 }
228
229 /*
230   comparison function used by sort_ip_list
231 */
232
233 int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
234 {
235         int max_bits1=0, max_bits2=0;
236         int num_interfaces = iface_count();
237         int i;
238
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);
247         }       
248         
249         /* bias towards directly reachable IPs */
250         if (iface_local(*ip1)) {
251                 max_bits1 += 32;
252         }
253         if (iface_local(*ip2)) {
254                 max_bits2 += 32;
255         }
256
257         return max_bits2 - max_bits1;
258 }
259
260 /*******************************************************************
261  compare 2 ldap IPs by nearness to our interfaces - used in qsort
262 *******************************************************************/
263
264 static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
265 {
266         int result;
267         
268         if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
269                 return result;
270                 
271         if ( ip1->port > ip2->port )
272                 return 1;
273         
274         if ( ip1->port < ip2->port )
275                 return -1;
276                 
277         return 0;
278 }
279
280 /*
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
284 */
285
286 static void sort_ip_list(struct in_addr *iplist, int count)
287 {
288         if (count <= 1) {
289                 return;
290         }
291
292         qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);    
293 }
294
295 void sort_ip_list2(struct ip_service *iplist, int count)
296 {
297         if (count <= 1) {
298                 return;
299         }
300
301         qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare); 
302 }
303
304 /**********************************************************************
305  Remove any duplicate address/port pairs in the list 
306  *********************************************************************/
307
308 static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
309 {
310         int i, j;
311         
312         DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
313         
314         /* one loop to remove duplicates */
315         for ( i=0; i<count; i++ ) {
316                 if ( is_zero_ip(iplist[i].ip) )
317                         continue;
318                                         
319                 for ( j=i+1; j<count; j++ ) {
320                         if ( ip_service_equal(iplist[i], iplist[j]) )
321                                 zero_ip(&iplist[j].ip);
322                 }
323         }
324                         
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;
333                 }
334                 i++;
335         }
336
337         return count;
338 }
339
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 ****************************************************************************/
346
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)
351 {
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;
360
361         if (lp_disable_netbios()) {
362                 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
363                 return NULL;
364         }
365
366         if (timed_out) {
367                 *timed_out = False;
368         }
369         
370         memset((char *)&p,'\0',sizeof(p));
371         (*count) = 0;
372         (*flags) = 0;
373         
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;
387         
388         make_nmb_name(&nmb->question.question_name,name,name_type);
389         
390         nmb->question.question_type = 0x20;
391         nmb->question.question_class = 0x1;
392         
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;
398         
399         GetTimeOfDay(&tval);
400         
401         if (!send_packet(&p)) 
402                 return NULL;
403         
404         retries--;
405         
406         while (1) {
407                 struct timeval tval2;
408                 struct in_addr *tmp_ip_list;
409                 
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--;
418                 }
419                 
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);
423                         
424                         /* If we get a Negative Name Query Response from a WINS
425                          * server, we should report it and give up.
426                          */
427                         if( 0 == nmb2->header.opcode            /* A query response   */
428                             && !(bcast)                 /* from a WINS server */
429                             && nmb2->header.rcode               /* Error returned     */
430                                 ) {
431                                 
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;
454                                         }
455                                 }
456                                 free_packet(p2);
457                                 return( NULL );
458                         }
459                         
460                         if (nmb2->header.opcode != 0 ||
461                             nmb2->header.nm_flags.bcast ||
462                             nmb2->header.rcode ||
463                             !nmb2->header.ancount) {
464                                 /* 
465                                  * XXXX what do we do with this? Could be a
466                                  * redirect, but we'll discard it for the
467                                  * moment.
468                                  */
469                                 free_packet(p2);
470                                 continue;
471                         }
472                         
473                         tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
474                                                                  * ( (*count) + nmb2->answers->rdlength/6 ) );
475                         
476                         if (!tmp_ip_list) {
477                                 DEBUG(0,("name_query: Realloc failed.\n"));
478                                 SAFE_FREE(ip_list);
479                         }
480                         
481                         ip_list = tmp_ip_list;
482                         
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)++;
489                                 }
490                                 DEBUGADD(2,(")\n"));
491                         }
492                         
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);
509                         /*
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.
513                          */
514                         if(!bcast && found)
515                                 break;
516                 }
517         }
518
519         /* only set timed_out if we didn't fund what we where looking for*/
520         
521         if ( !found && timed_out ) {
522                 *timed_out = True;
523         }
524
525         /* sort the ip list so we choose close servers first if possible */
526         sort_ip_list(ip_list, *count);
527
528         return ip_list;
529 }
530
531 /********************************************************
532  Start parsing the lmhosts file.
533 *********************************************************/
534
535 XFILE *startlmhosts(char *fname)
536 {
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;
542         }
543         return fp;
544 }
545
546 /********************************************************
547  Parse the next line in the lmhosts file.
548 *********************************************************/
549
550 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
551 {
552   pstring line;
553
554   while(!x_feof(fp) && !x_ferror(fp)) {
555     pstring ip,flags,extra;
556     const char *ptr;
557     char *ptr1;
558     int count = 0;
559
560     *name_type = -1;
561
562     if (!fgets_slash(line,sizeof(pstring),fp))
563       continue;
564
565     if (*line == '#')
566       continue;
567
568     pstrcpy(ip,"");
569     pstrcpy(name,"");
570     pstrcpy(flags,"");
571
572     ptr = line;
573
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;
582
583     if (count <= 0)
584       continue;
585
586     if (count > 0 && count < 2)
587     {
588       DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
589       continue;
590     }
591
592     if (count >= 4)
593     {
594       DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
595       continue;
596     }
597
598     DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
599
600     if (strchr_m(flags,'G') || strchr_m(flags,'S'))
601     {
602       DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
603       continue;
604     }
605
606     *ipaddr = *interpret_addr2(ip);
607
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)
611     {
612       char *endptr;
613
614       ptr1++;
615       *name_type = (int)strtol(ptr1, &endptr, 16);
616
617       if(!*ptr1 || (endptr == ptr1))
618       {
619         DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
620         continue;
621       }
622
623       *(--ptr1) = '\0'; /* Truncate at the '#' */
624     }
625
626     return True;
627   }
628
629   return False;
630 }
631
632 /********************************************************
633  Finish parsing the lmhosts file.
634 *********************************************************/
635
636 void endlmhosts(XFILE *fp)
637 {
638         x_fclose(fp);
639 }
640
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 *********************************************************/
645
646 static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
647 {
648         int i;
649
650         if ( count==0 || !ip_list )
651                 return False;
652                 
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;
657         }
658         
659         for ( i=0; i<count; i++ ) {
660                 (*return_iplist)[i].ip   = ip_list[i];
661                 (*return_iplist)[i].port = PORT_NONE;
662         }
663
664         return True;
665 }       
666 /********************************************************
667  Resolve via "bcast" method.
668 *********************************************************/
669
670 BOOL name_resolve_bcast(const char *name, int name_type,
671                         struct ip_service **return_iplist, int *return_count)
672 {
673         int sock, i;
674         int num_interfaces = iface_count();
675         struct in_addr *ip_list;
676         BOOL ret;
677
678         if (lp_disable_netbios()) {
679                 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
680                 return False;
681         }
682
683         *return_iplist = NULL;
684         *return_count = 0;
685         
686         /*
687          * "bcast" means do a broadcast lookup on all the local interfaces.
688          */
689
690         DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
691
692         sock = open_socket_in( SOCK_DGRAM, 0, 3,
693                                interpret_addr(lp_socket_address()), True );
694
695         if (sock == -1) return False;
696
697         set_socket_options(sock,"SO_BROADCAST");
698         /*
699          * Lookup the name on all the interfaces, return on
700          * the first successful match.
701          */
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;
711         }
712         
713         /* failed - no response */
714         
715         close(sock);
716         return False;
717         
718 success:
719         ret = True;
720         if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
721                 ret = False;
722         
723         SAFE_FREE( ip_list );
724         close(sock);
725         return ret;
726 }
727
728 /********************************************************
729  Resolve via "wins" method.
730 *********************************************************/
731
732 BOOL resolve_wins(const char *name, int name_type,
733                   struct ip_service **return_iplist, int *return_count)
734 {
735         int sock, t, i;
736         char **wins_tags;
737         struct in_addr src_ip, *ip_list = NULL;
738         BOOL ret;
739
740         if (lp_disable_netbios()) {
741                 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
742                 return False;
743         }
744
745         *return_iplist = NULL;
746         *return_count = 0;
747         
748         DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
749
750         if (wins_srv_count() < 1) {
751                 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
752                 return False;
753         }
754
755         /* we try a lookup on each of the WINS tags in turn */
756         wins_tags = wins_srv_tags();
757
758         if (!wins_tags) {
759                 /* huh? no tags?? give up in disgust */
760                 return False;
761         }
762
763         /* the address we will be sending from */
764         src_ip = *interpret_addr2(lp_socket_address());
765
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;
774
775                         wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
776
777                         if (global_in_nmbd && ismyip(wins_ip)) {
778                                 /* yikes! we'll loop forever */
779                                 continue;
780                         }
781
782                         /* skip any that have been unresponsive lately */
783                         if (wins_srv_is_dead(wins_ip, src_ip)) {
784                                 continue;
785                         }
786
787                         DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
788
789                         sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
790                         if (sock == -1) {
791                                 continue;
792                         }
793
794                         ip_list = name_query(sock,name,name_type, False, 
795                                                     True, wins_ip, return_count, &flags, 
796                                                     &timed_out);
797                                                     
798                         /* exit loop if we got a list of addresses */
799                         
800                         if ( ip_list ) 
801                                 goto success;
802                                 
803                         close(sock);
804
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;
812                         }
813                 }
814         }
815
816         wins_srv_tags_free(wins_tags);
817         return False;
818
819 success:
820         ret = True;
821         if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
822                 ret = False;
823         
824         SAFE_FREE( ip_list );
825         wins_srv_tags_free(wins_tags);
826         close(sock);
827         
828         return ret;
829 }
830
831 /********************************************************
832  Resolve via "lmhosts" method.
833 *********************************************************/
834
835 static BOOL resolve_lmhosts(const char *name, int name_type,
836                          struct ip_service **return_iplist, int *return_count)
837 {
838         /*
839          * "lmhosts" means parse the local lmhosts file.
840          */
841         
842         XFILE *fp;
843         pstring lmhost_name;
844         int name_type2;
845         struct in_addr return_ip;
846
847         *return_iplist = NULL;
848         *return_count = 0;
849
850         DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
851
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))
857                ) {
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;
862                                 }
863                                 (*return_iplist)[0].ip   = return_ip;
864                                 (*return_iplist)[0].port = PORT_NONE;
865                                 *return_count = 1;
866                                 return True; 
867                         }
868                 }
869                 endlmhosts(fp);
870         }
871         return False;
872 }
873
874
875 /********************************************************
876  Resolve via "hosts" method.
877 *********************************************************/
878
879 static BOOL resolve_hosts(const char *name, int name_type,
880                          struct ip_service **return_iplist, int *return_count)
881 {
882         /*
883          * "host" means do a localhost, or dns lookup.
884          */
885         struct hostent *hp;
886         
887 #ifdef HAVE_ADS
888         if ( name_type == 0x1c ) {
889                 int                     count, i = 0;
890                 char                    *list = NULL;
891                 const char              *ptr;
892                 pstring                 tok;
893                 
894                 /* try to lookup the _ldap._tcp.<domain> if we are using ADS */
895                 if ( lp_security() != SEC_ADS )
896                         return False;
897                         
898                 DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n",
899                         name));
900                         
901                 if (ldap_domain2hostlist(name, &list) != LDAP_SUCCESS)
902                         return False;
903                                 
904                 count = count_chars(list, ' ') + 1;
905                 if ( (*return_iplist = malloc(count * sizeof(struct ip_service))) == NULL ) {
906                         DEBUG(0,("resolve_hosts: malloc failed for %d entries\n", count ));
907                         return False;
908                 }
909
910                 ptr = list;
911                 while (next_token(&ptr, tok, " ", sizeof(tok))) {
912                         unsigned port = LDAP_PORT;      
913                         char *p = strchr(tok, ':');
914                         if (p) {
915                                 *p = 0;
916                                 port = atoi(p+1);
917                         }
918                         (*return_iplist)[i].ip   = *interpret_addr2(tok);
919                         (*return_iplist)[i].port = port;
920                         
921                         /* make sure it is a valid IP.  I considered checking the negative
922                            connection cache, but this is the wrong place for it.  Maybe only
923                            as a hac.  After think about it, if all of the IP addresses retuend
924                            from DNS are dead, what hope does a netbios name lookup have?
925                            The standard reason for falling back to netbios lookups is that 
926                            our DNS server doesn't know anything about the DC's   -- jerry */    
927                            
928                         if ( is_zero_ip((*return_iplist)[i].ip) )
929                                 continue;
930                 
931                         i++;
932                 }
933                 SAFE_FREE(list);
934                 
935                 *return_count = i;
936                                 
937                 return True;
938         }
939 #endif  /* HAVE_ADS */
940
941         *return_iplist = NULL;
942         *return_count = 0;
943
944         DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
945         
946         if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
947                 struct in_addr return_ip;
948                 putip((char *)&return_ip,(char *)hp->h_addr);
949                 *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service));
950                 if(*return_iplist == NULL) {
951                         DEBUG(3,("resolve_hosts: malloc fail !\n"));
952                         return False;
953                 }
954                 (*return_iplist)->ip   = return_ip;
955                 (*return_iplist)->port = PORT_NONE;
956                 *return_count = 1;
957                 return True;
958         }
959         return False;
960 }
961
962 /*******************************************************************
963  Internal interface to resolve a name into an IP address.
964  Use this function if the string is either an IP address, DNS
965  or host name or NetBIOS name. This uses the name switch in the
966  smb.conf to determine the order of name resolution.
967  
968  Added support for ip addr/port to support ADS ldap servers.
969  the only place we currently care about the port is in the 
970  resolve_hosts() when looking up DC's via SRV RR entries in DNS
971 **********************************************************************/
972
973 static BOOL internal_resolve_name(const char *name, int name_type,
974                                   struct ip_service **return_iplist, 
975                                   int *return_count, const char *resolve_order)
976 {
977   pstring name_resolve_list;
978   fstring tok;
979   const char *ptr;
980   BOOL allones = (strcmp(name,"255.255.255.255") == 0);
981   BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
982   BOOL is_address = is_ipaddress(name);
983   BOOL result = False;
984   int i;
985
986   *return_iplist = NULL;
987   *return_count = 0;
988
989   DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
990
991   if (allzeros || allones || is_address) {
992   
993         if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
994                 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
995                 return False;
996         }
997         
998         if(is_address) { 
999                 /* ignore the port here */
1000                 (*return_iplist)->port = PORT_NONE;
1001                 
1002                 /* if it's in the form of an IP address then get the lib to interpret it */
1003                 if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1004                         DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1005                         return False;
1006                 }
1007         } else {
1008                 (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1009                 *return_count = 1;
1010         }
1011     return True;
1012   }
1013   
1014   /* Check name cache */
1015
1016   if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1017         /* This could be a negative response */
1018         return (*return_count > 0);
1019   }
1020
1021   /* set the name resolution order */
1022   
1023   if ( !resolve_order )
1024     pstrcpy(name_resolve_list, lp_name_resolve_order());
1025   else
1026     pstrcpy(name_resolve_list, resolve_order);
1027   
1028   if ( !name_resolve_list[0] )
1029     ptr = "host";
1030   else
1031     ptr = name_resolve_list;
1032
1033   /* iterate through the name resolution backends */
1034   
1035   while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1036           if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1037                   /* deal with 0x20 & 0x1c names here.  The latter will result
1038                      in a SRV record lookup for _ldap._tcp.<domain> if we are using 
1039                      'security = ads' */
1040                   if ( name_type==0x20 || name_type == 0x1c ) {
1041                           if (resolve_hosts(name, name_type, return_iplist, return_count)) {
1042                                   result = True;
1043                                   goto done;
1044                           }
1045                   }
1046           } else if(strequal( tok, "lmhosts")) {
1047                   if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
1048                     result = True;
1049                     goto done;
1050                   }
1051           } else if(strequal( tok, "wins")) {
1052                   /* don't resolve 1D via WINS */
1053                   if (name_type != 0x1D &&
1054                       resolve_wins(name, name_type, return_iplist, return_count)) {
1055                     result = True;
1056                     goto done;
1057                   }
1058           } else if(strequal( tok, "bcast")) {
1059                   if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
1060                     result = True;
1061                     goto done;
1062                   }
1063           } else {
1064                   DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
1065           }
1066   }
1067
1068   /* All of the resolve_* functions above have returned false. */
1069
1070   SAFE_FREE(*return_iplist);
1071   *return_count = 0;
1072
1073   return False;
1074
1075  done:
1076
1077   /* Remove duplicate entries.  Some queries, notably #1c (domain
1078      controllers) return the PDC in iplist[0] and then all domain
1079      controllers including the PDC in iplist[1..n].  Iterating over
1080      the iplist when the PDC is down will cause two sets of timeouts. */
1081
1082   if ( *return_count ) {
1083     *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1084   }
1085  
1086   /* Save in name cache */
1087   if ( DEBUGLEVEL >= 100 ) {
1088     for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1089       DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1090                 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1091   }
1092    
1093   namecache_store(name, name_type, *return_count, *return_iplist);
1094
1095   /* Display some debugging info */
1096
1097   if ( DEBUGLEVEL >= 10 ) {
1098     DEBUG(10, ("internal_resolve_name: returning %d addresses: ", 
1099                *return_count));
1100
1101     for (i = 0; i < *return_count; i++)
1102           DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1103
1104     DEBUG(10, ("\n"));
1105   }
1106   
1107   return result;
1108 }
1109
1110 /********************************************************
1111  Internal interface to resolve a name into one IP address.
1112  Use this function if the string is either an IP address, DNS
1113  or host name or NetBIOS name. This uses the name switch in the
1114  smb.conf to determine the order of name resolution.
1115 *********************************************************/
1116
1117 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1118 {
1119         struct ip_service *ip_list = NULL;
1120         int count = 0;
1121
1122         if (is_ipaddress(name)) {
1123                 *return_ip = *interpret_addr2(name);
1124                 return True;
1125         }
1126
1127         if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
1128                 int i;
1129                 
1130                 /* only return valid addresses for TCP connections */
1131                 for (i=0; i<count; i++) {
1132                         char *ip_str = inet_ntoa(ip_list[i].ip);
1133                         if (ip_str &&
1134                             strcmp(ip_str, "255.255.255.255") != 0 &&
1135                             strcmp(ip_str, "0.0.0.0") != 0) 
1136                         {
1137                                 *return_ip = ip_list[i].ip;
1138                                 SAFE_FREE(ip_list);
1139                                 return True;
1140                         }
1141                 }
1142         }
1143         
1144         SAFE_FREE(ip_list);
1145         return False;
1146 }
1147
1148 /********************************************************
1149  Find the IP address of the master browser or DMB for a workgroup.
1150 *********************************************************/
1151
1152 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
1153 {
1154         struct ip_service *ip_list = NULL;
1155         int count = 0;
1156
1157         if (lp_disable_netbios()) {
1158                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1159                 return False;
1160         }
1161
1162         if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
1163                 *master_ip = ip_list[0].ip;
1164                 SAFE_FREE(ip_list);
1165                 return True;
1166         }
1167         if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
1168                 *master_ip = ip_list[0].ip;
1169                 SAFE_FREE(ip_list);
1170                 return True;
1171         }
1172
1173         SAFE_FREE(ip_list);
1174         return False;
1175 }
1176
1177 /********************************************************
1178  Get the IP address list of the primary domain controller
1179  for a domain.
1180 *********************************************************/
1181
1182 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1183 {
1184         struct ip_service *ip_list;
1185         int count;
1186
1187         /* Look up #1B name */
1188
1189         if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order()))
1190                 return False;
1191
1192         /* if we get more than 1 IP back we have to assume it is a
1193            multi-homed PDC and not a mess up */
1194
1195         if ( count > 1 ) {
1196                 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));             
1197                 sort_ip_list2( ip_list, count );
1198         }
1199
1200         *ip = ip_list[0].ip;
1201         
1202         SAFE_FREE(ip_list);
1203
1204         return True;
1205 }
1206
1207 /*********************************************************************
1208  small wrapper function to get the DC list and sort it if neccessary 
1209 *********************************************************************/
1210 BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL dns_only )
1211 {
1212         BOOL ordered;
1213         
1214         DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
1215                 (dns_only ? "hosts" : lp_name_resolve_order())));
1216         
1217         if ( !get_dc_list(domain, ip_list, count, dns_only, &ordered) )
1218                 return False;
1219                 
1220         /* only sort if we don't already have an ordered list */
1221         if ( !ordered )
1222                 sort_ip_list2( *ip_list, *count );
1223                 
1224         return True;
1225 }
1226
1227 /********************************************************
1228  Get the IP address list of the domain controllers for
1229  a domain.
1230 *********************************************************/
1231
1232 BOOL get_dc_list(const char *domain, struct ip_service **ip_list, 
1233                  int *count, BOOL dns_only, int *ordered)
1234 {
1235         /* defined the name resolve order to internal_name_resolve() 
1236            only used for looking up 0x1c names */
1237         const char *resolve_oder = (dns_only ? "hosts" : lp_name_resolve_order());
1238         
1239         *ordered = False;
1240                 
1241         /* If it's our domain then use the 'password server' parameter. */
1242
1243         if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1244                 const char *p;
1245                 char *pserver = lp_passwordserver(); /* UNIX charset. */
1246                 char *port_str;
1247                 int port;
1248                 fstring name;
1249                 int num_addresses = 0;
1250                 int  local_count, i, j;
1251                 struct ip_service *return_iplist = NULL;
1252                 struct ip_service *auto_ip_list = NULL;
1253                 BOOL done_auto_lookup = False;
1254                 int auto_count = 0;
1255                 
1256
1257                 if (!*pserver)
1258                         return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder);
1259
1260                 p = pserver;
1261
1262                 /*
1263                  * if '*' appears in the "password server" list then add
1264                  * an auto lookup to the list of manually configured
1265                  * DC's.  If any DC is listed by name, then the list should be 
1266                  * considered to be ordered 
1267                  */
1268                  
1269                 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1270                         if (strequal(name, "*")) {
1271                                 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_oder) )
1272                                         num_addresses += auto_count;
1273                                 done_auto_lookup = True;
1274                                 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1275                         }
1276                         else 
1277                                 num_addresses++;
1278                 }
1279
1280                 /* if we have no addresses and haven't done the auto lookup, then
1281                    just return the list of DC's */
1282                    
1283                 if ( (num_addresses == 0) && !done_auto_lookup )
1284                         return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder);
1285
1286                 /* maybe we just failed? */
1287                 
1288                 if ( num_addresses == 0 ) {
1289                         DEBUG(4,("get_dc_list: no servers found\n"));
1290                         return False;
1291                 }
1292                 
1293                 if ( (return_iplist = (struct ip_service *)
1294                         malloc(num_addresses * sizeof(struct ip_service))) == NULL ) 
1295                 {
1296                         DEBUG(3,("get_dc_list: malloc fail !\n"));
1297                         return False;
1298                 }
1299
1300                 p = pserver;
1301                 local_count = 0;
1302
1303                 /* fill in the return list now with real IP's */
1304                                 
1305                 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1306                         struct in_addr name_ip;
1307                         
1308                         /* copy any addersses from the auto lookup */
1309                         
1310                         if ( strequal(name, "*") ) {
1311                                 for ( j=0; j<auto_count; j++ ) {
1312                                         return_iplist[local_count].ip   = auto_ip_list[j].ip;
1313                                         return_iplist[local_count].port = auto_ip_list[j].port;
1314                                         local_count++;
1315                                 }
1316                                 continue;
1317                         }
1318                         
1319                         
1320                         /* added support for address:port syntax for ads (not that I think 
1321                            anyone will ever run the LDAP server in an AD domain on something 
1322                            other than port 389 */
1323                         
1324                         port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1325                         if ( (port_str=strchr(name, ':')) != NULL ) {
1326                                 *port_str = '\0';
1327                                 port_str++;
1328                                 port = atoi( port_str );
1329                         }
1330
1331                         /* explicit lookup; resolve_name() will handle names & IP addresses */
1332                         if ( resolve_name( name, &name_ip, 0x20 ) ) {
1333                                 return_iplist[local_count].ip   = name_ip;
1334                                 return_iplist[local_count].port = port;
1335                                 local_count++;
1336                                 *ordered = True;
1337                         }
1338                 }
1339                                 
1340                 SAFE_FREE(auto_ip_list);
1341
1342                 /* need to remove duplicates in the list if we have any 
1343                    explicit password servers */
1344                    
1345                 if ( local_count )
1346                         local_count = remove_duplicate_addrs2( return_iplist, local_count );
1347                 
1348                 if ( DEBUGLEVEL >= 4 ) {
1349                         DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, 
1350                                 *ordered ? "":"un"));
1351                         DEBUG(4,("get_dc_list: "));
1352                         for ( i=0; i<local_count; i++ )
1353                                 DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1354                         DEBUGADD(4,("\n"));
1355                 }
1356                         
1357                 *ip_list = return_iplist;
1358                 *count = local_count;
1359
1360                 return (*count != 0);
1361         }
1362         
1363         DEBUG(10,("get_dc_list: defaulting to internal auto lookup for domain %s\n", domain));
1364         
1365         return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder);
1366 }