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