2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1997
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 fstring myworkgroup;
41 extern struct in_addr ipzero;
42 extern struct in_addr wins_ip;
43 extern struct in_addr ipzero;
46 #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
49 /****************************************************************************
50 response for a reg release received. samba has asked a WINS server if it
52 **************************************************************************/
53 static void response_name_release(struct nmb_name *ans_name,
54 struct subnet_record *d, struct packet_struct *p)
56 struct nmb_packet *nmb = &p->packet.nmb;
57 char *name = ans_name->name;
58 int type = ans_name->name_type;
60 DEBUG(4,("response name release received\n"));
62 if (nmb->header.rcode == 0 && nmb->answers->rdata)
64 /* IMPORTANT: see expire_netbios_response_entries() */
66 struct in_addr found_ip;
67 putip((char*)&found_ip,&nmb->answers->rdata[2]);
69 /* NOTE: we only release our own names at present */
72 name_unregister_work(d,name,type);
76 DEBUG(2,("name release for different ip! %s %s\n",
77 inet_ntoa(found_ip), namestr(ans_name)));
82 DEBUG(2,("name release for %s rejected!\n", namestr(ans_name)));
84 /* XXXX PANIC! what to do if it's one of samba's own names? */
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. */
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)
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;
104 DEBUG(4,("response name registration received!\n"));
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.
114 if ( ((d != wins_subnet) && (nmb->header.rcode == 6) && strequal(myworkgroup, name) &&
116 (nmb->header.rcode == 0 && nmb->answers->rdata))
118 if (nmb->header.rcode == 0 && nmb->answers->rdata)
121 /* IMPORTANT: see expire_netbios_response_entries() */
123 int nb_flags = nmb->answers->rdata[0];
124 int ttl = nmb->answers->ttl;
125 struct in_addr found_ip;
127 putip((char*)&found_ip,&nmb->answers->rdata[2]);
129 name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
133 DEBUG(2,("name registration for %s rejected by ip %s!\n",
134 namestr(ans_name), inet_ntoa(p->ip)));
136 /* oh dear. we have problems. possibly unbecome a master browser. */
137 name_unregister_work(d,name,type);
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)
148 struct nmb_packet *nmb = &p->packet.nmb;
149 struct in_addr send_ip;
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.
157 if (nmb->header.rcode == 0 && nmb->answers->rdata)
158 putip((char*)&send_ip,&nmb->answers->rdata[2]);
162 DEBUG(2,("response_server_check: name query for %s failed\n",
167 /* issue another state: this time to do a name status check */
169 cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
170 NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
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);
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)
192 int numnames = CVAL(p,0);
195 DEBUG(4,("received %d names\n",numnames));
199 if (serv_name) *serv_name = 0;
216 trim_string(qname,NULL," ");
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;}
230 /* we want the server name */
231 if (serv_name && !*serv_name && !group && type == 0x20)
233 StrnCpy(serv_name,qname,15);
237 /* looking for a name and type? */
238 if (name && !found && (t == type))
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))
246 make_nmb_name(name,qname,type,scope);
250 DEBUG(4,("\t%s(0x%x)\t%s\n",qname,type,flags));
252 DEBUG(4,("num_good_sends=%d num_good_receives=%d\n",
253 IVAL(p,20),IVAL(p,24)));
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)
266 /* NMB_STATUS arrives: contains workgroup name and server name required.
267 amongst other things. */
269 struct nmb_name name;
272 if (interpret_node_status(d,nmb->answers->rdata,
273 &name,0x20,serv_name,ip,bcast))
277 /* response_record->my_name contains the
278 workgroup name to sync with. See
279 response_server_check() */
280 sync_server(n->state,serv_name,
281 n->my_name,name.name_type, d, n->send_ip);
286 DEBUG(1,("No 0x20 name type in interpret_node_status()\n"));
291 /****************************************************************************
292 response from a name query for secured WINS registration. a state of
293 NAME_REGISTER_CHALLENGE is dealt with here.
294 ****************************************************************************/
295 static void response_name_query_register(struct nmb_packet *nmb,
296 struct nmb_name *ans_name,
297 struct response_record *n, struct subnet_record *d)
299 struct in_addr register_ip;
302 DEBUG(4, ("Name query at %s ip %s - ",
303 namestr(&n->name), inet_ntoa(n->send_ip)));
305 if (!name_equal(&n->name, ans_name))
307 /* someone gave us the wrong name as a reply. oops. */
308 /* XXXX should say to them 'oi! release that name!' */
310 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
314 if (nmb->header.rcode == 0 && nmb->answers->rdata)
316 /* we had sent out a name query to the current owner
317 of a name because someone else wanted it. now they
318 have responded saying that they still want the name,
319 so the other host can't have it.
322 /* first check all the details are correct */
324 int nb_flags = nmb->answers->rdata[0];
325 struct in_addr found_ip;
327 putip((char*)&found_ip,&nmb->answers->rdata[2]);
329 if (nb_flags != n->nb_flags)
331 /* someone gave us the wrong nb_flags as a reply. oops. */
332 /* XXXX should say to them 'oi! release that name!' */
334 DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
335 DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
339 if (!ip_equal(n->send_ip, found_ip))
341 /* someone gave us the wrong ip as a reply. oops. */
342 /* XXXX should say to them 'oi! release that name!' */
344 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
345 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
349 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
351 /* fine: now tell the other host they can't have the name */
352 register_ip = n->send_ip;
357 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
359 /* the owner didn't want the name: the other host can have it */
360 register_ip = n->reply_to_ip;
364 /* register the old or the new owners' ip */
365 add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
366 GET_TTL(0), register_ip,
367 new_owner, n->reply_to_ip);
371 /****************************************************************************
372 response from a name query to sync browse lists or to update our netbios
373 entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
374 ****************************************************************************/
375 static void response_name_query_sync(struct nmb_packet *nmb,
376 struct nmb_name *ans_name, BOOL bcast,
377 struct response_record *n, struct subnet_record *d)
379 DEBUG(4, ("Name query at %s ip %s - ",
380 namestr(&n->name), inet_ntoa(n->send_ip)));
382 if (!name_equal(&n->name, ans_name))
384 /* someone gave us the wrong name as a reply. oops. */
385 DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
389 if (nmb->header.rcode == 0 && nmb->answers->rdata)
391 int nb_flags = nmb->answers->rdata[0];
392 struct in_addr found_ip;
394 putip((char*)&found_ip,&nmb->answers->rdata[2]);
396 if (!ip_equal(n->send_ip, found_ip))
398 /* someone gave us the wrong ip as a reply. oops. */
399 DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
400 DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
404 DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
406 if (n->state == NAME_QUERY_SYNC_LOCAL ||
407 n->state == NAME_QUERY_SYNC_REMOTE)
409 struct work_record *work = NULL;
410 /* We cheat here as we know that the workgroup name has
411 been placed in the my_comment field of the
412 response_record struct by the code in
413 start_sync_browse_entry().
415 if ((work = find_workgroupstruct(d, n->my_comment, False)))
417 BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
419 /* the server is there: sync quick before it (possibly) dies! */
420 sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
421 found_ip, local_list_only);
426 /* update our netbios name list (re-register it if necessary) */
427 add_netbios_entry(d, ans_name->name, ans_name->name_type,
428 nb_flags,GET_TTL(0),REGISTER,
429 found_ip,False,!bcast);
434 DEBUG(4, (" NEGATIVE RESPONSE!\n"));
436 if (n->state == NAME_QUERY_CONFIRM)
438 /* XXXX remove_netbios_entry()? */
439 /* lots of things we ought to do, here. if we get here,
440 then we're in a mess: our name database doesn't match
443 remove_netbios_name(d,n->name.name, n->name.name_type,
444 REGISTER,n->send_ip);
449 /****************************************************************************
450 response from a name query for DOMAIN<1b>
451 NAME_QUERY_DOMAIN is dealt with here - we are trying to become a domain
452 master browser and WINS replied - check it's our address.
453 ****************************************************************************/
454 static void response_name_query_domain(struct nmb_name *ans_name,
455 struct nmb_packet *nmb,
456 struct response_record *n, struct subnet_record *d)
458 DEBUG(4, ("response_name_query_domain: Got %s response from %s for query \
459 for %s\n", nmb->header.rcode == 0 ? "success" : "failure",
460 inet_ntoa(n->send_ip), namestr(ans_name)));
462 /* Check the name is correct and ip address returned is our own. If it is then we
463 just remove the response record.
465 if (name_equal(&n->name, ans_name) && (nmb->header.rcode == 0) && (nmb->answers->rdata))
467 struct in_addr found_ip;
469 putip((char*)&found_ip,&nmb->answers->rdata[2]);
470 /* Samba 1.9.16p11 servers seem to return the broadcast address for this
472 if (ismyip(found_ip) || ip_equal(wins_ip, found_ip) || ip_equal(ipzero, found_ip))
474 DEBUG(4, ("response_name_query_domain: WINS server returned our ip \
475 address. Pretending we never received response.\n"));
482 DEBUG(0,("response_name_query_domain: WINS server already has a \
483 domain master browser registered %s at address %s\n",
484 namestr(ans_name), inet_ntoa(found_ip)));
489 /* Negative/incorrect response. No domain master
490 browser was registered - pretend we didn't get this response.
499 /****************************************************************************
500 report the response record type
501 ****************************************************************************/
502 static void debug_rr_type(int rr_type)
506 case NMB_STATUS: DEBUG(3,("Name status ")); break;
507 case NMB_QUERY : DEBUG(3,("Name query ")); break;
508 case NMB_REG : DEBUG(3,("Name registration ")); break;
509 case NMB_REL : DEBUG(3,("Name release ")); break;
510 default : DEBUG(1,("wrong response packet type received")); break;
514 /****************************************************************************
515 report the response record nmbd state
516 ****************************************************************************/
517 void debug_state_type(int state)
519 /* report the state type to help debugging */
522 case NAME_QUERY_DOM_SRV_CHK : DEBUG(4,("NAME_QUERY_DOM_SRV_CHK\n")); break;
523 case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
524 case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
525 case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
526 case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
527 case NAME_QUERY_SYNC_LOCAL : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
528 case NAME_QUERY_SYNC_REMOTE : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
529 case NAME_QUERY_DOMAIN : DEBUG(4,("NAME_QUERY_DOMAIN\n")); break;
531 case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
532 case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
534 case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
536 case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STATUS_DOM_SRV_CHK\n")); break;
537 case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
543 /****************************************************************************
544 report any problems with the fact that a response has been received.
546 (responses for certain types of operations are only expected from one host)
547 ****************************************************************************/
548 static BOOL response_problem_check(struct response_record *n,
549 struct nmb_packet *nmb, char *ans_name)
551 switch (nmb->answers->rr_type)
557 DEBUG(1,("more than one release name response received!\n"));
567 DEBUG(1,("more than one register name response received!\n"));
577 if (nmb->header.rcode == 0 && nmb->answers->rdata)
579 int nb_flags = nmb->answers->rdata[0];
581 if ((!NAME_GROUP(nb_flags)))
583 /* oh dear. more than one person responded to a
585 there is either a network problem, a
586 configuration problem
587 or a server is mis-behaving */
589 /* XXXX mark the name as in conflict, and then let the
590 person who just responded know that they
592 as in conflict, and therefore must NOT use it.
593 see rfc1001.txt 15.1.3.5 */
595 /* this may cause problems for some
596 early versions of nmbd */
600 case NAME_QUERY_FIND_MST:
602 /* query for ^1^2__MSBROWSE__^2^1 expect
606 case NAME_QUERY_DOM_SRV_CHK:
607 case NAME_QUERY_SRV_CHK:
608 case NAME_QUERY_MST_CHK:
610 if (!strequal(ans_name,n->name.name))
612 /* one subnet, one master browser
614 /* XXXX force an election? */
616 DEBUG(3,("more than one master browser replied!\n"));
623 DEBUG(3,("Unique Name conflict detected!\n"));
629 /* we have received a negative reply,
630 having already received
631 at least one response (pos/neg).
632 something's really wrong! */
634 DEBUG(3,("wierd name query problem detected!\n"));
644 /****************************************************************************
645 check that the response received is compatible with the response record
646 ****************************************************************************/
647 static BOOL response_compatible(struct response_record *n,
648 struct nmb_packet *nmb)
654 if (nmb->answers->rr_type != 0x20)
656 DEBUG(1,("Name release reply has wrong answer rr_type\n"));
664 if (nmb->answers->rr_type != 0x20)
666 DEBUG(1,("Name register reply has wrong answer rr_type\n"));
672 case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
673 case NAME_QUERY_CONFIRM:
674 case NAME_QUERY_SYNC_LOCAL:
675 case NAME_QUERY_SYNC_REMOTE:
676 case NAME_QUERY_DOM_SRV_CHK:
677 case NAME_QUERY_SRV_CHK:
678 case NAME_QUERY_FIND_MST:
679 case NAME_QUERY_MST_CHK:
681 if (nmb->answers->rr_type != 0x20)
683 DEBUG(1,("Name query reply has wrong answer rr_type\n"));
689 case NAME_STATUS_DOM_SRV_CHK:
690 case NAME_STATUS_SRV_CHK:
692 if (nmb->answers->rr_type != 0x21)
694 DEBUG(1,("Name status reply has wrong answer rr_type\n"));
702 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
711 /****************************************************************************
712 process the response packet received
713 ****************************************************************************/
714 static void response_process(struct subnet_record *d, struct packet_struct *p,
715 struct response_record *n, struct nmb_packet *nmb,
716 BOOL bcast, struct nmb_name *ans_name)
722 response_name_release(ans_name, d, p);
728 response_name_reg(ans_name, d, p);
732 case NAME_REGISTER_CHALLENGE:
734 response_name_query_register(nmb, ans_name, n, d);
738 case NAME_QUERY_DOM_SRV_CHK:
739 case NAME_QUERY_SRV_CHK:
740 case NAME_QUERY_FIND_MST:
742 response_server_check(ans_name, n, d, p);
746 case NAME_STATUS_DOM_SRV_CHK:
747 case NAME_STATUS_SRV_CHK:
749 response_name_status_check(p->ip, nmb, bcast, n, d);
753 case NAME_QUERY_CONFIRM:
754 case NAME_QUERY_SYNC_LOCAL:
755 case NAME_QUERY_SYNC_REMOTE:
757 response_name_query_sync(nmb, ans_name, bcast, n, d);
760 case NAME_QUERY_MST_CHK:
762 /* no action required here. it's when NO responses are received
763 that we need to do something. see expire_name_query_entries() */
765 DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
766 namestr(&n->name), inet_ntoa(n->send_ip)));
770 case NAME_QUERY_DOMAIN:
772 /* We were asking to be a domain master browser, and someone
773 replied. If it was the WINS server and the IP it is
774 returning is our own - then remove the record and pretend
775 we didn't get a response. Else we do nothing and let
776 dead_netbios_entry deal with it.
777 We can only become domain master browser
778 when no broadcast responses are received and WINS
779 either contains no entry for the DOMAIN<1b> name or
780 contains our IP address.
782 response_name_query_domain(ans_name, nmb, n, d);
787 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
794 /****************************************************************************
795 response from a netbios packet.
796 ****************************************************************************/
797 void response_netbios_packet(struct packet_struct *p)
799 struct nmb_packet *nmb = &p->packet.nmb;
800 struct nmb_name *ans_name = NULL;
801 BOOL bcast = nmb->header.nm_flags.bcast;
802 struct response_record *n;
803 struct subnet_record *d = NULL;
805 if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
806 DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
812 DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
816 /* args wrong way round: spotted by ccm@shentel.net */
817 if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
819 DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
820 DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
823 if (nmb->answers == NULL)
825 /* hm. the packet received was a response, but with no answer. wierd! */
826 DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
827 inet_ntoa(p->ip), BOOLSTR(bcast)));
831 ans_name = &nmb->answers->rr_name;
832 DEBUG(3,("response for %s from %s (bcast=%s)\n",
833 namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
835 debug_rr_type(nmb->answers->rr_type);
837 n->num_msgs++; /* count number of responses received */
838 n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
840 debug_state_type(n->state);
842 /* problem checking: multiple responses etc */
843 if (response_problem_check(n, nmb, ans_name->name))
846 /* now deal with the current state */
847 response_process(d, p, n, nmb, bcast, ans_name);