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