Merge of get_dc_list() api change. This was slightly more intrusive
[nivanova/samba-autobuild/.git] / source3 / libsmb / namequery.c
1 /* 
2    Unix SMB/CIFS implementation.
3    name query routines
4    Copyright (C) Andrew Tridgell 1994-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19    
20 */
21
22 #include "includes.h"
23
24 /* nmbd.c sets this to True. */
25 BOOL global_in_nmbd = False;
26
27 /****************************************************************************
28 generate a random trn_id
29 ****************************************************************************/
30 static int generate_trn_id(void)
31 {
32         static int trn_id;
33
34         if (trn_id == 0) {
35                 sys_srandom(sys_getpid());
36         }
37
38         trn_id = sys_random();
39
40         return trn_id % (unsigned)0x7FFF;
41 }
42
43
44 /****************************************************************************
45  parse a node status response into an array of structures
46 ****************************************************************************/
47 static struct node_status *parse_node_status(char *p, int *num_names)
48 {
49         struct node_status *ret;
50         int i;
51
52         *num_names = CVAL(p,0);
53
54         if (*num_names == 0) return NULL;
55
56         ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
57         if (!ret) return NULL;
58
59         p++;
60         for (i=0;i< *num_names;i++) {
61                 StrnCpy(ret[i].name,p,15);
62                 trim_string(ret[i].name,NULL," ");
63                 ret[i].type = CVAL(p,15);
64                 ret[i].flags = p[16];
65                 p += 18;
66                 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, 
67                            ret[i].type, ret[i].flags));
68         }
69         return ret;
70 }
71
72
73 /****************************************************************************
74 do a NBT node status query on an open socket and return an array of
75 structures holding the returned names or NULL if the query failed
76 **************************************************************************/
77 struct node_status *node_status_query(int fd,struct nmb_name *name,
78                                       struct in_addr to_ip, int *num_names)
79 {
80         BOOL found=False;
81         int retries = 2;
82         int retry_time = 2000;
83         struct timeval tval;
84         struct packet_struct p;
85         struct packet_struct *p2;
86         struct nmb_packet *nmb = &p.packet.nmb;
87         struct node_status *ret;
88
89         ZERO_STRUCT(p);
90
91         nmb->header.name_trn_id = generate_trn_id();
92         nmb->header.opcode = 0;
93         nmb->header.response = False;
94         nmb->header.nm_flags.bcast = False;
95         nmb->header.nm_flags.recursion_available = False;
96         nmb->header.nm_flags.recursion_desired = False;
97         nmb->header.nm_flags.trunc = False;
98         nmb->header.nm_flags.authoritative = False;
99         nmb->header.rcode = 0;
100         nmb->header.qdcount = 1;
101         nmb->header.ancount = 0;
102         nmb->header.nscount = 0;
103         nmb->header.arcount = 0;
104         nmb->question.question_name = *name;
105         nmb->question.question_type = 0x21;
106         nmb->question.question_class = 0x1;
107
108         p.ip = to_ip;
109         p.port = NMB_PORT;
110         p.fd = fd;
111         p.timestamp = time(NULL);
112         p.packet_type = NMB_PACKET;
113         
114         GetTimeOfDay(&tval);
115   
116         if (!send_packet(&p)) 
117                 return NULL;
118
119         retries--;
120
121         while (1) {
122                 struct timeval tval2;
123                 GetTimeOfDay(&tval2);
124                 if (TvalDiff(&tval,&tval2) > retry_time) {
125                         if (!retries)
126                                 break;
127                         if (!found && !send_packet(&p))
128                                 return NULL;
129                         GetTimeOfDay(&tval);
130                         retries--;
131                 }
132
133                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
134                         struct nmb_packet *nmb2 = &p2->packet.nmb;
135                         debug_nmb_packet(p2);
136                         
137                         if (nmb2->header.opcode != 0 ||
138                             nmb2->header.nm_flags.bcast ||
139                             nmb2->header.rcode ||
140                             !nmb2->header.ancount ||
141                             nmb2->answers->rr_type != 0x21) {
142                                 /* XXXX what do we do with this? could be a
143                                    redirect, but we'll discard it for the
144                                    moment */
145                                 free_packet(p2);
146                                 continue;
147                         }
148
149                         ret = parse_node_status(&nmb2->answers->rdata[0], num_names);
150                         free_packet(p2);
151                         return ret;
152                 }
153         }
154         
155         return NULL;
156 }
157
158
159 /****************************************************************************
160 find the first type XX name in a node status reply - used for finding
161 a servers name given its IP
162 return the matched name in *name
163 **************************************************************************/
164
165 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
166 {
167         struct node_status *status = NULL;
168         struct nmb_name nname;
169         int count, i;
170         int sock;
171         BOOL result = False;
172
173         if (lp_disable_netbios()) {
174                 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
175                 return False;
176         }
177
178         DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, 
179                    q_type, inet_ntoa(to_ip)));
180
181         sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
182         if (sock == -1)
183                 goto done;
184
185         /* W2K PDC's seem not to respond to '*'#0. JRA */
186         make_nmb_name(&nname, q_name, q_type);
187         status = node_status_query(sock, &nname, to_ip, &count);
188         close(sock);
189         if (!status)
190                 goto done;
191
192         for (i=0;i<count;i++) {
193                 if (status[i].type == type)
194                         break;
195         }
196         if (i == count)
197                 goto done;
198
199         pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
200         result = True;
201
202  done:
203         SAFE_FREE(status);
204
205         DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
206
207         if (result)
208                 DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip)));
209
210         DEBUG(10, ("\n"));      
211
212         return result;
213 }
214
215
216 /*
217   comparison function used by sort_ip_list
218 */
219 int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
220 {
221         int max_bits1=0, max_bits2=0;
222         int num_interfaces = iface_count();
223         int i;
224
225         for (i=0;i<num_interfaces;i++) {
226                 struct in_addr ip;
227                 int bits1, bits2;
228                 ip = *iface_n_bcast(i);
229                 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
230                 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
231                 max_bits1 = MAX(bits1, max_bits1);
232                 max_bits2 = MAX(bits2, max_bits2);
233         }       
234         
235         /* bias towards directly reachable IPs */
236         if (iface_local(*ip1)) {
237                 max_bits1 += 32;
238         }
239         if (iface_local(*ip2)) {
240                 max_bits2 += 32;
241         }
242
243         return max_bits2 - max_bits1;
244 }
245
246 /*
247   sort an IP list so that names that are close to one of our interfaces 
248   are at the top. This prevents the problem where a WINS server returns an IP that
249   is not reachable from our subnet as the first match
250 */
251 static void sort_ip_list(struct in_addr *iplist, int count)
252 {
253         if (count <= 1) {
254                 return;
255         }
256
257         qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);    
258 }
259
260
261 /****************************************************************************
262  Do a netbios name query to find someones IP.
263  Returns an array of IP addresses or NULL if none.
264  *count will be set to the number of addresses returned.
265  *timed_out is set if we failed by timing out
266 ****************************************************************************/
267 struct in_addr *name_query(int fd,const char *name,int name_type, 
268                            BOOL bcast,BOOL recurse,
269                            struct in_addr to_ip, int *count, int *flags,
270                            BOOL *timed_out)
271 {
272         BOOL found=False;
273         int i, retries = 3;
274         int retry_time = bcast?250:2000;
275         struct timeval tval;
276         struct packet_struct p;
277         struct packet_struct *p2;
278         struct nmb_packet *nmb = &p.packet.nmb;
279         struct in_addr *ip_list = NULL;
280
281         if (lp_disable_netbios()) {
282                 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
283                 return NULL;
284         }
285
286         if (timed_out) {
287                 *timed_out = False;
288         }
289         
290         memset((char *)&p,'\0',sizeof(p));
291         (*count) = 0;
292         (*flags) = 0;
293         
294         nmb->header.name_trn_id = generate_trn_id();
295         nmb->header.opcode = 0;
296         nmb->header.response = False;
297         nmb->header.nm_flags.bcast = bcast;
298         nmb->header.nm_flags.recursion_available = False;
299         nmb->header.nm_flags.recursion_desired = recurse;
300         nmb->header.nm_flags.trunc = False;
301         nmb->header.nm_flags.authoritative = False;
302         nmb->header.rcode = 0;
303         nmb->header.qdcount = 1;
304         nmb->header.ancount = 0;
305         nmb->header.nscount = 0;
306         nmb->header.arcount = 0;
307         
308         make_nmb_name(&nmb->question.question_name,name,name_type);
309         
310         nmb->question.question_type = 0x20;
311         nmb->question.question_class = 0x1;
312         
313         p.ip = to_ip;
314         p.port = NMB_PORT;
315         p.fd = fd;
316         p.timestamp = time(NULL);
317         p.packet_type = NMB_PACKET;
318         
319         GetTimeOfDay(&tval);
320         
321         if (!send_packet(&p)) 
322                 return NULL;
323         
324         retries--;
325         
326         while (1) {
327                 struct timeval tval2;
328                 struct in_addr *tmp_ip_list;
329                 
330                 GetTimeOfDay(&tval2);
331                 if (TvalDiff(&tval,&tval2) > retry_time) {
332                         if (!retries)
333                                 break;
334                         if (!found && !send_packet(&p))
335                                 return NULL;
336                         GetTimeOfDay(&tval);
337                         retries--;
338                 }
339                 
340                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
341                         struct nmb_packet *nmb2 = &p2->packet.nmb;
342                         debug_nmb_packet(p2);
343                         
344                         /* If we get a Negative Name Query Response from a WINS
345                          * server, we should report it and give up.
346                          */
347                         if( 0 == nmb2->header.opcode            /* A query response   */
348                             && !(bcast)                 /* from a WINS server */
349                             && nmb2->header.rcode               /* Error returned     */
350                                 ) {
351                                 
352                                 if( DEBUGLVL( 3 ) ) {
353                                         /* Only executed if DEBUGLEVEL >= 3 */
354                                         dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
355                                         switch( nmb2->header.rcode ) {
356                                         case 0x01:
357                                                 dbgtext( "Request was invalidly formatted.\n" );
358                                                 break;
359                                         case 0x02:
360                                                 dbgtext( "Problem with NBNS, cannot process name.\n");
361                                                 break;
362                                         case 0x03:
363                                                 dbgtext( "The name requested does not exist.\n" );
364                                                 break;
365                                         case 0x04:
366                                                 dbgtext( "Unsupported request error.\n" );
367                                                 break;
368                                         case 0x05:
369                                                 dbgtext( "Query refused error.\n" );
370                                                 break;
371                                         default:
372                                                 dbgtext( "Unrecognized error code.\n" );
373                                                 break;
374                                         }
375                                 }
376                                 free_packet(p2);
377                                 return( NULL );
378                         }
379                         
380                         if (nmb2->header.opcode != 0 ||
381                             nmb2->header.nm_flags.bcast ||
382                             nmb2->header.rcode ||
383                             !nmb2->header.ancount) {
384                                 /* 
385                                  * XXXX what do we do with this? Could be a
386                                  * redirect, but we'll discard it for the
387                                  * moment.
388                                  */
389                                 free_packet(p2);
390                                 continue;
391                         }
392                         
393                         tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
394                                                                  * ( (*count) + nmb2->answers->rdlength/6 ) );
395                         
396                         if (!tmp_ip_list) {
397                                 DEBUG(0,("name_query: Realloc failed.\n"));
398                                 SAFE_FREE(ip_list);
399                         }
400                         
401                         ip_list = tmp_ip_list;
402                         
403                         if (ip_list) {
404                                 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
405                                 for (i=0;i<nmb2->answers->rdlength/6;i++) {
406                                         putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
407                                         DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
408                                         (*count)++;
409                                 }
410                                 DEBUGADD(2,(")\n"));
411                         }
412                         
413                         found=True;
414                         retries=0;
415                         /* We add the flags back ... */
416                         if (nmb2->header.response)
417                                 (*flags) |= NM_FLAGS_RS;
418                         if (nmb2->header.nm_flags.authoritative)
419                                 (*flags) |= NM_FLAGS_AA;
420                         if (nmb2->header.nm_flags.trunc)
421                                 (*flags) |= NM_FLAGS_TC;
422                         if (nmb2->header.nm_flags.recursion_desired)
423                                 (*flags) |= NM_FLAGS_RD;
424                         if (nmb2->header.nm_flags.recursion_available)
425                                 (*flags) |= NM_FLAGS_RA;
426                         if (nmb2->header.nm_flags.bcast)
427                                 (*flags) |= NM_FLAGS_B;
428                         free_packet(p2);
429                         /*
430                          * If we're doing a unicast lookup we only
431                          * expect one reply. Don't wait the full 2
432                          * seconds if we got one. JRA.
433                          */
434                         if(!bcast && found)
435                                 break;
436                 }
437         }
438
439         if (timed_out) {
440                 *timed_out = True;
441         }
442
443         /* sort the ip list so we choose close servers first if possible */
444         sort_ip_list(ip_list, *count);
445
446         return ip_list;
447 }
448
449 /********************************************************
450  Start parsing the lmhosts file.
451 *********************************************************/
452
453 XFILE *startlmhosts(char *fname)
454 {
455         XFILE *fp = x_fopen(fname,O_RDONLY, 0);
456         if (!fp) {
457                 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
458                          fname, strerror(errno)));
459                 return NULL;
460         }
461         return fp;
462 }
463
464 /********************************************************
465  Parse the next line in the lmhosts file.
466 *********************************************************/
467
468 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
469 {
470   pstring line;
471
472   while(!x_feof(fp) && !x_ferror(fp)) {
473     pstring ip,flags,extra;
474     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   /* Check netbios name cache */
820
821   if (namecache_fetch(name, name_type, return_iplist, return_count)) {
822
823           /* This could be a negative response */
824
825           return (*return_count > 0);
826   }
827
828   pstrcpy(name_resolve_list, lp_name_resolve_order());
829   ptr = name_resolve_list;
830   if (!ptr || !*ptr)
831     ptr = "host";
832
833   while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
834           if((strequal(tok, "host") || strequal(tok, "hosts"))) {
835                   if (name_type == 0x20) {
836                           if (resolve_hosts(name, return_iplist, return_count)) {
837                                   result = True;
838                                   goto done;
839                           } else {
840
841                                   /* Store negative lookup result */
842
843                                   namecache_store(name, name_type, 0, NULL);
844                           }
845                   }
846           } else if(strequal( tok, "lmhosts")) {
847                   if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
848                     result = True;
849                     goto done;
850                   }
851           } else if(strequal( tok, "wins")) {
852                   /* don't resolve 1D via WINS */
853                   if (name_type != 0x1D &&
854                       resolve_wins(name, name_type, return_iplist, return_count)) {
855                     result = True;
856                     goto done;
857                   }
858           } else if(strequal( tok, "bcast")) {
859                   if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
860                     result = True;
861                     goto done;
862                   }
863           } else {
864                   DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
865           }
866   }
867
868   /* All of the resolve_* functions above have returned false. */
869
870   SAFE_FREE(*return_iplist);
871   *return_count = 0;
872
873   return False;
874
875  done:
876
877   /* Remove duplicate entries.  Some queries, notably #1c (domain
878      controllers) return the PDC in iplist[0] and then all domain
879      controllers including the PDC in iplist[1..n].  Iterating over
880      the iplist when the PDC is down will cause two sets of timeouts. */
881
882   if (*return_count && (nodupes_iplist = (struct in_addr *)
883        malloc(sizeof(struct in_addr) * (*return_count)))) {
884           int nodupes_count = 0;
885
886           /* Iterate over return_iplist looking for duplicates */
887
888           for (i = 0; i < *return_count; i++) {
889                   BOOL is_dupe = False;
890                   int j;
891
892                   for (j = i + 1; j < *return_count; j++) {
893                           if (ip_equal((*return_iplist)[i], 
894                                        (*return_iplist)[j])) {
895                                   is_dupe = True;
896                                   break;
897                           }
898                   }
899
900                   if (!is_dupe) {
901
902                           /* This one not a duplicate */
903
904                           nodupes_iplist[nodupes_count] = (*return_iplist)[i];
905                           nodupes_count++;
906                   }
907           }
908           
909           /* Switcheroo with original list */
910           
911           free(*return_iplist);
912
913           *return_iplist = nodupes_iplist;
914           *return_count = nodupes_count;
915   }
916  
917   /* Save in name cache */
918
919   namecache_store(name, name_type, *return_count, *return_iplist);
920
921   /* Display some debugging info */
922
923   DEBUG(10, ("internal_resolve_name: returning %d addresses: ", 
924              *return_count));
925
926   for (i = 0; i < *return_count; i++)
927           DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
928
929   DEBUG(10, ("\n"));
930
931   return result;
932 }
933
934 /********************************************************
935  Internal interface to resolve a name into one IP address.
936  Use this function if the string is either an IP address, DNS
937  or host name or NetBIOS name. This uses the name switch in the
938  smb.conf to determine the order of name resolution.
939 *********************************************************/
940
941 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
942 {
943         struct in_addr *ip_list = NULL;
944         int count = 0;
945
946         if (is_ipaddress(name)) {
947                 *return_ip = *interpret_addr2(name);
948                 return True;
949         }
950
951         if (internal_resolve_name(name, name_type, &ip_list, &count)) {
952                 int i;
953                 /* only return valid addresses for TCP connections */
954                 for (i=0; i<count; i++) {
955                         char *ip_str = inet_ntoa(ip_list[i]);
956                         if (ip_str &&
957                             strcmp(ip_str, "255.255.255.255") != 0 &&
958                             strcmp(ip_str, "0.0.0.0") != 0) {
959                                 *return_ip = ip_list[i];
960                                 SAFE_FREE(ip_list);
961                                 return True;
962                         }
963                 }
964         }
965         SAFE_FREE(ip_list);
966         return False;
967 }
968
969 /********************************************************
970  Find the IP address of the master browser or DMB for a workgroup.
971 *********************************************************/
972
973 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
974 {
975         struct in_addr *ip_list = NULL;
976         int count = 0;
977
978         if (lp_disable_netbios()) {
979                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
980                 return False;
981         }
982
983         if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
984                 *master_ip = ip_list[0];
985                 SAFE_FREE(ip_list);
986                 return True;
987         }
988         if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
989                 *master_ip = ip_list[0];
990                 SAFE_FREE(ip_list);
991                 return True;
992         }
993
994         SAFE_FREE(ip_list);
995         return False;
996 }
997
998 /********************************************************
999  Lookup a DC name given a Domain name and IP address.
1000 *********************************************************/
1001
1002 BOOL lookup_dc_name(const char *srcname, const char *domain, 
1003                     struct in_addr *dc_ip, char *ret_name)
1004 {
1005 #if !defined(I_HATE_WINDOWS_REPLY_CODE) 
1006         fstring dc_name;
1007         BOOL ret;
1008
1009         if (lp_disable_netbios()) {
1010                 DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
1011                 return False;
1012         }
1013         
1014         /*
1015          * Due to the fact win WinNT *sucks* we must do a node status
1016          * query here... JRA.
1017          */
1018         
1019         *dc_name = '\0';
1020         
1021         ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
1022
1023         if(ret && *dc_name) {
1024                 fstrcpy(ret_name, dc_name);
1025                 return True;
1026         }
1027         
1028         return False;
1029
1030 #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1031
1032 JRA - This code is broken with BDC rollover - we need to do a full
1033 NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
1034
1035         int retries = 3;
1036         int retry_time = 2000;
1037         struct timeval tval;
1038         struct packet_struct p;
1039         struct dgram_packet *dgram = &p.packet.dgram;
1040         char *ptr,*p2;
1041         char tmp[4];
1042         int len;
1043         struct sockaddr_in sock_name;
1044         int sock_len = sizeof(sock_name);
1045         const char *mailslot = NET_LOGON_MAILSLOT;
1046         char *mailslot_name;
1047         char buffer[1024];
1048         char *bufp;
1049         int dgm_id = generate_trn_id();
1050         int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
1051         
1052         if(sock == -1)
1053                 return False;
1054         
1055         /* Find out the transient UDP port we have been allocated. */
1056         if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
1057                 DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
1058                          strerror(errno)));
1059                 close(sock);
1060                 return False;
1061         }
1062
1063         /*
1064          * Create the request data.
1065          */
1066
1067         memset(buffer,'\0',sizeof(buffer));
1068         bufp = buffer;
1069         SSVAL(bufp,0,QUERYFORPDC);
1070         bufp += 2;
1071         fstrcpy(bufp,srcname);
1072         bufp += (strlen(bufp) + 1);
1073         slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
1074         mailslot_name = bufp;
1075         bufp += (strlen(bufp) + 1);
1076         bufp = ALIGN2(bufp, buffer);
1077         bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);        
1078         
1079         SIVAL(bufp,0,1);
1080         SSVAL(bufp,4,0xFFFF); 
1081         SSVAL(bufp,6,0xFFFF); 
1082         bufp += 8;
1083         len = PTR_DIFF(bufp,buffer);
1084
1085         memset((char *)&p,'\0',sizeof(p));
1086
1087         /* DIRECT GROUP or UNIQUE datagram. */
1088         dgram->header.msg_type = 0x10;
1089         dgram->header.flags.node_type = M_NODE;
1090         dgram->header.flags.first = True;
1091         dgram->header.flags.more = False;
1092         dgram->header.dgm_id = dgm_id;
1093         dgram->header.source_ip = *iface_ip(*pdc_ip);
1094         dgram->header.source_port = ntohs(sock_name.sin_port);
1095         dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
1096         dgram->header.packet_offset = 0;
1097         
1098         make_nmb_name(&dgram->source_name,srcname,0);
1099         make_nmb_name(&dgram->dest_name,domain,0x1C);
1100         
1101         ptr = &dgram->data[0];
1102         
1103         /* Setup the smb part. */
1104         ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
1105         memcpy(tmp,ptr,4);
1106         set_message(ptr,17,17 + len,True);
1107         memcpy(ptr,tmp,4);
1108
1109         CVAL(ptr,smb_com) = SMBtrans;
1110         SSVAL(ptr,smb_vwv1,len);
1111         SSVAL(ptr,smb_vwv11,len);
1112         SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
1113         SSVAL(ptr,smb_vwv13,3);
1114         SSVAL(ptr,smb_vwv14,1);
1115         SSVAL(ptr,smb_vwv15,1);
1116         SSVAL(ptr,smb_vwv16,2);
1117         p2 = smb_buf(ptr);
1118         pstrcpy(p2,mailslot);
1119         p2 = skip_string(p2,1);
1120         
1121         memcpy(p2,buffer,len);
1122         p2 += len;
1123         
1124         dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
1125         
1126         p.ip = *pdc_ip;
1127         p.port = DGRAM_PORT;
1128         p.fd = sock;
1129         p.timestamp = time(NULL);
1130         p.packet_type = DGRAM_PACKET;
1131         
1132         GetTimeOfDay(&tval);
1133         
1134         if (!send_packet(&p)) {
1135                 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1136                 close(sock);
1137                 return False;
1138         }
1139         
1140         retries--;
1141         
1142         while (1) {
1143                 struct timeval tval2;
1144                 struct packet_struct *p_ret;
1145                 
1146                 GetTimeOfDay(&tval2);
1147                 if (TvalDiff(&tval,&tval2) > retry_time) {
1148                         if (!retries)
1149                                 break;
1150                         if (!send_packet(&p)) {
1151                                 DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
1152                                 close(sock);
1153                                 return False;
1154                         }
1155                         GetTimeOfDay(&tval);
1156                         retries--;
1157                 }
1158
1159                 if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
1160                         struct dgram_packet *dgram2 = &p_ret->packet.dgram;
1161                         char *buf;
1162                         char *buf2;
1163
1164                         buf = &dgram2->data[0];
1165                         buf -= 4;
1166
1167                         if (CVAL(buf,smb_com) != SMBtrans) {
1168                                 DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
1169                                          CVAL(buf,smb_com), (unsigned int)SMBtrans ));
1170                                 free_packet(p_ret);
1171                                 continue;
1172                         }
1173                         
1174                         len = SVAL(buf,smb_vwv11);
1175                         buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
1176                         
1177                         if (len <= 0) {
1178                                 DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
1179                                 free_packet(p_ret);
1180                                 continue;
1181                         }
1182
1183                         DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
1184                                  nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
1185                                  inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
1186
1187                         if(SVAL(buf2,0) != QUERYFORPDC_R) {
1188                                 DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
1189                                          (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
1190                                 free_packet(p_ret);
1191                                 continue;
1192                         }
1193
1194                         buf2 += 2;
1195                         /* Note this is safe as it is a bounded strcpy. */
1196                         fstrcpy(ret_name, buf2);
1197                         ret_name[sizeof(fstring)-1] = '\0';
1198                         close(sock);
1199                         free_packet(p_ret);
1200                         return True;
1201                 }
1202         }
1203         
1204         close(sock);
1205         return False;
1206 #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
1207 }
1208
1209 /********************************************************
1210  Get the IP address list of the primary domain controller
1211  for a domain.
1212 *********************************************************/
1213
1214 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1215 {
1216         struct in_addr *ip_list;
1217         int count;
1218
1219         /* Look up #1B name */
1220
1221         if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
1222                 return False;
1223
1224         SMB_ASSERT(count == 1);
1225
1226         *ip = ip_list[0];
1227         SAFE_FREE(ip_list);
1228
1229         return True;
1230 }
1231
1232 /********************************************************
1233  Get the IP address list of the domain controllers for
1234  a domain.
1235 *********************************************************/
1236
1237 BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count)
1238 {
1239         /*
1240          * If it's our domain then
1241          * use the 'password server' parameter.
1242          */
1243
1244         if (strequal(domain, lp_workgroup())) {
1245                 char *p;
1246                 char *pserver = lp_passwordserver();
1247                 fstring name;
1248                 int num_adresses = 0;
1249                 struct in_addr *return_iplist = NULL;
1250
1251                 if (!*pserver)
1252                         return internal_resolve_name(
1253                                 domain, 0x1C, ip_list, count);
1254
1255                 p = pserver;
1256
1257                 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1258                         if (strequal(name, "*"))
1259                                 return internal_resolve_name(
1260                                         domain, 0x1C, ip_list, count);
1261                         num_adresses++;
1262                 }
1263
1264                 if (num_adresses == 0)
1265                         return internal_resolve_name(
1266                                 domain, 0x1C, ip_list, count);
1267
1268                 return_iplist = (struct in_addr *)malloc(
1269                         num_adresses * 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                 *count = 0;
1278
1279                 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1280                         struct in_addr name_ip;
1281                         if (resolve_name( name, &name_ip, 0x20) == False)
1282                                 continue;
1283                         return_iplist[(*count)++] = name_ip;
1284                 }
1285
1286                 *ip_list = return_iplist;
1287
1288                 return (*count != 0);
1289         }
1290         
1291         return internal_resolve_name(domain, 0x1C, ip_list, count);
1292 }