lots of changes to nmbd
[Samba.git] / source / nameservresp.c
blob46acc2b99276ed56d2bd62a4112563228654ef43
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1996
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.
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.
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.
21 Revision History:
23 Module name: nameservresp.c
25 14 jan 96: lkcl@pires.co.uk
26 added multiple workgroup domain master support
28 05 jul 96: lkcl@pires.co.uk
29 created module nameservresp containing NetBIOS response functions
33 #include "includes.h"
35 extern int ClientNMB;
37 extern int DEBUGLEVEL;
39 extern pstring scope;
40 extern struct in_addr ipzero;
42 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
45 /****************************************************************************
46 response for a reg release received. samba has asked a WINS server if it
47 could release a name.
48 **************************************************************************/
49 static void response_name_release(struct subnet_record *d,
50 struct packet_struct *p)
52 struct nmb_packet *nmb = &p->packet.nmb;
53 char *name = nmb->question.question_name.name;
54 int type = nmb->question.question_name.name_type;
56 DEBUG(4,("response name release received\n"));
58 if (nmb->header.rcode == 0 && nmb->answers->rdata)
60 /* IMPORTANT: see expire_netbios_response_entries() */
62 struct in_addr found_ip;
63 putip((char*)&found_ip,&nmb->answers->rdata[2]);
65 /* NOTE: we only release our own names at present */
66 if (ismyip(found_ip))
68 name_unregister_work(d,name,type);
70 else
72 DEBUG(2,("name release for different ip! %s %s\n",
73 inet_ntoa(found_ip),
74 namestr(&nmb->question.question_name)));
77 else
79 DEBUG(2,("name release for %s rejected!\n",
80 namestr(&nmb->question.question_name)));
82 /* XXXX PANIC! what to do if it's one of samba's own names? */
84 /* XXXX do we honestly care if our name release was rejected?
85 only if samba is issuing the release on behalf of some out-of-sync
86 server. if it's one of samba's SELF names, we don't care. */
91 /****************************************************************************
92 response for a reg request received
93 **************************************************************************/
94 static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
96 struct nmb_packet *nmb = &p->packet.nmb;
97 char *name = nmb->question.question_name.name;
98 int type = nmb->question.question_name.name_type;
99 BOOL bcast = nmb->header.nm_flags.bcast;
101 DEBUG(4,("response name registration received!\n"));
103 if (nmb->header.rcode == 0 && nmb->answers->rdata)
105 /* IMPORTANT: see expire_netbios_response_entries() */
107 int nb_flags = nmb->answers->rdata[0];
108 int ttl = nmb->answers->ttl;
109 struct in_addr found_ip;
111 putip((char*)&found_ip,&nmb->answers->rdata[2]);
113 name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
115 else
117 DEBUG(1,("name registration for %s rejected!\n",
118 namestr(&nmb->question.question_name)));
120 /* oh dear. we have problems. possibly unbecome a master browser. */
121 name_unregister_work(d,name,type);
126 /****************************************************************************
127 response from a name query server check. states of type NAME_QUERY_PDC_SRV_CHK,
128 NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
129 ****************************************************************************/
130 static void response_server_check(struct nmb_name *ans_name,
131 struct response_record *n, struct subnet_record *d)
133 /* issue another state: this time to do a name status check */
135 enum state_type cmd = (n->state == NAME_QUERY_PDC_SRV_CHK) ?
136 NAME_STATUS_PDC_SRV_CHK : NAME_STATUS_SRV_CHK;
138 /* initiate a name status check on the server that replied */
139 queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
140 ans_name->name, ans_name->name_type,
141 0,0,
142 False,False,n->send_ip,n->reply_to_ip);
146 /****************************************************************************
147 interpret a node status response. this is pretty hacked: we need two bits of
148 info. a) the name of the workgroup b) the name of the server. it will also
149 add all the names it finds into the namelist.
150 ****************************************************************************/
151 static BOOL interpret_node_status(struct subnet_record *d,
152 char *p, struct nmb_name *name,int t,
153 char *serv_name, struct in_addr ip, BOOL bcast)
155 int level = t==0x20 ? 4 : 0;
156 int numnames = CVAL(p,0);
157 BOOL found = False;
159 DEBUG(level,("received %d names\n",numnames));
161 p += 1;
163 if (serv_name) *serv_name = 0;
165 while (numnames--)
167 char qname[17];
168 int type;
169 fstring flags;
170 int nb_flags;
172 BOOL group = False;
173 BOOL add = False;
175 *flags = 0;
177 StrnCpy(qname,p,15);
178 type = CVAL(p,15);
179 nb_flags = p[16];
180 trim_string(qname,NULL," ");
182 p += 18;
184 if (NAME_GROUP (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
185 if (NAME_BFLAG (nb_flags)) { strcat(flags,"B "); }
186 if (NAME_PFLAG (nb_flags)) { strcat(flags,"P "); }
187 if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
188 if (NAME__FLAG (nb_flags)) { strcat(flags,"_ "); }
189 if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
190 if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
191 if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
192 if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
194 /* might as well update our namelist while we're at it */
195 if (add)
197 struct in_addr nameip;
198 enum name_source src;
200 if (ismyip(ip)) {
201 nameip = ipzero;
202 src = SELF;
203 } else {
204 nameip = ip;
205 src = STATUS_QUERY;
207 add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
210 /* we want the server name */
211 if (serv_name && !*serv_name && !group && t == 0)
213 StrnCpy(serv_name,qname,15);
214 serv_name[15] = 0;
217 /* looking for a name and type? */
218 if (name && !found && (t == type))
220 /* take a guess at some of the name types we're going to ask for.
221 evaluate whether they are group names or no... */
222 if (((t == 0x1b || t == 0x1d ) && !group) ||
223 ((t == 0x20 || t == 0x1c || t == 0x1e) && group))
225 found = True;
226 make_nmb_name(name,qname,type,scope);
230 DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
232 DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
233 IVAL(p,20),IVAL(p,24)));
234 return found;
238 /****************************************************************************
239 response from a name status check. states of type NAME_STATUS_PDC_SRV_CHK
240 and NAME_STATUS_SRV_CHK dealt with here.
241 ****************************************************************************/
242 static void response_name_status_check(struct in_addr ip,
243 struct nmb_packet *nmb, BOOL bcast,
244 struct response_record *n, struct subnet_record *d)
246 /* NMB_STATUS arrives: contains workgroup name and server name required.
247 amongst other things. */
249 struct nmb_name name;
250 fstring serv_name;
252 if (interpret_node_status(d,nmb->answers->rdata,
253 &name,name.name_type,serv_name,ip,bcast))
255 if (*serv_name)
257 sync_server(n->state,serv_name,
258 name.name,name.name_type, n->send_ip);
261 else
263 DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
268 /****************************************************************************
269 response from a name query for secured WINS registration. a state of
270 NAME_REGISTER_CHALLENGE is dealt with here.
271 ****************************************************************************/
272 static void response_name_query_register(struct nmb_packet *nmb,
273 struct nmb_name *ans_name,
274 struct response_record *n, struct subnet_record *d)
276 struct in_addr register_ip;
277 BOOL new_owner;
279 DEBUG(4, ("Name query at %s ip %s - ",
280 namestr(&n->name), inet_ntoa(n->send_ip)));
282 if (!name_equal(&n->name, ans_name))
284 /* someone gave us the wrong name as a reply. oops. */
285 /* XXXX should say to them 'oi! release that name!' */
287 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
288 return;
291 if (nmb->header.rcode == 0 && nmb->answers->rdata)
293 /* we had sent out a name query to the current owner
294 of a name because someone else wanted it. now they
295 have responded saying that they still want the name,
296 so the other host can't have it.
299 /* first check all the details are correct */
301 int nb_flags = nmb->answers->rdata[0];
302 struct in_addr found_ip;
304 putip((char*)&found_ip,&nmb->answers->rdata[2]);
306 if (nb_flags != n->nb_flags)
308 /* someone gave us the wrong nb_flags as a reply. oops. */
309 /* XXXX should say to them 'oi! release that name!' */
311 DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
312 DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
313 return;
316 if (!ip_equal(n->send_ip, found_ip))
318 /* someone gave us the wrong ip as a reply. oops. */
319 /* XXXX should say to them 'oi! release that name!' */
321 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
322 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
323 return;
326 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
328 /* fine: now tell the other host they can't have the name */
329 register_ip = n->send_ip;
330 new_owner = False;
332 else
334 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
336 /* the owner didn't want the name: the other host can have it */
337 register_ip = n->reply_to_ip;
338 new_owner = True;
341 /* register the old or the new owners' ip */
342 add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
343 GET_TTL(0), register_ip,
344 new_owner, n->reply_to_ip);
348 /****************************************************************************
349 response from a name query to sync browse lists or to update our netbios
350 entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
351 ****************************************************************************/
352 static void response_name_query_sync(struct nmb_packet *nmb,
353 struct nmb_name *ans_name, BOOL bcast,
354 struct response_record *n, struct subnet_record *d)
356 DEBUG(4, ("Name query at %s ip %s - ",
357 namestr(&n->name), inet_ntoa(n->send_ip)));
359 if (!name_equal(&n->name, ans_name))
361 /* someone gave us the wrong name as a reply. oops. */
362 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
363 return;
366 if (nmb->header.rcode == 0 && nmb->answers->rdata)
368 int nb_flags = nmb->answers->rdata[0];
369 struct in_addr found_ip;
371 putip((char*)&found_ip,&nmb->answers->rdata[2]);
373 if (!ip_equal(n->send_ip, found_ip))
375 /* someone gave us the wrong ip as a reply. oops. */
376 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
377 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
378 return;
381 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
383 if (n->state == NAME_QUERY_SYNC)
385 struct work_record *work = NULL;
386 if ((work = find_workgroupstruct(d, ans_name->name, False)))
388 /* the server is there: sync quick before it (possibly) dies! */
389 sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
390 found_ip);
393 else
395 /* update our netbios name list (re-register it if necessary) */
396 add_netbios_entry(d, ans_name->name, ans_name->name_type,
397 nb_flags,GET_TTL(0),REGISTER,
398 found_ip,False,!bcast);
401 else
403 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
405 if (n->state == NAME_QUERY_CONFIRM)
407 /* XXXX remove_netbios_entry()? */
408 /* lots of things we ought to do, here. if we get here,
409 then we're in a mess: our name database doesn't match
410 reality. sort it out
412 remove_netbios_name(d,n->name.name, n->name.name_type,
413 REGISTER,n->send_ip);
419 /****************************************************************************
420 report the response record type
421 ****************************************************************************/
422 static void debug_rr_type(int rr_type)
424 switch (rr_type)
426 case NMB_STATUS: DEBUG(3,("Name status ")); break;
427 case NMB_QUERY : DEBUG(3,("Name query ")); break;
428 case NMB_REG : DEBUG(3,("Name registration ")); break;
429 case NMB_REL : DEBUG(3,("Name release ")); break;
430 default : DEBUG(1,("wrong response packet type received")); break;
434 /****************************************************************************
435 report the response record nmbd state
436 ****************************************************************************/
437 void debug_state_type(int state)
439 /* report the state type to help debugging */
440 switch (state)
442 case NAME_QUERY_PDC_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
443 case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
444 case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
445 case NAME_STATUS_PDC_SRV_CHK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
446 case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
447 case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
448 case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
449 case NAME_REGISTER_CHALLENGE: DEBUG(4,("NAME_REGISTER_CHALLENGE\n")); break;
450 case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
451 case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
452 case NAME_QUERY_SYNC : DEBUG(4,("NAME_QUERY_SYNC\n")); break;
453 default: break;
457 /****************************************************************************
458 report any problems with the fact that a response has been received.
460 (responses for certain types of operations are only expected from one host)
461 ****************************************************************************/
462 static BOOL response_problem_check(struct response_record *n,
463 struct nmb_packet *nmb, char *qname)
465 switch (nmb->answers->rr_type)
467 case NMB_REL:
469 if (n->num_msgs > 1)
471 DEBUG(1,("more than one release name response received!\n"));
472 return True;
474 break;
477 case NMB_REG:
479 if (n->num_msgs > 1)
481 DEBUG(1,("more than one register name response received!\n"));
482 return True;
484 break;
487 case NMB_QUERY:
489 if (n->num_msgs > 1)
491 if (nmb->header.rcode == 0 && nmb->answers->rdata)
493 int nb_flags = nmb->answers->rdata[0];
495 if ((!NAME_GROUP(nb_flags)))
497 /* oh dear. more than one person responded to a unique name.
498 there is either a network problem, a configuration problem
499 or a server is mis-behaving */
501 /* XXXX mark the name as in conflict, and then let the
502 person who just responded know that they must also mark it
503 as in conflict, and therefore must NOT use it.
504 see rfc1001.txt 15.1.3.5 */
506 /* this may cause problems for some early versions of nmbd */
508 switch (n->state)
510 case NAME_QUERY_FIND_MST:
512 /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
513 return False;
515 case NAME_QUERY_PDC_SRV_CHK:
516 case NAME_QUERY_SRV_CHK:
517 case NAME_QUERY_MST_CHK:
519 if (!strequal(qname,n->name.name))
521 /* one subnet, one master browser per workgroup */
522 /* XXXX force an election? */
524 DEBUG(3,("more than one master browser replied!\n"));
525 return True;
527 break;
529 default: break;
531 DEBUG(3,("Unique Name conflict detected!\n"));
532 return True;
535 else
537 /* we have received a negative reply, having already received
538 at least one response (pos/neg). something's really wrong! */
540 DEBUG(3,("wierd name query problem detected!\n"));
541 return True;
546 return False;
549 /****************************************************************************
550 check that the response received is compatible with the response record
551 ****************************************************************************/
552 static BOOL response_compatible(struct response_record *n,
553 struct nmb_packet *nmb)
555 switch (n->state)
557 case NAME_RELEASE:
559 if (nmb->answers->rr_type != NMB_REL)
561 DEBUG(1,("Name release reply has wrong answer rr_type\n"));
562 return False;
564 break;
567 case NAME_REGISTER:
569 if (nmb->answers->rr_type != NMB_REG)
571 DEBUG(1,("Name register reply has wrong answer rr_type\n"));
572 return False;
574 break;
577 case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
578 case NAME_QUERY_CONFIRM:
579 case NAME_QUERY_SYNC:
580 case NAME_QUERY_PDC_SRV_CHK:
581 case NAME_QUERY_SRV_CHK:
582 case NAME_QUERY_FIND_MST:
583 case NAME_QUERY_MST_CHK:
585 if (nmb->answers->rr_type != NMB_QUERY)
587 DEBUG(1,("Name query reply has wrong answer rr_type\n"));
588 return False;
590 break;
593 case NAME_STATUS_PDC_SRV_CHK:
594 case NAME_STATUS_SRV_CHK:
596 if (nmb->answers->rr_type != NMB_STATUS)
598 DEBUG(1,("Name status reply has wrong answer rr_type\n"));
599 return False;
601 break;
604 default:
606 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
607 return False;
610 return True;
614 /****************************************************************************
615 process the response packet received
616 ****************************************************************************/
617 static void response_process(struct subnet_record *d, struct packet_struct *p,
618 struct response_record *n, struct nmb_packet *nmb,
619 BOOL bcast, struct nmb_name *ans_name)
621 switch (n->state)
623 case NAME_RELEASE:
625 response_name_release(d, p);
626 break;
629 case NAME_REGISTER:
631 response_name_reg(d, p);
632 break;
635 case NAME_REGISTER_CHALLENGE:
637 response_name_query_register(nmb, ans_name, n, d);
638 break;
641 case NAME_QUERY_PDC_SRV_CHK:
642 case NAME_QUERY_SRV_CHK:
643 case NAME_QUERY_FIND_MST:
645 response_server_check(ans_name, n, d);
646 break;
649 case NAME_STATUS_PDC_SRV_CHK:
650 case NAME_STATUS_SRV_CHK:
652 response_name_status_check(p->ip, nmb, bcast, n, d);
653 break;
656 case NAME_QUERY_CONFIRM:
657 case NAME_QUERY_SYNC:
659 response_name_query_sync(nmb, ans_name, bcast, n, d);
660 break;
662 case NAME_QUERY_MST_CHK:
664 /* no action required here. it's when NO responses are received
665 that we need to do something. see expire_name_query_entries() */
667 DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
668 namestr(&n->name), inet_ntoa(n->send_ip)));
669 break;
672 default:
674 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
675 break;
681 /****************************************************************************
682 response from a netbios packet.
683 ****************************************************************************/
684 void response_netbios_packet(struct packet_struct *p)
686 struct nmb_packet *nmb = &p->packet.nmb;
687 struct nmb_name *question = &nmb->question.question_name;
688 struct nmb_name *ans_name = NULL;
689 char *qname = question->name;
690 BOOL bcast = nmb->header.nm_flags.bcast;
691 struct response_record *n;
692 struct subnet_record *d = NULL;
694 if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
695 DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
696 return;
699 if (!d)
701 DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
702 return;
705 if (!same_net(d->bcast_ip, d->mask_ip, p->ip)) /* copes with WINS 'subnet' */
707 DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
708 DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
709 return;
712 if (nmb->answers == NULL)
714 /* hm. the packet received was a response, but with no answer. wierd! */
715 DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
716 inet_ntoa(p->ip), BOOLSTR(bcast)));
717 return;
720 ans_name = &nmb->answers->rr_name;
721 DEBUG(3,("response for %s from %s (bcast=%s)\n",
722 namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
724 debug_rr_type(nmb->answers->rr_type);
726 n->num_msgs++; /* count number of responses received */
727 n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
729 debug_state_type(n->state);
731 /* problem checking: multiple responses etc */
732 if (response_problem_check(n, nmb, qname))
733 return;
735 /* now check whether the 'state' has received the correct type of response */
736 if (!response_compatible(n, nmb))
737 return;
739 /* now deal with the current state */
740 response_process(d, p, n, nmb, bcast, ans_name);