This fixes a number of ADS problems, particularly with netbiosless
[samba.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     char *ptr;
475     int count = 0;
476
477     *name_type = -1;
478
479     if (!fgets_slash(line,sizeof(pstring),fp))
480       continue;
481
482     if (*line == '#')
483       continue;
484
485     pstrcpy(ip,"");
486     pstrcpy(name,"");
487     pstrcpy(flags,"");
488
489     ptr = line;
490
491     if (next_token(&ptr,ip   ,NULL,sizeof(ip)))
492       ++count;
493     if (next_token(&ptr,name ,NULL, sizeof(pstring)))
494       ++count;
495     if (next_token(&ptr,flags,NULL, sizeof(flags)))
496       ++count;
497     if (next_token(&ptr,extra,NULL, sizeof(extra)))
498       ++count;
499
500     if (count <= 0)
501       continue;
502
503     if (count > 0 && count < 2)
504     {
505       DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
506       continue;
507     }
508
509     if (count >= 4)
510     {
511       DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
512       continue;
513     }
514
515     DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
516
517     if (strchr_m(flags,'G') || strchr_m(flags,'S'))
518     {
519       DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
520       continue;
521     }
522
523     *ipaddr = *interpret_addr2(ip);
524
525     /* Extra feature. If the name ends in '#XX', where XX is a hex number,
526        then only add that name type. */
527     if((ptr = strchr_m(name, '#')) != NULL)
528     {
529       char *endptr;
530
531       ptr++;
532       *name_type = (int)strtol(ptr, &endptr, 16);
533
534       if(!*ptr || (endptr == ptr))
535       {
536         DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
537         continue;
538       }
539
540       *(--ptr) = '\0'; /* Truncate at the '#' */
541     }
542
543     return True;
544   }
545
546   return False;
547 }
548
549 /********************************************************
550  Finish parsing the lmhosts file.
551 *********************************************************/
552
553 void endlmhosts(XFILE *fp)
554 {
555         x_fclose(fp);
556 }
557
558
559 /********************************************************
560  Resolve via "bcast" method.
561 *********************************************************/
562
563 BOOL name_resolve_bcast(const char *name, int name_type,
564                         struct in_addr **return_ip_list, int *return_count)
565 {
566         int sock, i;
567         int num_interfaces = iface_count();
568
569         if (lp_disable_netbios()) {
570                 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
571                 return False;
572         }
573
574         *return_ip_list = NULL;
575         *return_count = 0;
576         
577         /*
578          * "bcast" means do a broadcast lookup on all the local interfaces.
579          */
580
581         DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
582
583         sock = open_socket_in( SOCK_DGRAM, 0, 3,
584                                interpret_addr(lp_socket_address()), True );
585
586         if (sock == -1) return False;
587
588         set_socket_options(sock,"SO_BROADCAST");
589         /*
590          * Lookup the name on all the interfaces, return on
591          * the first successful match.
592          */
593         for( i = num_interfaces-1; i >= 0; i--) {
594                 struct in_addr sendto_ip;
595                 int flags;
596                 /* Done this way to fix compiler error on IRIX 5.x */
597                 sendto_ip = *iface_n_bcast(i);
598                 *return_ip_list = name_query(sock, name, name_type, True, 
599                                     True, sendto_ip, return_count, &flags, NULL);
600                 if(*return_ip_list != NULL) {
601                         close(sock);
602                         return True;
603                 }
604         }
605
606         close(sock);
607         return False;
608 }
609
610 /********************************************************
611  Resolve via "wins" method.
612 *********************************************************/
613 BOOL resolve_wins(const char *name, int name_type,
614                   struct in_addr **return_iplist, int *return_count)
615 {
616         int sock, t, i;
617         char **wins_tags;
618         struct in_addr src_ip;
619
620         if (lp_disable_netbios()) {
621                 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
622                 return False;
623         }
624
625         *return_iplist = NULL;
626         *return_count = 0;
627         
628         DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
629
630         if (wins_srv_count() < 1) {
631                 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
632                 return False;
633         }
634
635         /* we try a lookup on each of the WINS tags in turn */
636         wins_tags = wins_srv_tags();
637
638         if (!wins_tags) {
639                 /* huh? no tags?? give up in disgust */
640                 return False;
641         }
642
643         /* the address we will be sending from */
644         src_ip = *interpret_addr2(lp_socket_address());
645
646         /* in the worst case we will try every wins server with every
647            tag! */
648         for (t=0; wins_tags && wins_tags[t]; t++) {
649                 int srv_count = wins_srv_count_tag(wins_tags[t]);
650                 for (i=0; i<srv_count; i++) {
651                         struct in_addr wins_ip;
652                         int flags;
653                         BOOL timed_out;
654
655                         wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
656
657                         if (global_in_nmbd && ismyip(wins_ip)) {
658                                 /* yikes! we'll loop forever */
659                                 continue;
660                         }
661
662                         /* skip any that have been unresponsive lately */
663                         if (wins_srv_is_dead(wins_ip, src_ip)) {
664                                 continue;
665                         }
666
667                         DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
668
669                         sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
670                         if (sock == -1) {
671                                 continue;
672                         }
673
674                         *return_iplist = name_query(sock,name,name_type, False, 
675                                                     True, wins_ip, return_count, &flags, 
676                                                     &timed_out);
677                         if (*return_iplist != NULL) {
678                                 goto success;
679                         }
680                         close(sock);
681
682                         if (timed_out) {
683                                 /* Timed out wating for WINS server to respond.  Mark it dead. */
684                                 wins_srv_died(wins_ip, src_ip);
685                         } else {
686                                 /* The name definately isn't in this
687                                    group of WINS servers. goto the next group  */
688                                 break;
689                         }
690                 }
691         }
692
693         wins_srv_tags_free(wins_tags);
694         return False;
695
696 success:
697         wins_srv_tags_free(wins_tags);
698         close(sock);
699         return True;
700 }
701
702 /********************************************************
703  Resolve via "lmhosts" method.
704 *********************************************************/
705
706 static BOOL resolve_lmhosts(const char *name, int name_type,
707                          struct in_addr **return_iplist, int *return_count)
708 {
709         /*
710          * "lmhosts" means parse the local lmhosts file.
711          */
712         
713         XFILE *fp;
714         pstring lmhost_name;
715         int name_type2;
716         struct in_addr return_ip;
717
718         *return_iplist = NULL;
719         *return_count = 0;
720
721         DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
722
723         fp = startlmhosts(dyn_LMHOSTSFILE);
724         if(fp) {
725                 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
726                         if (strequal(name, lmhost_name) && 
727                 ((name_type2 == -1) || (name_type == name_type2))
728                ) {
729                                 endlmhosts(fp);
730                                 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
731                                 if(*return_iplist == NULL) {
732                                         DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
733                                         return False;
734                                 }
735                                 **return_iplist = return_ip;
736                                 *return_count = 1;
737                                 return True; 
738                         }
739                 }
740                 endlmhosts(fp);
741         }
742         return False;
743 }
744
745
746 /********************************************************
747  Resolve via "hosts" method.
748 *********************************************************/
749
750 static BOOL resolve_hosts(const char *name,
751                          struct in_addr **return_iplist, int *return_count)
752 {
753         /*
754          * "host" means do a localhost, or dns lookup.
755          */
756         struct hostent *hp;
757
758         *return_iplist = NULL;
759         *return_count = 0;
760
761         DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
762         
763         if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
764                 struct in_addr return_ip;
765                 putip((char *)&return_ip,(char *)hp->h_addr);
766                 *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
767                 if(*return_iplist == NULL) {
768                         DEBUG(3,("resolve_hosts: malloc fail !\n"));
769                         return False;
770                 }
771                 **return_iplist = return_ip;
772                 *return_count = 1;
773                 return True;
774         }
775         return False;
776 }
777
778 /********************************************************
779  Internal interface to resolve a name into an IP address.
780  Use this function if the string is either an IP address, DNS
781  or host name or NetBIOS name. This uses the name switch in the
782  smb.conf to determine the order of name resolution.
783 *********************************************************/
784
785 static BOOL internal_resolve_name(const char *name, int name_type,
786                                         struct in_addr **return_iplist, int *return_count)
787 {
788   pstring name_resolve_list;
789   fstring tok;
790   char *ptr;
791   BOOL allones = (strcmp(name,"255.255.255.255") == 0);
792   BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
793   BOOL is_address = is_ipaddress(name);
794   BOOL result = False;
795   struct in_addr *nodupes_iplist;
796   int i;
797
798   *return_iplist = NULL;
799   *return_count = 0;
800
801   DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
802
803   if (allzeros || allones || is_address) {
804         *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
805         if(*return_iplist == NULL) {
806                 DEBUG(3,("internal_resolve_name: malloc fail !\n"));
807                 return False;
808         }
809         if(is_address) { 
810                 /* if it's in the form of an IP address then get the lib to interpret it */
811                 (*return_iplist)->s_addr = inet_addr(name);
812     } else {
813                 (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
814                 *return_count = 1;
815         }
816     return True;
817   }
818   
819   pstrcpy(name_resolve_list, lp_name_resolve_order());
820   ptr = name_resolve_list;
821   if (!ptr || !*ptr)
822     ptr = "host";
823
824   while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
825           if((strequal(tok, "host") || strequal(tok, "hosts"))) {
826                   if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
827                     result = True;
828                     goto done;
829                   }
830           } else if(strequal( tok, "lmhosts")) {
831                   if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
832                     result = True;
833                     goto done;
834                   }
835           } else if(strequal( tok, "wins")) {
836                   /* don't resolve 1D via WINS */
837                   if (name_type != 0x1D &&
838                       resolve_wins(name, name_type, return_iplist, return_count)) {
839                     result = True;
840                     goto done;
841                   }
842           } else if(strequal( tok, "bcast")) {
843                   if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
844                     result = True;
845                     goto done;
846                   }
847           } else {
848                   DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
849           }
850   }
851
852   /* All of the resolve_* functions above have returned false. */
853
854   SAFE_FREE(*return_iplist);
855   *return_count = 0;
856
857   return False;
858
859  done:
860
861   /* Remove duplicate entries.  Some queries, notably #1c (domain
862      controllers) return the PDC in iplist[0] and then all domain
863      controllers including the PDC in iplist[1..n].  Iterating over
864      the iplist when the PDC is down will cause two sets of timeouts. */
865
866   if (*return_count && (nodupes_iplist = (struct in_addr *)
867        malloc(sizeof(struct in_addr) * (*return_count)))) {
868           int nodupes_count = 0;
869
870           /* Iterate over return_iplist looking for duplicates */
871
872           for (i = 0; i < *return_count; i++) {
873                   BOOL is_dupe = False;
874                   int j;
875
876                   for (j = i + 1; j < *return_count; j++) {
877                           if (ip_equal((*return_iplist)[i], 
878                                        (*return_iplist)[j])) {
879                                   is_dupe = True;
880                                   break;
881                           }
882                   }
883
884                   if (!is_dupe) {
885
886                           /* This one not a duplicate */
887
888                           nodupes_iplist[nodupes_count] = (*return_iplist)[i];
889                           nodupes_count++;
890                   }
891           }
892           
893           /* Switcheroo with original list */
894           
895           free(*return_iplist);
896
897           *return_iplist = nodupes_iplist;
898           *return_count = nodupes_count;
899   }
900
901   /* Display some debugging info */
902
903   DEBUG(10, ("internal_resolve_name: returning %d addresses: ", 
904              *return_count));
905
906   for (i = 0; i < *return_count; i++)
907           DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
908
909   DEBUG(10, ("\n"));
910
911   return result;
912 }
913
914 /********************************************************
915  Internal interface to resolve a name into one IP address.
916  Use this function if the string is either an IP address, DNS
917  or host name or NetBIOS name. This uses the name switch in the
918  smb.conf to determine the order of name resolution.
919 *********************************************************/
920
921 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
922 {
923         struct in_addr *ip_list = NULL;
924         int count = 0;
925
926         if (is_ipaddress(name)) {
927                 *return_ip = *interpret_addr2(name);
928                 return True;
929         }
930
931         if (internal_resolve_name(name, name_type, &ip_list, &count)) {
932                 int i;
933                 /* only return valid addresses for TCP connections */
934                 for (i=0; i<count; i++) {
935                         char *ip_str = inet_ntoa(ip_list[i]);
936                         if (ip_str &&
937                             strcmp(ip_str, "255.255.255.255") != 0 &&
938                             strcmp(ip_str, "0.0.0.0") != 0) {
939                                 *return_ip = ip_list[i];
940                                 SAFE_FREE(ip_list);
941                                 return True;
942                         }
943                 }
944         }
945         SAFE_FREE(ip_list);
946         return False;
947 }
948
949 /********************************************************
950  Find the IP address of the master browser or DMB for a workgroup.
951 *********************************************************/
952
953 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
954 {
955         struct in_addr *ip_list = NULL;
956         int count = 0;
957
958         if (lp_disable_netbios()) {
959                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
960                 return False;
961         }
962
963         if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
964                 *master_ip = ip_list[0];
965                 SAFE_FREE(ip_list);
966                 return True;
967         }
968         if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
969                 *master_ip = ip_list[0];
970                 SAFE_FREE(ip_list);
971                 return True;
972         }
973
974         SAFE_FREE(ip_list);
975         return False;
976 }
977
978 /********************************************************
979  Lookup a DC name given a Domain name and IP address.
980 *********************************************************/
981
982 BOOL lookup_dc_name(const char *srcname, const char *domain, 
983                     struct in_addr *dc_ip, char *ret_name)
984 {
985 #if !defined(I_HATE_WINDOWS_REPLY_CODE) 
986         fstring dc_name;
987         BOOL ret;
988
989         if (lp_disable_netbios()) {
990                 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
991                 return False;
992         }
993         
994         /*
995          * Due to the fact win WinNT *sucks* we must do a node status
996          * query here... JRA.
997          */
998         
999         *dc_name = '\0';
1000         
1001         ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1002
1003         if(ret && *dc_name) {
1004                 fstrcpy(ret_name, dc_name);
1005                 return True;
1006         }
1007         
1008         return False;
1009
1010 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1011
1012 JRA - This code is broken with BDC rollover - we need to do a full
1013 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1014
1015         int retries = 3;
1016         int retry_time = 2000;
1017         struct timeval tval;
1018         struct packet_struct p;
1019         struct dgram_packet *dgram = &p.packet.dgram;
1020         char *ptr,*p2;
1021         char tmp[4];
1022         int len;
1023         struct sockaddr_in sock_name;
1024         int sock_len = sizeof(sock_name);
1025         const char *mailslot = NET_LOGON_MAILSLOT;
1026         char *mailslot_name;
1027         char buffer[1024];
1028         char *bufp;
1029         int dgm_id = generate_trn_id();
1030         int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1031         
1032         if(sock == -1)
1033                 return False;
1034         
1035         /* Find out the transient UDP port we have been allocated. */
1036         if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1037                 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1038                          strerror(errno)));
1039                 close(sock);
1040                 return False;
1041         }
1042
1043         /*
1044          * Create the request data.
1045          */
1046
1047         memset(buffer,'\0',sizeof(buffer));
1048         bufp = buffer;
1049         SSVAL(bufp,0,QUERYFORPDC);
1050         bufp += 2;
1051         fstrcpy(bufp,srcname);
1052         bufp += (strlen(bufp) + 1);
1053         slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1054         mailslot_name = bufp;
1055         bufp += (strlen(bufp) + 1);
1056         bufp = ALIGN2(bufp, buffer);
1057         bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);        
1058         
1059         SIVAL(bufp,0,1);
1060         SSVAL(bufp,4,0xFFFF); 
1061         SSVAL(bufp,6,0xFFFF); 
1062         bufp += 8;
1063         len = PTR_DIFF(bufp,buffer);
1064
1065         memset((char *)&p,'\0',sizeof(p));
1066
1067         /* DIRECT GROUP or UNIQUE datagram. */
1068         dgram->header.msg_type = 0x10;
1069         dgram->header.flags.node_type = M_NODE;
1070         dgram->header.flags.first = True;
1071         dgram->header.flags.more = False;
1072         dgram->header.dgm_id = dgm_id;
1073         dgram->header.source_ip = *iface_ip(*pdc_ip);
1074         dgram->header.source_port = ntohs(sock_name.sin_port);
1075         dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1076         dgram->header.packet_offset = 0;
1077         
1078         make_nmb_name(&dgram->source_name,srcname,0);
1079         make_nmb_name(&dgram->dest_name,domain,0x1C);
1080         
1081         ptr = &dgram->data[0];
1082         
1083         /* Setup the smb part. */
1084         ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1085         memcpy(tmp,ptr,4);
1086         set_message(ptr,17,17 + len,True);
1087         memcpy(ptr,tmp,4);
1088
1089         CVAL(ptr,smb_com) = SMBtrans;
1090         SSVAL(ptr,smb_vwv1,len);
1091         SSVAL(ptr,smb_vwv11,len);
1092         SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1093         SSVAL(ptr,smb_vwv13,3);
1094         SSVAL(ptr,smb_vwv14,1);
1095         SSVAL(ptr,smb_vwv15,1);
1096         SSVAL(ptr,smb_vwv16,2);
1097         p2 = smb_buf(ptr);
1098         pstrcpy(p2,mailslot);
1099         p2 = skip_string(p2,1);
1100         
1101         memcpy(p2,buffer,len);
1102         p2 += len;
1103         
1104         dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1105         
1106         p.ip = *pdc_ip;
1107         p.port = DGRAM_PORT;
1108         p.fd = sock;
1109         p.timestamp = time(NULL);
1110         p.packet_type = DGRAM_PACKET;
1111         
1112         GetTimeOfDay(&tval);
1113         
1114         if (!send_packet(&p)) {
1115                 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1116                 close(sock);
1117                 return False;
1118         }
1119         
1120         retries--;
1121         
1122         while (1) {
1123                 struct timeval tval2;
1124                 struct packet_struct *p_ret;
1125                 
1126                 GetTimeOfDay(&tval2);
1127                 if (TvalDiff(&tval,&tval2) > retry_time) {
1128                         if (!retries)
1129                                 break;
1130                         if (!send_packet(&p)) {
1131                                 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1132                                 close(sock);
1133                                 return False;
1134                         }
1135                         GetTimeOfDay(&tval);
1136                         retries--;
1137                 }
1138
1139                 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1140                         struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1141                         char *buf;
1142                         char *buf2;
1143
1144                         buf = &dgram2->data[0];
1145                         buf -= 4;
1146
1147                         if (CVAL(buf,smb_com) != SMBtrans) {
1148                                 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1149                                          CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1150                                 free_packet(p_ret);
1151                                 continue;
1152                         }
1153                         
1154                         len = SVAL(buf,smb_vwv11);
1155                         buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1156                         
1157                         if (len <= 0) {
1158                                 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1159                                 free_packet(p_ret);
1160                                 continue;
1161                         }
1162
1163                         DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1164                                  nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1165                                  inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1166
1167                         if(SVAL(buf2,0) != QUERYFORPDC_R) {
1168                                 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1169                                          (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1170                                 free_packet(p_ret);
1171                                 continue;
1172                         }
1173
1174                         buf2 += 2;
1175                         /* Note this is safe as it is a bounded strcpy. */
1176                         fstrcpy(ret_name, buf2);
1177                         ret_name[sizeof(fstring)-1] = '\0';
1178                         close(sock);
1179                         free_packet(p_ret);
1180                         return True;
1181                 }
1182         }
1183         
1184         close(sock);
1185         return False;
1186 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1187 }
1188
1189
1190 /********************************************************
1191  Get the IP address list of the PDC/BDC's of a Domain.
1192 *********************************************************/
1193
1194 BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count)
1195 {
1196         int name_type = pdc_only ? 0x1B : 0x1C;
1197
1198         /*
1199          * If it's our domain then
1200          * use the 'password server' parameter.
1201          */
1202
1203         if (strequal(group, lp_workgroup())) {
1204                 char *p;
1205                 char *pserver = lp_passwordserver();
1206                 fstring name;
1207                 int num_adresses = 0;
1208                 struct in_addr *return_iplist = NULL;
1209
1210                 if (! *pserver)
1211                         return internal_resolve_name(group, name_type, ip_list, count);
1212
1213                 p = pserver;
1214                 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1215                         if (strequal(name, "*"))
1216                                 return internal_resolve_name(group, name_type, ip_list, count);
1217                         num_adresses++;
1218                 }
1219                 if (num_adresses == 0)
1220                         return internal_resolve_name(group, name_type, ip_list, count);
1221
1222                 return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr));
1223                 if(return_iplist == NULL) {
1224                         DEBUG(3,("get_dc_list: malloc fail !\n"));
1225                         return False;
1226                 }
1227                 p = pserver;
1228                 *count = 0;
1229                 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1230                         struct in_addr name_ip;
1231                         if (resolve_name( name, &name_ip, 0x20) == False)
1232                                 continue;
1233                         return_iplist[(*count)++] = name_ip;
1234                 }
1235                 *ip_list = return_iplist;
1236                 return (*count != 0);
1237         } else
1238                 return internal_resolve_name(group, name_type, ip_list, count);
1239 }