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