damn. We need root privilages to do semaphore operations even if we
[kai/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 && 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_client_subnet) && (nmb->header.rcode == 6) && strequal(myworkgroup, name) &&
115          (type == 0x1b)) ||
116        (nmb->header.rcode == 0 && nmb->answers && nmb->answers->rdata))
117 #else
118   if (nmb->header.rcode == 0 && nmb->answers && 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   response from a name query server check. states of type NAME_QUERY_DOM_SRV_CHK,
143   NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
144   ****************************************************************************/
145 static void response_server_check(struct nmb_name *ans_name, 
146         struct response_record *n, struct subnet_record *d, struct packet_struct *p)
147 {
148     struct nmb_packet *nmb = &p->packet.nmb;
149     struct in_addr send_ip;
150     enum state_type cmd;
151
152     /* This next fix was from Bernhard Laeser <nlaesb@ascom.ch>
153        who noticed we were replying directly back to the server
154        we sent to - rather than reading the response.
155      */
156
157     if (nmb->header.rcode == 0 && nmb->answers && nmb->answers->rdata)
158       putip((char*)&send_ip,&nmb->answers->rdata[2]);
159     else
160       {
161       
162         DEBUG(2,("response_server_check: name query for %s failed\n", 
163               namestr(ans_name)));
164         return;
165       }
166
167     /* issue another state: this time to do a name status check */
168
169     cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
170               NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
171
172     /* initiate a name status check on address given in the reply
173        record. In addition, the workgroup being checked has been stored
174        in the response_record->my_name (see announce_master) we
175        also propagate this into the same field. */
176     queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
177                                 ans_name->name, ans_name->name_type,
178                                 0,0,0,n->my_name,NULL,
179                                 False,False,send_ip,n->reply_to_ip, 0);
180 }
181
182
183 /****************************************************************************
184   interpret a node status response. this is pretty hacked: we need two bits of
185   info. a) the name of the workgroup b) the name of the server. it will also
186   add all the names it finds into the namelist.
187 ****************************************************************************/
188 static BOOL interpret_node_status(struct subnet_record *d,
189                                 char *p, struct nmb_name *name,int t,
190                            char *serv_name, struct in_addr ip, BOOL bcast)
191 {
192   int numnames = CVAL(p,0);
193   BOOL found = False;
194
195   DEBUG(4,("received %d names\n",numnames));
196
197   p += 1;
198
199   if (serv_name) *serv_name = 0;
200
201   while (numnames--)
202     {
203       char qname[17];
204       int type;
205       fstring flags;
206       int nb_flags;
207       
208       BOOL group = False;
209       BOOL add   = False;
210       
211       *flags = 0;
212       
213       StrnCpy(qname,p,15);
214       type = CVAL(p,15);
215       nb_flags = p[16];
216       trim_string(qname,NULL," ");
217       
218       p += 18;
219       
220       if (NAME_GROUP    (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
221       if (NAME_BFLAG    (nb_flags)) { strcat(flags,"B "); }
222       if (NAME_PFLAG    (nb_flags)) { strcat(flags,"P "); }
223       if (NAME_MFLAG    (nb_flags)) { strcat(flags,"M "); }
224       if (NAME_HFLAG    (nb_flags)) { strcat(flags,"H "); }
225       if (NAME_DEREG    (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
226       if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); }
227       if (NAME_ACTIVE   (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
228       if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
229
230       /* we want the server name */
231       if (serv_name && !*serv_name && !group && type == 0x20)
232         {
233           StrnCpy(serv_name,qname,15);
234           serv_name[15] = 0;
235         }
236       
237       /* looking for a name and type? */
238       if (name && !found && (t == type))
239         {
240           /* take a guess at some of the name types we're going to ask for.
241              evaluate whether they are group names or no... */
242           if (((t == 0x1b || t == 0x1d || t == 0x20 ) && !group) ||
243               ((t == 0x1c || t == 0x1e              ) &&  group))
244             {
245               found = True;
246               make_nmb_name(name,qname,type,scope);
247             }
248         }
249       
250       DEBUG(4,("\t%s(0x%x)\t%s\n",qname,type,flags));
251     }
252   DEBUG(4,("num_good_sends=%d num_good_receives=%d\n",
253                IVAL(p,20),IVAL(p,24)));
254   return found;
255 }
256
257
258 /****************************************************************************
259   response from a name status check. states of type NAME_STATUS_DOM_SRV_CHK
260   and NAME_STATUS_SRV_CHK dealt with here.
261   ****************************************************************************/
262 static void response_name_status_check(struct in_addr ip,
263                 struct nmb_packet *nmb, BOOL bcast,
264                 struct response_record *n, struct subnet_record *d)
265 {
266         /* NMB_STATUS arrives: contains workgroup name and server name required.
267        amongst other things. */
268
269         struct nmb_name name;
270         fstring serv_name;
271
272         if (nmb->answers && 
273             interpret_node_status(d,nmb->answers->rdata,
274                                   &name,0x20,serv_name,ip,bcast))
275         {
276                 if (*serv_name)
277                 {
278                         /* response_record->my_name contains the
279                            workgroup name to sync with. See 
280                            response_server_check() */
281                         sync_server(n->state,serv_name,
282                                     n->my_name,name.name_type, d, n->send_ip);
283                 }
284         }
285         else
286         {
287                 DEBUG(1,("No 0x20 name type in interpret_node_status()\n"));
288         }
289 }
290
291
292 /****************************************************************************
293   response from a name query for secured WINS registration. a state of
294   NAME_REGISTER_CHALLENGE is dealt with here.
295   ****************************************************************************/
296 static void response_name_query_register(struct nmb_packet *nmb, 
297                 struct nmb_name *ans_name, 
298                 struct response_record *n, struct subnet_record *d)
299 {
300         struct in_addr register_ip;
301         BOOL new_owner;
302
303         DEBUG(4, ("Name query at %s ip %s - ",
304                   namestr(&n->name), inet_ntoa(n->send_ip)));
305
306         if (!name_equal(&n->name, ans_name))
307         {
308                 /* someone gave us the wrong name as a reply. oops. */
309                 /* XXXX should say to them 'oi! release that name!' */
310
311                 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
312                 return;
313         }
314
315         if (nmb->header.rcode == 0 && nmb->answers && nmb->answers->rdata)
316     {
317                 /* we had sent out a name query to the current owner
318                    of a name because someone else wanted it. now they
319                    have responded saying that they still want the name,
320                    so the other host can't have it.
321                  */
322
323                 /* first check all the details are correct */
324
325                 int nb_flags = nmb->answers->rdata[0];
326                 struct in_addr found_ip;
327
328                 putip((char*)&found_ip,&nmb->answers->rdata[2]);
329
330                 if (nb_flags != n->nb_flags)
331                 {
332                         /* someone gave us the wrong nb_flags as a reply. oops. */
333                         /* XXXX should say to them 'oi! release that name!' */
334
335                         DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
336                         DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
337                         return;
338                 }
339
340                 if (!ip_equal(n->send_ip, found_ip))
341                 {
342                         /* someone gave us the wrong ip as a reply. oops. */
343                         /* XXXX should say to them 'oi! release that name!' */
344
345                         DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
346                         DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
347                         return;
348                 }
349
350                 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
351
352                 /* fine: now tell the other host they can't have the name */
353                 register_ip = n->send_ip;
354                 new_owner = False;
355         }
356         else
357         {
358                 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
359
360                 /* the owner didn't want the name: the other host can have it */
361                 register_ip = n->reply_to_ip;
362                 new_owner = True;
363         }
364
365         /* register the old or the new owners' ip */
366         add_name_respond(d, n->fd, d->myip, n->reply_id,&n->name,n->nb_flags,
367                                         GET_TTL(0), register_ip,
368                                         new_owner, n->reply_to_ip);
369
370         remove_response_record(d,n); /* remove the response record */
371 }
372
373
374 /****************************************************************************
375   response from a name query to sync browse lists or to update our netbios
376   entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM 
377   ****************************************************************************/
378 static void response_name_query_sync(struct nmb_packet *nmb, 
379                 struct nmb_name *ans_name, BOOL bcast,
380                 struct response_record *n, struct subnet_record *d)
381 {
382   DEBUG(4, ("Name query at %s ip %s - ",
383             namestr(&n->name), inet_ntoa(n->send_ip)));
384
385   if (!name_equal(&n->name, ans_name))
386     {
387       /* someone gave us the wrong name as a reply. oops. */
388       DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
389       return;
390     }
391
392   if (nmb->header.rcode == 0 && nmb->answers && nmb->answers->rdata)
393     {
394       int nb_flags = nmb->answers->rdata[0];
395       struct in_addr found_ip;
396       
397       putip((char*)&found_ip,&nmb->answers->rdata[2]);
398       
399       if (!ip_equal(n->send_ip, found_ip))
400         {
401           /* someone gave us the wrong ip as a reply. oops. */
402           DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
403           DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
404           return;
405         }
406
407       DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
408       
409       if (n->state == NAME_QUERY_SYNC_LOCAL ||
410           n->state == NAME_QUERY_SYNC_REMOTE)
411         {
412           struct work_record *work = NULL;
413           /* We cheat here as we know that the workgroup name has
414              been placed in the my_comment field of the 
415              response_record struct by the code in 
416              start_sync_browse_entry().
417           */
418           if ((work = find_workgroupstruct(d, n->my_comment, False)))
419             {
420               BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
421               
422               /* the server is there: sync quick before it (possibly) dies! */
423               sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
424                                 found_ip, local_list_only);
425             }
426         }
427       else
428         {
429           struct subnet_record *add_rec = (!bcast) ? wins_client_subnet : d;
430
431           /* update our netbios name list (re-register it if necessary) */
432           add_netbios_entry(add_rec, ans_name->name, ans_name->name_type,
433                             nb_flags,GET_TTL(0),REGISTER,
434                             found_ip,False);
435         }
436     }
437   else
438     {
439       DEBUG(4, (" NEGATIVE RESPONSE!\n"));
440       
441       if (n->state == NAME_QUERY_CONFIRM)
442         {
443           /* XXXX remove_netbios_entry()? */
444           /* lots of things we ought to do, here. if we get here,
445              then we're in a mess: our name database doesn't match
446              reality. sort it out
447              */
448           remove_netbios_name(d,n->name.name, n->name.name_type, REGISTER);
449         }
450     }
451 }
452
453 /****************************************************************************
454   response from a name query for DOMAIN<1b>
455   NAME_QUERY_DOMAIN is dealt with here - we are trying to become a domain
456   master browser and WINS replied - check it's our address.
457   ****************************************************************************/
458 static void response_name_query_domain(struct nmb_name *ans_name,
459                 struct nmb_packet *nmb,
460                 struct response_record *n, struct subnet_record *d)
461 {
462   DEBUG(4, ("response_name_query_domain: Got %s response from %s for query \
463 for %s\n", nmb->header.rcode == 0 ? "success" : "failure",
464            inet_ntoa(n->send_ip), namestr(ans_name)));
465
466   /* Check the name is correct and ip address returned is our own. If it is then we
467      just remove the response record.
468    */
469   if (name_equal(&n->name, ans_name) && (nmb->header.rcode == 0) && nmb->answers && (nmb->answers->rdata))
470   {
471     struct in_addr found_ip;
472
473     putip((char*)&found_ip,&nmb->answers->rdata[2]);
474     /* Samba 1.9.16p11 servers seem to return the broadcast address for this
475        query. */
476     if (ismyip(found_ip) || ip_equal(wins_ip, found_ip) || ip_equal(ipzero, found_ip))
477     {
478       DEBUG(4, ("response_name_query_domain: WINS server returned our ip \
479 address. Pretending we never received response.\n"));
480       n->num_msgs = 0;
481       n->repeat_count = 0;
482       n->repeat_time = 0;
483     }
484     else
485     {
486       DEBUG(0,("response_name_query_domain: WINS server already has a \
487 domain master browser registered %s at address %s\n", 
488            namestr(ans_name), inet_ntoa(found_ip)));
489     }
490   }
491   else
492   {
493     /* Negative/incorrect response. No domain master
494        browser was registered - pretend we didn't get this response.
495      */
496     n->num_msgs = 0;
497     n->repeat_count = 0;
498     n->repeat_time = 0;
499   }
500
501 }
502
503 /****************************************************************************
504   report the response record type
505   ****************************************************************************/
506 static void debug_rr_type(int rr_type)
507 {
508   switch (rr_type)
509     {
510     case NMB_STATUS: DEBUG(3,("Name status ")); break;
511     case NMB_QUERY : DEBUG(3,("Name query ")); break;
512     case NMB_REG   : DEBUG(3,("Name registration ")); break;
513     case NMB_REL   : DEBUG(3,("Name release ")); break;
514     default        : DEBUG(1,("wrong response packet type received")); break;
515     }
516 }
517
518 /****************************************************************************
519   report the response record nmbd state
520   ****************************************************************************/
521 void debug_state_type(int state)
522 {
523   /* report the state type to help debugging */
524   switch (state)
525     {
526     case NAME_QUERY_DOM_SRV_CHK  : DEBUG(4,("NAME_QUERY_DOM_SRV_CHK\n")); break;
527     case NAME_QUERY_SRV_CHK      : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
528     case NAME_QUERY_FIND_MST     : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
529     case NAME_QUERY_MST_CHK      : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
530     case NAME_QUERY_CONFIRM      : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
531     case NAME_QUERY_SYNC_LOCAL   : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
532     case NAME_QUERY_SYNC_REMOTE  : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
533     case NAME_QUERY_DOMAIN       : DEBUG(4,("NAME_QUERY_DOMAIN\n")); break;
534       
535     case NAME_REGISTER           : DEBUG(4,("NAME_REGISTER\n")); break;
536     case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
537       
538     case NAME_RELEASE            : DEBUG(4,("NAME_RELEASE\n")); break;
539       
540     case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STATUS_DOM_SRV_CHK\n")); break;
541     case NAME_STATUS_SRV_CHK     : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
542       
543     default: break;
544     }
545 }
546
547 /****************************************************************************
548   report any problems with the fact that a response has been received.
549
550   (responses for certain types of operations are only expected from one host)
551   ****************************************************************************/
552 static BOOL response_problem_check(struct response_record *n,
553                         struct nmb_packet *nmb, char *ans_name)
554 {
555   switch (nmb->answers->rr_type)
556     {
557     case NMB_REL:
558       {
559         if (n->num_msgs > 1)
560           {
561             DEBUG(1,("more than one release name response received!\n"));
562             return True;
563           }
564         break;
565       }
566
567     case NMB_REG:
568       {
569         if (n->num_msgs > 1)
570           {
571             DEBUG(1,("more than one register name response received!\n"));
572             return True;
573           }
574         break;
575       }
576     
577     case NMB_QUERY:
578       { 
579         if (n->num_msgs > 1)
580           {
581             if (nmb->header.rcode == 0 && nmb->answers && nmb->answers->rdata)
582               {
583                 int nb_flags = nmb->answers->rdata[0];
584                 
585                 if ((!NAME_GROUP(nb_flags)))
586                   {
587                     /* oh dear. more than one person responded to a 
588                        unique name.
589                        there is either a network problem, a 
590                        configuration problem
591                        or a server is mis-behaving */
592                     
593                     /* XXXX mark the name as in conflict, and then let the
594                        person who just responded know that they 
595                        must also mark it
596                        as in conflict, and therefore must NOT use it.
597                        see rfc1001.txt 15.1.3.5 */
598                     
599                     /* this may cause problems for some 
600                        early versions of nmbd */
601                     
602                     switch (n->state)
603                       {
604                       case NAME_QUERY_FIND_MST:
605                         {
606                           /* query for ^1^2__MSBROWSE__^2^1 expect
607                              lots of responses */
608                           return False;
609                         }
610                       case NAME_QUERY_DOM_SRV_CHK:
611                       case NAME_QUERY_SRV_CHK:
612                       case NAME_QUERY_MST_CHK:
613                         {
614                           if (!strequal(ans_name,n->name.name))
615                             {
616                               /* one subnet, one master browser 
617                                  per workgroup */
618                               /* XXXX force an election? */
619                               
620                               DEBUG(3,("more than one master browser replied!\n"));
621                               return True;
622                             }
623                           break;
624                         }
625                       default: break;
626                       }
627                     DEBUG(3,("Unique Name conflict detected!\n"));
628                     return True;
629                   }
630               }
631             else
632               {
633                 /* we have received a negative reply, 
634                    having already received
635                    at least one response (pos/neg). 
636                    something's really wrong! */
637                 
638                 DEBUG(3,("wierd name query problem detected!\n"));
639                 return True;
640               }
641           }
642       }
643     }
644   return False;
645 }
646
647 #if 0
648 /****************************************************************************
649   check that the response received is compatible with the response record
650   ****************************************************************************/
651 static BOOL response_compatible(struct response_record *n,
652                         struct nmb_packet *nmb)
653 {
654   switch (n->state)
655   {
656     case NAME_RELEASE:
657     {
658                 if (nmb->answers->rr_type != 0x20)
659                 {
660                         DEBUG(1,("Name release reply has wrong answer rr_type\n"));
661                         return False;
662                 }
663         break;
664     }
665
666     case NAME_REGISTER:
667     {
668                 if (nmb->answers->rr_type != 0x20)
669                 {
670                         DEBUG(1,("Name register reply has wrong answer rr_type\n"));
671                         return False;
672                 }
673         break;
674     }
675
676     case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
677     case NAME_QUERY_CONFIRM:
678     case NAME_QUERY_SYNC_LOCAL:
679     case NAME_QUERY_SYNC_REMOTE:
680     case NAME_QUERY_DOM_SRV_CHK:
681     case NAME_QUERY_SRV_CHK:
682     case NAME_QUERY_FIND_MST:
683     case NAME_QUERY_MST_CHK:
684     {
685                 if (nmb->answers->rr_type != 0x20)
686                 {
687                         DEBUG(1,("Name query reply has wrong answer rr_type\n"));
688                         return False;
689                 }
690                 break;
691     }
692       
693     case NAME_STATUS_DOM_SRV_CHK:
694     case NAME_STATUS_SRV_CHK:
695     {
696                 if (nmb->answers->rr_type != 0x21)
697                 {
698                         DEBUG(1,("Name status reply has wrong answer rr_type\n"));
699                         return False;
700                 }
701                 break;
702     }
703       
704     default:
705     {
706                 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
707                 return False;
708     }
709   }
710   return True;
711 }
712 #endif
713
714
715 /****************************************************************************
716   process the response packet received
717   ****************************************************************************/
718 static void response_process(struct subnet_record *d, struct packet_struct *p,
719                              struct response_record *n, struct nmb_packet *nmb,
720                              BOOL bcast, struct nmb_name *ans_name)
721 {
722   switch (n->state)
723     {
724     case NAME_RELEASE:
725       {
726         response_name_release(ans_name, d, p);
727         break;
728       }
729
730     case NAME_REGISTER:
731       {
732         response_name_reg(ans_name, d, p);
733         break;
734       }
735
736     case NAME_REGISTER_CHALLENGE:
737       {
738         response_name_query_register(nmb, ans_name, n, d);
739         break;
740       }
741
742     case NAME_QUERY_DOM_SRV_CHK:
743     case NAME_QUERY_SRV_CHK:
744     case NAME_QUERY_FIND_MST:
745       {
746         response_server_check(ans_name, n, d, p);
747         break;
748       }
749     
750     case NAME_STATUS_DOM_SRV_CHK:
751     case NAME_STATUS_SRV_CHK:
752       {
753         response_name_status_check(p->ip, nmb, bcast, n, d);
754         break;
755       }
756     
757     case NAME_QUERY_CONFIRM:
758     case NAME_QUERY_SYNC_LOCAL:
759     case NAME_QUERY_SYNC_REMOTE:
760       {
761         response_name_query_sync(nmb, ans_name, bcast, n, d);
762         break;
763       }
764     case NAME_QUERY_MST_CHK:
765       {
766         /* no action required here. it's when NO responses are received
767            that we need to do something. see expire_name_query_entries() */
768         
769         DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
770                   namestr(&n->name), inet_ntoa(n->send_ip)));
771         break;
772       }
773    
774     case NAME_QUERY_DOMAIN:
775       {
776         /* We were asking to be a domain master browser, and someone
777            replied. If it was the WINS server and the IP it is
778            returning is our own - then remove the record and pretend
779            we didn't get a response. Else we do nothing and let 
780            dead_netbios_entry deal with it. 
781            We can only become domain master browser
782            when no broadcast responses are received and WINS
783            either contains no entry for the DOMAIN<1b> name or
784            contains our IP address.
785          */
786         response_name_query_domain(ans_name, nmb, n, d);
787         break;
788       }
789     default:
790       {
791         DEBUG(1,("unknown state type received in response_netbios_packet\n"));
792         break;
793       }
794     }
795 }
796
797
798 /****************************************************************************
799   response from a netbios packet.
800   ****************************************************************************/
801 void response_netbios_packet(struct packet_struct *p)
802 {
803   struct nmb_packet *nmb = &p->packet.nmb;
804   struct nmb_name *ans_name = NULL;
805   BOOL bcast = nmb->header.nm_flags.bcast;
806   struct response_record *n;
807   struct subnet_record *d = NULL;
808
809   if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
810     DEBUG(2,("unknown netbios response id %d (received late or from nmblookup?)\n",
811            nmb->header.name_trn_id));
812     return;
813   }
814
815   if (!d)
816     {
817       DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
818       return;
819     }
820
821   /* args wrong way round: spotted by ccm@shentel.net */
822   if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
823     {
824       DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
825       DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
826     }
827   
828   if (nmb->answers == NULL) {
829           /* if there is no name is the response then the name is the one
830              we queried on */
831           ans_name = &n->name;
832   } else {
833           ans_name = &nmb->answers->rr_name;
834           debug_rr_type(nmb->answers->rr_type);
835   }
836
837   DEBUG(3,("response for %s from %s(%d) (bcast=%s)\n",
838            namestr(ans_name), inet_ntoa(p->ip), p->port, BOOLSTR(bcast)));
839   
840   n->num_msgs++; /* count number of responses received */
841   n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
842   
843   debug_state_type(n->state);
844   
845   /* problem checking: multiple responses etc */
846   if (nmb->answers && response_problem_check(n, nmb, ans_name->name))
847     return;
848   
849   /* now deal with the current state */
850   response_process(d, p, n, nmb, bcast, ans_name);
851 }