Fixup of ordered cleanup of get_dc_list - bug found by Dominik 'Aeneas' Schnitzer...
[ira/wip.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 static int generate_trn_id(void)
31 {
32         static int trn_id;
33
34         if (trn_id == 0) {
35                 sys_srandom(sys_getpid());
36         }
37
38         trn_id = sys_random();
39
40         return trn_id % (unsigned)0x7FFF;
41 }
42
43
44 /****************************************************************************
45  parse a node status response into an array of structures
46 ****************************************************************************/
47 static struct node_status *parse_node_status(char *p, int *num_names)
48 {
49         struct node_status *ret;
50         int i;
51
52         *num_names = CVAL(p,0);
53
54         if (*num_names == 0) return NULL;
55
56         ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
57         if (!ret) return NULL;
58
59         p++;
60         for (i=0;i< *num_names;i++) {
61                 StrnCpy(ret[i].name,p,15);
62                 trim_string(ret[i].name,NULL," ");
63                 ret[i].type = CVAL(p,15);
64                 ret[i].flags = p[16];
65                 p += 18;
66                 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, 
67                            ret[i].type, ret[i].flags));
68         }
69         return ret;
70 }
71
72
73 /****************************************************************************
74 do a NBT node status query on an open socket and return an array of
75 structures holding the returned names or NULL if the query failed
76 **************************************************************************/
77 struct node_status *node_status_query(int fd,struct nmb_name *name,
78                                       struct in_addr to_ip, int *num_names)
79 {
80         BOOL found=False;
81         int retries = 2;
82         int retry_time = 2000;
83         struct timeval tval;
84         struct packet_struct p;
85         struct packet_struct *p2;
86         struct nmb_packet *nmb = &p.packet.nmb;
87         struct node_status *ret;
88
89         ZERO_STRUCT(p);
90
91         nmb->header.name_trn_id = generate_trn_id();
92         nmb->header.opcode = 0;
93         nmb->header.response = False;
94         nmb->header.nm_flags.bcast = False;
95         nmb->header.nm_flags.recursion_available = False;
96         nmb->header.nm_flags.recursion_desired = False;
97         nmb->header.nm_flags.trunc = False;
98         nmb->header.nm_flags.authoritative = False;
99         nmb->header.rcode = 0;
100         nmb->header.qdcount = 1;
101         nmb->header.ancount = 0;
102         nmb->header.nscount = 0;
103         nmb->header.arcount = 0;
104         nmb->question.question_name = *name;
105         nmb->question.question_type = 0x21;
106         nmb->question.question_class = 0x1;
107
108         p.ip = to_ip;
109         p.port = NMB_PORT;
110         p.fd = fd;
111         p.timestamp = time(NULL);
112         p.packet_type = NMB_PACKET;
113         
114         GetTimeOfDay(&tval);
115   
116         if (!send_packet(&p)) 
117                 return NULL;
118
119         retries--;
120
121         while (1) {
122                 struct timeval tval2;
123                 GetTimeOfDay(&tval2);
124                 if (TvalDiff(&tval,&tval2) > retry_time) {
125                         if (!retries)
126                                 break;
127                         if (!found && !send_packet(&p))
128                                 return NULL;
129                         GetTimeOfDay(&tval);
130                         retries--;
131                 }
132
133                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
134                         struct nmb_packet *nmb2 = &p2->packet.nmb;
135                         debug_nmb_packet(p2);
136                         
137                         if (nmb2->header.opcode != 0 ||
138                             nmb2->header.nm_flags.bcast ||
139                             nmb2->header.rcode ||
140                             !nmb2->header.ancount ||
141                             nmb2->answers->rr_type != 0x21) {
142                                 /* XXXX what do we do with this? could be a
143                                    redirect, but we'll discard it for the
144                                    moment */
145                                 free_packet(p2);
146                                 continue;
147                         }
148
149                         ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
150                         free_packet(p2);
151                         return ret;
152                 }
153         }
154         
155         return NULL;
156 }
157
158
159 /****************************************************************************
160 find the first type XX name in a node status reply - used for finding
161 a servers name given its IP
162 return the matched name in *name
163 **************************************************************************/
164
165 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
166 {
167         struct node_status *status = NULL;
168         struct nmb_name nname;
169         int count, i;
170         int sock;
171         BOOL result = False;
172
173         if (lp_disable_netbios()) {
174                 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
175                 return False;
176         }
177
178         DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, 
179                    q_type, inet_ntoa(to_ip)));
180
181         sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
182         if (sock == -1)
183                 goto done;
184
185         /* W2K PDC's seem not to respond to '*'#0. JRA */
186         make_nmb_name(&nname, q_name, q_type);
187         status = node_status_query(sock, &nname, to_ip, &count);
188         close(sock);
189         if (!status)
190                 goto done;
191
192         for (i=0;i<count;i++) {
193                 if (status[i].type == type)
194                         break;
195         }
196         if (i == count)
197                 goto done;
198
199         pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
200         result = True;
201
202  done:
203         SAFE_FREE(status);
204
205         DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
206
207         if (result)
208                 DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip)));
209
210         DEBUG(10, ("\n"));      
211
212         return result;
213 }
214
215
216 /*
217   comparison function used by sort_ip_list
218 */
219 int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
220 {
221         int max_bits1=0, max_bits2=0;
222         int num_interfaces = iface_count();
223         int i;
224
225         for (i=0;i<num_interfaces;i++) {
226                 struct in_addr ip;
227                 int bits1, bits2;
228                 ip = *iface_n_bcast(i);
229                 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
230                 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
231                 max_bits1 = MAX(bits1, max_bits1);
232                 max_bits2 = MAX(bits2, max_bits2);
233         }       
234         
235         /* bias towards directly reachable IPs */
236         if (iface_local(*ip1)) {
237                 max_bits1 += 32;
238         }
239         if (iface_local(*ip2)) {
240                 max_bits2 += 32;
241         }
242
243         return max_bits2 - max_bits1;
244 }
245
246 /*
247   sort an IP list so that names that are close to one of our interfaces 
248   are at the top. This prevents the problem where a WINS server returns an IP that
249   is not reachable from our subnet as the first match
250 */
251 static void sort_ip_list(struct in_addr *iplist, int count)
252 {
253         if (count <= 1) {
254                 return;
255         }
256
257         qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);    
258 }
259
260
261 /****************************************************************************
262  Do a netbios name query to find someones IP.
263  Returns an array of IP addresses or NULL if none.
264  *count will be set to the number of addresses returned.
265  *timed_out is set if we failed by timing out
266 ****************************************************************************/
267 struct in_addr *name_query(int fd,const char *name,int name_type, 
268                            BOOL bcast,BOOL recurse,
269                            struct in_addr to_ip, int *count, int *flags,
270                            BOOL *timed_out)
271 {
272         BOOL found=False;
273         int i, retries = 3;
274         int retry_time = bcast?250:2000;
275         struct timeval tval;
276         struct packet_struct p;
277         struct packet_struct *p2;
278         struct nmb_packet *nmb = &p.packet.nmb;
279         struct in_addr *ip_list = NULL;
280
281         if (lp_disable_netbios()) {
282                 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
283                 return NULL;
284         }
285
286         if (timed_out) {
287                 *timed_out = False;
288         }
289         
290         memset((char *)&p,'\0',sizeof(p));
291         (*count) = 0;
292         (*flags) = 0;
293         
294         nmb->header.name_trn_id = generate_trn_id();
295         nmb->header.opcode = 0;
296         nmb->header.response = False;
297         nmb->header.nm_flags.bcast = bcast;
298         nmb->header.nm_flags.recursion_available = False;
299         nmb->header.nm_flags.recursion_desired = recurse;
300         nmb->header.nm_flags.trunc = False;
301         nmb->header.nm_flags.authoritative = False;
302         nmb->header.rcode = 0;
303         nmb->header.qdcount = 1;
304         nmb->header.ancount = 0;
305         nmb->header.nscount = 0;
306         nmb->header.arcount = 0;
307         
308         make_nmb_name(&nmb->question.question_name,name,name_type);
309         
310         nmb->question.question_type = 0x20;
311         nmb->question.question_class = 0x1;
312         
313         p.ip = to_ip;
314         p.port = NMB_PORT;
315         p.fd = fd;
316         p.timestamp = time(NULL);
317         p.packet_type = NMB_PACKET;
318         
319         GetTimeOfDay(&tval);
320         
321         if (!send_packet(&p)) 
322                 return NULL;
323         
324         retries--;
325         
326         while (1) {
327                 struct timeval tval2;
328                 struct in_addr *tmp_ip_list;
329                 
330                 GetTimeOfDay(&tval2);
331                 if (TvalDiff(&tval,&tval2) > retry_time) {
332                         if (!retries)
333                                 break;
334                         if (!found && !send_packet(&p))
335                                 return NULL;
336                         GetTimeOfDay(&tval);
337                         retries--;
338                 }
339                 
340                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
341                         struct nmb_packet *nmb2 = &p2->packet.nmb;
342                         debug_nmb_packet(p2);
343                         
344                         /* If we get a Negative Name Query Response from a WINS
345                          * server, we should report it and give up.
346                          */
347                         if( 0 == nmb2->header.opcode            /* A query response   */
348                             && !(bcast)                 /* from a WINS server */
349                             && nmb2->header.rcode               /* Error returned     */
350                                 ) {
351                                 
352                                 if( DEBUGLVL( 3 ) ) {
353                                         /* Only executed if DEBUGLEVEL >= 3 */
354                                         dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
355                                         switch( nmb2->header.rcode ) {
356                                         case 0x01:
357                                                 dbgtext( "Request was invalidly formatted.\n" );
358                                                 break;
359                                         case 0x02:
360                                                 dbgtext( "Problem with NBNS, cannot process name.\n");
361                                                 break;
362                                         case 0x03:
363                                                 dbgtext( "The name requested does not exist.\n" );
364                                                 break;
365                                         case 0x04:
366                                                 dbgtext( "Unsupported request error.\n" );
367                                                 break;
368                                         case 0x05:
369                                                 dbgtext( "Query refused error.\n" );
370                                                 break;
371                                         default:
372                                                 dbgtext( "Unrecognized error code.\n" );
373                                                 break;
374                                         }
375                                 }
376                                 free_packet(p2);
377                                 return( NULL );
378                         }
379                         
380                         if (nmb2->header.opcode != 0 ||
381                             nmb2->header.nm_flags.bcast ||
382                             nmb2->header.rcode ||
383                             !nmb2->header.ancount) {
384                                 /* 
385                                  * XXXX what do we do with this? Could be a
386                                  * redirect, but we'll discard it for the
387                                  * moment.
388                                  */
389                                 free_packet(p2);
390                                 continue;
391                         }
392                         
393                         tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
394                                                                  * ( (*count) + nmb2->answers->rdlength/6 ) );
395                         
396                         if (!tmp_ip_list) {
397                                 DEBUG(0,("name_query: Realloc failed.\n"));
398                                 SAFE_FREE(ip_list);
399                         }
400                         
401                         ip_list = tmp_ip_list;
402                         
403                         if (ip_list) {
404                                 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
405                                 for (i=0;i<nmb2->answers->rdlength/6;i++) {
406                                         putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
407                                         DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
408                                         (*count)++;
409                                 }
410                                 DEBUGADD(2,(")\n"));
411                         }
412                         
413                         found=True;
414                         retries=0;
415                         /* We add the flags back ... */
416                         if (nmb2->header.response)
417                                 (*flags) |= NM_FLAGS_RS;
418                         if (nmb2->header.nm_flags.authoritative)
419                                 (*flags) |= NM_FLAGS_AA;
420                         if (nmb2->header.nm_flags.trunc)
421                                 (*flags) |= NM_FLAGS_TC;
422                         if (nmb2->header.nm_flags.recursion_desired)
423                                 (*flags) |= NM_FLAGS_RD;
424                         if (nmb2->header.nm_flags.recursion_available)
425                                 (*flags) |= NM_FLAGS_RA;
426                         if (nmb2->header.nm_flags.bcast)
427                                 (*flags) |= NM_FLAGS_B;
428                         free_packet(p2);
429                         /*
430                          * If we're doing a unicast lookup we only
431                          * expect one reply. Don't wait the full 2
432                          * seconds if we got one. JRA.
433                          */
434                         if(!bcast && found)
435                                 break;
436                 }
437         }
438
439         if (timed_out) {
440                 *timed_out = True;
441         }
442
443         /* sort the ip list so we choose close servers first if possible */
444         sort_ip_list(ip_list, *count);
445
446         return ip_list;
447 }
448
449 /********************************************************
450  Start parsing the lmhosts file.
451 *********************************************************/
452
453 XFILE *startlmhosts(char *fname)
454 {
455         XFILE *fp = x_fopen(fname,O_RDONLY, 0);
456         if (!fp) {
457                 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
458                          fname, strerror(errno)));
459                 return NULL;
460         }
461         return fp;
462 }
463
464 /********************************************************
465  Parse the next line in the lmhosts file.
466 *********************************************************/
467
468 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
469 {
470   pstring line;
471
472   while(!x_feof(fp) && !x_ferror(fp)) {
473     pstring ip,flags,extra;
474     const char *ptr;
475     char *ptr1;
476     int count = 0;
477
478     *name_type = -1;
479
480     if (!fgets_slash(line,sizeof(pstring),fp))
481       continue;
482
483     if (*line == '#')
484       continue;
485
486     pstrcpy(ip,"");
487     pstrcpy(name,"");
488     pstrcpy(flags,"");
489
490     ptr = line;
491
492     if (next_token(&ptr,ip   ,NULL,sizeof(ip)))
493       ++count;
494     if (next_token(&ptr,name ,NULL, sizeof(pstring)))
495       ++count;
496     if (next_token(&ptr,flags,NULL, sizeof(flags)))
497       ++count;
498     if (next_token(&ptr,extra,NULL, sizeof(extra)))
499       ++count;
500
501     if (count <= 0)
502       continue;
503
504     if (count > 0 && count < 2)
505     {
506       DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
507       continue;
508     }
509
510     if (count >= 4)
511     {
512       DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
513       continue;
514     }
515
516     DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
517
518     if (strchr_m(flags,'G') || strchr_m(flags,'S'))
519     {
520       DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
521       continue;
522     }
523
524     *ipaddr = *interpret_addr2(ip);
525
526     /* Extra feature. If the name ends in '#XX', where XX is a hex number,
527        then only add that name type. */
528     if((ptr1 = strchr_m(name, '#')) != NULL)
529     {
530       char *endptr;
531
532       ptr1++;
533       *name_type = (int)strtol(ptr1, &endptr, 16);
534
535       if(!*ptr1 || (endptr == ptr1))
536       {
537         DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
538         continue;
539       }
540
541       *(--ptr1) = '\0'; /* Truncate at the '#' */
542     }
543
544     return True;
545   }
546
547   return False;
548 }
549
550 /********************************************************
551  Finish parsing the lmhosts file.
552 *********************************************************/
553
554 void endlmhosts(XFILE *fp)
555 {
556         x_fclose(fp);
557 }
558
559
560 /********************************************************
561  Resolve via "bcast" method.
562 *********************************************************/
563
564 BOOL name_resolve_bcast(const char *name, int name_type,
565                         struct in_addr **return_ip_list, int *return_count)
566 {
567         int sock, i;
568         int num_interfaces = iface_count();
569
570         if (lp_disable_netbios()) {
571                 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
572                 return False;
573         }
574
575         *return_ip_list = NULL;
576         *return_count = 0;
577         
578         /*
579          * "bcast" means do a broadcast lookup on all the local interfaces.
580          */
581
582         DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
583
584         sock = open_socket_in( SOCK_DGRAM, 0, 3,
585                                interpret_addr(lp_socket_address()), True );
586
587         if (sock == -1) return False;
588
589         set_socket_options(sock,"SO_BROADCAST");
590         /*
591          * Lookup the name on all the interfaces, return on
592          * the first successful match.
593          */
594         for( i = num_interfaces-1; i >= 0; i--) {
595                 struct in_addr sendto_ip;
596                 int flags;
597                 /* Done this way to fix compiler error on IRIX 5.x */
598                 sendto_ip = *iface_n_bcast(i);
599                 *return_ip_list = name_query(sock, name, name_type, True, 
600                                     True, sendto_ip, return_count, &flags, NULL);
601                 if(*return_ip_list != NULL) {
602                         close(sock);
603                         return True;
604                 }
605         }
606
607         close(sock);
608         return False;
609 }
610
611 /********************************************************
612  Resolve via "wins" method.
613 *********************************************************/
614 BOOL resolve_wins(const char *name, int name_type,
615                   struct in_addr **return_iplist, int *return_count)
616 {
617         int sock, t, i;
618         char **wins_tags;
619         struct in_addr src_ip;
620
621         if (lp_disable_netbios()) {
622                 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
623                 return False;
624         }
625
626         *return_iplist = NULL;
627         *return_count = 0;
628         
629         DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
630
631         if (wins_srv_count() < 1) {
632                 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
633                 return False;
634         }
635
636         /* we try a lookup on each of the WINS tags in turn */
637         wins_tags = wins_srv_tags();
638
639         if (!wins_tags) {
640                 /* huh? no tags?? give up in disgust */
641                 return False;
642         }
643
644         /* the address we will be sending from */
645         src_ip = *interpret_addr2(lp_socket_address());
646
647         /* in the worst case we will try every wins server with every
648            tag! */
649         for (t=0; wins_tags && wins_tags[t]; t++) {
650                 int srv_count = wins_srv_count_tag(wins_tags[t]);
651                 for (i=0; i<srv_count; i++) {
652                         struct in_addr wins_ip;
653                         int flags;
654                         BOOL timed_out;
655
656                         wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
657
658                         if (global_in_nmbd && ismyip(wins_ip)) {
659                                 /* yikes! we'll loop forever */
660                                 continue;
661                         }
662
663                         /* skip any that have been unresponsive lately */
664                         if (wins_srv_is_dead(wins_ip, src_ip)) {
665                                 continue;
666                         }
667
668                         DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
669
670                         sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
671                         if (sock == -1) {
672                                 continue;
673                         }
674
675                         *return_iplist = name_query(sock,name,name_type, False, 
676                                                     True, wins_ip, return_count, &flags, 
677                                                     &timed_out);
678                         if (*return_iplist != NULL) {
679                                 goto success;
680                         }
681                         close(sock);
682
683                         if (timed_out) {
684                                 /* Timed out wating for WINS server to respond.  Mark it dead. */
685                                 wins_srv_died(wins_ip, src_ip);
686                         } else {
687                                 /* The name definately isn't in this
688                                    group of WINS servers. goto the next group  */
689                                 break;
690                         }
691                 }
692         }
693
694         wins_srv_tags_free(wins_tags);
695         return False;
696
697 success:
698         wins_srv_tags_free(wins_tags);
699         close(sock);
700         return True;
701 }
702
703 /********************************************************
704  Resolve via "lmhosts" method.
705 *********************************************************/
706
707 static BOOL resolve_lmhosts(const char *name, int name_type,
708                          struct in_addr **return_iplist, int *return_count)
709 {
710         /*
711          * "lmhosts" means parse the local lmhosts file.
712          */
713         
714         XFILE *fp;
715         pstring lmhost_name;
716         int name_type2;
717         struct in_addr return_ip;
718
719         *return_iplist = NULL;
720         *return_count = 0;
721
722         DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
723
724         fp = startlmhosts(dyn_LMHOSTSFILE);
725         if(fp) {
726                 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
727                         if (strequal(name, lmhost_name) && 
728                 ((name_type2 == -1) || (name_type == name_type2))
729                ) {
730                                 endlmhosts(fp);
731                                 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
732                                 if(*return_iplist == NULL) {
733                                         DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
734                                         return False;
735                                 }
736                                 **return_iplist = return_ip;
737                                 *return_count = 1;
738                                 return True; 
739                         }
740                 }
741                 endlmhosts(fp);
742         }
743         return False;
744 }
745
746
747 /********************************************************
748  Resolve via "hosts" method.
749 *********************************************************/
750
751 static BOOL resolve_hosts(const char *name,
752                          struct in_addr **return_iplist, int *return_count)
753 {
754         /*
755          * "host" means do a localhost, or dns lookup.
756          */
757         struct hostent *hp;
758
759         *return_iplist = NULL;
760         *return_count = 0;
761
762         DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
763         
764         if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
765                 struct in_addr return_ip;
766                 putip((char *)&return_ip,(char *)hp->h_addr);
767                 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
768                 if(*return_iplist == NULL) {
769                         DEBUG(3,("resolve_hosts: malloc fail !\n"));
770                         return False;
771                 }
772                 **return_iplist = return_ip;
773                 *return_count = 1;
774                 return True;
775         }
776         return False;
777 }
778
779 /********************************************************
780  Internal interface to resolve a name into an IP address.
781  Use this function if the string is either an IP address, DNS
782  or host name or NetBIOS name. This uses the name switch in the
783  smb.conf to determine the order of name resolution.
784 *********************************************************/
785
786 static BOOL internal_resolve_name(const char *name, int name_type,
787                                   struct in_addr **return_iplist, int *return_count)
788 {
789   pstring name_resolve_list;
790   fstring tok;
791   const char *ptr;
792   BOOL allones = (strcmp(name,"255.255.255.255") == 0);
793   BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
794   BOOL is_address = is_ipaddress(name);
795   BOOL result = False;
796   struct in_addr *nodupes_iplist;
797   int i;
798
799   *return_iplist = NULL;
800   *return_count = 0;
801
802   DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
803
804   if (allzeros || allones || is_address) {
805         *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
806         if(*return_iplist == NULL) {
807                 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
808                 return False;
809         }
810         if(is_address) { 
811                 /* if it's in the form of an IP address then get the lib to interpret it */
812                 (*return_iplist)->s_addr = inet_addr(name);
813     } else {
814                 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
815                 *return_count = 1;
816         }
817     return True;
818   }
819   
820   /* Check netbios name cache */
821
822   if (namecache_fetch(name, name_type, return_iplist, return_count)) {
823
824           /* This could be a negative response */
825
826           return (*return_count > 0);
827   }
828
829   pstrcpy(name_resolve_list, lp_name_resolve_order());
830   ptr = name_resolve_list;
831   if (!ptr || !*ptr)
832     ptr = "host";
833
834   while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
835           if((strequal(tok, "host") || strequal(tok, "hosts"))) {
836                   if (name_type == 0x20) {
837                           if (resolve_hosts(name, return_iplist, return_count)) {
838                                   result = True;
839                                   goto done;
840                           }
841                   }
842           } else if(strequal( tok, "lmhosts")) {
843                   if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
844                     result = True;
845                     goto done;
846                   }
847           } else if(strequal( tok, "wins")) {
848                   /* don't resolve 1D via WINS */
849                   if (name_type != 0x1D &&
850                       resolve_wins(name, name_type, return_iplist, return_count)) {
851                     result = True;
852                     goto done;
853                   }
854           } else if(strequal( tok, "bcast")) {
855                   if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
856                     result = True;
857                     goto done;
858                   }
859           } else {
860                   DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
861           }
862   }
863
864   /* All of the resolve_* functions above have returned false. */
865
866   SAFE_FREE(*return_iplist);
867   *return_count = 0;
868
869   return False;
870
871  done:
872
873   /* Remove duplicate entries.  Some queries, notably #1c (domain
874      controllers) return the PDC in iplist[0] and then all domain
875      controllers including the PDC in iplist[1..n].  Iterating over
876      the iplist when the PDC is down will cause two sets of timeouts. */
877
878   if (*return_count && (nodupes_iplist = (struct in_addr *)
879        malloc(sizeof(struct in_addr) * (*return_count)))) {
880           int nodupes_count = 0;
881
882           /* Iterate over return_iplist looking for duplicates */
883
884           for (i = 0; i < *return_count; i++) {
885                   BOOL is_dupe = False;
886                   int j;
887
888                   for (j = i + 1; j < *return_count; j++) {
889                           if (ip_equal((*return_iplist)[i], 
890                                        (*return_iplist)[j])) {
891                                   is_dupe = True;
892                                   break;
893                           }
894                   }
895
896                   if (!is_dupe) {
897
898                           /* This one not a duplicate */
899
900                           nodupes_iplist[nodupes_count] = (*return_iplist)[i];
901                           nodupes_count++;
902                   }
903           }
904           
905           /* Switcheroo with original list */
906           
907           free(*return_iplist);
908
909           *return_iplist = nodupes_iplist;
910           *return_count = nodupes_count;
911   }
912  
913   /* Save in name cache */
914   for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
915     DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name,
916                 name_type, inet_ntoa(*return_iplist[i])));
917     
918   namecache_store(name, name_type, *return_count, *return_iplist);
919
920   /* Display some debugging info */
921
922   DEBUG(10, ("internal_resolve_name: returning %d addresses: ", 
923              *return_count));
924
925   for (i = 0; i < *return_count; i++)
926           DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
927
928   DEBUG(10, ("\n"));
929
930   return result;
931 }
932
933 /********************************************************
934  Internal interface to resolve a name into one IP address.
935  Use this function if the string is either an IP address, DNS
936  or host name or NetBIOS name. This uses the name switch in the
937  smb.conf to determine the order of name resolution.
938 *********************************************************/
939
940 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
941 {
942         struct in_addr *ip_list = NULL;
943         int count = 0;
944
945         if (is_ipaddress(name)) {
946                 *return_ip = *interpret_addr2(name);
947                 return True;
948         }
949
950         if (internal_resolve_name(name, name_type, &ip_list, &count)) {
951                 int i;
952                 /* only return valid addresses for TCP connections */
953                 for (i=0; i<count; i++) {
954                         char *ip_str = inet_ntoa(ip_list[i]);
955                         if (ip_str &&
956                             strcmp(ip_str, "255.255.255.255") != 0 &&
957                             strcmp(ip_str, "0.0.0.0") != 0) {
958                                 *return_ip = ip_list[i];
959                                 SAFE_FREE(ip_list);
960                                 return True;
961                         }
962                 }
963         }
964         SAFE_FREE(ip_list);
965         return False;
966 }
967
968 /********************************************************
969  Find the IP address of the master browser or DMB for a workgroup.
970 *********************************************************/
971
972 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
973 {
974         struct in_addr *ip_list = NULL;
975         int count = 0;
976
977         if (lp_disable_netbios()) {
978                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
979                 return False;
980         }
981
982         if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
983                 *master_ip = ip_list[0];
984                 SAFE_FREE(ip_list);
985                 return True;
986         }
987         if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
988                 *master_ip = ip_list[0];
989                 SAFE_FREE(ip_list);
990                 return True;
991         }
992
993         SAFE_FREE(ip_list);
994         return False;
995 }
996
997 /********************************************************
998  Lookup a DC name given a Domain name and IP address.
999 *********************************************************/
1000
1001 BOOL lookup_dc_name(const char *srcname, const char *domain, 
1002                     struct in_addr *dc_ip, char *ret_name)
1003 {
1004 #if !defined(I_HATE_WINDOWS_REPLY_CODE) 
1005         fstring dc_name;
1006         BOOL ret;
1007
1008         if (lp_disable_netbios()) {
1009                 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
1010                 return False;
1011         }
1012         
1013         /*
1014          * Due to the fact win WinNT *sucks* we must do a node status
1015          * query here... JRA.
1016          */
1017         
1018         *dc_name = '\0';
1019         
1020         ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1021
1022         if(ret && *dc_name) {
1023                 fstrcpy(ret_name, dc_name);
1024                 return True;
1025         }
1026         
1027         return False;
1028
1029 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1030
1031 JRA - This code is broken with BDC rollover - we need to do a full
1032 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1033
1034         int retries = 3;
1035         int retry_time = 2000;
1036         struct timeval tval;
1037         struct packet_struct p;
1038         struct dgram_packet *dgram = &p.packet.dgram;
1039         char *ptr,*p2;
1040         char tmp[4];
1041         int len;
1042         struct sockaddr_in sock_name;
1043         int sock_len = sizeof(sock_name);
1044         const char *mailslot = NET_LOGON_MAILSLOT;
1045         char *mailslot_name;
1046         char buffer[1024];
1047         char *bufp;
1048         int dgm_id = generate_trn_id();
1049         int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1050         
1051         if(sock == -1)
1052                 return False;
1053         
1054         /* Find out the transient UDP port we have been allocated. */
1055         if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1056                 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1057                          strerror(errno)));
1058                 close(sock);
1059                 return False;
1060         }
1061
1062         /*
1063          * Create the request data.
1064          */
1065
1066         memset(buffer,'\0',sizeof(buffer));
1067         bufp = buffer;
1068         SSVAL(bufp,0,QUERYFORPDC);
1069         bufp += 2;
1070         fstrcpy(bufp,srcname);
1071         bufp += (strlen(bufp) + 1);
1072         slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1073         mailslot_name = bufp;
1074         bufp += (strlen(bufp) + 1);
1075         bufp = ALIGN2(bufp, buffer);
1076         bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);        
1077         
1078         SIVAL(bufp,0,1);
1079         SSVAL(bufp,4,0xFFFF); 
1080         SSVAL(bufp,6,0xFFFF); 
1081         bufp += 8;
1082         len = PTR_DIFF(bufp,buffer);
1083
1084         memset((char *)&p,'\0',sizeof(p));
1085
1086         /* DIRECT GROUP or UNIQUE datagram. */
1087         dgram->header.msg_type = 0x10;
1088         dgram->header.flags.node_type = M_NODE;
1089         dgram->header.flags.first = True;
1090         dgram->header.flags.more = False;
1091         dgram->header.dgm_id = dgm_id;
1092         dgram->header.source_ip = *iface_ip(*pdc_ip);
1093         dgram->header.source_port = ntohs(sock_name.sin_port);
1094         dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1095         dgram->header.packet_offset = 0;
1096         
1097         make_nmb_name(&dgram->source_name,srcname,0);
1098         make_nmb_name(&dgram->dest_name,domain,0x1C);
1099         
1100         ptr = &dgram->data[0];
1101         
1102         /* Setup the smb part. */
1103         ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1104         memcpy(tmp,ptr,4);
1105         set_message(ptr,17,17 + len,True);
1106         memcpy(ptr,tmp,4);
1107
1108         CVAL(ptr,smb_com) = SMBtrans;
1109         SSVAL(ptr,smb_vwv1,len);
1110         SSVAL(ptr,smb_vwv11,len);
1111         SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1112         SSVAL(ptr,smb_vwv13,3);
1113         SSVAL(ptr,smb_vwv14,1);
1114         SSVAL(ptr,smb_vwv15,1);
1115         SSVAL(ptr,smb_vwv16,2);
1116         p2 = smb_buf(ptr);
1117         pstrcpy(p2,mailslot);
1118         p2 = skip_string(p2,1);
1119         
1120         memcpy(p2,buffer,len);
1121         p2 += len;
1122         
1123         dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1124         
1125         p.ip = *pdc_ip;
1126         p.port = DGRAM_PORT;
1127         p.fd = sock;
1128         p.timestamp = time(NULL);
1129         p.packet_type = DGRAM_PACKET;
1130         
1131         GetTimeOfDay(&tval);
1132         
1133         if (!send_packet(&p)) {
1134                 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1135                 close(sock);
1136                 return False;
1137         }
1138         
1139         retries--;
1140         
1141         while (1) {
1142                 struct timeval tval2;
1143                 struct packet_struct *p_ret;
1144                 
1145                 GetTimeOfDay(&tval2);
1146                 if (TvalDiff(&tval,&tval2) > retry_time) {
1147                         if (!retries)
1148                                 break;
1149                         if (!send_packet(&p)) {
1150                                 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1151                                 close(sock);
1152                                 return False;
1153                         }
1154                         GetTimeOfDay(&tval);
1155                         retries--;
1156                 }
1157
1158                 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1159                         struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1160                         char *buf;
1161                         char *buf2;
1162
1163                         buf = &dgram2->data[0];
1164                         buf -= 4;
1165
1166                         if (CVAL(buf,smb_com) != SMBtrans) {
1167                                 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1168                                          CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1169                                 free_packet(p_ret);
1170                                 continue;
1171                         }
1172                         
1173                         len = SVAL(buf,smb_vwv11);
1174                         buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1175                         
1176                         if (len <= 0) {
1177                                 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1178                                 free_packet(p_ret);
1179                                 continue;
1180                         }
1181
1182                         DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1183                                  nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1184                                  inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1185
1186                         if(SVAL(buf2,0) != QUERYFORPDC_R) {
1187                                 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1188                                          (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1189                                 free_packet(p_ret);
1190                                 continue;
1191                         }
1192
1193                         buf2 += 2;
1194                         /* Note this is safe as it is a bounded strcpy. */
1195                         fstrcpy(ret_name, buf2);
1196                         ret_name[sizeof(fstring)-1] = '\0';
1197                         close(sock);
1198                         free_packet(p_ret);
1199                         return True;
1200                 }
1201         }
1202         
1203         close(sock);
1204         return False;
1205 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1206 }
1207
1208 /********************************************************
1209  Get the IP address list of the primary domain controller
1210  for a domain.
1211 *********************************************************/
1212
1213 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1214 {
1215         struct in_addr *ip_list;
1216         int count;
1217
1218         /* Look up #1B name */
1219
1220         if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
1221                 return False;
1222
1223         SMB_ASSERT(count == 1);
1224
1225         *ip = ip_list[0];
1226         SAFE_FREE(ip_list);
1227
1228         return True;
1229 }
1230
1231 /********************************************************
1232  Get the IP address list of the domain controllers for
1233  a domain.
1234 *********************************************************/
1235
1236 BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *ordered)
1237 {
1238
1239         *ordered = False;
1240                 
1241         /* If it's our domain then use the 'password server' parameter. */
1242
1243         if (strequal(domain, lp_workgroup())) {
1244                 char *p;
1245                 char *pserver = lp_passwordserver(); /* UNIX charset. */
1246                 fstring name;
1247                 int num_addresses = 0;
1248                 int  local_count, i, j;
1249                 struct in_addr *return_iplist = NULL;
1250                 struct in_addr *auto_ip_list = NULL;
1251                 BOOL done_auto_lookup = False;
1252                 int auto_count = 0;
1253                 
1254
1255                 if (!*pserver)
1256                         return internal_resolve_name(
1257                                 domain, 0x1C, ip_list, count);
1258
1259                 p = pserver;
1260
1261                 /*
1262                  * if '*' appears in the "password server" list then add
1263                  * an auto lookup to the list of manually configured
1264                  * DC's.  If any DC is listed by name, then the list should be 
1265                  * considered to be ordered 
1266                  */
1267                  
1268                 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1269                         if (strequal(name, "*")) {
1270                                 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count) )
1271                                         num_addresses += auto_count;
1272                                 done_auto_lookup = True;
1273                                 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1274                         }
1275                         else 
1276                                 num_addresses++;
1277                 }
1278
1279                 /* if we have no addresses and haven't done the auto lookup, then
1280                    just return the list of DC's */
1281                    
1282                 if ( (num_addresses == 0) && !done_auto_lookup )
1283                         return internal_resolve_name(domain, 0x1C, ip_list, count);
1284
1285                 return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
1286
1287                 if (return_iplist == NULL) {
1288                         DEBUG(3,("get_dc_list: malloc fail !\n"));
1289                         return False;
1290                 }
1291
1292                 p = pserver;
1293                 local_count = 0;
1294
1295                 /* fill in the return list now with real IP's */
1296                                 
1297                 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1298                         struct in_addr name_ip;
1299                         
1300                         /* copy any addersses from the auto lookup */
1301                         
1302                         if ( strequal(name, "*") ) {
1303                                 for ( j=0; j<auto_count; j++ ) 
1304                                         return_iplist[local_count++] = auto_ip_list[j];
1305                                 continue;
1306                         }
1307                         
1308                         /* explicit lookup */
1309                                         
1310                         if ( resolve_name( name, &name_ip, 0x20) ) {
1311                                 return_iplist[local_count++] = name_ip;
1312                                 *ordered = True;
1313                         }
1314                                 
1315                 }
1316                                 
1317                 /* need to remove duplicates in the list if we have 
1318                    any explicit password servers */
1319                    
1320                 if ( *ordered ) {               
1321                         /* one loop to remove duplicates */
1322                         for ( i=0; i<local_count; i++ ) {
1323                                 if ( is_zero_ip(return_iplist[i]) )
1324                                         continue;
1325                                         
1326                                 for ( j=i+1; j<local_count; j++ ) {
1327                                         if ( ip_equal( return_iplist[i], return_iplist[j]) )
1328                                                 zero_ip(&return_iplist[j]);
1329                                 }
1330                         }
1331                         
1332                         /* one loop to clean up any holes we left */
1333                         /* first ip should never be a zero_ip() */
1334                         for (i = 0; i<local_count; ) {
1335                                 if ( is_zero_ip(return_iplist[i]) ) {
1336                                         if (i != local_count-1 )
1337                                                 memmove(&return_iplist[i], &return_iplist[i+1],
1338                                                         (local_count - i - 1)*sizeof(return_iplist[i]));
1339                                         local_count--;
1340                                         continue;
1341                                 }
1342                                 i++;
1343                         }
1344                 }
1345                 
1346                 *ip_list = return_iplist;
1347                 *count = local_count;
1348                 
1349                 DEBUG(8,("get_dc_list: return %d ip addresses\n", *count));
1350
1351                 return (*count != 0);
1352         }
1353         
1354         return internal_resolve_name(domain, 0x1C, ip_list, count);
1355 }
1356