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 /****************************************************************************
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;
61 BOOL bcast = nmb->header.nm_flags.bcast;
62 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
63 BOOL group = (nb_flags & NB_GROUP) ? True : False;
64 struct name_record *namerec;
67 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 if( !group && !ismyip(owner_ip) && strequal(question->name, lp_workgroup()) &&
102 ((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, &nmb->question.question_name, FIND_ANY_NAME);
112 /* We only care about someone trying to release one of our names. */
114 && ( (namerec->data.source == SELF_NAME)
115 || (namerec->data.source == PERMANENT_NAME) ) )
118 DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
119 on subnet %s being rejected as it is one of our names.\n",
120 nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
126 /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
127 send_name_release_response(rcode, p);
130 /****************************************************************************
131 Send a name registration response.
132 **************************************************************************/
134 static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p)
136 struct nmb_packet *nmb = &p->packet.nmb;
139 memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
141 reply_netbios_packet(p, /* Packet to reply to. */
142 rcode, /* Result code. */
143 NMB_REG, /* nmbd type code. */
144 NMB_NAME_REG_OPCODE, /* opcode. */
146 rdata, /* data to send. */
147 6); /* data length. */
150 /****************************************************************************
151 Process a name refresh request on a broadcast subnet.
152 **************************************************************************/
154 void process_name_refresh_request(struct subnet_record *subrec,
155 struct packet_struct *p)
158 struct nmb_packet *nmb = &p->packet.nmb;
159 struct nmb_name *question = &nmb->question.question_name;
160 BOOL bcast = nmb->header.nm_flags.bcast;
161 struct in_addr from_ip;
163 putip((char *)&from_ip,&nmb->additional->rdata[2]);
167 /* We should only get broadcast name refresh packets here.
168 Anyone trying to refresh unicast should be going to a WINS
169 server. If the code gets here, then either we are not a wins
170 server and they sent it anyway, or we are a WINS server and
171 the request was malformed. Either way, log an error here.
172 and send an error reply back.
174 DEBUG(0,("process_name_refresh_request: unicast name registration request \
175 received for name %s from IP %s on subnet %s.\n",
176 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
177 DEBUG(0,("Error - should be sent to WINS server\n"));
179 send_name_registration_response(FMT_ERR, 0, p);
183 /* Just log a message. We really don't care about broadcast name
186 DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
187 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
191 /****************************************************************************
192 Process a name registration request on a broadcast subnet.
193 **************************************************************************/
195 void process_name_registration_request(struct subnet_record *subrec,
196 struct packet_struct *p)
198 struct nmb_packet *nmb = &p->packet.nmb;
199 struct nmb_name *question = &nmb->question.question_name;
200 BOOL bcast = nmb->header.nm_flags.bcast;
201 uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
202 BOOL group = (nb_flags & NB_GROUP) ? True : False;
203 struct name_record *namerec = NULL;
204 int ttl = nmb->additional->ttl;
205 struct in_addr from_ip;
207 putip((char *)&from_ip,&nmb->additional->rdata[2]);
211 /* We should only get broadcast name registration packets here.
212 Anyone trying to register unicast should be going to a WINS
213 server. If the code gets here, then either we are not a wins
214 server and they sent it anyway, or we are a WINS server and
215 the request was malformed. Either way, log an error here.
216 and send an error reply back.
218 DEBUG(0,("process_name_registration_request: unicast name registration request \
219 received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
220 nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
222 send_name_registration_response(FMT_ERR, 0, p);
226 DEBUG(3,("process_name_registration_request: Name registration for name %s \
227 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
229 /* See if the name already exists. */
230 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
233 * If the name being registered exists and is a WINS_PROXY_NAME
234 * then delete the WINS proxy name entry so we don't reply erroneously
238 if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
240 remove_name_from_namelist( subrec, namerec );
248 if( (namerec != NULL)
249 && ( (namerec->data.source == SELF_NAME)
250 || (namerec->data.source == PERMANENT_NAME)
251 || NAME_GROUP(namerec) ) )
253 /* No-one can register one of Samba's names, nor can they
254 register a name that's a group name as a unique name */
256 send_name_registration_response(ACT_ERR, 0, p);
259 else if(namerec != NULL)
261 /* Update the namelist record with the new information. */
262 namerec->data.ip[0] = from_ip;
263 update_name_ttl(namerec, ttl);
265 DEBUG(3,("process_name_registration_request: Updated name record %s \
266 with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
274 if( (namerec != NULL)
275 && !NAME_GROUP(namerec)
276 && ( (namerec->data.source == SELF_NAME)
277 || (namerec->data.source == PERMANENT_NAME) ) )
279 /* Disallow group names when we have a unique name. */
280 send_name_registration_response(ACT_ERR, 0, p);
286 /****************************************************************************
287 This is used to sort names for a name status into a sensible order.
288 We put our own names first, then in alphabetical order.
289 **************************************************************************/
291 static int status_compare(char *n1,char *n2)
295 /* It's a bit tricky because the names are space padded */
296 for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) ;
297 for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) ;
298 l3 = strlen(global_myname());
300 if ((l1==l3) && strncmp(n1,global_myname(),l3) == 0 &&
301 (l2!=l3 || strncmp(n2,global_myname(),l3) != 0))
304 if ((l2==l3) && strncmp(n2,global_myname(),l3) == 0 &&
305 (l1!=l3 || strncmp(n1,global_myname(),l3) != 0))
308 return memcmp(n1,n2,18);
312 /****************************************************************************
313 Process a node status query
314 ****************************************************************************/
316 void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p)
318 struct nmb_packet *nmb = &p->packet.nmb;
319 char *qname = nmb->question.question_name.name;
320 int ques_type = nmb->question.question_name.name_type;
321 char rdata[MAX_DGRAM_SIZE];
322 char *countptr, *buf, *bufend, *buf0;
324 struct name_record *namerec;
326 DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
327 subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip),
328 subrec->subnet_name));
330 if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name,
331 FIND_SELF_NAME)) == 0)
333 DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
334 subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
335 inet_ntoa(p->ip), subrec->subnet_name));
340 /* this is not an exact calculation. the 46 is for the stats buffer
341 and the 60 is to leave room for the header etc */
342 bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
343 countptr = buf = rdata;
349 namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
353 if( (namerec->data.source == SELF_NAME)
354 || (namerec->data.source == PERMANENT_NAME) )
356 int name_type = namerec->name.name_type;
358 if (!strequal(namerec->name.name,"*") &&
359 !strequal(namerec->name.name,"__SAMBA__") &&
360 (name_type < 0x1b || name_type >= 0x20 ||
361 ques_type < 0x1b || ques_type >= 0x20 ||
362 strequal(qname, namerec->name.name)))
364 /* Start with the name. */
366 slprintf(buf, 17, "%-15.15s",namerec->name.name);
369 /* Put the name type and netbios flags in the buffer. */
371 set_nb_flags( &buf[16],namerec->data.nb_flags );
372 buf[16] |= NB_ACTIVE; /* all our names are active */
380 /* Remove duplicate names. */
381 if (names_added > 1) {
382 qsort( buf0, names_added, 18, QSORT_CAST status_compare );
385 for( i=1; i < names_added ; i++ )
387 if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0)
390 if (names_added == i)
392 memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
397 buf = buf0 + 18*names_added;
399 namerec = (struct name_record *)ubi_trNext( namerec );
403 /* End of the subnet specific name list. Now
404 add the names on the unicast subnet . */
405 struct subnet_record *uni_subrec = unicast_subnet;
407 if (uni_subrec != subrec)
410 namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
418 SCVAL(countptr,0,names_added);
420 /* We don't send any stats as they could be used to attack
426 /* Send a NODE STATUS RESPONSE */
427 reply_netbios_packet(p, /* Packet to reply to. */
428 0, /* Result code. */
429 NMB_STATUS, /* nmbd type code. */
430 NMB_NAME_QUERY_OPCODE, /* opcode. */
432 rdata, /* data to send. */
433 PTR_DIFF(buf,rdata)); /* data length. */
437 /***************************************************************************
438 Process a name query.
440 For broadcast name queries:
442 - Only reply if the query is for one of YOUR names.
443 - NEVER send a negative response to a broadcast query.
445 ****************************************************************************/
447 void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
449 struct nmb_packet *nmb = &p->packet.nmb;
450 struct nmb_name *question = &nmb->question.question_name;
451 int name_type = question->name_type;
452 BOOL bcast = nmb->header.nm_flags.bcast;
457 BOOL success = False;
458 struct name_record *namerec = NULL;
459 int reply_data_len = 0;
462 DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n",
463 inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
465 /* Look up the name in the cache - if the request is a broadcast request that
466 came from a subnet we don't know about then search all the broadcast subnets
467 for a match (as we don't know what interface the request came in on). */
469 if(subrec == remote_broadcast_subnet)
470 namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
472 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
474 /* Check if it is a name that expired */
476 ((namerec->data.death_time != PERMANENT_TTL) &&
477 (namerec->data.death_time < p->timestamp))) {
478 DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
484 * Always respond to unicast queries.
485 * Don't respond to broadcast queries unless the query is for
486 * a name we own, a Primary Domain Controller name, or a WINS_PROXY
487 * name with type 0 or 0x20. WINS_PROXY names are only ever added
488 * into the namelist if we were configured as a WINS proxy.
492 (bcast && ((name_type == 0x1b) ||
493 (namerec->data.source == SELF_NAME) ||
494 (namerec->data.source == PERMANENT_NAME) ||
495 ((namerec->data.source == WINS_PROXY_NAME) &&
496 ((name_type == 0) || (name_type == 0x20)))))) {
497 /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY,
498 or it's a Domain Master type. */
501 * If this is a WINS_PROXY_NAME, then ceck that none of the IP
502 * addresses we are returning is on the same broadcast subnet
503 * as the requesting packet. If it is then don't reply as the
504 * actual machine will be replying also and we don't want two
505 * replies to a broadcast query.
508 if (namerec->data.source == WINS_PROXY_NAME) {
509 for( i = 0; i < namerec->data.num_ips; i++) {
510 if (same_net(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) {
511 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",
512 nmb_namestr(&namerec->name), subrec->subnet_name ));
518 ttl = (namerec->data.death_time != PERMANENT_TTL) ?
519 namerec->data.death_time - p->timestamp : lp_max_ttl();
521 /* Copy all known ip addresses into the return data. */
522 /* Optimise for the common case of one IP address so
523 we don't need a malloc. */
525 if (namerec->data.num_ips == 1) {
528 if ((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL) {
529 DEBUG(0,("process_name_query_request: malloc fail !\n"));
534 for (i = 0; i < namerec->data.num_ips; i++) {
535 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
536 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
539 sort_query_replies(prdata, i, p->ip);
541 reply_data_len = namerec->data.num_ips * 6;
547 * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
548 * set we should initiate a WINS query here. On success we add the resolved name
549 * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
552 if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() &&
553 bcast && (subrec != remote_broadcast_subnet)) {
554 make_wins_proxy_name_query_request( subrec, p, question );
558 if (!success && bcast) {
561 return; /* Never reply with a negative response to broadcasts. */
565 * Final check. From observation, if a unicast packet is sent
566 * to a non-WINS server with the recursion desired bit set
567 * then never send a negative response.
570 if(!success && !bcast && nmb->header.nm_flags.recursion_desired) {
581 DEBUG(3,("UNKNOWN\n"));
584 /* See rfc1002.txt 4.2.13. */
586 reply_netbios_packet(p, /* Packet to reply to. */
587 rcode, /* Result code. */
588 NMB_QUERY, /* nmbd type code. */
589 NMB_NAME_QUERY_OPCODE, /* opcode. */
591 prdata, /* data to send. */
592 reply_data_len); /* data length. */