This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[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 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                           } else {
841
842                                   /* Store negative lookup result */
843
844                                   namecache_store(name, name_type, 0, NULL);
845                           }
846                   }
847           } else if(strequal( tok, "lmhosts")) {
848                   if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
849                     result = True;
850                     goto done;
851                   }
852           } else if(strequal( tok, "wins")) {
853                   /* don't resolve 1D via WINS */
854                   if (name_type != 0x1D &&
855                       resolve_wins(name, name_type, return_iplist, return_count)) {
856                     result = True;
857                     goto done;
858                   }
859           } else if(strequal( tok, "bcast")) {
860                   if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
861                     result = True;
862                     goto done;
863                   }
864           } else {
865                   DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
866           }
867   }
868
869   /* All of the resolve_* functions above have returned false. */
870
871   SAFE_FREE(*return_iplist);
872   *return_count = 0;
873
874   return False;
875
876  done:
877
878   /* Remove duplicate entries.  Some queries, notably #1c (domain
879      controllers) return the PDC in iplist[0] and then all domain
880      controllers including the PDC in iplist[1..n].  Iterating over
881      the iplist when the PDC is down will cause two sets of timeouts. */
882
883   if (*return_count && (nodupes_iplist = (struct in_addr *)
884        malloc(sizeof(struct in_addr) * (*return_count)))) {
885           int nodupes_count = 0;
886
887           /* Iterate over return_iplist looking for duplicates */
888
889           for (i = 0; i < *return_count; i++) {
890                   BOOL is_dupe = False;
891                   int j;
892
893                   for (j = i + 1; j < *return_count; j++) {
894                           if (ip_equal((*return_iplist)[i], 
895                                        (*return_iplist)[j])) {
896                                   is_dupe = True;
897                                   break;
898                           }
899                   }
900
901                   if (!is_dupe) {
902
903                           /* This one not a duplicate */
904
905                           nodupes_iplist[nodupes_count] = (*return_iplist)[i];
906                           nodupes_count++;
907                   }
908           }
909           
910           /* Switcheroo with original list */
911           
912           free(*return_iplist);
913
914           *return_iplist = nodupes_iplist;
915           *return_count = nodupes_count;
916   }
917  
918   /* Save in name cache */
919
920   namecache_store(name, name_type, *return_count, *return_iplist);
921
922   /* Display some debugging info */
923
924   DEBUG(10, ("internal_resolve_name: returning %d addresses: ", 
925              *return_count));
926
927   for (i = 0; i < *return_count; i++)
928           DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
929
930   DEBUG(10, ("\n"));
931
932   return result;
933 }
934
935 /********************************************************
936  Internal interface to resolve a name into one IP address.
937  Use this function if the string is either an IP address, DNS
938  or host name or NetBIOS name. This uses the name switch in the
939  smb.conf to determine the order of name resolution.
940 *********************************************************/
941
942 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
943 {
944         struct in_addr *ip_list = NULL;
945         int count = 0;
946
947         if (is_ipaddress(name)) {
948                 *return_ip = *interpret_addr2(name);
949                 return True;
950         }
951
952         if (internal_resolve_name(name, name_type, &ip_list, &count)) {
953                 int i;
954                 /* only return valid addresses for TCP connections */
955                 for (i=0; i<count; i++) {
956                         char *ip_str = inet_ntoa(ip_list[i]);
957                         if (ip_str &&
958                             strcmp(ip_str, "255.255.255.255") != 0 &&
959                             strcmp(ip_str, "0.0.0.0") != 0) {
960                                 *return_ip = ip_list[i];
961                                 SAFE_FREE(ip_list);
962                                 return True;
963                         }
964                 }
965         }
966         SAFE_FREE(ip_list);
967         return False;
968 }
969
970 /********************************************************
971  Find the IP address of the master browser or DMB for a workgroup.
972 *********************************************************/
973
974 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
975 {
976         struct in_addr *ip_list = NULL;
977         int count = 0;
978
979         if (lp_disable_netbios()) {
980                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
981                 return False;
982         }
983
984         if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
985                 *master_ip = ip_list[0];
986                 SAFE_FREE(ip_list);
987                 return True;
988         }
989         if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
990                 *master_ip = ip_list[0];
991                 SAFE_FREE(ip_list);
992                 return True;
993         }
994
995         SAFE_FREE(ip_list);
996         return False;
997 }
998
999 /********************************************************
1000  Lookup a DC name given a Domain name and IP address.
1001 *********************************************************/
1002
1003 BOOL lookup_dc_name(const char *srcname, const char *domain, 
1004                     struct in_addr *dc_ip, char *ret_name)
1005 {
1006 #if !defined(I_HATE_WINDOWS_REPLY_CODE) 
1007         fstring dc_name;
1008         BOOL ret;
1009
1010         if (lp_disable_netbios()) {
1011                 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
1012                 return False;
1013         }
1014         
1015         /*
1016          * Due to the fact win WinNT *sucks* we must do a node status
1017          * query here... JRA.
1018          */
1019         
1020         *dc_name = '\0';
1021         
1022         ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1023
1024         if(ret && *dc_name) {
1025                 fstrcpy(ret_name, dc_name);
1026                 return True;
1027         }
1028         
1029         return False;
1030
1031 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1032
1033 JRA - This code is broken with BDC rollover - we need to do a full
1034 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1035
1036         int retries = 3;
1037         int retry_time = 2000;
1038         struct timeval tval;
1039         struct packet_struct p;
1040         struct dgram_packet *dgram = &p.packet.dgram;
1041         char *ptr,*p2;
1042         char tmp[4];
1043         int len;
1044         struct sockaddr_in sock_name;
1045         int sock_len = sizeof(sock_name);
1046         const char *mailslot = NET_LOGON_MAILSLOT;
1047         char *mailslot_name;
1048         char buffer[1024];
1049         char *bufp;
1050         int dgm_id = generate_trn_id();
1051         int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1052         
1053         if(sock == -1)
1054                 return False;
1055         
1056         /* Find out the transient UDP port we have been allocated. */
1057         if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1058                 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1059                          strerror(errno)));
1060                 close(sock);
1061                 return False;
1062         }
1063
1064         /*
1065          * Create the request data.
1066          */
1067
1068         memset(buffer,'\0',sizeof(buffer));
1069         bufp = buffer;
1070         SSVAL(bufp,0,QUERYFORPDC);
1071         bufp += 2;
1072         fstrcpy(bufp,srcname);
1073         bufp += (strlen(bufp) + 1);
1074         slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1075         mailslot_name = bufp;
1076         bufp += (strlen(bufp) + 1);
1077         bufp = ALIGN2(bufp, buffer);
1078         bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);        
1079         
1080         SIVAL(bufp,0,1);
1081         SSVAL(bufp,4,0xFFFF); 
1082         SSVAL(bufp,6,0xFFFF); 
1083         bufp += 8;
1084         len = PTR_DIFF(bufp,buffer);
1085
1086         memset((char *)&p,'\0',sizeof(p));
1087
1088         /* DIRECT GROUP or UNIQUE datagram. */
1089         dgram->header.msg_type = 0x10;
1090         dgram->header.flags.node_type = M_NODE;
1091         dgram->header.flags.first = True;
1092         dgram->header.flags.more = False;
1093         dgram->header.dgm_id = dgm_id;
1094         dgram->header.source_ip = *iface_ip(*pdc_ip);
1095         dgram->header.source_port = ntohs(sock_name.sin_port);
1096         dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1097         dgram->header.packet_offset = 0;
1098         
1099         make_nmb_name(&dgram->source_name,srcname,0);
1100         make_nmb_name(&dgram->dest_name,domain,0x1C);
1101         
1102         ptr = &dgram->data[0];
1103         
1104         /* Setup the smb part. */
1105         ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1106         memcpy(tmp,ptr,4);
1107         set_message(ptr,17,17 + len,True);
1108         memcpy(ptr,tmp,4);
1109
1110         CVAL(ptr,smb_com) = SMBtrans;
1111         SSVAL(ptr,smb_vwv1,len);
1112         SSVAL(ptr,smb_vwv11,len);
1113         SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1114         SSVAL(ptr,smb_vwv13,3);
1115         SSVAL(ptr,smb_vwv14,1);
1116         SSVAL(ptr,smb_vwv15,1);
1117         SSVAL(ptr,smb_vwv16,2);
1118         p2 = smb_buf(ptr);
1119         pstrcpy(p2,mailslot);
1120         p2 = skip_string(p2,1);
1121         
1122         memcpy(p2,buffer,len);
1123         p2 += len;
1124         
1125         dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1126         
1127         p.ip = *pdc_ip;
1128         p.port = DGRAM_PORT;
1129         p.fd = sock;
1130         p.timestamp = time(NULL);
1131         p.packet_type = DGRAM_PACKET;
1132         
1133         GetTimeOfDay(&tval);
1134         
1135         if (!send_packet(&p)) {
1136                 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1137                 close(sock);
1138                 return False;
1139         }
1140         
1141         retries--;
1142         
1143         while (1) {
1144                 struct timeval tval2;
1145                 struct packet_struct *p_ret;
1146                 
1147                 GetTimeOfDay(&tval2);
1148                 if (TvalDiff(&tval,&tval2) > retry_time) {
1149                         if (!retries)
1150                                 break;
1151                         if (!send_packet(&p)) {
1152                                 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1153                                 close(sock);
1154                                 return False;
1155                         }
1156                         GetTimeOfDay(&tval);
1157                         retries--;
1158                 }
1159
1160                 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1161                         struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1162                         char *buf;
1163                         char *buf2;
1164
1165                         buf = &dgram2->data[0];
1166                         buf -= 4;
1167
1168                         if (CVAL(buf,smb_com) != SMBtrans) {
1169                                 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1170                                          CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1171                                 free_packet(p_ret);
1172                                 continue;
1173                         }
1174                         
1175                         len = SVAL(buf,smb_vwv11);
1176                         buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1177                         
1178                         if (len <= 0) {
1179                                 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1180                                 free_packet(p_ret);
1181                                 continue;
1182                         }
1183
1184                         DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1185                                  nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1186                                  inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1187
1188                         if(SVAL(buf2,0) != QUERYFORPDC_R) {
1189                                 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1190                                          (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1191                                 free_packet(p_ret);
1192                                 continue;
1193                         }
1194
1195                         buf2 += 2;
1196                         /* Note this is safe as it is a bounded strcpy. */
1197                         fstrcpy(ret_name, buf2);
1198                         ret_name[sizeof(fstring)-1] = '\0';
1199                         close(sock);
1200                         free_packet(p_ret);
1201                         return True;
1202                 }
1203         }
1204         
1205         close(sock);
1206         return False;
1207 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1208 }
1209
1210 /********************************************************
1211  Get the IP address list of the primary domain controller
1212  for a domain.
1213 *********************************************************/
1214
1215 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1216 {
1217         struct in_addr *ip_list;
1218         int count;
1219
1220         /* Look up #1B name */
1221
1222         if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
1223                 return False;
1224
1225         SMB_ASSERT(count == 1);
1226
1227         *ip = ip_list[0];
1228         SAFE_FREE(ip_list);
1229
1230         return True;
1231 }
1232
1233 /********************************************************
1234  Get the IP address list of the domain controllers for
1235  a domain.
1236 *********************************************************/
1237
1238 BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *ordered)
1239 {
1240
1241         *ordered = False;
1242                 
1243         /* If it's our domain then use the 'password server' parameter. */
1244
1245         if (strequal(domain, lp_workgroup())) {
1246                 char *p;
1247                 char *pserver = lp_passwordserver(); /* UNIX charset. */
1248                 fstring name;
1249                 int num_addresses = 0;
1250                 int  local_count, i, j;
1251                 struct in_addr *return_iplist = NULL;
1252                 struct in_addr *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(
1259                                 domain, 0x1C, ip_list, count);
1260
1261                 p = pserver;
1262
1263                 /*
1264                  * if '*' appears in the "password server" list then add
1265                  * an auto lookup to the list of manually configured
1266                  * DC's.  If any DC is listed by name, then the list should be 
1267                  * considered to be ordered 
1268                  */
1269                  
1270                 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1271                         if (strequal(name, "*")) {
1272                                 if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count) )
1273                                         num_addresses += auto_count;
1274                                 done_auto_lookup = True;
1275                                 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1276                         }
1277                         else 
1278                                 num_addresses++;
1279                 }
1280
1281                 /* if we have no addresses and haven't done the auto lookup, then
1282                    just return the list of DC's */
1283                    
1284                 if ( (num_addresses == 0) && !done_auto_lookup )
1285                         return internal_resolve_name(domain, 0x1C, ip_list, count);
1286
1287                 return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
1288
1289                 if (return_iplist == NULL) {
1290                         DEBUG(3,("get_dc_list: malloc fail !\n"));
1291                         return False;
1292                 }
1293
1294                 p = pserver;
1295                 local_count = 0;
1296
1297                 /* fill in the return list now with real IP's */
1298                                 
1299                 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) 
1300                 {
1301                         struct in_addr name_ip;
1302                         
1303                         /* copy any addersses from the auto lookup */
1304                         
1305                         if ( strequal(name, "*") ) {
1306                                 for ( j=0; j<auto_count; j++ ) 
1307                                         return_iplist[local_count++] = auto_ip_list[j];
1308                                 continue;
1309                         }
1310                         
1311                         /* explicit lookup */
1312                                         
1313                         if ( resolve_name( name, &name_ip, 0x20) ) {
1314                                 return_iplist[local_count++] = name_ip;
1315                                 *ordered = True;
1316                         }
1317                                 
1318                 }
1319                                 
1320                 /* need to remove duplicates in the list if we have 
1321                    any explicit password servers */
1322                    
1323                 if ( *ordered )
1324                 {               
1325                         int hole_index = -1;
1326
1327                         /* one loop to remove duplicates */
1328                         for ( i=0; i<local_count; i++ )
1329                         {
1330                                 if ( is_zero_ip(return_iplist[i]) )
1331                                         continue;
1332                                         
1333                                 for ( j=i+1; j<local_count; j++ ) {
1334                                         if ( ip_equal( return_iplist[i], return_iplist[j]) )
1335                                                 zero_ip(&return_iplist[j]);
1336                                 }
1337                         }
1338                         
1339                         /* one loop to clean up any holes we left */
1340                         /* first ip can never be a zero_ip() */
1341                         i = 0;
1342                         while ( i<local_count )
1343                         {
1344                                 if ( !is_zero_ip(return_iplist[i]) ) {
1345                                         i++;
1346                                         continue;
1347                                 }
1348                                 
1349                                 hole_index = i;
1350                                 i++;
1351                                 
1352                                 while ( i<local_count ) {
1353                                         if ( !is_zero_ip(return_iplist[i]) )
1354                                                 return_iplist[hole_index++] = return_iplist[i];
1355                                         i++;
1356                                 }
1357                                 
1358                                 /* we should exit the loop implicitly here, but ... */
1359                                 break;
1360                         }
1361                         
1362                         local_count = hole_index;
1363                 }
1364                 
1365                 *ip_list = return_iplist;
1366                 *count = local_count;
1367                 
1368                 DEBUG(8,("get_dc_list: return %d ip addresses\n", *count));
1369
1370                 return (*count != 0);
1371         }
1372         
1373         return internal_resolve_name(domain, 0x1C, ip_list, count);
1374 }
1375