2
Unix SMB/CIFS implementation.
3
NBT netbios routines and daemon - version 2
4
Copyright (C) Andrew Tridgell 1994-1998
5
Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6
Copyright (C) Jeremy Allison 1994-2003
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
This file contains all the code to process NetBIOS requests coming
23
in on port 137. It does not deal with the code needed to service
24
WINS server requests, but only broadcast and unicast requests.
30
/****************************************************************************
31
Send a name release response.
32
**************************************************************************/
34
static void send_name_release_response(int rcode, struct packet_struct *p)
36
struct nmb_packet *nmb = &p->packet.nmb;
39
memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
41
reply_netbios_packet(p, /* Packet to reply to. */
42
rcode, /* Result code. */
43
NMB_REL, /* nmbd type code. */
44
NMB_NAME_RELEASE_OPCODE, /* opcode. */
46
rdata, /* data to send. */
47
6); /* data length. */
50
/****************************************************************************
51
Process a name release packet on a broadcast subnet.
52
Ignore it if it's not one of our names.
53
****************************************************************************/
55
void process_name_release_request(struct subnet_record *subrec,
56
struct packet_struct *p)
58
struct nmb_packet *nmb = &p->packet.nmb;
59
struct in_addr owner_ip;
60
struct nmb_name *question = &nmb->question.question_name;
62
BOOL bcast = nmb->header.nm_flags.bcast;
63
uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
64
BOOL group = (nb_flags & NB_GROUP) ? True : False;
65
struct name_record *namerec;
68
putip((char *)&owner_ip,&nmb->additional->rdata[2]);
71
/* We should only get broadcast name release packets here.
72
Anyone trying to release unicast should be going to a WINS
73
server. If the code gets here, then either we are not a wins
74
server and they sent it anyway, or we are a WINS server and
75
the request was malformed. Either way, log an error here.
76
and send an error reply back.
78
DEBUG(0,("process_name_release_request: unicast name release request \
79
received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
80
nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
82
send_name_release_response(FMT_ERR, p);
86
DEBUG(3,("process_name_release_request: Name release on name %s, \
87
subnet %s from owner IP %s\n",
88
nmb_namestr(&nmb->question.question_name),
89
subrec->subnet_name, inet_ntoa(owner_ip)));
91
/* If someone is releasing a broadcast group name, just ignore it. */
92
if( group && !ismyip(owner_ip) )
96
* Code to work around a bug in FTP OnNet software NBT implementation.
97
* They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e>
98
* names and *don't set the group bit* !!!!!
101
pull_ascii_nstring(qname, sizeof(qname), question->name);
102
if( !group && !ismyip(owner_ip) && strequal(qname, lp_workgroup()) &&
103
((question->name_type == 0x0) || (question->name_type == 0x1e))) {
104
DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
105
group release name %s from IP %s on subnet %s with no group bit set.\n",
106
nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
110
namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
112
/* We only care about someone trying to release one of our names. */
113
if( namerec && ( (namerec->data.source == SELF_NAME)
114
|| (namerec->data.source == PERMANENT_NAME) ) ) {
116
DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
117
on subnet %s being rejected as it is one of our names.\n",
118
nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
124
/* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
125
send_name_release_response(rcode, p);
128
/****************************************************************************
129
Send a name registration response.
130
**************************************************************************/
132
static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p)
134
struct nmb_packet *nmb = &p->packet.nmb;
137
memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
139
reply_netbios_packet(p, /* Packet to reply to. */
140
rcode, /* Result code. */
141
NMB_REG, /* nmbd type code. */
142
NMB_NAME_REG_OPCODE, /* opcode. */
144
rdata, /* data to send. */
145
6); /* data length. */
148
/****************************************************************************
149
Process a name refresh request on a broadcast subnet.
150
**************************************************************************/
152
void process_name_refresh_request(struct subnet_record *subrec,
153
struct packet_struct *p)
155
struct nmb_packet *nmb = &p->packet.nmb;
156
struct nmb_name *question = &nmb->question.question_name;
157
BOOL bcast = nmb->header.nm_flags.bcast;
158
struct in_addr from_ip;
160
putip((char *)&from_ip,&nmb->additional->rdata[2]);
163
/* We should only get broadcast name refresh packets here.
164
Anyone trying to refresh unicast should be going to a WINS
165
server. If the code gets here, then either we are not a wins
166
server and they sent it anyway, or we are a WINS server and
167
the request was malformed. Either way, log an error here.
168
and send an error reply back.
170
DEBUG(0,("process_name_refresh_request: unicast name registration request \
171
received for name %s from IP %s on subnet %s.\n",
172
nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
173
DEBUG(0,("Error - should be sent to WINS server\n"));
175
send_name_registration_response(FMT_ERR, 0, p);
179
/* Just log a message. We really don't care about broadcast name refreshes. */
181
DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
182
IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
185
/****************************************************************************
186
Process a name registration request on a broadcast subnet.
187
**************************************************************************/
189
void process_name_registration_request(struct subnet_record *subrec,
190
struct packet_struct *p)
192
struct nmb_packet *nmb = &p->packet.nmb;
193
struct nmb_name *question = &nmb->question.question_name;
194
BOOL bcast = nmb->header.nm_flags.bcast;
195
uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
196
BOOL group = (nb_flags & NB_GROUP) ? True : False;
197
struct name_record *namerec = NULL;
198
int ttl = nmb->additional->ttl;
199
struct in_addr from_ip;
201
putip((char *)&from_ip,&nmb->additional->rdata[2]);
204
/* We should only get broadcast name registration packets here.
205
Anyone trying to register unicast should be going to a WINS
206
server. If the code gets here, then either we are not a wins
207
server and they sent it anyway, or we are a WINS server and
208
the request was malformed. Either way, log an error here.
209
and send an error reply back.
211
DEBUG(0,("process_name_registration_request: unicast name registration request \
212
received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
213
nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
215
send_name_registration_response(FMT_ERR, 0, p);
219
DEBUG(3,("process_name_registration_request: Name registration for name %s \
220
IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
222
/* See if the name already exists. */
223
namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
226
* If the name being registered exists and is a WINS_PROXY_NAME
227
* then delete the WINS proxy name entry so we don't reply erroneously
231
if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME)) {
232
remove_name_from_namelist( subrec, namerec );
239
if( (namerec != NULL)
240
&& ( (namerec->data.source == SELF_NAME)
241
|| (namerec->data.source == PERMANENT_NAME)
242
|| NAME_GROUP(namerec) ) ) {
243
/* No-one can register one of Samba's names, nor can they
244
register a name that's a group name as a unique name */
246
send_name_registration_response(ACT_ERR, 0, p);
248
} else if(namerec != NULL) {
249
/* Update the namelist record with the new information. */
250
namerec->data.ip[0] = from_ip;
251
update_name_ttl(namerec, ttl);
253
DEBUG(3,("process_name_registration_request: Updated name record %s \
254
with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
260
if( (namerec != NULL)
261
&& !NAME_GROUP(namerec)
262
&& ( (namerec->data.source == SELF_NAME)
263
|| (namerec->data.source == PERMANENT_NAME) ) ) {
264
/* Disallow group names when we have a unique name. */
265
send_name_registration_response(ACT_ERR, 0, p);
271
/****************************************************************************
272
This is used to sort names for a name status into a sensible order.
273
We put our own names first, then in alphabetical order.
274
**************************************************************************/
276
static int status_compare(char *n1,char *n2)
278
unstring name1, name2;
281
memset(name1, '\0', sizeof(name1));
282
memset(name2, '\0', sizeof(name2));
283
pull_ascii_nstring(name1, sizeof(name1), n1);
284
pull_ascii_nstring(name2, sizeof(name2), n2);
288
/* It's a bit tricky because the names are space padded */
289
for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++)
291
for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++)
293
l3 = strlen(global_myname());
295
if ((l1==l3) && strncmp(n1,global_myname(),l3) == 0 &&
296
(l2!=l3 || strncmp(n2,global_myname(),l3) != 0))
299
if ((l2==l3) && strncmp(n2,global_myname(),l3) == 0 &&
300
(l1!=l3 || strncmp(n1,global_myname(),l3) != 0))
303
return memcmp(n1,n2,sizeof(name1));
306
/****************************************************************************
307
Process a node status query
308
****************************************************************************/
310
void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p)
312
struct nmb_packet *nmb = &p->packet.nmb;
314
int ques_type = nmb->question.question_name.name_type;
315
char rdata[MAX_DGRAM_SIZE];
316
char *countptr, *buf, *bufend, *buf0;
318
struct name_record *namerec;
320
pull_ascii_nstring(qname, sizeof(qname), nmb->question.question_name.name);
322
DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
323
subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip), subrec->subnet_name));
325
if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_SELF_NAME)) == 0) {
326
DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
327
subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
328
inet_ntoa(p->ip), subrec->subnet_name));
333
/* this is not an exact calculation. the 46 is for the stats buffer
334
and the 60 is to leave room for the header etc */
335
bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
336
countptr = buf = rdata;
342
namerec = subrec->namelist;
344
while (buf < bufend) {
345
if( (namerec->data.source == SELF_NAME) || (namerec->data.source == PERMANENT_NAME) ) {
346
int name_type = namerec->name.name_type;
349
pull_ascii_nstring(name, sizeof(name), namerec->name.name);
351
if (!strequal(name,"*") &&
352
!strequal(name,"__SAMBA__") &&
353
(name_type < 0x1b || name_type >= 0x20 ||
354
ques_type < 0x1b || ques_type >= 0x20 ||
355
strequal(qname, name))) {
356
/* Start with the name. */
358
push_ascii_nstring(buf, name);
360
memset(buf + len, ' ', MAX_NETBIOSNAME_LEN - len - 1);
361
buf[MAX_NETBIOSNAME_LEN - 1] = '\0';
363
/* Put the name type and netbios flags in the buffer. */
366
set_nb_flags( &buf[16],namerec->data.nb_flags );
367
buf[16] |= NB_ACTIVE; /* all our names are active */
375
/* Remove duplicate names. */
376
if (names_added > 1) {
377
qsort( buf0, names_added, 18, QSORT_CAST status_compare );
380
for( i=1; i < names_added ; i++ ) {
381
if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0) {
383
if (names_added == i)
385
memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
390
buf = buf0 + 18*names_added;
392
namerec = namerec->next;
395
/* End of the subnet specific name list. Now
396
add the names on the unicast subnet . */
397
struct subnet_record *uni_subrec = unicast_subnet;
399
if (uni_subrec != subrec) {
401
namerec = subrec->namelist;
409
SCVAL(countptr,0,names_added);
411
/* We don't send any stats as they could be used to attack
417
/* Send a NODE STATUS RESPONSE */
418
reply_netbios_packet(p, /* Packet to reply to. */
419
0, /* Result code. */
420
NMB_STATUS, /* nmbd type code. */
421
NMB_NAME_QUERY_OPCODE, /* opcode. */
423
rdata, /* data to send. */
424
PTR_DIFF(buf,rdata)); /* data length. */
428
/***************************************************************************
429
Process a name query.
431
For broadcast name queries:
433
- Only reply if the query is for one of YOUR names.
434
- NEVER send a negative response to a broadcast query.
436
****************************************************************************/
438
void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
440
struct nmb_packet *nmb = &p->packet.nmb;
441
struct nmb_name *question = &nmb->question.question_name;
442
int name_type = question->name_type;
443
BOOL bcast = nmb->header.nm_flags.bcast;
448
BOOL success = False;
449
struct name_record *namerec = NULL;
450
int reply_data_len = 0;
453
DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n",
454
inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
456
/* Look up the name in the cache - if the request is a broadcast request that
457
came from a subnet we don't know about then search all the broadcast subnets
458
for a match (as we don't know what interface the request came in on). */
460
if(subrec == remote_broadcast_subnet)
461
namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
463
namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
465
/* Check if it is a name that expired */
467
((namerec->data.death_time != PERMANENT_TTL) &&
468
(namerec->data.death_time < p->timestamp))) {
469
DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
475
* Always respond to unicast queries.
476
* Don't respond to broadcast queries unless the query is for
477
* a name we own, a Primary Domain Controller name, or a WINS_PROXY
478
* name with type 0 or 0x20. WINS_PROXY names are only ever added
479
* into the namelist if we were configured as a WINS proxy.
483
(bcast && ((name_type == 0x1b) ||
484
(namerec->data.source == SELF_NAME) ||
485
(namerec->data.source == PERMANENT_NAME) ||
486
((namerec->data.source == WINS_PROXY_NAME) &&
487
((name_type == 0) || (name_type == 0x20)))))) {
488
/* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY,
489
or it's a Domain Master type. */
492
* If this is a WINS_PROXY_NAME, then ceck that none of the IP
493
* addresses we are returning is on the same broadcast subnet
494
* as the requesting packet. If it is then don't reply as the
495
* actual machine will be replying also and we don't want two
496
* replies to a broadcast query.
499
if (namerec->data.source == WINS_PROXY_NAME) {
500
for( i = 0; i < namerec->data.num_ips; i++) {
501
if (same_net(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) {
502
DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also on the same subnet (%s) as the requestor. Not replying.\n",
503
nmb_namestr(&namerec->name), subrec->subnet_name ));
509
ttl = (namerec->data.death_time != PERMANENT_TTL) ?
510
namerec->data.death_time - p->timestamp : lp_max_ttl();
512
/* Copy all known ip addresses into the return data. */
513
/* Optimise for the common case of one IP address so
514
we don't need a malloc. */
516
if (namerec->data.num_ips == 1) {
519
if ((prdata = (char *)SMB_MALLOC( namerec->data.num_ips * 6 )) == NULL) {
520
DEBUG(0,("process_name_query_request: malloc fail !\n"));
525
for (i = 0; i < namerec->data.num_ips; i++) {
526
set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
527
putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
530
sort_query_replies(prdata, i, p->ip);
532
reply_data_len = namerec->data.num_ips * 6;
538
* If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
539
* set we should initiate a WINS query here. On success we add the resolved name
540
* into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
543
if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() &&
544
bcast && (subrec != remote_broadcast_subnet)) {
545
make_wins_proxy_name_query_request( subrec, p, question );
549
if (!success && bcast) {
552
return; /* Never reply with a negative response to broadcasts. */
556
* Final check. From observation, if a unicast packet is sent
557
* to a non-WINS server with the recursion desired bit set
558
* then never send a negative response.
561
if(!success && !bcast && nmb->header.nm_flags.recursion_desired) {
572
DEBUG(3,("UNKNOWN\n"));
575
/* See rfc1002.txt 4.2.13. */
577
reply_netbios_packet(p, /* Packet to reply to. */
578
rcode, /* Result code. */
579
NMB_QUERY, /* nmbd type code. */
580
NMB_NAME_QUERY_OPCODE, /* opcode. */
582
prdata, /* data to send. */
583
reply_data_len); /* data length. */