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-1998
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 extern fstring global_myworkgroup;
32 /****************************************************************************
33 Send a name release response.
34 **************************************************************************/
36 static void send_name_release_response(int rcode, struct packet_struct *p)
38 struct nmb_packet *nmb = &p->packet.nmb;
41 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
43 reply_netbios_packet(p, /* Packet to reply to. */
44 rcode, /* Result code. */
45 NMB_REL, /* nmbd type code. */
46 NMB_NAME_RELEASE_OPCODE, /* opcode. */
48 rdata, /* data to send. */
49 6); /* data length. */
52 /****************************************************************************
53 Process a name release packet on a broadcast subnet.
54 Ignore it if it's not one of our names.
55 ****************************************************************************/
57 void process_name_release_request(struct subnet_record *subrec,
58 struct packet_struct *p)
60 struct nmb_packet *nmb = &p->packet.nmb;
61 struct in_addr owner_ip;
62 struct nmb_name *question = &nmb->question.question_name;
63 BOOL bcast = nmb->header.nm_flags.bcast;
64 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
65 BOOL group = (nb_flags & NB_GROUP) ? True : False;
66 struct name_record *namerec;
69 putip((char *)&owner_ip,&nmb->additional->rdata[2]);
73 /* We should only get broadcast name release packets here.
74 Anyone trying to release unicast should be going to a WINS
75 server. If the code gets here, then either we are not a wins
76 server and they sent it anyway, or we are a WINS server and
77 the request was malformed. Either way, log an error here.
78 and send an error reply back.
80 DEBUG(0,("process_name_release_request: unicast name release request \
81 received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
82 nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
84 send_name_release_response(FMT_ERR, p);
88 DEBUG(3,("process_name_release_request: Name release on name %s, \
89 subnet %s from owner IP %s\n",
90 nmb_namestr(&nmb->question.question_name),
91 subrec->subnet_name, inet_ntoa(owner_ip)));
93 /* If someone is releasing a broadcast group name, just ignore it. */
94 if( group && !ismyip(owner_ip) )
98 * Code to work around a bug in FTP OnNet software NBT implementation.
99 * They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e>
100 * names and *don't set the group bit* !!!!!
103 if( !group && !ismyip(owner_ip) && strequal(question->name, global_myworkgroup) &&
104 ((question->name_type == 0x0) || (question->name_type == 0x1e)))
106 DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
107 group release name %s from IP %s on subnet %s with no group bit set.\n",
108 nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
112 namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_ANY_NAME);
114 /* We only care about someone trying to release one of our names. */
116 && ( (namerec->data.source == SELF_NAME)
117 || (namerec->data.source == PERMANENT_NAME) ) )
120 DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
121 on subnet %s being rejected as it is one of our names.\n",
122 nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
128 /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
129 send_name_release_response(rcode, p);
132 /****************************************************************************
133 Send a name registration response.
134 **************************************************************************/
136 static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p)
138 struct nmb_packet *nmb = &p->packet.nmb;
141 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
143 reply_netbios_packet(p, /* Packet to reply to. */
144 rcode, /* Result code. */
145 NMB_REG, /* nmbd type code. */
146 NMB_NAME_REG_OPCODE, /* opcode. */
148 rdata, /* data to send. */
149 6); /* data length. */
152 /****************************************************************************
153 Process a name refresh request on a broadcast subnet.
154 **************************************************************************/
156 void process_name_refresh_request(struct subnet_record *subrec,
157 struct packet_struct *p)
160 struct nmb_packet *nmb = &p->packet.nmb;
161 struct nmb_name *question = &nmb->question.question_name;
162 BOOL bcast = nmb->header.nm_flags.bcast;
163 struct in_addr from_ip;
165 putip((char *)&from_ip,&nmb->additional->rdata[2]);
169 /* We should only get broadcast name refresh packets here.
170 Anyone trying to refresh unicast should be going to a WINS
171 server. If the code gets here, then either we are not a wins
172 server and they sent it anyway, or we are a WINS server and
173 the request was malformed. Either way, log an error here.
174 and send an error reply back.
176 DEBUG(0,("process_name_refresh_request: unicast name registration request \
177 received for name %s from IP %s on subnet %s.\n",
178 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
179 DEBUG(0,("Error - should be sent to WINS server\n"));
181 send_name_registration_response(FMT_ERR, 0, p);
185 /* Just log a message. We really don't care about broadcast name
188 DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
189 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
193 /****************************************************************************
194 Process a name registration request on a broadcast subnet.
195 **************************************************************************/
197 void process_name_registration_request(struct subnet_record *subrec,
198 struct packet_struct *p)
200 struct nmb_packet *nmb = &p->packet.nmb;
201 struct nmb_name *question = &nmb->question.question_name;
202 BOOL bcast = nmb->header.nm_flags.bcast;
203 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
204 BOOL group = (nb_flags & NB_GROUP) ? True : False;
205 struct name_record *namerec = NULL;
206 int ttl = nmb->additional->ttl;
207 struct in_addr from_ip;
209 putip((char *)&from_ip,&nmb->additional->rdata[2]);
213 /* We should only get broadcast name registration packets here.
214 Anyone trying to register unicast should be going to a WINS
215 server. If the code gets here, then either we are not a wins
216 server and they sent it anyway, or we are a WINS server and
217 the request was malformed. Either way, log an error here.
218 and send an error reply back.
220 DEBUG(0,("process_name_registration_request: unicast name registration request \
221 received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
222 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
224 send_name_registration_response(FMT_ERR, 0, p);
228 DEBUG(3,("process_name_registration_request: Name registration for name %s \
229 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
231 /* See if the name already exists. */
232 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
235 * If the name being registered exists and is a WINS_PROXY_NAME
236 * then delete the WINS proxy name entry so we don't reply erroneously
240 if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
242 remove_name_from_namelist( subrec, namerec );
250 if( (namerec != NULL)
251 && ( (namerec->data.source == SELF_NAME)
252 || (namerec->data.source == PERMANENT_NAME)
253 || NAME_GROUP(namerec) ) )
255 /* No-one can register one of Samba's names, nor can they
256 register a name that's a group name as a unique name */
258 send_name_registration_response(ACT_ERR, 0, p);
261 else if(namerec != NULL)
263 /* Update the namelist record with the new information. */
264 namerec->data.ip[0] = from_ip;
265 update_name_ttl(namerec, ttl);
267 DEBUG(3,("process_name_registration_request: Updated name record %s \
268 with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
276 if( (namerec != NULL)
277 && !NAME_GROUP(namerec)
278 && ( (namerec->data.source == SELF_NAME)
279 || (namerec->data.source == PERMANENT_NAME) ) )
281 /* Disallow group names when we have a unique name. */
282 send_name_registration_response(ACT_ERR, 0, p);
288 /****************************************************************************
289 This is used to sort names for a name status into a sensible order.
290 We put our own names first, then in alphabetical order.
291 **************************************************************************/
293 static int status_compare(char *n1,char *n2)
295 extern pstring global_myname;
298 /* It's a bit tricky because the names are space padded */
299 for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) ;
300 for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) ;
301 l3 = strlen(global_myname);
303 if ((l1==l3) && strncmp(n1,global_myname,l3) == 0 &&
304 (l2!=l3 || strncmp(n2,global_myname,l3) != 0))
307 if ((l2==l3) && strncmp(n2,global_myname,l3) == 0 &&
308 (l1!=l3 || strncmp(n1,global_myname,l3) != 0))
311 return memcmp(n1,n2,18);
315 /****************************************************************************
316 Process a node status query
317 ****************************************************************************/
319 void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p)
321 struct nmb_packet *nmb = &p->packet.nmb;
322 char *qname = nmb->question.question_name.name;
323 int ques_type = nmb->question.question_name.name_type;
324 char rdata[MAX_DGRAM_SIZE];
325 char *countptr, *buf, *bufend, *buf0;
327 struct name_record *namerec;
329 DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
330 subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip),
331 subrec->subnet_name));
333 if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name,
334 FIND_SELF_NAME)) == 0)
336 DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
337 subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
338 inet_ntoa(p->ip), subrec->subnet_name));
343 /* this is not an exact calculation. the 46 is for the stats buffer
344 and the 60 is to leave room for the header etc */
345 bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
346 countptr = buf = rdata;
352 namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
356 if( (namerec->data.source == SELF_NAME)
357 || (namerec->data.source == PERMANENT_NAME) )
359 int name_type = namerec->name.name_type;
361 if (!strequal(namerec->name.name,"*") &&
362 !strequal(namerec->name.name,"__SAMBA__") &&
363 (name_type < 0x1b || name_type >= 0x20 ||
364 ques_type < 0x1b || ques_type >= 0x20 ||
365 strequal(qname, namerec->name.name)))
367 /* Start with the name. */
369 slprintf(buf, 17, "%-15.15s",namerec->name.name);
372 /* Put the name type and netbios flags in the buffer. */
374 set_nb_flags( &buf[16],namerec->data.nb_flags );
375 buf[16] |= NB_ACTIVE; /* all our names are active */
383 /* Remove duplicate names. */
384 if (names_added > 1) {
385 qsort( buf0, names_added, 18, QSORT_CAST status_compare );
388 for( i=1; i < names_added ; i++ )
390 if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0)
393 if (names_added == i)
395 memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
400 buf = buf0 + 18*names_added;
402 namerec = (struct name_record *)ubi_trNext( namerec );
406 /* End of the subnet specific name list. Now
407 add the names on the unicast subnet . */
408 struct subnet_record *uni_subrec = unicast_subnet;
410 if (uni_subrec != subrec)
413 namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
421 SCVAL(countptr,0,names_added);
423 /* We don't send any stats as they could be used to attack
429 /* Send a NODE STATUS RESPONSE */
430 reply_netbios_packet(p, /* Packet to reply to. */
431 0, /* Result code. */
432 NMB_STATUS, /* nmbd type code. */
433 NMB_NAME_QUERY_OPCODE, /* opcode. */
435 rdata, /* data to send. */
436 PTR_DIFF(buf,rdata)); /* data length. */
440 /***************************************************************************
441 Process a name query.
443 For broadcast name queries:
445 - Only reply if the query is for one of YOUR names.
446 - NEVER send a negative response to a broadcast query.
448 ****************************************************************************/
450 void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
452 struct nmb_packet *nmb = &p->packet.nmb;
453 struct nmb_name *question = &nmb->question.question_name;
454 int name_type = question->name_type;
455 BOOL bcast = nmb->header.nm_flags.bcast;
460 BOOL success = False;
461 struct name_record *namerec = NULL;
462 int reply_data_len = 0;
465 DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n",
466 inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
468 /* Look up the name in the cache - if the request is a broadcast request that
469 came from a subnet we don't know about then search all the broadcast subnets
470 for a match (as we don't know what interface the request came in on). */
472 if(subrec == remote_broadcast_subnet)
473 namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
475 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
478 /* Check if it is a name that expired */
480 && ( (namerec->data.death_time != PERMANENT_TTL)
481 && (namerec->data.death_time < p->timestamp) ) )
483 DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
491 * Always respond to unicast queries.
492 * Don't respond to broadcast queries unless the query is for
493 * a name we own, a Primary Domain Controller name, or a WINS_PROXY
494 * name with type 0 or 0x20. WINS_PROXY names are only ever added
495 * into the namelist if we were configured as a WINS proxy.
500 && ( (name_type == 0x1b)
501 || (namerec->data.source == SELF_NAME)
502 || (namerec->data.source == PERMANENT_NAME)
503 || ( (namerec->data.source == WINS_PROXY_NAME)
504 && ( (name_type == 0) || (name_type == 0x20) )
511 /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY,
512 or it's a Domain Master type. */
515 * If this is a WINS_PROXY_NAME, then ceck that none of the IP
516 * addresses we are returning is on the same broadcast subnet
517 * as the requesting packet. If it is then don't reply as the
518 * actual machine will be replying also and we don't want two
519 * replies to a broadcast query.
522 if( namerec->data.source == WINS_PROXY_NAME )
524 for( i = 0; i < namerec->data.num_ips; i++)
526 if(same_net( namerec->data.ip[i], subrec->myip, subrec->mask_ip ))
528 DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also \
529 on the same subnet (%s) as the requestor. Not replying.\n",
530 nmb_namestr(&namerec->name), subrec->subnet_name ));
536 ttl = (namerec->data.death_time != PERMANENT_TTL) ?
537 namerec->data.death_time - p->timestamp : lp_max_ttl();
539 /* Copy all known ip addresses into the return data. */
540 /* Optimise for the common case of one IP address so
541 we don't need a malloc. */
543 if( namerec->data.num_ips == 1 )
547 if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
549 DEBUG(0,("process_name_query_request: malloc fail !\n"));
554 for( i = 0; i < namerec->data.num_ips; i++ )
556 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
557 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
560 sort_query_replies(prdata, i, p->ip);
562 reply_data_len = namerec->data.num_ips * 6;
568 * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
569 * set we should initiate a WINS query here. On success we add the resolved name
570 * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
573 if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() &&
574 bcast && (subrec != remote_broadcast_subnet))
576 make_wins_proxy_name_query_request( subrec, p, question );
580 if (!success && bcast)
584 return; /* Never reply with a negative response to broadcasts. */
588 * Final check. From observation, if a unicast packet is sent
589 * to a non-WINS server with the recursion desired bit set
590 * then never send a negative response.
593 if(!success && !bcast && nmb->header.nm_flags.recursion_desired)
608 DEBUG(3,("UNKNOWN\n"));
611 /* See rfc1002.txt 4.2.13. */
613 reply_netbios_packet(p, /* Packet to reply to. */
614 rcode, /* Result code. */
615 NMB_QUERY, /* nmbd type code. */
616 NMB_NAME_QUERY_OPCODE, /* opcode. */
618 prdata, /* data to send. */
619 reply_data_len); /* data length. */