2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1998
6 Copyright (C) Luke Kenneth Casson Leighton 1994-1998
7 Copyright (C) Jeremy Allison 1994-1998
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 This file contains all the code to process NetBIOS requests coming
24 in on port 137. It does not deal with the code needed to service
25 WINS server requests, but only broadcast and unicast requests.
31 extern int DEBUGLEVEL;
32 extern fstring global_myworkgroup;
34 /****************************************************************************
35 Send a name release response.
36 **************************************************************************/
38 static void send_name_release_response(int rcode, struct packet_struct *p)
40 struct nmb_packet *nmb = &p->packet.nmb;
43 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
45 reply_netbios_packet(p, /* Packet to reply to. */
46 rcode, /* Result code. */
47 NMB_REL, /* nmbd type code. */
48 NMB_NAME_RELEASE_OPCODE, /* opcode. */
50 rdata, /* data to send. */
51 6); /* data length. */
54 /****************************************************************************
55 Process a name release packet on a broadcast subnet.
56 Ignore it if it's not one of our names.
57 ****************************************************************************/
59 void process_name_release_request(struct subnet_record *subrec,
60 struct packet_struct *p)
62 struct nmb_packet *nmb = &p->packet.nmb;
63 struct in_addr owner_ip;
64 struct nmb_name *question = &nmb->question.question_name;
65 BOOL bcast = nmb->header.nm_flags.bcast;
66 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
67 BOOL group = (nb_flags & NB_GROUP) ? True : False;
68 struct name_record *namerec;
71 putip((char *)&owner_ip,&nmb->additional->rdata[2]);
75 /* We should only get broadcast name release packets here.
76 Anyone trying to release unicast should be going to a WINS
77 server. If the code gets here, then either we are not a wins
78 server and they sent it anyway, or we are a WINS server and
79 the request was malformed. Either way, log an error here.
80 and send an error reply back.
82 DEBUG(0,("process_name_release_request: unicast name release request \
83 received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
84 nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
86 send_name_release_response(FMT_ERR, p);
90 DEBUG(3,("process_name_release_request: Name release on name %s, \
91 subnet %s from owner IP %s\n",
92 nmb_namestr(&nmb->question.question_name),
93 subrec->subnet_name, inet_ntoa(owner_ip)));
95 /* If someone is releasing a broadcast group name, just ignore it. */
96 if( group && !ismyip(owner_ip) )
100 * Code to work around a bug in FTP OnNet software NBT implementation.
101 * They do a broadcast name release for WORKGROUP<0> and WORKGROUP<1e>
102 * names and *don't set the group bit* !!!!!
105 if( !group && !ismyip(owner_ip) && strequal(question->name, global_myworkgroup) &&
106 ((question->name_type == 0x0) || (question->name_type == 0x1e)))
108 DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
109 group release name %s from IP %s on subnet %s with no group bit set.\n",
110 nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
114 namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_ANY_NAME);
116 /* We only care about someone trying to release one of our names. */
118 && ( (namerec->data.source == SELF_NAME)
119 || (namerec->data.source == PERMANENT_NAME) ) )
122 DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
123 on subnet %s being rejected as it is one of our names.\n",
124 nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
130 /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
131 send_name_release_response(rcode, p);
134 /****************************************************************************
135 Send a name registration response.
136 **************************************************************************/
138 static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p)
140 struct nmb_packet *nmb = &p->packet.nmb;
143 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
145 reply_netbios_packet(p, /* Packet to reply to. */
146 rcode, /* Result code. */
147 NMB_REG, /* nmbd type code. */
148 NMB_NAME_REG_OPCODE, /* opcode. */
150 rdata, /* data to send. */
151 6); /* data length. */
154 /****************************************************************************
155 Process a name refresh request on a broadcast subnet.
156 **************************************************************************/
158 void process_name_refresh_request(struct subnet_record *subrec,
159 struct packet_struct *p)
162 struct nmb_packet *nmb = &p->packet.nmb;
163 struct nmb_name *question = &nmb->question.question_name;
164 BOOL bcast = nmb->header.nm_flags.bcast;
165 struct in_addr from_ip;
167 putip((char *)&from_ip,&nmb->additional->rdata[2]);
171 /* We should only get broadcast name refresh packets here.
172 Anyone trying to refresh unicast should be going to a WINS
173 server. If the code gets here, then either we are not a wins
174 server and they sent it anyway, or we are a WINS server and
175 the request was malformed. Either way, log an error here.
176 and send an error reply back.
178 DEBUG(0,("process_name_refresh_request: unicast name registration request \
179 received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
180 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
182 send_name_registration_response(FMT_ERR, 0, p);
186 /* Just log a message. We really don't care about broadcast name
189 DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
190 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
194 /****************************************************************************
195 Process a name registration request on a broadcast subnet.
196 **************************************************************************/
198 void process_name_registration_request(struct subnet_record *subrec,
199 struct packet_struct *p)
201 struct nmb_packet *nmb = &p->packet.nmb;
202 struct nmb_name *question = &nmb->question.question_name;
203 BOOL bcast = nmb->header.nm_flags.bcast;
204 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
205 BOOL group = (nb_flags & NB_GROUP) ? True : False;
206 struct name_record *namerec = NULL;
207 int ttl = nmb->additional->ttl;
208 struct in_addr from_ip;
210 putip((char *)&from_ip,&nmb->additional->rdata[2]);
214 /* We should only get broadcast name registration packets here.
215 Anyone trying to register unicast should be going to a WINS
216 server. If the code gets here, then either we are not a wins
217 server and they sent it anyway, or we are a WINS server and
218 the request was malformed. Either way, log an error here.
219 and send an error reply back.
221 DEBUG(0,("process_name_registration_request: unicast name registration request \
222 received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
223 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
225 send_name_registration_response(FMT_ERR, 0, p);
229 DEBUG(3,("process_name_registration_request: Name registration for name %s \
230 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
232 /* See if the name already exists. */
233 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
236 * If the name being registered exists and is a WINS_PROXY_NAME
237 * then delete the WINS proxy name entry so we don't reply erroneously
241 if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
243 remove_name_from_namelist( subrec, namerec );
251 if( (namerec != NULL)
252 && ( (namerec->data.source == SELF_NAME)
253 || (namerec->data.source == PERMANENT_NAME)
254 || NAME_GROUP(namerec) ) )
256 /* No-one can register one of Samba's names, nor can they
257 register a name that's a group name as a unique name */
259 send_name_registration_response(ACT_ERR, 0, p);
262 else if(namerec != NULL)
264 /* Update the namelist record with the new information. */
265 namerec->data.ip[0] = from_ip;
266 update_name_ttl(namerec, ttl);
268 DEBUG(3,("process_name_registration_request: Updated name record %s \
269 with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
277 if( (namerec != NULL)
278 && !NAME_GROUP(namerec)
279 && ( (namerec->data.source == SELF_NAME)
280 || (namerec->data.source == PERMANENT_NAME) ) )
282 /* Disallow group names when we have a unique name. */
283 send_name_registration_response(ACT_ERR, 0, p);
289 /****************************************************************************
290 This is used to sort names for a name status into a sensible order.
291 We put our own names first, then in alphabetical order.
292 **************************************************************************/
294 static int status_compare(char *n1,char *n2)
296 extern pstring global_myname;
299 /* It's a bit tricky because the names are space padded */
300 for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) ;
301 for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) ;
302 l3 = strlen(global_myname);
304 if ((l1==l3) && strncmp(n1,global_myname,l3) == 0 &&
305 (l2!=l3 || strncmp(n2,global_myname,l3) != 0))
308 if ((l2==l3) && strncmp(n2,global_myname,l3) == 0 &&
309 (l1!=l3 || strncmp(n1,global_myname,l3) != 0))
312 return memcmp(n1,n2,18);
316 /****************************************************************************
317 Process a node status query
318 ****************************************************************************/
320 void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p)
322 struct nmb_packet *nmb = &p->packet.nmb;
323 char *qname = nmb->question.question_name.name;
324 int ques_type = nmb->question.question_name.name_type;
325 char rdata[MAX_DGRAM_SIZE];
326 char *countptr, *buf, *bufend, *buf0;
328 struct name_record *namerec;
330 DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
331 subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip),
332 subrec->subnet_name));
334 if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name,
335 FIND_SELF_NAME)) == 0)
337 DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
338 subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
339 inet_ntoa(p->ip), subrec->subnet_name));
344 /* this is not an exact calculation. the 46 is for the stats buffer
345 and the 60 is to leave room for the header etc */
346 bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
347 countptr = buf = rdata;
353 namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
357 if( (namerec->data.source == SELF_NAME)
358 || (namerec->data.source == PERMANENT_NAME) )
360 int name_type = namerec->name.name_type;
362 if (!strequal(namerec->name.name,"*") &&
363 !strequal(namerec->name.name,"__SAMBA__") &&
364 (name_type < 0x1b || name_type >= 0x20 ||
365 ques_type < 0x1b || ques_type >= 0x20 ||
366 strequal(qname, namerec->name.name)))
368 /* Start with the name. */
370 slprintf(buf, 17, "%-15.15s",namerec->name.name);
373 /* Put the name type and netbios flags in the buffer. */
375 set_nb_flags( &buf[16],namerec->data.nb_flags );
376 buf[16] |= NB_ACTIVE; /* all our names are active */
384 /* Remove duplicate names. */
385 qsort( buf0, names_added, 18, QSORT_CAST status_compare );
387 for( i=1; i < names_added ; i++ )
389 if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0)
392 if (names_added == i)
394 memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
399 buf = buf0 + 18*names_added;
401 namerec = (struct name_record *)ubi_trNext( namerec );
405 /* End of the subnet specific name list. Now
406 add the names on the unicast subnet . */
407 struct subnet_record *uni_subrec = unicast_subnet;
409 if (uni_subrec != subrec)
412 namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
420 SCVAL(countptr,0,names_added);
422 /* We don't send any stats as they could be used to attack
428 /* Send a NODE STATUS RESPONSE */
429 reply_netbios_packet(p, /* Packet to reply to. */
430 0, /* Result code. */
431 NMB_STATUS, /* nmbd type code. */
432 NMB_NAME_QUERY_OPCODE, /* opcode. */
434 rdata, /* data to send. */
435 PTR_DIFF(buf,rdata)); /* data length. */
439 /***************************************************************************
440 Process a name query.
442 For broadcast name queries:
444 - Only reply if the query is for one of YOUR names.
445 - NEVER send a negative response to a broadcast query.
447 ****************************************************************************/
449 void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
451 struct nmb_packet *nmb = &p->packet.nmb;
452 struct nmb_name *question = &nmb->question.question_name;
453 int name_type = question->name_type;
454 BOOL bcast = nmb->header.nm_flags.bcast;
459 BOOL success = False;
460 struct name_record *namerec = NULL;
461 int reply_data_len = 0;
464 DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n",
465 inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
467 /* Look up the name in the cache - if the request is a broadcast request that
468 came from a subnet we don't know about then search all the broadcast subnets
469 for a match (as we don't know what interface the request came in on). */
471 if(subrec == remote_broadcast_subnet)
472 namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
474 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
477 /* Check if it is a name that expired */
479 && ( (namerec->data.death_time != PERMANENT_TTL)
480 && (namerec->data.death_time < p->timestamp) ) )
482 DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
490 * Always respond to unicast queries.
491 * Don't respond to broadcast queries unless the query is for
492 * a name we own, a Primary Domain Controller name, or a WINS_PROXY
493 * name with type 0 or 0x20. WINS_PROXY names are only ever added
494 * into the namelist if we were configured as a WINS proxy.
499 && ( (name_type == 0x1b)
500 || (namerec->data.source == SELF_NAME)
501 || (namerec->data.source == PERMANENT_NAME)
502 || ( (namerec->data.source == WINS_PROXY_NAME)
503 && ( (name_type == 0) || (name_type == 0x20) )
510 /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY,
511 or it's a Domain Master type. */
514 * If this is a WINS_PROXY_NAME, then ceck that none of the IP
515 * addresses we are returning is on the same broadcast subnet
516 * as the requesting packet. If it is then don't reply as the
517 * actual machine will be replying also and we don't want two
518 * replies to a broadcast query.
521 if( namerec->data.source == WINS_PROXY_NAME )
523 for( i = 0; i < namerec->data.num_ips; i++)
525 if(same_net( namerec->data.ip[i], subrec->myip, subrec->mask_ip ))
527 DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also \
528 on the same subnet (%s) as the requestor. Not replying.\n",
529 nmb_namestr(&namerec->name), subrec->subnet_name ));
535 ttl = (namerec->data.death_time != PERMANENT_TTL) ?
536 namerec->data.death_time - p->timestamp : lp_max_ttl();
538 /* Copy all known ip addresses into the return data. */
539 /* Optimise for the common case of one IP address so
540 we don't need a malloc. */
542 if( namerec->data.num_ips == 1 )
546 if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
548 DEBUG(0,("process_name_query_request: malloc fail !\n"));
553 for( i = 0; i < namerec->data.num_ips; i++ )
555 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
556 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
559 sort_query_replies(prdata, i, p->ip);
561 reply_data_len = namerec->data.num_ips * 6;
567 * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
568 * set we should initiate a WINS query here. On success we add the resolved name
569 * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
572 if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() &&
573 bcast && (subrec != remote_broadcast_subnet))
575 make_wins_proxy_name_query_request( subrec, p, question );
579 if (!success && bcast)
581 if((prdata != rdata) && (prdata != NULL))
583 return; /* Never reply with a negative response to broadcasts. */
587 * Final check. From observation, if a unicast packet is sent
588 * to a non-WINS server with the recursion desired bit set
589 * then never send a negative response.
592 if(!success && !bcast && nmb->header.nm_flags.recursion_desired)
594 if((prdata != rdata) && (prdata != NULL))
607 DEBUG(3,("UNKNOWN\n"));
610 /* See rfc1002.txt 4.2.13. */
612 reply_netbios_packet(p, /* Packet to reply to. */
613 rcode, /* Result code. */
614 NMB_QUERY, /* nmbd type code. */
615 NMB_NAME_QUERY_OPCODE, /* opcode. */
617 prdata, /* data to send. */
618 reply_data_len); /* data length. */
620 if((prdata != rdata) && (prdata != NULL))