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