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