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