2 Unix SMB/Netbios implementation.
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.
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
37 extern int DEBUGLEVEL;
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
48 **************************************************************************/
49 void response_name_release(struct subnet_record *d, struct packet_struct *p)
51 struct nmb_packet *nmb = &p->packet.nmb;
52 char *name = nmb->question.question_name.name;
53 int type = nmb->question.question_name.name_type;
55 DEBUG(4,("response name release received\n"));
57 if (nmb->header.rcode == 0 && nmb->answers->rdata)
59 /* IMPORTANT: see expire_netbios_response_entries() */
61 struct in_addr found_ip;
62 putip((char*)&found_ip,&nmb->answers->rdata[2]);
66 remove_netbios_name(d,name,type,SELF,found_ip);
71 DEBUG(2,("name release for %s rejected!\n",
72 namestr(&nmb->question.question_name)));
74 /* XXXX do we honestly care if our name release was rejected?
75 only if samba is issuing the release on behalf of some out-of-sync
76 server. if it's one of samba's SELF names, we don't care. */
81 /****************************************************************************
82 response for a reg request received
83 **************************************************************************/
84 void response_name_reg(struct subnet_record *d, struct packet_struct *p)
86 struct nmb_packet *nmb = &p->packet.nmb;
87 char *name = nmb->question.question_name.name;
88 int type = nmb->question.question_name.name_type;
89 BOOL bcast = nmb->header.nm_flags.bcast;
91 DEBUG(4,("response name registration received!\n"));
93 if (nmb->header.rcode == 0 && nmb->answers->rdata)
95 /* IMPORTANT: see expire_netbios_response_entries() */
97 int nb_flags = nmb->answers->rdata[0];
98 int ttl = nmb->answers->ttl;
99 struct in_addr found_ip;
101 putip((char*)&found_ip,&nmb->answers->rdata[2]);
103 name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
107 DEBUG(1,("name registration for %s rejected!\n",
108 namestr(&nmb->question.question_name)));
110 /* XXXX oh dear. we have problems. must deal with our name having
111 been rejected: e.g if it was our GROUP(1d) name, we must unbecome
114 name_unregister_work(d,name,type);
119 /****************************************************************************
120 response from a name query server check. states of type NAME_QUERY_PDC_SRV_CHK,
121 NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
122 ****************************************************************************/
123 static void response_server_check(struct nmb_name *ans_name,
124 struct response_record *n, struct subnet_record *d)
126 /* issue another state: this time to do a name status check */
128 enum state_type cmd = (n->state == NAME_QUERY_PDC_SRV_CHK) ?
129 NAME_STATUS_PDC_SRV_CHK : NAME_STATUS_SRV_CHK;
131 /* initiate a name status check on the server that replied */
132 queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
133 ans_name->name, ans_name->name_type,
135 False,False,n->send_ip,n->reply_to_ip);
139 /****************************************************************************
140 interpret a node status response. this is pretty hacked: we need two bits of
141 info. a) the name of the workgroup b) the name of the server. it will also
142 add all the names it finds into the namelist.
143 ****************************************************************************/
144 static BOOL interpret_node_status(struct subnet_record *d,
145 char *p, struct nmb_name *name,int t,
146 char *serv_name, struct in_addr ip, BOOL bcast)
148 int level = t==0x20 ? 4 : 0;
149 int numnames = CVAL(p,0);
152 DEBUG(level,("received %d names\n",numnames));
156 if (serv_name) *serv_name = 0;
173 trim_string(qname,NULL," ");
177 if (NAME_GROUP (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
178 if (NAME_BFLAG (nb_flags)) { strcat(flags,"B "); }
179 if (NAME_PFLAG (nb_flags)) { strcat(flags,"P "); }
180 if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
181 if (NAME__FLAG (nb_flags)) { strcat(flags,"_ "); }
182 if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
183 if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
184 if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
185 if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
187 /* might as well update our namelist while we're at it */
190 struct in_addr nameip;
191 enum name_source src;
200 add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
203 /* we want the server name */
204 if (serv_name && !*serv_name && !group && t == 0)
206 StrnCpy(serv_name,qname,15);
210 /* looking for a name and type? */
211 if (name && !found && (t == type))
213 /* take a guess at some of the name types we're going to ask for.
214 evaluate whether they are group names or no... */
215 if (((t == 0x1b || t == 0x1d ) && !group) ||
216 ((t == 0x20 || t == 0x1c || t == 0x1e) && group))
219 make_nmb_name(name,qname,type,scope);
223 DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
225 DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
226 IVAL(p,20),IVAL(p,24)));
231 /****************************************************************************
232 response from a name status check. states of type NAME_STATUS_PDC_SRV_CHK
233 and NAME_STATUS_SRV_CHK dealt with here.
234 ****************************************************************************/
235 static void response_name_status_check(struct in_addr ip,
236 struct nmb_packet *nmb, BOOL bcast,
237 struct response_record *n, struct subnet_record *d)
239 /* NMB_STATUS arrives: contains workgroup name and server name required.
240 amongst other things. */
242 struct nmb_name name;
245 if (interpret_node_status(d,nmb->answers->rdata,
246 &name,name.name_type,serv_name,ip,bcast))
250 sync_server(n->state,serv_name,
251 name.name,name.name_type, n->send_ip);
256 DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
261 /****************************************************************************
262 response from a name query for secured WINS registration. a state of
263 NAME_REGISTER_CHALLENGE is dealt with here.
264 ****************************************************************************/
265 static void response_name_query_register(struct nmb_packet *nmb,
266 struct nmb_name *ans_name,
267 struct response_record *n, struct subnet_record *d)
269 struct in_addr register_ip;
272 DEBUG(4, ("Name query at %s ip %s - ",
273 namestr(&n->name), inet_ntoa(n->send_ip)));
275 if (!name_equal(&n->name, ans_name))
277 /* someone gave us the wrong name as a reply. oops. */
278 /* XXXX should say to them 'oi! release that name!' */
280 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
284 if (nmb->header.rcode == 0 && nmb->answers->rdata)
286 /* we had sent out a name query to the current owner
287 of a name because someone else wanted it. now they
288 have responded saying that they still want the name,
289 so the other host can't have it.
292 /* first check all the details are correct */
294 int nb_flags = nmb->answers->rdata[0];
295 struct in_addr found_ip;
297 putip((char*)&found_ip,&nmb->answers->rdata[2]);
299 if (nb_flags != n->nb_flags)
301 /* someone gave us the wrong nb_flags as a reply. oops. */
302 /* XXXX should say to them 'oi! release that name!' */
304 DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
305 DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
309 if (!ip_equal(n->send_ip, found_ip))
311 /* someone gave us the wrong ip as a reply. oops. */
312 /* XXXX should say to them 'oi! release that name!' */
314 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
315 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
319 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
321 /* fine: now tell the other host they can't have the name */
322 register_ip = n->send_ip;
327 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
329 /* the owner didn't want the name: the other host can have it */
330 register_ip = n->reply_to_ip;
334 /* register the old or the new owners' ip */
335 add_netbios_entry(d, ans_name->name, ans_name->name_type,
336 n->nb_flags,GET_TTL(0),REGISTER,
337 register_ip,False,True);
339 /* reply yes or no to the host that requested the name */
340 send_name_response(n->fd, n->response_id, NMB_REG,
342 &n->name, n->nb_flags, GET_TTL(0), n->reply_to_ip);
346 /****************************************************************************
347 response from a name query to sync browse lists or to update our netbios
348 entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
349 ****************************************************************************/
350 static void response_name_query_sync(struct nmb_packet *nmb,
351 struct nmb_name *ans_name, BOOL bcast,
352 struct response_record *n, struct subnet_record *d)
354 DEBUG(4, ("Name query at %s ip %s - ",
355 namestr(&n->name), inet_ntoa(n->send_ip)));
357 if (!name_equal(&n->name, ans_name))
359 /* someone gave us the wrong name as a reply. oops. */
360 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
364 if (nmb->header.rcode == 0 && nmb->answers->rdata)
366 int nb_flags = nmb->answers->rdata[0];
367 struct in_addr found_ip;
369 putip((char*)&found_ip,&nmb->answers->rdata[2]);
371 if (!ip_equal(n->send_ip, found_ip))
373 /* someone gave us the wrong ip as a reply. oops. */
374 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
375 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
379 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
381 if (n->state == NAME_QUERY_SYNC)
383 struct work_record *work = NULL;
384 if ((work = find_workgroupstruct(d, ans_name->name, False)))
386 /* the server is there: sync quick before it (possibly) dies! */
387 sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
393 /* update our netbios name list (re-register it if necessary) */
394 add_netbios_entry(d, ans_name->name, ans_name->name_type,
395 nb_flags,GET_TTL(0),REGISTER,
396 found_ip,False,!bcast);
401 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
403 if (n->state == NAME_QUERY_CONFIRM)
405 /* XXXX remove_netbios_entry()? */
406 /* lots of things we ought to do, here. if we get here,
407 then we're in a mess: our name database doesn't match
410 remove_netbios_name(d,n->name.name, n->name.name_type,
411 REGISTER,n->send_ip);
417 /****************************************************************************
418 report the response record type
419 ****************************************************************************/
420 static void debug_rr_type(int rr_type)
424 case NMB_STATUS: DEBUG(3,("Name status ")); break;
425 case NMB_QUERY : DEBUG(3,("Name query ")); break;
426 case NMB_REG : DEBUG(3,("Name registration ")); break;
427 case NMB_REL : DEBUG(3,("Name release ")); break;
428 default : DEBUG(1,("wrong response packet type received")); break;
432 /****************************************************************************
433 report the response record nmbd state
434 ****************************************************************************/
435 static void debug_state_type(int state)
437 /* report the state type to help debugging */
440 case NAME_QUERY_PDC_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
441 case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
442 case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
443 case NAME_STATUS_PDC_SRV_CHK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
444 case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
445 case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
446 case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
447 case NAME_REGISTER_CHALLENGE: DEBUG(4,("NAME_REGISTER_CHALLENGE\n")); break;
448 case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
449 case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
450 case NAME_QUERY_SYNC : DEBUG(4,("NAME_QUERY_SYNC\n")); break;
455 /****************************************************************************
456 report any problems with the fact that a response has been received.
458 (responses for certain types of operations are only expected from one host)
459 ****************************************************************************/
460 static BOOL response_problem_check(struct response_record *n,
461 struct nmb_packet *nmb, char *qname)
463 switch (nmb->answers->rr_type)
469 DEBUG(1,("more than one release name response received!\n"));
479 DEBUG(1,("more than one register name response received!\n"));
489 if (nmb->header.rcode == 0 && nmb->answers->rdata)
491 int nb_flags = nmb->answers->rdata[0];
493 if ((!NAME_GROUP(nb_flags)))
495 /* oh dear. more than one person responded to a unique name.
496 there is either a network problem, a configuration problem
497 or a server is mis-behaving */
499 /* XXXX mark the name as in conflict, and then let the
500 person who just responded know that they must also mark it
501 as in conflict, and therefore must NOT use it.
502 see rfc1001.txt 15.1.3.5 */
504 /* this may cause problems for some early versions of nmbd */
508 case NAME_QUERY_FIND_MST:
510 /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
513 case NAME_QUERY_PDC_SRV_CHK:
514 case NAME_QUERY_SRV_CHK:
515 case NAME_QUERY_MST_CHK:
517 if (!strequal(qname,n->name.name))
519 /* one subnet, one master browser per workgroup */
520 /* XXXX force an election? */
522 DEBUG(3,("more than one master browser replied!\n"));
529 DEBUG(3,("Unique Name conflict detected!\n"));
535 /* we have received a negative reply, having already received
536 at least one response (pos/neg). something's really wrong! */
538 DEBUG(3,("wierd name query problem detected!\n"));
547 /****************************************************************************
548 check that the response received is compatible with the response record
549 ****************************************************************************/
550 static BOOL response_compatible(struct response_record *n,
551 struct nmb_packet *nmb)
557 if (nmb->answers->rr_type != NMB_REL)
559 DEBUG(1,("Name release reply has wrong answer rr_type\n"));
567 if (nmb->answers->rr_type != NMB_REG)
569 DEBUG(1,("Name register reply has wrong answer rr_type\n"));
575 case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
576 case NAME_QUERY_CONFIRM:
577 case NAME_QUERY_SYNC:
578 case NAME_QUERY_PDC_SRV_CHK:
579 case NAME_QUERY_SRV_CHK:
580 case NAME_QUERY_FIND_MST:
581 case NAME_QUERY_MST_CHK:
583 if (nmb->answers->rr_type != NMB_QUERY)
585 DEBUG(1,("Name query reply has wrong answer rr_type\n"));
591 case NAME_STATUS_PDC_SRV_CHK:
592 case NAME_STATUS_SRV_CHK:
594 if (nmb->answers->rr_type != NMB_STATUS)
596 DEBUG(1,("Name status reply has wrong answer rr_type\n"));
604 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
612 /****************************************************************************
613 process the response packet received
614 ****************************************************************************/
615 static void response_process(struct subnet_record *d, struct packet_struct *p,
616 struct response_record *n, struct nmb_packet *nmb,
617 BOOL bcast, struct nmb_name *ans_name)
623 response_name_release(d, p);
629 response_name_reg(d, p);
633 case NAME_REGISTER_CHALLENGE:
635 response_name_query_register(nmb, ans_name, n, d);
639 case NAME_QUERY_PDC_SRV_CHK:
640 case NAME_QUERY_SRV_CHK:
641 case NAME_QUERY_FIND_MST:
643 response_server_check(ans_name, n, d);
647 case NAME_STATUS_PDC_SRV_CHK:
648 case NAME_STATUS_SRV_CHK:
650 response_name_status_check(p->ip, nmb, bcast, n, d);
654 case NAME_QUERY_CONFIRM:
655 case NAME_QUERY_SYNC:
657 response_name_query_sync(nmb, ans_name, bcast, n, d);
660 case NAME_QUERY_MST_CHK:
662 /* no action required here. it's when NO responses are received
663 that we need to do something. see expire_name_query_entries() */
665 DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
666 namestr(&n->name), inet_ntoa(n->send_ip)));
672 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
679 /****************************************************************************
680 response from a netbios packet.
681 ****************************************************************************/
682 void response_netbios_packet(struct packet_struct *p)
684 struct nmb_packet *nmb = &p->packet.nmb;
685 struct nmb_name *question = &nmb->question.question_name;
686 struct nmb_name *ans_name = NULL;
687 char *qname = question->name;
688 BOOL bcast = nmb->header.nm_flags.bcast;
689 struct response_record *n;
690 struct subnet_record *d = NULL;
692 if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
693 DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
699 DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
703 if (!same_net(d->bcast_ip, d->mask_ip, p->ip)) /* copes with WINS 'subnet' */
705 DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
706 DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
710 if (nmb->answers == NULL)
712 /* hm. the packet received was a response, but with no answer. wierd! */
713 DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
714 inet_ntoa(p->ip), BOOLSTR(bcast)));
718 ans_name = &nmb->answers->rr_name;
719 DEBUG(3,("response for %s from %s (bcast=%s)\n",
720 namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
722 debug_rr_type(nmb->answers->rr_type);
724 n->num_msgs++; /* count number of responses received */
725 n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
727 debug_state_type(n->state);
729 /* problem checking: multiple responses etc */
730 if (response_problem_check(n, nmb, qname))
733 /* now check whether the 'state' has received the correct type of response */
734 if (!response_compatible(n, nmb))
737 /* now deal with the current state */
738 response_process(d, p, n, nmb, bcast, ans_name);