557bad73c3cc900d9d1aacef6a7c50b16daf4e26
[kai/samba.git] / source3 / nameserv.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5    Copyright (C) Andrew Tridgell 1994-1995
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    Revision History:
22
23    14 jan 96: lkcl@pires.co.uk
24    added multiple workgroup domain master support
25
26 */
27
28 #include "includes.h"
29
30 extern int ClientNMB;
31 extern int ClientDGRAM;
32
33 #define FIND_SELF  0x01
34 #define FIND_WINS  0x02
35 #define FIND_LOCAL 0x04
36
37 extern int DEBUGLEVEL;
38
39 extern pstring scope;
40 extern BOOL CanRecurse;
41 extern pstring myname;
42 extern struct in_addr ipzero;
43 extern struct in_addr ipgrp;
44
45 extern struct subnet_record *subnetlist;
46
47 #define WINS_LIST "wins.dat"
48
49 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
50
51 /****************************************************************************
52   finds the appropriate subnet structure. directed packets (non-bcast) are
53   assumed to come from a point-to-point (P or M node), and so the subnet we
54   return in this instance is the WINS 'pseudo-subnet' with ip 255.255.255.255
55   ****************************************************************************/
56 static struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast)
57 {
58   if (bcast)
59   {
60     /* identify the subnet the broadcast request came from */
61     return find_subnet(*iface_bcast(ip));
62   }
63   /* find the subnet under the pseudo-ip of 255.255.255.255 */
64   return find_subnet(ipgrp);
65 }
66
67 /****************************************************************************
68   true if two netbios names are equal
69 ****************************************************************************/
70 static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
71 {
72   if (n1->name_type != n2->name_type) return(False);
73
74   return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope));
75 }
76
77 /****************************************************************************
78   add a netbios name into the namelist
79   **************************************************************************/
80 static void add_name(struct subnet_record *d, struct name_record *n)
81 {
82   struct name_record *n2;
83
84   if (!d) return;
85
86   if (!d->namelist)
87   {
88     d->namelist = n;
89     n->prev = NULL;
90     n->next = NULL;
91     return;
92   }
93
94   for (n2 = d->namelist; n2->next; n2 = n2->next) ;
95
96   n2->next = n;
97   n->next = NULL;
98   n->prev = n2;
99 }
100
101 /****************************************************************************
102   remove a name from the namelist. The pointer must be an element just 
103   retrieved
104   **************************************************************************/
105 void remove_name(struct subnet_record *d, struct name_record *n)
106 {
107   struct name_record *nlist;
108   if (!d) return;
109
110   nlist = d->namelist;
111
112   while (nlist && nlist != n) nlist = nlist->next;
113
114   if (nlist)
115   {
116     if (nlist->next) nlist->next->prev = nlist->prev;
117     if (nlist->prev) nlist->prev->next = nlist->next;
118     free(nlist);
119   }
120 }
121
122
123 /****************************************************************************
124   find a name in a namelist.
125   **************************************************************************/
126 static struct name_record *find_name(struct name_record *n,
127                         struct nmb_name *name,
128                         int search, struct in_addr ip)
129 {
130         struct name_record *ret;
131   
132         for (ret = n; ret; ret = ret->next)
133         {
134                 if (name_equal(&ret->name,name))
135                 {
136                         /* self search: self names only */
137                         if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
138                                 continue;
139           
140                         /* zero ip is either samba's ip or a way of finding a
141                            name without needing to know the ip address */
142                         if (zero_ip(ip) || ip_equal(ip, ret->ip))
143                         {
144                                 return ret;
145                         }
146                 }
147         }
148     return NULL;
149 }
150
151
152 /****************************************************************************
153   find a name in the domain database namelist 
154   search can be any of:
155   FIND_SELF - look exclusively for names the samba server has added for itself
156   FIND_LOCAL - look for names in the local subnet record.
157   FIND_WINS - look for names in the WINS record
158   **************************************************************************/
159 static struct name_record *find_name_search(struct subnet_record **d,
160                         struct nmb_name *name,
161                         int search, struct in_addr ip)
162 {
163         if (d == NULL) return NULL; /* bad error! */
164         
165     if ((search & FIND_LOCAL) == FIND_LOCAL)
166         {
167                 if (*d != NULL)
168         {
169                         return find_name((*d)->namelist, name, search, ip);
170                 }
171         else
172         {
173                         DEBUG(4,("local find_name_search with a NULL subnet pointer\n"));
174             return NULL;
175                 }
176         }
177
178         if ((search & FIND_WINS) != FIND_WINS) return NULL;
179
180         if (*d == NULL)
181         {
182                 /* find WINS subnet record */
183                 *d = find_subnet(ipgrp);
184     }
185
186         if (*d == NULL) return NULL;
187
188         return find_name((*d)->namelist, name, search, ip);
189 }
190
191
192 /****************************************************************************
193   dump a copy of the name table
194   **************************************************************************/
195 void dump_names(void)
196 {
197   struct name_record *n;
198   struct subnet_record *d;
199   fstring fname, fnamenew;
200   time_t t = time(NULL);
201   
202   FILE *f;
203   
204   strcpy(fname,lp_lockdir());
205   trim_string(fname,NULL,"/");
206   strcat(fname,"/");
207   strcat(fname,WINS_LIST);
208   strcpy(fnamenew,fname);
209   strcat(fnamenew,".");
210   
211   f = fopen(fnamenew,"w");
212   
213   if (!f)
214   {
215     DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
216   }
217   
218   DEBUG(3,("Dump of local name table:\n"));
219   
220   for (d = subnetlist; d; d = d->next)
221    for (n = d->namelist; n; n = n->next)
222     {
223       if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER)
224       {
225         fstring data;
226
227       /* XXXX i have little imagination as to how to output nb_flags as
228          anything other than as a hexadecimal number :-) */
229
230         sprintf(data, "%s#%02x %s %ld %2x",
231                n->name.name,n->name.name_type, /* XXXX ignore the scope for now */
232                inet_ntoa(n->ip),
233                n->death_time,
234                n->nb_flags);
235             fprintf(f, "%s\n", data);
236       }
237
238           DEBUG(3,("%15s ", inet_ntoa(d->bcast_ip)));
239           DEBUG(3,("%15s ", inet_ntoa(d->mask_ip)));
240       DEBUG(3,("%s %15s TTL=%15d NBFLAGS=%2x\n",
241                namestr(&n->name),
242                inet_ntoa(n->ip),
243            n->death_time?n->death_time-t:0,
244                n->nb_flags));
245     }
246
247   fclose(f);
248   unlink(fname);
249   chmod(fnamenew,0644);
250   rename(fnamenew,fname);   
251
252   DEBUG(3,("Wrote wins database %s\n",fname));
253 }
254
255 /****************************************************************************
256 load a netbios name database file
257 ****************************************************************************/
258 void load_netbios_names(void)
259 {
260   struct subnet_record *d = find_subnet(ipgrp);
261   fstring fname;
262
263   FILE *f;
264   pstring line;
265
266   if (!d) return;
267
268   strcpy(fname,lp_lockdir());
269   trim_string(fname,NULL,"/");
270   strcat(fname,"/");
271   strcat(fname,WINS_LIST);
272
273   f = fopen(fname,"r");
274
275   if (!f) {
276     DEBUG(2,("Can't open wins database file %s\n",fname));
277     return;
278   }
279
280   while (!feof(f))
281     {
282       pstring name_str, ip_str, ttd_str, nb_flags_str;
283
284       pstring name;
285       int type = 0;
286       int nb_flags;
287       time_t ttd;
288           struct in_addr ipaddr;
289
290           enum name_source source;
291
292       char *ptr;
293           int count = 0;
294
295       char *p;
296
297       if (!fgets_slash(line,sizeof(pstring),f)) continue;
298
299       if (*line == '#') continue;
300
301         ptr = line;
302
303         if (next_token(&ptr,name_str    ,NULL)) ++count;
304         if (next_token(&ptr,ip_str      ,NULL)) ++count;
305         if (next_token(&ptr,ttd_str     ,NULL)) ++count;
306         if (next_token(&ptr,nb_flags_str,NULL)) ++count;
307
308         if (count <= 0) continue;
309
310         if (count != 4) {
311           DEBUG(0,("Ill formed wins line"));
312           DEBUG(0,("[%s]: name#type ip nb_flags abs_time\n",line));
313           continue;
314         }
315
316       /* netbios name. # divides the name from the type (hex): netbios#xx */
317       strcpy(name,name_str);
318
319       p = strchr(name,'#');
320
321       if (p) {
322             *p = 0;
323             sscanf(p+1,"%x",&type);
324       }
325
326       /* decode the netbios flags (hex) and the time-to-die (seconds) */
327           sscanf(nb_flags_str,"%x",&nb_flags);
328           sscanf(ttd_str,"%ld",&ttd);
329
330           ipaddr = *interpret_addr2(ip_str);
331
332       if (ip_equal(ipaddr,ipzero)) {
333          source = SELF;
334       }
335       else
336       {
337          source = REGISTER;
338       }
339
340       DEBUG(4, ("add WINS line: %s#%02x %s %ld %2x\n",
341                name,type, inet_ntoa(ipaddr), ttd, nb_flags));
342
343       /* add all entries that have 60 seconds or more to live */
344       if (ttd - 10 < time(NULL) || ttd == 0)
345       {
346         time_t t = (ttd?ttd-time(NULL):0) / 3;
347
348         /* add netbios entry read from the wins.dat file. IF it's ok */
349         add_netbios_entry(d,name,type,nb_flags,t,source,ipaddr,True,True);
350       }
351     }
352
353   fclose(f);
354 }
355
356
357 /****************************************************************************
358   remove an entry from the name list
359   ****************************************************************************/
360 void remove_netbios_name(struct subnet_record *d,
361                         char *name,int type, enum name_source source,
362                          struct in_addr ip)
363 {
364   struct nmb_name nn;
365   struct name_record *n;
366   int search = FIND_LOCAL;
367
368   /* if it's not a special browser name, search the WINS database */
369   if (type != 0x01 && type != 0x1d && type != 0x1e)
370     search |= FIND_WINS;
371
372   make_nmb_name(&nn, name, type, scope);
373   n = find_name_search(&d, &nn, search, ip);
374   
375   if (n && n->source == source) remove_name(d,n);
376 }
377
378
379 /****************************************************************************
380   add an entry to the name list.
381
382   this is a multi-purpose function.
383
384   it adds samba's own names in to its records on each interface, keeping a
385   record of whether it is a master browser, domain master, or WINS server.
386
387   it also keeps a record of WINS entries (names of type 0x00, 0x20, 0x03 etc)
388
389   ****************************************************************************/
390 struct name_record *add_netbios_entry(struct subnet_record *d,
391                 char *name, int type, int nb_flags, 
392                 int ttl, enum name_source source, struct in_addr ip,
393                 BOOL new_only,BOOL wins)
394 {
395   struct name_record *n;
396   struct name_record *n2=NULL;
397   int search = 0;
398   BOOL self = source == SELF;
399
400   /* add the name to the WINS list if the name comes from a directed query */
401   search |= wins ? FIND_WINS : FIND_LOCAL;
402   /* search for SELF names only */
403   search |= self ? FIND_SELF : 0;
404
405   if (!self)
406   {
407     if (wins)
408     {
409           if (type == 0x01 || type == 0x1d || type == 0x1e)
410       {
411          /* XXXX WINS server supposed to ignore special browser names. hm.
412             but is a primary domain controller supposed to ignore special
413             browser names? luke doesn't think so, but can't test it! :-)
414           */
415          return NULL;
416       }
417     }
418     else /* !wins */
419     {
420        /* the only broadcast (non-WINS) names we are adding are ours (SELF) */
421        return NULL;
422     }
423   }
424
425   n = (struct name_record *)malloc(sizeof(*n));
426   if (!n) return(NULL);
427
428   bzero((char *)n,sizeof(*n));
429
430   make_nmb_name(&n->name,name,type,scope);
431
432   if ((n2 = find_name_search(&d, &n->name, search, new_only?ipzero:ip)))
433   {
434     free(n);
435     if (new_only || (n2->source==SELF && source!=SELF)) return n2;
436     n = n2;
437   }
438
439   if (ttl)
440      n->death_time = time(NULL)+ttl*3;
441   n->refresh_time = time(NULL)+GET_TTL(ttl);
442
443   n->ip = ip;
444   n->nb_flags = nb_flags;
445   n->source = source;
446   
447   if (!n2) add_name(d,n);
448
449   DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
450                 namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
451
452   return(n);
453 }
454
455
456 /****************************************************************************
457   remove an entry from the name list
458   ****************************************************************************/
459 void remove_name_entry(struct subnet_record *d, char *name,int type)
460 {
461   /* XXXX BUG: if samba is offering WINS support, it should still broadcast
462       a de-registration packet to the local subnet before removing the
463       name from its local-subnet name database. */
464
465   if (lp_wins_support())
466     {
467       /* we are a WINS server. */
468       /* XXXX assume that if we are a WINS server that we are therefore
469          not pointing to another WINS server as well. this may later NOT
470          actually be true */
471       remove_netbios_name(d,name,type,SELF,ipzero);
472     }
473   else
474     {
475       /* not a WINS server: cannot just remove our own names: we have to
476          ask permission from the WINS server, or if no reply is received,
477                  _then_ we can remove the name */
478
479           struct name_record n;
480           struct name_record *n2=NULL;
481       
482       make_nmb_name(&n.name,name,type,scope);
483
484       if ((n2 = find_name_search(&d, &n.name, FIND_SELF, ipzero)))
485       {
486         /* check name isn't already being de-registered */
487                 if (NAME_DEREG(n2->nb_flags))
488           return;
489
490                 /* mark the name as in the process of deletion. */
491          n2->nb_flags &= NB_DEREG;
492       }
493       queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
494                              name, type, 0, 0,
495                              False, True, ipzero);
496     }
497 }
498
499
500 /****************************************************************************
501   add an entry to the name list
502   ****************************************************************************/
503 void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
504 {
505   BOOL re_reg = False;
506   struct nmb_name n;
507
508   if (!d) return;
509
510   /* not that it particularly matters, but if the SELF name already exists,
511      it must be re-registered, rather than just registered */
512
513   make_nmb_name(&n, name, type, scope);
514   if (find_name(d->namelist, &n, SELF, ipzero))
515         re_reg = True;
516
517   /* always add our own entries */
518   add_netbios_entry(d,name,type,nb_flags,0,SELF,ipzero,False,lp_wins_support());
519
520   /* XXXX BUG: if samba is offering WINS support, it should still add the
521      name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
522      regarding the point about M-nodes. */
523
524   if (!lp_wins_support())
525   {
526     /* samba isn't supporting WINS itself: register the name using broadcast
527        or with another WINS server.
528        XXXX note: we may support WINS and also know about other WINS servers
529        in the future.
530      */
531       
532     queue_netbios_pkt_wins(d,ClientNMB,
533                                  re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
534                              name, type, nb_flags, GET_TTL(0),
535                              False, True, ipzero);
536   }
537 }
538
539
540 /****************************************************************************
541   add the magic samba names, useful for finding samba servers
542   **************************************************************************/
543 void add_my_names(void)
544 {
545   BOOL wins = lp_wins_support();
546   struct subnet_record *d;
547
548   struct in_addr ip = ipzero;
549
550   /* each subnet entry, including WINS pseudo-subnet, has SELF names */
551
552   /* XXXX if there was a transport layer added to samba (ipx/spx etc) then
553      there would be yet _another_ for-loop, this time on the transport type
554    */
555
556   for (d = subnetlist; d; d = d->next)
557   {
558         add_my_name_entry(d, myname,0x20,NB_ACTIVE);
559         add_my_name_entry(d, myname,0x03,NB_ACTIVE);
560         add_my_name_entry(d, myname,0x00,NB_ACTIVE);
561         add_my_name_entry(d, myname,0x1f,NB_ACTIVE);
562
563         add_netbios_entry(d,"*",0x0,NB_ACTIVE,0,SELF,ip,False,wins);
564         add_netbios_entry(d,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins);
565         add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
566
567     if (wins) {
568         /* the 0x1c name gets added by any WINS server it seems */
569           add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
570     }
571   }
572 }
573
574
575 /****************************************************************************
576   remove all the samba names... from a WINS server if necessary.
577   **************************************************************************/
578 void remove_my_names()
579 {
580         struct subnet_record *d;
581
582         for (d = subnetlist; d; d = d->next)
583         {
584                 struct name_record *n, *next;
585
586                 for (n = d->namelist; n; n = next)
587                 {
588                         next = n->next;
589                         if (n->source == SELF)
590                         {
591                                 /* get all SELF names removed from the WINS server's database */
592                                 /* XXXX note: problem occurs if this removes the wrong one! */
593
594                                 remove_name_entry(d,n->name.name, n->name.name_type);
595                         }
596                 }
597         }
598 }
599
600
601 /*******************************************************************
602   refresh my own names
603   ******************************************************************/
604 void refresh_my_names(time_t t)
605 {
606   struct subnet_record *d;
607
608   for (d = subnetlist; d; d = d->next)
609   {
610     struct name_record *n;
611           
612         for (n = d->namelist; n; n = n->next)
613     {
614       /* each SELF name has an individual time to be refreshed */
615       if (n->source == SELF && n->refresh_time < time(NULL))
616       {
617         add_my_name_entry(d,n->name.name,n->name.name_type,n->nb_flags);
618       }
619     }
620   }
621 }
622
623 /*******************************************************************
624   queries names occasionally. an over-cautious, non-trusting WINS server!
625
626   this function has been added because nmbd could be restarted. it
627   is generally a good idea to check all the names that have been
628   reloaded from file.
629
630   XXXX which names to poll and which not can be refined at a later date.
631   ******************************************************************/
632 void query_refresh_names(void)
633 {
634         struct name_record *n;
635         struct subnet_record *d = find_subnet(ipgrp);
636
637         static time_t lasttime = 0;
638         time_t t = time(NULL);
639
640         int count = 0;
641         int name_refresh_time = NAME_POLL_REFRESH_TIME;
642         int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
643         if (max_count > 10) max_count = 10;
644
645         name_refresh_time = NAME_POLL_INTERVAL * max_count / 2;
646
647         /* if (!lp_poll_wins()) return; polling of registered names allowed */
648
649         if (!d) return;
650
651         if (t - lasttime < NAME_POLL_INTERVAL) return;
652
653         for (n = d->namelist; n; n = n->next)
654         {
655                 /* only do unique, registered names */
656
657                 if (n->source != REGISTER) continue;
658                 if (!NAME_GROUP(n->nb_flags)) continue;
659
660                 if (n->refresh_time < t)
661                 {
662                   DEBUG(3,("Polling name %s\n", namestr(&n->name)));
663                   
664           queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
665                                 n->name.name, n->name.name_type,
666                                 0,0,
667                                 False,False,n->ip);
668                   count++;
669                 }
670
671                 if (count >= max_count)
672                 {
673                         /* don't do too many of these at once, but do enough to
674                            cover everyone in the list */
675                         return;
676                 }
677
678                 /* this name will be checked on again, if it's not removed */
679                 n->refresh_time += name_refresh_time;
680         }
681 }
682
683
684 /*******************************************************************
685   expires old names in the namelist
686   ******************************************************************/
687 void expire_names(time_t t)
688 {
689         struct name_record *n;
690         struct name_record *next;
691         struct subnet_record *d;
692
693         /* expire old names */
694         for (d = subnetlist; d; d = d->next)
695         {
696           for (n = d->namelist; n; n = next)
697                 {
698                   if (n->death_time && n->death_time < t)
699                 {
700                   DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
701                   
702                   next = n->next;
703                   
704                   if (n->prev) n->prev->next = n->next;
705                   if (n->next) n->next->prev = n->prev;
706                   
707                   if (d->namelist == n) d->namelist = n->next; 
708                   
709                   free(n);
710                 }
711                   else
712                 {
713                   next = n->next;
714                 }
715                 }
716         }
717 }
718
719
720 /****************************************************************************
721   response for a reg release received. samba has asked a WINS server if it
722   could release a name.
723   **************************************************************************/
724 void response_name_release(struct subnet_record *d, struct packet_struct *p)
725 {
726   struct nmb_packet *nmb = &p->packet.nmb;
727   char *name = nmb->question.question_name.name;
728   int   type = nmb->question.question_name.name_type;
729   
730   DEBUG(4,("response name release received\n"));
731   
732   if (nmb->header.rcode == 0 && nmb->answers->rdata)
733     {
734       /* IMPORTANT: see expire_netbios_response_entries() */
735
736       struct in_addr found_ip;
737       putip((char*)&found_ip,&nmb->answers->rdata[2]);
738       
739       if (ismyip(found_ip))
740       {
741             remove_netbios_name(d,name,type,SELF,found_ip);
742           }
743     }
744   else
745     {
746       DEBUG(2,("name release for %s rejected!\n",
747                namestr(&nmb->question.question_name)));
748
749                 /* XXXX do we honestly care if our name release was rejected? 
750            only if samba is issuing the release on behalf of some out-of-sync
751            server. if it's one of samba's SELF names, we don't care. */
752     }
753 }
754
755
756 /****************************************************************************
757 reply to a name release
758 ****************************************************************************/
759 void reply_name_release(struct packet_struct *p)
760 {
761   struct nmb_packet *nmb = &p->packet.nmb;
762   struct in_addr ip;
763   int rcode=0;
764   int opcode = nmb->header.opcode;  
765   int nb_flags = nmb->additional->rdata[0];
766   BOOL bcast = nmb->header.nm_flags.bcast;
767   struct name_record *n;
768   struct subnet_record *d = NULL;
769   char rdata[6];
770   int search = 0;
771   
772   putip((char *)&ip,&nmb->additional->rdata[2]);  
773   
774   DEBUG(3,("Name release on name %s rcode=%d\n",
775            namestr(&nmb->question.question_name),rcode));
776   
777   if (!(d = find_req_subnet(p->ip, bcast)))
778   {
779     DEBUG(3,("response packet: bcast %s not known\n",
780                         inet_ntoa(p->ip)));
781     return;
782   }
783
784   if (bcast)
785         search &= FIND_LOCAL;
786   else
787         search &= FIND_WINS;
788
789   n = find_name_search(&d, &nmb->question.question_name, 
790                                         search, ip);
791   
792   /* XXXX under what conditions should we reject the removal?? */
793   if (n && n->nb_flags == nb_flags)
794     {
795       /* success = True;
796          rcode = 6; */
797       
798       remove_name(d,n);
799       n = NULL;
800     }
801   
802   if (bcast) return;
803   
804   rdata[0] = nb_flags;
805   rdata[1] = 0;
806   putip(&rdata[2],(char *)&ip);
807   
808   /* Send a NAME RELEASE RESPONSE */
809   reply_netbios_packet(p,nmb->header.name_trn_id,
810                            rcode,opcode,True,
811                        &nmb->question.question_name,
812                        nmb->question.question_type,
813                        nmb->question.question_class,
814                        0,
815                        rdata, 6);
816 }
817
818
819 /****************************************************************************
820 response for a reg request received
821 **************************************************************************/
822 void response_name_reg(struct subnet_record *d, struct packet_struct *p)
823 {
824   struct nmb_packet *nmb = &p->packet.nmb;
825   char *name = nmb->question.question_name.name;
826   int   type = nmb->question.question_name.name_type;
827   BOOL bcast = nmb->header.nm_flags.bcast;
828   
829   DEBUG(4,("response name registration received!\n"));
830   
831   if (nmb->header.rcode == 0 && nmb->answers->rdata)
832     {
833       /* IMPORTANT: see expire_netbios_response_entries() */
834
835       int nb_flags = nmb->answers->rdata[0];
836       struct in_addr found_ip;
837       int ttl = nmb->answers->ttl;
838       enum name_source source = REGISTER;
839       
840       putip((char*)&found_ip,&nmb->answers->rdata[2]);
841       
842       if (ismyip(found_ip)) source = SELF;
843       
844       add_netbios_entry(d, name,type,nb_flags,ttl,source,found_ip,True,!bcast);
845     }
846   else
847     {
848                 struct work_record *work;
849
850       DEBUG(1,("name registration for %s rejected!\n",
851                namestr(&nmb->question.question_name)));
852
853           /* XXXX oh dear. we have problems. must deal with our name having
854          been rejected: e.g if it was our GROUP(1d) name, we must unbecome
855          a master browser. */
856         
857         remove_netbios_name(d,name,type,SELF,ipzero);
858
859                 if (!(work = find_workgroupstruct(d, name, False))) return;
860
861                 if (AM_MASTER(work) && (type == 0x1d || type == 0x1b))
862                 {
863                         int remove_type = 0;
864                         if (type == 0x1d) remove_type = SV_TYPE_MASTER_BROWSER;
865                         if (type == 0x1b) remove_type = SV_TYPE_DOMAIN_MASTER;
866                         
867                         become_nonmaster(d, work, remove_type);
868                 }
869     }
870 }
871
872
873 /****************************************************************************
874 reply to a reg request
875 **************************************************************************/
876 void reply_name_reg(struct packet_struct *p)
877 {
878   struct nmb_packet *nmb = &p->packet.nmb;
879   struct nmb_name *question = &nmb->question.question_name;
880   
881   struct nmb_name *reply_name = question;
882   char *qname = question->name;
883   int name_type  = question->name_type;
884   int name_class = nmb->question.question_class;
885  
886   BOOL bcast = nmb->header.nm_flags.bcast;
887   
888   int ttl = GET_TTL(nmb->additional->ttl);
889   int nb_flags = nmb->additional->rdata[0];
890   BOOL group = NAME_GROUP(nb_flags);
891   int rcode = 0;  
892   int opcode = nmb->header.opcode;  
893
894   struct subnet_record *d = NULL;
895   struct name_record *n = NULL;
896   BOOL success = True;
897   BOOL recurse = True; /* true if samba replies yes/no: false if caller */
898   /* must challenge the current owner of the unique name */
899   char rdata[6];
900   struct in_addr ip, from_ip;
901   int search = 0;
902   
903   putip((char *)&from_ip,&nmb->additional->rdata[2]);
904   ip = from_ip;
905   
906   DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
907            namestr(question),inet_ntoa(ip),rcode));
908   
909   if (group)
910     {
911       /* apparently we should return 255.255.255.255 for group queries
912          (email from MS) */
913       ip = ipgrp;
914     }
915   
916   if (!(d = find_req_subnet(p->ip, bcast)))
917   {
918     DEBUG(3,("response packet: bcast %s not known\n",
919                                 inet_ntoa(p->ip)));
920     return;
921   }
922
923   if (bcast)
924         search &= FIND_LOCAL;
925   else
926         search &= FIND_WINS;
927
928   /* see if the name already exists */
929   n = find_name_search(&d, question, search, from_ip);
930   
931   if (n)
932   {
933     if (!group) /* unique names */
934         {
935           if (n->source == SELF || NAME_GROUP(n->nb_flags))
936           {
937               /* no-one can register one of samba's names, nor can they
938                  register a name that's a group name as a unique name */
939               
940               rcode = 6;
941               success = False;
942           }
943           else if(!ip_equal(ip, n->ip))
944           {
945               /* hm. this unique name doesn't belong to them. */
946               
947               /* XXXX rfc1001.txt says:
948                * if we are doing secured WINS, we must send a Wait-Acknowledge
949                * packet (WACK) to the person who wants the name, then do a
950                * name query on the person who currently owns the unique name.
951                * if the current owner still says they own it, the person who wants
952                    * the name can't have it. if they do not, or are not alive, they can.
953                *
954                * if we are doing non-secured WINS (which is much simpler) then
955                * we send a message to the person wanting the name saying 'he
956                * owns this name: i don't want to hear from you ever again
957                * until you've checked with him if you can have it!'. we then
958                * abandon the registration. once the person wanting the name
959                * has checked with the current owner, they will repeat the
960                * registration packet if the current owner is dead or doesn't
961                * want the name.
962                */
963               
964               /* non-secured WINS implementation: caller is responsible
965                  for checking with current owner of name, then getting back
966                  to us... IF current owner no longer owns the unique name */
967               
968            /* XXXX please note also that samba cannot cope with 
969               _receiving_ such redirecting, non-secured registration
970               packets. code to do this needs to be added.
971             */
972
973               rcode = 0;
974               success = False;
975               recurse = False;
976               
977               /* we inform on the current owner to the caller (which is
978                  why it's non-secure */
979               
980               reply_name = &n->name;
981               
982               /* name_type  = ?;
983                  name_class = ?;
984                  XXXX sorry, guys: i really can't see what name_type
985                  and name_class should be set to according to rfc1001 */
986           }
987           else
988           {
989               n->ip = ip;
990               n->death_time = ttl?p->timestamp+ttl*3:0;
991               DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip)));
992           }
993         }
994     else
995         {
996           /* refresh the name */
997           if (n->source != SELF)
998           {
999               n->death_time = ttl?p->timestamp + ttl*3:0;
1000           }
1001         }
1002
1003     /* XXXX bug reported by terryt@ren.pc.athabascau.ca */
1004     /* names that people have checked for and not found get DNSFAILed. 
1005        we need to update the name record if someone then registers */
1006
1007     if (n->source == DNSFAIL)
1008       n->source = REGISTER;
1009
1010   }
1011   else
1012   {
1013       /* add the name to our name/subnet, or WINS, database */
1014       n = add_netbios_entry(d,qname,name_type,nb_flags,ttl,REGISTER,ip,
1015                                 True,!bcast);
1016   }
1017   
1018   /* if samba owns a unique name on a subnet, then it must respond and
1019      disallow the attempted registration. if the registration is
1020      successful by broadcast, only then is there no need to respond
1021      (implicit registration: see rfc1001.txt 15.2.1).
1022    */
1023
1024   if (bcast || !success) return;
1025   
1026   rdata[0] = nb_flags;
1027   rdata[1] = 0;
1028   putip(&rdata[2],(char *)&ip);
1029   
1030   /* Send a NAME REGISTRATION RESPONSE (pos/neg)
1031      or an END-NODE CHALLENGE REGISTRATION RESPONSE */
1032   reply_netbios_packet(p,nmb->header.name_trn_id,
1033                        rcode,opcode,recurse,
1034                        reply_name, name_type, name_class,
1035                        ttl,
1036                        rdata, 6);
1037 }
1038
1039
1040 /****************************************************************************
1041 reply to a name status query
1042 ****************************************************************************/
1043 void reply_name_status(struct packet_struct *p)
1044 {
1045   struct nmb_packet *nmb = &p->packet.nmb;
1046   char *qname   = nmb->question.question_name.name;
1047   int ques_type = nmb->question.question_name.name_type;
1048   char rdata[MAX_DGRAM_SIZE];
1049   char *countptr, *buf, *bufend;
1050   int names_added;
1051   struct name_record *n;
1052   struct subnet_record *d = NULL;
1053
1054   BOOL bcast = nmb->header.nm_flags.bcast;
1055   
1056   if (!(d = find_req_subnet(p->ip, bcast)))
1057   {
1058     DEBUG(3,("Name status req: bcast %s not known\n",
1059                         inet_ntoa(p->ip)));
1060     return;
1061   }
1062
1063   DEBUG(3,("Name status for name %s %s\n",
1064            namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
1065   
1066   n = find_name_search(&d, &nmb->question.question_name,
1067                                 FIND_SELF|FIND_LOCAL,
1068                                 p->ip);
1069   
1070   if (!n) return;
1071   
1072   /* XXXX hack, we should calculate exactly how many will fit */
1073   bufend = &rdata[MAX_DGRAM_SIZE] - 18;
1074   countptr = buf = rdata;
1075   buf += 1;
1076   
1077   names_added = 0;
1078   
1079   for (n = d->namelist ; n && buf < bufend; n = n->next) 
1080     {
1081       int name_type = n->name.name_type;
1082       
1083       if (n->source != SELF) continue;
1084       
1085       /* start with first bit of putting info in buffer: the name */
1086       
1087       bzero(buf,18);
1088           sprintf(buf,"%-15.15s",n->name.name);
1089       strupper(buf);
1090       
1091       /* now check if we want to exclude other workgroup names
1092          from the response. if we don't exclude them, windows clients
1093          get confused and will respond with an error for NET VIEW */
1094       
1095       if (name_type >= 0x1b && name_type <= 0x20 && 
1096           ques_type >= 0x1b && ques_type <= 0x20)
1097         {
1098           if (!strequal(qname, n->name.name)) continue;
1099         }
1100       
1101       /* carry on putting name info in buffer */
1102       
1103       buf[15] = name_type;
1104       buf[16]  = n->nb_flags;
1105       
1106       buf += 18;
1107       
1108       names_added++;
1109     }
1110   
1111   SCVAL(countptr,0,names_added);
1112   
1113   /* XXXXXXX we should fill in more fields of the statistics structure */
1114   bzero(buf,64);
1115   {
1116     extern int num_good_sends,num_good_receives;
1117     SIVAL(buf,20,num_good_sends);
1118     SIVAL(buf,24,num_good_receives);
1119   }
1120   
1121   SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
1122   
1123   buf += 64;
1124   
1125   /* Send a POSITIVE NAME STATUS RESPONSE */
1126   reply_netbios_packet(p,nmb->header.name_trn_id,
1127                            0,0,True,
1128                        &nmb->question.question_name,
1129                        nmb->question.question_type,
1130                        nmb->question.question_class,
1131                        0,
1132                        rdata,PTR_DIFF(buf,rdata));
1133 }
1134
1135
1136 /***************************************************************************
1137   reply to a name query
1138   ****************************************************************************/
1139 struct name_record *search_for_name(struct subnet_record **d,
1140                                         struct nmb_name *question,
1141                                     struct in_addr ip, int Time, int search)
1142 {
1143   int name_type = question->name_type;
1144   char *qname = question->name;
1145   BOOL dns_type = name_type == 0x20 || name_type == 0;
1146   
1147   struct name_record *n;
1148   
1149   DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
1150   
1151   /* first look up name in cache */
1152   n = find_name_search(d,question,search,ip);
1153   
1154   if (*d == NULL) return NULL;
1155
1156   /* now try DNS lookup. */
1157   if (!n)
1158     {
1159       struct in_addr dns_ip;
1160       unsigned long a;
1161       
1162       /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
1163       if (!dns_type)
1164         {
1165           DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
1166           return NULL;
1167         }
1168       
1169       /* look it up with DNS */      
1170       a = interpret_addr(qname);
1171       
1172       putip((char *)&dns_ip,(char *)&a);
1173       
1174       if (!a)
1175         {
1176           /* no luck with DNS. We could possibly recurse here XXXX */
1177           DEBUG(3,("no recursion.\n"));
1178       /* add the fail to our WINS cache of names. give it 1 hour in the cache */
1179           add_netbios_entry(*d,qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,
1180                                                 True, True);
1181           return NULL;
1182         }
1183       
1184       /* add it to our WINS cache of names. give it 2 hours in the cache */
1185       n = add_netbios_entry(*d,qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip,
1186                                                 True,True);
1187       
1188       /* failed to add it? yikes! */
1189       if (!n) return NULL;
1190     }
1191   
1192   /* is our entry already dead? */
1193   if (n->death_time)
1194     {
1195       if (n->death_time < Time) return False;
1196     }
1197   
1198   /* it may have been an earlier failure */
1199   if (n->source == DNSFAIL)
1200     {
1201       DEBUG(3,("DNSFAIL\n"));
1202       return NULL;
1203     }
1204   
1205   DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));      
1206   
1207   return n;
1208 }
1209
1210
1211 /***************************************************************************
1212 reply to a name query.
1213
1214 with broadcast name queries:
1215
1216         - only reply if the query is for one of YOUR names. all other machines on
1217           the network will be doing the same thing (that is, only replying to a
1218           broadcast query if they own it)
1219           NOTE: broadcast name queries should only be sent out by a machine
1220           if they HAVEN'T been configured to use WINS. this is generally bad news
1221           in a wide area tcp/ip network and should be rectified by the systems
1222           administrator. USE WINS! :-)
1223         - the exception to this is if the query is for a Primary Domain Controller
1224           type name (0x1b), in which case, a reply is sent.
1225
1226         - NEVER send a negative response to a broadcast query. no-one else will!
1227
1228 with directed name queries:
1229
1230         - if you are the WINS server, you are expected to respond with either
1231       a negative response, a positive response, or a wait-for-acknowledgement
1232       packet, and then later on a pos/neg response.
1233
1234 ****************************************************************************/
1235 void reply_name_query(struct packet_struct *p)
1236 {
1237   struct nmb_packet *nmb = &p->packet.nmb;
1238   struct nmb_name *question = &nmb->question.question_name;
1239   int name_type = question->name_type;
1240   BOOL bcast = nmb->header.nm_flags.bcast;
1241   int ttl=0;
1242   int rcode = 0;
1243   int nb_flags = 0;
1244   struct in_addr retip;
1245   char rdata[6];
1246   struct subnet_record *d = NULL;
1247
1248   BOOL success = True;
1249   
1250   struct name_record *n;
1251   int search = 0;
1252
1253   if (name_type == 0x20 || name_type == 0x00 || name_type == 0x1b ||
1254       name_type == 0x1f || name_type == 0x03 || name_type == 0x01 ||
1255       name_type == 0x1c)
1256   {
1257     /* search for any of the non-'special browser' names, or for a PDC type
1258        (0x1b) name in the WINS database.
1259        XXXX should we include name type 0x1c: WINS server type?
1260      */
1261         search |= FIND_WINS;
1262   }
1263   else
1264   {
1265         /* special browser name types e.g 
1266        ^1^2__MSBROWSE__^2^1, GROUP(1d) and GROUP(1e)
1267
1268        name_type == 0x01 || name_type == 0x1d || name_type == 0x1e.
1269
1270        XXXX luke reckons we should be able to search for any SELF name
1271        in the WINS database, if we are a primary domain controller.
1272      */
1273
1274     if (!(d = find_req_subnet(p->ip, bcast)))
1275     {
1276       DEBUG(3,("name query: bcast %s not known\n",
1277                                   inet_ntoa(p->ip)));
1278       success = False;
1279     }
1280
1281     /* XXXX delete if shouldn't search for SELF names in WINS database */
1282     search |= FIND_WINS;
1283   }
1284
1285   if (bcast)
1286   {
1287     /* a name query has been made by a non-WINS configured host. search the
1288        local interface database as well */
1289     search |= FIND_LOCAL;
1290   }
1291
1292   DEBUG(3,("Name query "));
1293   
1294   if (search == 0)
1295   {
1296     /* eh? no criterion for searching database. help! */
1297     success = False;
1298   }
1299
1300   if (success && (n = search_for_name(&d,question,p->ip,p->timestamp, search)))
1301   {
1302       /* don't respond to broadcast queries unless the query is for
1303          a name we own or it is for a Primary Domain Controller name */
1304
1305       if (bcast && n->source != SELF && name_type != 0x1b) {
1306             if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) {
1307               /* never reply with a negative response to broadcast queries */
1308               return;
1309             }
1310           }
1311       
1312       /* name is directed query, or it's self, or it's a PDC type name, or
1313              we're replying on behalf of a caller because they are on a different
1314          subnet and cannot hear the broadcast. XXXX lp_wins_proxy should be
1315                  switched off in environments where broadcasts are forwarded */
1316
1317       /* XXXX note: for proxy servers, we should forward the query on to
1318          another WINS server if the name is not in our database, or we are
1319          not a WINS server ourselves
1320        */
1321       ttl = n->death_time - p->timestamp;
1322       retip = n->ip;
1323       nb_flags = n->nb_flags;
1324   }
1325   else
1326   {
1327       if (bcast) return; /* never reply negative response to bcasts */
1328       success = False;
1329   }
1330   
1331   /* if the IP is 0 then substitute my IP */
1332   if (zero_ip(retip)) retip = *iface_ip(p->ip);
1333
1334   if (success)
1335   {
1336       rcode = 0;
1337       DEBUG(3,("OK %s\n",inet_ntoa(retip)));      
1338   }
1339   else
1340   {
1341       rcode = 3;
1342       DEBUG(3,("UNKNOWN\n"));      
1343   }
1344   
1345   if (success)
1346   {
1347       rdata[0] = nb_flags;
1348       rdata[1] = 0;
1349       putip(&rdata[2],(char *)&retip);
1350   }
1351   
1352   reply_netbios_packet(p,nmb->header.name_trn_id,
1353                            rcode,0,True,
1354                        &nmb->question.question_name,
1355                        nmb->question.question_type,
1356                        nmb->question.question_class,
1357                        ttl,
1358                        rdata, success ? 6 : 0);
1359 }
1360
1361
1362 /****************************************************************************
1363   response from a name query server check. commands of type NAME_QUERY_MST_SRV_CHK,
1364   NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
1365   ****************************************************************************/
1366 static void response_server_check(struct nmb_name *ans_name, 
1367                 struct response_record *n, struct subnet_record *d)
1368 {
1369     /* issue another command: this time to do a name status check */
1370
1371     enum cmd_type cmd = (n->cmd_type == NAME_QUERY_MST_SRV_CHK) ?
1372               NAME_STATUS_MASTER_CHECK : NAME_STATUS_CHECK;
1373
1374     /* initiate a name status check on the server that replied */
1375     queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
1376                                 ans_name->name, ans_name->name_type,
1377                                 0,0,
1378                                 False,False,n->to_ip);
1379 }
1380
1381 /****************************************************************************
1382   response from a name status check. commands of type NAME_STATUS_MASTER_CHECK
1383   and NAME_STATUS_CHECK dealt with here.
1384   ****************************************************************************/
1385 static void response_name_status_check(struct in_addr ip,
1386                 struct nmb_packet *nmb, BOOL bcast,
1387                 struct response_record *n, struct subnet_record *d)
1388 {
1389         /* NMB_STATUS arrives: contains workgroup name and server name required.
1390        amongst other things. */
1391
1392         struct nmb_name name;
1393         fstring serv_name;
1394
1395         if (interpret_node_status(d,nmb->answers->rdata,
1396                                   &name,0x1d,serv_name,ip,bcast))
1397         {
1398                 if (*serv_name)
1399                 {
1400                         sync_server(n->cmd_type,serv_name,
1401                                     name.name,name.name_type, n->to_ip);
1402                 }
1403         }
1404         else
1405         {
1406                 DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
1407         }
1408 }
1409
1410
1411 /****************************************************************************
1412   response from a name query to sync browse lists or to update our netbios
1413   entry. commands of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM 
1414   ****************************************************************************/
1415 static void response_name_query_sync(struct nmb_packet *nmb, 
1416                 struct nmb_name *ans_name, BOOL bcast,
1417                 struct response_record *n, struct subnet_record *d)
1418 {
1419         DEBUG(4, ("Name query at %s ip %s - ",
1420                   namestr(&n->name), inet_ntoa(n->to_ip)));
1421
1422         if (!name_equal(n->name, ans_name))
1423         {
1424                 /* someone gave us the wrong name as a reply. oops. */
1425                 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
1426                 return;
1427         }
1428
1429         if (nmb->header.rcode == 0 && nmb->answers->rdata)
1430     {
1431                 int nb_flags = nmb->answers->rdata[0];
1432                 struct in_addr found_ip;
1433
1434                 putip((char*)&found_ip,&nmb->answers->rdata[2]);
1435
1436                 if (!ip_equal(n->ip, found_ip))
1437                 {
1438                         /* someone gave us the wrong ip as a reply. oops. */
1439                         DEBUG(4,("expected ip: %s\n", inet_ntoa(n->ip)));
1440                         DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
1441                         return;
1442                 }
1443
1444                 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
1445
1446                 if (n->cmd_type == NAME_QUERY_SYNC)
1447                 {
1448                         struct work_record *work = NULL;
1449                         if ((work = find_workgroupstruct(d, ans_name->name, False)))
1450                         {
1451                                 /* the server is there: sync quick before it (possibly) dies! */
1452                                 sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
1453                                                         found_ip);
1454                         }
1455                 }
1456                 else
1457                 {
1458                         /* update our netbios name list (re-register it if necessary) */
1459                         add_netbios_entry(d, ans_name->name, ans_name->name_type,
1460                                                                 nb_flags,GET_TTL(0),REGISTER,
1461                                                                 found_ip,False,!bcast);
1462                 }
1463         }
1464         else
1465         {
1466                 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
1467
1468                 if (n->cmd_type == NAME_QUERY_CONFIRM)
1469                 {
1470                         /* XXXX remove_netbios_entry()? */
1471                         /* lots of things we ought to do, here. if we get here,
1472                            then we're in a mess: our name database doesn't match
1473                            reality. sort it out
1474              */
1475                 remove_netbios_name(d,n->name.name, n->name.name_type,
1476                                                                 REGISTER,n->ip);
1477                 }
1478         }
1479 }
1480
1481 /****************************************************************************
1482   report the response record type
1483   ****************************************************************************/
1484 static void debug_rr_type(int rr_type)
1485 {
1486   switch (rr_type)
1487   {
1488       case NMB_STATUS: DEBUG(3,("Name status ")); break;
1489           case NMB_QUERY : DEBUG(3,("Name query ")); break;
1490           case NMB_REG   : DEBUG(3,("Name registration ")); break;
1491           case NMB_REL   : DEBUG(3,("Name release ")); break;
1492       default        : DEBUG(1,("wrong response packet type received")); break;
1493   }
1494 }
1495
1496 /****************************************************************************
1497   report the response record nmbd command type
1498   ****************************************************************************/
1499 static void debug_cmd_type(int cmd_type)
1500 {
1501   /* report the command type to help debugging */
1502   switch (cmd_type)
1503   {
1504     case NAME_QUERY_MST_SRV_CHK  : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
1505     case NAME_QUERY_SRV_CHK      : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
1506     case NAME_QUERY_FIND_MST     : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
1507     case NAME_STATUS_MASTER_CHECK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
1508     case NAME_STATUS_CHECK       : DEBUG(4,("NAME_STATUS_CHECK\n")); break;
1509     case NAME_QUERY_MST_CHK      : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
1510     case NAME_REGISTER           : DEBUG(4,("NAME_REGISTER\n")); break;
1511     case NAME_RELEASE            : DEBUG(4,("NAME_RELEASE\n")); break;
1512     case NAME_QUERY_CONFIRM      : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
1513     case NAME_QUERY_SYNC         : DEBUG(4,("NAME_QUERY_SYNC\n")); break;
1514     default: break;
1515   }
1516 }
1517
1518 /****************************************************************************
1519   report any problems with the fact that a response has been received.
1520
1521   (responses for certain types of operations are only expected from one host)
1522   ****************************************************************************/
1523 static BOOL response_problem_check(struct response_record *n,
1524                         struct nmb_packet *nmb, char *qname)
1525 {
1526   switch (nmb->answers->rr_type)
1527   {
1528     case NMB_REL:
1529     {
1530         if (n->num_msgs > 1)
1531         {
1532             DEBUG(1,("more than one release name response received!\n"));
1533             return True;
1534         }
1535         break;
1536     }
1537
1538     case NMB_REG:
1539     {
1540         if (n->num_msgs > 1)
1541         {
1542             DEBUG(1,("more than one register name response received!\n"));
1543             return True;
1544         }
1545         break;
1546     }
1547
1548     case NMB_QUERY:
1549     { 
1550       if (n->num_msgs > 1)
1551       {
1552                   if (nmb->header.rcode == 0 && nmb->answers->rdata)
1553                   {
1554                         int nb_flags = nmb->answers->rdata[0];
1555
1556                         if ((!NAME_GROUP(nb_flags)))
1557                         {
1558                            /* oh dear. more than one person responded to a unique name.
1559                                   there is either a network problem, a configuration problem
1560                                   or a server is mis-behaving */
1561
1562                            /* XXXX mark the name as in conflict, and then let the
1563                                   person who just responded know that they must also mark it
1564                                   as in conflict, and therefore must NOT use it.
1565                   see rfc1001.txt 15.1.3.5 */
1566                                         
1567                /* this may cause problems for some early versions of nmbd */
1568
1569                switch (n->cmd_type)
1570                {
1571                         case NAME_QUERY_MST_SRV_CHK:
1572                 case NAME_QUERY_SRV_CHK:
1573                 case NAME_QUERY_MST_CHK:
1574                 /* don't do case NAME_QUERY_FIND_MST: MSBROWSE isn't a unique name. */
1575                 {
1576                       if (!strequal(qname,n->name.name))
1577                       {
1578                              /* one subnet, one master browser per workgroup */
1579                              /* XXXX force an election? */
1580
1581                              DEBUG(3,("more than one master browser replied!\n"));
1582                                  return True;
1583                           }
1584                    break;
1585                 }
1586                 default: break;
1587                }
1588                DEBUG(3,("Unique Name conflict detected!\n"));
1589                            return True;
1590                         }
1591                   }
1592                   else
1593                   {
1594              /* we have received a negative reply, having already received
1595                 at least one response (pos/neg). something's really wrong! */
1596
1597                  DEBUG(3,("wierd name query problem detected!\n"));
1598                      return True;
1599                   }
1600        }
1601     }
1602   }
1603   return False;
1604 }
1605
1606 /****************************************************************************
1607   check that the response received is compatible with the response record
1608   ****************************************************************************/
1609 static BOOL response_compatible(struct response_record *n,
1610                         struct nmb_packet *nmb)
1611 {
1612   switch (n->cmd_type)
1613   {
1614     case NAME_RELEASE:
1615     {
1616                 if (nmb->answers->rr_type != NMB_REL)
1617                 {
1618                         DEBUG(1,("Name release reply has wrong answer rr_type\n"));
1619                         return False;
1620                 }
1621         break;
1622     }
1623
1624     case NAME_REGISTER:
1625     {
1626                 if (nmb->answers->rr_type != NMB_REG)
1627                 {
1628                         DEBUG(1,("Name register reply has wrong answer rr_type\n"));
1629                         return False;
1630                 }
1631         break;
1632     }
1633
1634     case NAME_QUERY_CONFIRM:
1635     case NAME_QUERY_SYNC:
1636     case NAME_QUERY_MST_SRV_CHK:
1637     case NAME_QUERY_SRV_CHK:
1638     case NAME_QUERY_FIND_MST:
1639     case NAME_QUERY_MST_CHK:
1640     {
1641                 if (nmb->answers->rr_type != NMB_QUERY)
1642                 {
1643                         DEBUG(1,("Name query reply has wrong answer rr_type\n"));
1644                         return False;
1645                 }
1646                 break;
1647     }
1648       
1649     case NAME_STATUS_MASTER_CHECK:
1650     case NAME_STATUS_CHECK:
1651     {
1652                 if (nmb->answers->rr_type != NMB_STATUS)
1653                 {
1654                         DEBUG(1,("Name status reply has wrong answer rr_type\n"));
1655                         return False;
1656                 }
1657                 break;
1658     }
1659       
1660     default:
1661     {
1662                 DEBUG(0,("unknown command received in response_netbios_packet\n"));
1663                 break;
1664     }
1665   }
1666   return True;
1667 }
1668
1669
1670 /****************************************************************************
1671   process the response packet received
1672   ****************************************************************************/
1673 static void response_process(struct subnet_record *d, struct packet_struct *p,
1674                                 struct response_record *n, struct nmb_packet *nmb,
1675                                 BOOL bcast, struct nmb_name *ans_name)
1676 {
1677   switch (n->cmd_type)
1678   {
1679     case NAME_RELEASE:
1680     {
1681         response_name_release(d, p);
1682         break;
1683     }
1684
1685     case NAME_REGISTER:
1686     {
1687         response_name_reg(d, p);
1688         break;
1689     }
1690
1691     case NAME_QUERY_MST_SRV_CHK:
1692     case NAME_QUERY_SRV_CHK:
1693     case NAME_QUERY_FIND_MST:
1694     {
1695                 response_server_check(ans_name, n, d);
1696                 break;
1697     }
1698       
1699     case NAME_STATUS_MASTER_CHECK:
1700     case NAME_STATUS_CHECK:
1701     {
1702                 response_name_status_check(p->ip, nmb, bcast, n, d);
1703                 break;
1704     }
1705       
1706     case NAME_QUERY_CONFIRM:
1707     case NAME_QUERY_SYNC:
1708     {
1709                 response_name_query_sync(nmb, ans_name, bcast, n, d);
1710                 break;
1711     }
1712     case NAME_QUERY_MST_CHK:
1713     {
1714                 /* no action required here. it's when NO responses are received
1715                    that we need to do something. see expire_name_query_entries() */
1716         
1717                 DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
1718                                         namestr(&n->name), inet_ntoa(n->to_ip)));
1719                 break;
1720     }
1721
1722     default:
1723     {
1724                 DEBUG(0,("unknown command received in response_netbios_packet\n"));
1725                 break;
1726     }
1727   }
1728 }
1729
1730
1731 /****************************************************************************
1732   response from a netbios packet.
1733   ****************************************************************************/
1734 static void response_netbios_packet(struct packet_struct *p)
1735 {
1736   struct nmb_packet *nmb = &p->packet.nmb;
1737   struct nmb_name *question = &nmb->question.question_name;
1738   struct nmb_name *ans_name = NULL;
1739   char *qname = question->name;
1740   BOOL bcast = nmb->header.nm_flags.bcast;
1741   struct response_record *n;
1742   struct subnet_record *d = NULL;
1743
1744   if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
1745     DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
1746     return;
1747   }
1748
1749   if (!d)
1750   {
1751     DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
1752     return;
1753   }
1754
1755   if (!same_net(d->bcast_ip, d->mask_ip, p->ip)) /* copes with WINS 'subnet' */
1756   {
1757     DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
1758     DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
1759     return;
1760   }
1761
1762   if (nmb->answers == NULL)
1763   {
1764       /* hm. the packet received was a response, but with no answer. wierd! */
1765       DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
1766                inet_ntoa(p->ip), BOOLSTR(bcast)));
1767       return;
1768   }
1769
1770   ans_name = &nmb->answers->rr_name;
1771   DEBUG(3,("response for %s from %s (bcast=%s)\n",
1772            namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
1773   
1774   debug_rr_type(nmb->answers->rr_type);
1775
1776   n->num_msgs++; /* count number of responses received */
1777   n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
1778
1779   debug_cmd_type(n->cmd_type);
1780
1781   /* problem checking: multiple responses etc */
1782   if (response_problem_check(n, nmb, qname))
1783     return;
1784
1785   /* now check whether the command has received the correct type of response*/
1786   if (!response_compatible(n, nmb))
1787     return;
1788
1789   /* now deal with the command */
1790   response_process(d, p, n, nmb, bcast, ans_name);
1791 }
1792
1793
1794 /****************************************************************************
1795   process a nmb packet
1796   ****************************************************************************/
1797 void process_nmb(struct packet_struct *p)
1798 {
1799   struct nmb_packet *nmb = &p->packet.nmb;
1800
1801   debug_nmb_packet(p);
1802
1803   switch (nmb->header.opcode) 
1804   {
1805     case 8: /* what is this?? */
1806     case NMB_REG:
1807     case NMB_REG_REFRESH:
1808     {
1809         if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
1810         if (nmb->header.response)
1811           response_netbios_packet(p); /* response to registration dealt with here */
1812         else
1813           reply_name_reg(p);
1814         break;
1815     }
1816       
1817     case 0:
1818     {
1819           if (nmb->header.response)
1820           {
1821             switch (nmb->question.question_type)
1822               {
1823               case 0x0:
1824                 {
1825                   response_netbios_packet(p);
1826                   break;
1827                 }
1828               }
1829             return;
1830           }
1831       else if (nmb->header.qdcount>0) 
1832           {
1833             switch (nmb->question.question_type)
1834               {
1835               case NMB_QUERY:
1836                 {
1837                   reply_name_query(p);
1838                   break;
1839                 }
1840               case NMB_STATUS:
1841                 {
1842                   reply_name_status(p);
1843                   break;
1844                 }
1845               }
1846             return;
1847           }
1848         break;
1849       }
1850       
1851     case NMB_REL:
1852     {
1853       if (nmb->header.qdcount==0 || nmb->header.arcount==0)
1854           {
1855             DEBUG(2,("netbios release packet rejected\n"));
1856             break;
1857           }
1858         
1859         if (nmb->header.response)
1860           response_netbios_packet(p); /* response to reply dealt with in here */
1861         else
1862           reply_name_release(p);
1863       break;
1864     }
1865   }
1866 }
1867