JHT ===> Getting ready for release of 1.9.17alpha5
[samba.git] / source3 / nameservresp.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-1997
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    Module name: nameservresp.c
24
25    14 jan 96: lkcl@pires.co.uk
26    added multiple workgroup domain master support
27
28    05 jul 96: lkcl@pires.co.uk
29    created module nameservresp containing NetBIOS response functions
30
31 */
32
33 #include "includes.h"
34
35 extern int ClientNMB;
36
37 extern int DEBUGLEVEL;
38
39 extern pstring scope;
40 extern fstring myworkgroup;
41 extern struct in_addr ipzero;
42 extern struct in_addr wins_ip;
43 extern struct in_addr ipzero;
44
45
46 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
47
48
49 /****************************************************************************
50   response for a reg release received. samba has asked a WINS server if it
51   could release a name.
52   **************************************************************************/
53 static void response_name_release(struct nmb_name *ans_name,
54                         struct subnet_record *d, struct packet_struct *p)
55 {
56   struct nmb_packet *nmb = &p->packet.nmb;
57   char *name = ans_name->name;
58   int   type = ans_name->name_type;
59   
60   DEBUG(4,("response name release received\n"));
61   
62   if (nmb->header.rcode == 0 && nmb->answers->rdata)
63   {
64     /* IMPORTANT: see expire_netbios_response_entries() */
65
66     struct in_addr found_ip;
67     putip((char*)&found_ip,&nmb->answers->rdata[2]);
68       
69     /* NOTE: we only release our own names at present */
70     if (ismyip(found_ip))
71     {
72       name_unregister_work(d,name,type);
73     }
74     else
75     {
76       DEBUG(2,("name release for different ip! %s %s\n",
77                   inet_ntoa(found_ip), namestr(ans_name)));
78     }
79   }
80   else
81   {
82     DEBUG(2,("name release for %s rejected!\n", namestr(ans_name)));
83
84     /* XXXX PANIC! what to do if it's one of samba's own names? */
85
86     /* XXXX do we honestly care if our name release was rejected? 
87        only if samba is issuing the release on behalf of some out-of-sync
88        server. if it's one of samba's SELF names, we don't care. */
89   }
90 }
91
92
93 /****************************************************************************
94 response for a reg request received
95 **************************************************************************/
96 static void response_name_reg(struct nmb_name *ans_name,
97                         struct subnet_record *d, struct packet_struct *p)
98 {
99   struct nmb_packet *nmb = &p->packet.nmb;
100   BOOL bcast = nmb->header.nm_flags.bcast;
101   char *name = ans_name->name;
102   int   type = ans_name->name_type;
103   
104   DEBUG(4,("response name registration received!\n"));
105   
106 #if 1
107   /* This code is neccesitated due to bugs in earlier versions of
108      Samba (up to 1.9.16p11). They respond to a broadcast
109      name registration of WORKGROUP<1b> when they should
110      not. Hence, until these versions are gone, we should
111      treat such errors as success for this particular
112      case only. jallison@whistle.com.
113    */
114   if ( ((d != wins_subnet) && (nmb->header.rcode == 6) && strequal(myworkgroup, name) &&
115          (type == 0x1b)) ||
116        (nmb->header.rcode == 0 && nmb->answers->rdata))
117 #else
118   if (nmb->header.rcode == 0 && nmb->answers->rdata)
119 #endif
120   {
121     /* IMPORTANT: see expire_netbios_response_entries() */
122
123     int nb_flags = nmb->answers->rdata[0];
124     int ttl = nmb->answers->ttl;
125     struct in_addr found_ip;
126
127     putip((char*)&found_ip,&nmb->answers->rdata[2]);
128       
129     name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
130   }
131   else
132   {
133     DEBUG(2,("name registration for %s rejected by ip %s!\n", 
134               namestr(ans_name), inet_ntoa(p->ip)));
135
136         /* oh dear. we have problems. possibly unbecome a master browser. */
137     name_unregister_work(d,name,type);
138   }
139 }
140
141
142 /****************************************************************************
143   response from a name query announce host
144   NAME_QUERY_ANNOUNCE_HOST is dealt with here
145   ****************************************************************************/
146 static void response_announce_host(struct nmb_name *ans_name, 
147                 struct nmb_packet *nmb, 
148                 struct response_record *n, struct subnet_record *d)
149 {
150         DEBUG(4, ("Name query at %s ip %s - ",
151                   namestr(&n->name), inet_ntoa(n->send_ip)));
152
153         if (!name_equal(&n->name, ans_name))
154         {
155                 /* someone gave us the wrong name as a reply. oops. */
156                 /* XXXX should say to them 'oi! release that name!' */
157
158                 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
159                 return;
160         }
161
162         if (nmb->header.rcode == 0 && nmb->answers->rdata)
163     {
164                 /* we had sent out a name query to the current owner
165                    of a name because someone else wanted it. now they
166                    have responded saying that they still want the name,
167                    so the other host can't have it.
168                  */
169
170                 /* first check all the details are correct */
171
172                 int nb_flags = nmb->answers->rdata[0];
173                 struct in_addr found_ip;
174
175                 putip((char*)&found_ip,&nmb->answers->rdata[2]);
176
177                 if (nb_flags != n->nb_flags)
178                 {
179                         /* someone gave us the wrong nb_flags as a reply. oops. */
180                         /* XXXX should say to them 'oi! release that name!' */
181
182                         DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
183                         DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
184                         return;
185                 }
186
187         /* do an announce host */
188         do_announce_host(ANN_HostAnnouncement,
189                                 n->my_name  , 0x00, d->myip,
190                                 n->name.name, 0x1d, found_ip,
191                                 n->ttl,
192                                 n->my_name, n->server_type, n->my_comment);
193         }
194         else
195         {
196                 /* XXXX negative name query response. no master exists. oops */
197         }
198 }
199
200
201 /****************************************************************************
202   response from a name query server check. states of type NAME_QUERY_DOM_SRV_CHK,
203   NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
204   ****************************************************************************/
205 static void response_server_check(struct nmb_name *ans_name, 
206                 struct response_record *n, struct subnet_record *d)
207 {
208     /* issue another state: this time to do a name status check */
209
210     enum state_type cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
211               NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
212
213     /* initiate a name status check on the server that replied 
214        in addition, the workgroup being checked has been stored
215        in the response_record->my_name (see announce_master) we
216        also propagate this into the same field. */
217     queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
218                                 ans_name->name, ans_name->name_type,
219                                 0,0,0,n->my_name,NULL,
220                                 False,False,n->send_ip,n->reply_to_ip);
221 }
222
223
224 /****************************************************************************
225   interpret a node status response. this is pretty hacked: we need two bits of
226   info. a) the name of the workgroup b) the name of the server. it will also
227   add all the names it finds into the namelist.
228 ****************************************************************************/
229 static BOOL interpret_node_status(struct subnet_record *d,
230                                 char *p, struct nmb_name *name,int t,
231                            char *serv_name, struct in_addr ip, BOOL bcast)
232 {
233   int numnames = CVAL(p,0);
234   BOOL found = False;
235
236   DEBUG(4,("received %d names\n",numnames));
237
238   p += 1;
239
240   if (serv_name) *serv_name = 0;
241
242   while (numnames--)
243     {
244       char qname[17];
245       int type;
246       fstring flags;
247       int nb_flags;
248       
249       BOOL group = False;
250       BOOL add   = False;
251       
252       *flags = 0;
253       
254       StrnCpy(qname,p,15);
255       type = CVAL(p,15);
256       nb_flags = p[16];
257       trim_string(qname,NULL," ");
258       
259       p += 18;
260       
261       if (NAME_GROUP    (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
262       if (NAME_BFLAG    (nb_flags)) { strcat(flags,"B "); }
263       if (NAME_PFLAG    (nb_flags)) { strcat(flags,"P "); }
264       if (NAME_MFLAG    (nb_flags)) { strcat(flags,"M "); }
265       if (NAME_HFLAG    (nb_flags)) { strcat(flags,"H "); }
266       if (NAME_DEREG    (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
267       if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); }
268       if (NAME_ACTIVE   (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
269       if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
270
271 /* I don't think we should be messing with our namelist here... JRA */      
272 #if 0
273       /* might as well update our namelist while we're at it */
274       if (add)
275         {
276           struct in_addr nameip;
277           enum name_source src;
278           
279           if (ismyip(ip)) {
280             nameip = ipzero;
281             src = SELF;
282           } else {
283             nameip = ip;
284             src = STATUS_QUERY;
285           }
286           add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
287         } 
288 #endif /* JRA */
289
290       /* we want the server name */
291       if (serv_name && !*serv_name && !group && type == 0x20)
292         {
293           StrnCpy(serv_name,qname,15);
294           serv_name[15] = 0;
295         }
296       
297       /* looking for a name and type? */
298       if (name && !found && (t == type))
299         {
300           /* take a guess at some of the name types we're going to ask for.
301              evaluate whether they are group names or no... */
302           if (((t == 0x1b || t == 0x1d || t == 0x20 ) && !group) ||
303               ((t == 0x1c || t == 0x1e              ) &&  group))
304             {
305               found = True;
306               make_nmb_name(name,qname,type,scope);
307             }
308         }
309       
310       DEBUG(4,("\t%s(0x%x)\t%s\n",qname,type,flags));
311     }
312   DEBUG(4,("num_good_sends=%d num_good_receives=%d\n",
313                IVAL(p,20),IVAL(p,24)));
314   return found;
315 }
316
317
318 /****************************************************************************
319   response from a name status check. states of type NAME_STATUS_DOM_SRV_CHK
320   and NAME_STATUS_SRV_CHK dealt with here.
321   ****************************************************************************/
322 static void response_name_status_check(struct in_addr ip,
323                 struct nmb_packet *nmb, BOOL bcast,
324                 struct response_record *n, struct subnet_record *d)
325 {
326         /* NMB_STATUS arrives: contains workgroup name and server name required.
327        amongst other things. */
328
329         struct nmb_name name;
330         fstring serv_name;
331
332         if (interpret_node_status(d,nmb->answers->rdata,
333                                   &name,0x20,serv_name,ip,bcast))
334         {
335                 if (*serv_name)
336                 {
337                         /* response_record->my_name contains the
338                            workgroup name to sync with. See 
339                            response_server_check() */
340                         sync_server(n->state,serv_name,
341                                     n->my_name,name.name_type, d, n->send_ip);
342                 }
343         }
344         else
345         {
346                 DEBUG(1,("No 0x20 name type in interpret_node_status()\n"));
347         }
348 }
349
350
351 /****************************************************************************
352   response from a name query for secured WINS registration. a state of
353   NAME_REGISTER_CHALLENGE is dealt with here.
354   ****************************************************************************/
355 static void response_name_query_register(struct nmb_packet *nmb, 
356                 struct nmb_name *ans_name, 
357                 struct response_record *n, struct subnet_record *d)
358 {
359         struct in_addr register_ip;
360         BOOL new_owner;
361
362         DEBUG(4, ("Name query at %s ip %s - ",
363                   namestr(&n->name), inet_ntoa(n->send_ip)));
364
365         if (!name_equal(&n->name, ans_name))
366         {
367                 /* someone gave us the wrong name as a reply. oops. */
368                 /* XXXX should say to them 'oi! release that name!' */
369
370                 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
371                 return;
372         }
373
374         if (nmb->header.rcode == 0 && nmb->answers->rdata)
375     {
376                 /* we had sent out a name query to the current owner
377                    of a name because someone else wanted it. now they
378                    have responded saying that they still want the name,
379                    so the other host can't have it.
380                  */
381
382                 /* first check all the details are correct */
383
384                 int nb_flags = nmb->answers->rdata[0];
385                 struct in_addr found_ip;
386
387                 putip((char*)&found_ip,&nmb->answers->rdata[2]);
388
389                 if (nb_flags != n->nb_flags)
390                 {
391                         /* someone gave us the wrong nb_flags as a reply. oops. */
392                         /* XXXX should say to them 'oi! release that name!' */
393
394                         DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
395                         DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
396                         return;
397                 }
398
399                 if (!ip_equal(n->send_ip, found_ip))
400                 {
401                         /* someone gave us the wrong ip as a reply. oops. */
402                         /* XXXX should say to them 'oi! release that name!' */
403
404                         DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
405                         DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
406                         return;
407                 }
408
409                 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
410
411                 /* fine: now tell the other host they can't have the name */
412                 register_ip = n->send_ip;
413                 new_owner = False;
414         }
415         else
416         {
417                 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
418
419                 /* the owner didn't want the name: the other host can have it */
420                 register_ip = n->reply_to_ip;
421                 new_owner = True;
422         }
423
424         /* register the old or the new owners' ip */
425         add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
426                                         GET_TTL(0), register_ip,
427                                         new_owner, n->reply_to_ip);
428 }
429
430
431 /****************************************************************************
432   response from a name query to sync browse lists or to update our netbios
433   entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM 
434   ****************************************************************************/
435 static void response_name_query_sync(struct nmb_packet *nmb, 
436                 struct nmb_name *ans_name, BOOL bcast,
437                 struct response_record *n, struct subnet_record *d)
438 {
439   DEBUG(4, ("Name query at %s ip %s - ",
440             namestr(&n->name), inet_ntoa(n->send_ip)));
441
442   if (!name_equal(&n->name, ans_name))
443     {
444       /* someone gave us the wrong name as a reply. oops. */
445       DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
446       return;
447     }
448
449   if (nmb->header.rcode == 0 && nmb->answers->rdata)
450     {
451       int nb_flags = nmb->answers->rdata[0];
452       struct in_addr found_ip;
453       
454       putip((char*)&found_ip,&nmb->answers->rdata[2]);
455       
456       if (!ip_equal(n->send_ip, found_ip))
457         {
458           /* someone gave us the wrong ip as a reply. oops. */
459           DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
460           DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
461           return;
462         }
463
464       DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
465       
466       if (n->state == NAME_QUERY_SYNC_LOCAL ||
467           n->state == NAME_QUERY_SYNC_REMOTE)
468         {
469           struct work_record *work = NULL;
470           /* We cheat here as we know that the workgroup name has
471              been placed in the my_comment field of the 
472              response_record struct by the code in 
473              start_sync_browse_entry().
474           */
475           if ((work = find_workgroupstruct(d, n->my_comment, False)))
476             {
477               BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
478               
479               /* the server is there: sync quick before it (possibly) dies! */
480               sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
481                                 found_ip, local_list_only);
482             }
483         }
484       else
485         {
486           /* update our netbios name list (re-register it if necessary) */
487           add_netbios_entry(d, ans_name->name, ans_name->name_type,
488                             nb_flags,GET_TTL(0),REGISTER,
489                             found_ip,False,!bcast);
490         }
491     }
492   else
493     {
494       DEBUG(4, (" NEGATIVE RESPONSE!\n"));
495       
496       if (n->state == NAME_QUERY_CONFIRM)
497         {
498           /* XXXX remove_netbios_entry()? */
499           /* lots of things we ought to do, here. if we get here,
500              then we're in a mess: our name database doesn't match
501              reality. sort it out
502              */
503           remove_netbios_name(d,n->name.name, n->name.name_type,
504                               REGISTER,n->send_ip);
505         }
506     }
507 }
508
509 /****************************************************************************
510   response from a name query for DOMAIN<1b>
511   NAME_QUERY_DOMAIN is dealt with here - we are trying to become a domain
512   master browser and WINS replied - check it's our address.
513   ****************************************************************************/
514 static void response_name_query_domain(struct nmb_name *ans_name,
515                 struct nmb_packet *nmb,
516                 struct response_record *n, struct subnet_record *d)
517 {
518   DEBUG(4, ("response_name_query_domain: Got %s response from %s for query \
519 for %s\n", nmb->header.rcode == 0 ? "success" : "failure",
520            inet_ntoa(n->send_ip), namestr(ans_name)));
521
522   /* Check the name is correct and ip address returned is our own. If it is then we
523      just remove the response record.
524    */
525   if (name_equal(&n->name, ans_name) && (nmb->header.rcode == 0) && (nmb->answers->rdata))
526   {
527     struct in_addr found_ip;
528
529     putip((char*)&found_ip,&nmb->answers->rdata[2]);
530     /* Samba 1.9.16p11 servers seem to return the broadcast address for this
531        query. */
532     if (ismyip(found_ip) || ip_equal(wins_ip, found_ip) || ip_equal(ipzero, found_ip))
533     {
534       DEBUG(4, ("response_name_query_domain: WINS server returned our ip \
535 address. Pretending we never received response.\n"));
536       n->num_msgs = 0;
537       n->repeat_count = 0;
538       n->repeat_time = 0;
539     }
540     else
541     {
542       DEBUG(0,("response_name_query_domain: WINS server already has a \
543 domain master browser registered %s at address %s\n", 
544            namestr(ans_name), inet_ntoa(found_ip)));
545     }
546   }
547   else
548   {
549     /* Negative/incorrect response. No domain master
550        browser was registered - pretend we didn't get this response.
551      */
552     n->num_msgs = 0;
553     n->repeat_count = 0;
554     n->repeat_time = 0;
555   }
556
557 }
558
559 /****************************************************************************
560   report the response record type
561   ****************************************************************************/
562 static void debug_rr_type(int rr_type)
563 {
564   switch (rr_type)
565     {
566     case NMB_STATUS: DEBUG(3,("Name status ")); break;
567     case NMB_QUERY : DEBUG(3,("Name query ")); break;
568     case NMB_REG   : DEBUG(3,("Name registration ")); break;
569     case NMB_REL   : DEBUG(3,("Name release ")); break;
570     default        : DEBUG(1,("wrong response packet type received")); break;
571     }
572 }
573
574 /****************************************************************************
575   report the response record nmbd state
576   ****************************************************************************/
577 void debug_state_type(int state)
578 {
579   /* report the state type to help debugging */
580   switch (state)
581     {
582     case NAME_QUERY_DOM_SRV_CHK  : DEBUG(4,("NAME_QUERY_DOM_SRV_CHK\n")); break;
583     case NAME_QUERY_SRV_CHK      : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
584     case NAME_QUERY_FIND_MST     : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
585     case NAME_QUERY_MST_CHK      : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
586     case NAME_QUERY_CONFIRM      : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
587     case NAME_QUERY_SYNC_LOCAL   : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
588     case NAME_QUERY_SYNC_REMOTE  : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
589     case NAME_QUERY_ANNOUNCE_HOST: DEBUG(4,("NAME_QUERY_ANNCE_HOST\n"));break;
590     case NAME_QUERY_DOMAIN       : DEBUG(4,("NAME_QUERY_DOMAIN\n")); break;
591       
592     case NAME_REGISTER           : DEBUG(4,("NAME_REGISTER\n")); break;
593     case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
594       
595     case NAME_RELEASE            : DEBUG(4,("NAME_RELEASE\n")); break;
596       
597     case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STATUS_DOM_SRV_CHK\n")); break;
598     case NAME_STATUS_SRV_CHK     : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
599       
600     default: break;
601     }
602 }
603
604 /****************************************************************************
605   report any problems with the fact that a response has been received.
606
607   (responses for certain types of operations are only expected from one host)
608   ****************************************************************************/
609 static BOOL response_problem_check(struct response_record *n,
610                         struct nmb_packet *nmb, char *ans_name)
611 {
612   switch (nmb->answers->rr_type)
613     {
614     case NMB_REL:
615       {
616         if (n->num_msgs > 1)
617           {
618             DEBUG(1,("more than one release name response received!\n"));
619             return True;
620           }
621         break;
622       }
623
624     case NMB_REG:
625       {
626         if (n->num_msgs > 1)
627           {
628             DEBUG(1,("more than one register name response received!\n"));
629             return True;
630           }
631         break;
632       }
633     
634     case NMB_QUERY:
635       { 
636         if (n->num_msgs > 1)
637           {
638             if (nmb->header.rcode == 0 && nmb->answers->rdata)
639               {
640                 int nb_flags = nmb->answers->rdata[0];
641                 
642                 if ((!NAME_GROUP(nb_flags)))
643                   {
644                     /* oh dear. more than one person responded to a 
645                        unique name.
646                        there is either a network problem, a 
647                        configuration problem
648                        or a server is mis-behaving */
649                     
650                     /* XXXX mark the name as in conflict, and then let the
651                        person who just responded know that they 
652                        must also mark it
653                        as in conflict, and therefore must NOT use it.
654                        see rfc1001.txt 15.1.3.5 */
655                     
656                     /* this may cause problems for some 
657                        early versions of nmbd */
658                     
659                     switch (n->state)
660                       {
661                       case NAME_QUERY_FIND_MST:
662                         {
663                           /* query for ^1^2__MSBROWSE__^2^1 expect
664                              lots of responses */
665                           return False;
666                         }
667                       case NAME_QUERY_ANNOUNCE_HOST:
668                       case NAME_QUERY_DOM_SRV_CHK:
669                       case NAME_QUERY_SRV_CHK:
670                       case NAME_QUERY_MST_CHK:
671                         {
672                           if (!strequal(ans_name,n->name.name))
673                             {
674                               /* one subnet, one master browser 
675                                  per workgroup */
676                               /* XXXX force an election? */
677                               
678                               DEBUG(3,("more than one master browser replied!\n"));
679                               return True;
680                             }
681                           break;
682                         }
683                       default: break;
684                       }
685                     DEBUG(3,("Unique Name conflict detected!\n"));
686                     return True;
687                   }
688               }
689             else
690               {
691                 /* we have received a negative reply, 
692                    having already received
693                    at least one response (pos/neg). 
694                    something's really wrong! */
695                 
696                 DEBUG(3,("wierd name query problem detected!\n"));
697                 return True;
698               }
699           }
700       }
701     }
702   return False;
703 }
704
705 #if 0
706 /****************************************************************************
707   check that the response received is compatible with the response record
708   ****************************************************************************/
709 static BOOL response_compatible(struct response_record *n,
710                         struct nmb_packet *nmb)
711 {
712   switch (n->state)
713   {
714     case NAME_RELEASE:
715     {
716                 if (nmb->answers->rr_type != 0x20)
717                 {
718                         DEBUG(1,("Name release reply has wrong answer rr_type\n"));
719                         return False;
720                 }
721         break;
722     }
723
724     case NAME_REGISTER:
725     {
726                 if (nmb->answers->rr_type != 0x20)
727                 {
728                         DEBUG(1,("Name register reply has wrong answer rr_type\n"));
729                         return False;
730                 }
731         break;
732     }
733
734     case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
735     case NAME_QUERY_CONFIRM:
736     case NAME_QUERY_ANNOUNCE_HOST:
737     case NAME_QUERY_SYNC_LOCAL:
738     case NAME_QUERY_SYNC_REMOTE:
739     case NAME_QUERY_DOM_SRV_CHK:
740     case NAME_QUERY_SRV_CHK:
741     case NAME_QUERY_FIND_MST:
742     case NAME_QUERY_MST_CHK:
743     {
744                 if (nmb->answers->rr_type != 0x20)
745                 {
746                         DEBUG(1,("Name query reply has wrong answer rr_type\n"));
747                         return False;
748                 }
749                 break;
750     }
751       
752     case NAME_STATUS_DOM_SRV_CHK:
753     case NAME_STATUS_SRV_CHK:
754     {
755                 if (nmb->answers->rr_type != 0x21)
756                 {
757                         DEBUG(1,("Name status reply has wrong answer rr_type\n"));
758                         return False;
759                 }
760                 break;
761     }
762       
763     default:
764     {
765                 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
766                 return False;
767     }
768   }
769   return True;
770 }
771 #endif
772
773
774 /****************************************************************************
775   process the response packet received
776   ****************************************************************************/
777 static void response_process(struct subnet_record *d, struct packet_struct *p,
778                              struct response_record *n, struct nmb_packet *nmb,
779                              BOOL bcast, struct nmb_name *ans_name)
780 {
781   switch (n->state)
782     {
783     case NAME_RELEASE:
784       {
785         response_name_release(ans_name, d, p);
786         break;
787       }
788
789     case NAME_REGISTER:
790       {
791         response_name_reg(ans_name, d, p);
792         break;
793       }
794
795     case NAME_REGISTER_CHALLENGE:
796       {
797         response_name_query_register(nmb, ans_name, n, d);
798         break;
799       }
800
801     case NAME_QUERY_DOM_SRV_CHK:
802     case NAME_QUERY_SRV_CHK:
803     case NAME_QUERY_FIND_MST:
804       {
805         response_server_check(ans_name, n, d);
806         break;
807       }
808     
809     case NAME_STATUS_DOM_SRV_CHK:
810     case NAME_STATUS_SRV_CHK:
811       {
812         response_name_status_check(p->ip, nmb, bcast, n, d);
813         break;
814       }
815     
816     case NAME_QUERY_ANNOUNCE_HOST:
817       {
818         response_announce_host(ans_name, nmb, n, d);
819         break;
820       }
821       
822     case NAME_QUERY_CONFIRM:
823     case NAME_QUERY_SYNC_LOCAL:
824     case NAME_QUERY_SYNC_REMOTE:
825       {
826         response_name_query_sync(nmb, ans_name, bcast, n, d);
827         break;
828       }
829     case NAME_QUERY_MST_CHK:
830       {
831         /* no action required here. it's when NO responses are received
832            that we need to do something. see expire_name_query_entries() */
833         
834         DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
835                   namestr(&n->name), inet_ntoa(n->send_ip)));
836         break;
837       }
838    
839     case NAME_QUERY_DOMAIN:
840       {
841         /* We were asking to be a domain master browser, and someone
842            replied. If it was the WINS server and the IP it is
843            returning is our own - then remove the record and pretend
844            we didn't get a response. Else we do nothing and let 
845            dead_netbios_entry deal with it. 
846            We can only become domain master browser
847            when no broadcast responses are received and WINS
848            either contains no entry for the DOMAIN<1b> name or
849            contains our IP address.
850          */
851         response_name_query_domain(ans_name, nmb, n, d);
852         break;
853       }
854     default:
855       {
856         DEBUG(1,("unknown state type received in response_netbios_packet\n"));
857         break;
858       }
859     }
860 }
861
862
863 /****************************************************************************
864   response from a netbios packet.
865   ****************************************************************************/
866 void response_netbios_packet(struct packet_struct *p)
867 {
868   struct nmb_packet *nmb = &p->packet.nmb;
869   struct nmb_name *ans_name = NULL;
870   BOOL bcast = nmb->header.nm_flags.bcast;
871   struct response_record *n;
872   struct subnet_record *d = NULL;
873
874   if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
875     DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
876     return;
877   }
878
879   if (!d)
880     {
881       DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
882       return;
883     }
884
885   /* args wrong way round: spotted by ccm@shentel.net */
886   if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
887     {
888       DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
889       DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
890     }
891   
892   if (nmb->answers == NULL)
893     {
894       /* hm. the packet received was a response, but with no answer. wierd! */
895       DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
896                inet_ntoa(p->ip), BOOLSTR(bcast)));
897       return;
898     }
899
900   ans_name = &nmb->answers->rr_name;
901   DEBUG(3,("response for %s from %s (bcast=%s)\n",
902            namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
903   
904   debug_rr_type(nmb->answers->rr_type);
905   
906   n->num_msgs++; /* count number of responses received */
907   n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
908   
909   debug_state_type(n->state);
910   
911   /* problem checking: multiple responses etc */
912   if (response_problem_check(n, nmb, ans_name->name))
913     return;
914   
915   /* now deal with the current state */
916   response_process(d, p, n, nmb, bcast, ans_name);
917 }