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 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 */
68 name_unregister_work(d
,name
,type
);
72 DEBUG(2,("name release for different ip! %s %s\n",
74 namestr(&nmb
->question
.question_name
)));
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
);
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
,
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);
159 DEBUG(level
,("received %d names\n",numnames
));
163 if (serv_name
) *serv_name
= 0;
180 trim_string(qname
,NULL
," ");
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 */
197 struct in_addr nameip
;
198 enum name_source src
;
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);
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
))
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)));
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
;
252 if (interpret_node_status(d
,nmb
->answers
->rdata
,
253 &name
,name
.name_type
,serv_name
,ip
,bcast
))
257 sync_server(n
->state
,serv_name
,
258 name
.name
,name
.name_type
, n
->send_ip
);
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
;
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
)));
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
));
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
)));
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
;
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
;
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
)));
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
)));
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
,
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
);
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
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
)
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 */
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;
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
)
471 DEBUG(1,("more than one release name response received!\n"));
481 DEBUG(1,("more than one register name response received!\n"));
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 */
510 case NAME_QUERY_FIND_MST
:
512 /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
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"));
531 DEBUG(3,("Unique Name conflict detected!\n"));
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"));
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
)
559 if (nmb
->answers
->rr_type
!= NMB_REL
)
561 DEBUG(1,("Name release reply has wrong answer rr_type\n"));
569 if (nmb
->answers
->rr_type
!= NMB_REG
)
571 DEBUG(1,("Name register reply has wrong answer rr_type\n"));
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"));
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"));
606 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
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
)
625 response_name_release(d
, p
);
631 response_name_reg(d
, p
);
635 case NAME_REGISTER_CHALLENGE
:
637 response_name_query_register(nmb
, ans_name
, n
, d
);
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
);
649 case NAME_STATUS_PDC_SRV_CHK
:
650 case NAME_STATUS_SRV_CHK
:
652 response_name_status_check(p
->ip
, nmb
, bcast
, n
, d
);
656 case NAME_QUERY_CONFIRM
:
657 case NAME_QUERY_SYNC
:
659 response_name_query_sync(nmb
, ans_name
, bcast
, n
, d
);
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
)));
674 DEBUG(1,("unknown state type received in response_netbios_packet\n"));
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"));
701 DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p
->ip
)));
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
)));
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
)));
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
))
735 /* now check whether the 'state' has received the correct type of response */
736 if (!response_compatible(n
, nmb
))
739 /* now deal with the current state */
740 response_process(d
, p
, n
, nmb
, bcast
, ans_name
);