loadparm.c:
[Samba/gebeck_regimport.git] / source / nmbd / nmbd_incomingrequests.c
blob3c9438ace35b003b38387f9da923d49c1c8706e5
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
29 #include "includes.h"
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;
41 char rdata[6];
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. */
49 0, /* ttl. */
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;
69 int rcode = 0;
71 putip((char *)&owner_ip,&nmb->additional->rdata[2]);
73 if(!bcast)
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 namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
86 send_name_release_response(FMT_ERR, p);
87 return;
90 DEBUG(3,("process_name_release_request: Name release on name %s, \
91 subnet %s from owner IP %s\n",
92 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) )
97 return;
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 namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
111 return;
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. */
117 if( namerec
118 && ( (namerec->data.source == SELF_NAME)
119 || (namerec->data.source == PERMANENT_NAME) ) )
121 rcode = ACT_ERR;
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 namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
127 if(rcode == 0)
128 return;
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;
141 char rdata[6];
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. */
149 ttl, /* ttl. */
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]);
169 if(!bcast)
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 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
182 send_name_registration_response(FMT_ERR, 0, p);
183 return;
186 /* Just log a message. We really don't care about broadcast name
187 refreshes. */
189 DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
190 IP %s on subnet %s\n", 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]);
212 if(!bcast)
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 namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
225 send_name_registration_response(FMT_ERR, 0, p);
226 return;
229 DEBUG(3,("process_name_registration_request: Name registration for name %s \
230 IP %s on subnet %s\n", 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
238 * later to queries.
241 if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
243 remove_name_from_namelist( subrec, namerec );
244 namerec = NULL;
247 if (!group)
249 /* Unique name. */
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);
260 return;
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",namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
270 return;
273 else
275 /* Group 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);
284 return;
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;
297 int l1,l2,l3;
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))
306 return -1;
308 if ((l2==l3) && strncmp(n2,global_myname,l3) == 0 &&
309 (l1!=l3 || strncmp(n1,global_myname,l3) != 0))
310 return 1;
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;
327 int names_added,i;
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", 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", namestr(&nmb->question.question_name),
339 inet_ntoa(p->ip), subrec->subnet_name));
341 return;
344 /* XXXX hack, we should calculate exactly how many will fit. */
345 bufend = &rdata[MAX_DGRAM_SIZE] - 18;
346 countptr = buf = rdata;
347 buf += 1;
348 buf0 = buf;
350 names_added = 0;
352 namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
354 while (buf < bufend)
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. */
368 bzero(buf,18);
369 slprintf(buf, 17, "%-15.15s",namerec->name.name);
370 strupper(buf);
372 /* Put the name type and netbios flags in the buffer. */
373 buf[15] = name_type;
374 set_nb_flags( &buf[16],namerec->data.nb_flags );
375 buf[16] |= NB_ACTIVE; /* all our names are active */
377 buf += 18;
379 names_added++;
383 /* Remove duplicate names. */
384 qsort( buf0, names_added, 18, QSORT_CAST status_compare );
386 for( i=1; i < names_added ; i++ )
388 if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0)
390 names_added--;
391 if (names_added == i)
392 break;
393 memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
394 i--;
398 buf = buf0 + 18*names_added;
400 namerec = (struct name_record *)ubi_trNext( namerec );
402 if (!namerec)
404 /* End of the subnet specific name list. Now
405 add the names on the unicast subnet . */
406 struct subnet_record *uni_subrec = unicast_subnet;
408 if (uni_subrec != subrec)
410 subrec = uni_subrec;
411 namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
414 if (!namerec)
415 break;
419 SCVAL(countptr,0,names_added);
421 /* We don't send any stats as they could be used to attack
422 the protocol. */
423 bzero(buf,46);
425 buf += 46;
427 /* Send a NODE STATUS RESPONSE */
428 reply_netbios_packet(p, /* Packet to reply to. */
429 0, /* Result code. */
430 NMB_STATUS, /* nmbd type code. */
431 NMB_NAME_QUERY_OPCODE, /* opcode. */
432 0, /* ttl. */
433 rdata, /* data to send. */
434 PTR_DIFF(buf,rdata)); /* data length. */
438 /***************************************************************************
439 Process a name query.
441 For broadcast name queries:
443 - Only reply if the query is for one of YOUR names.
444 - NEVER send a negative response to a broadcast query.
446 ****************************************************************************/
448 void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
450 struct nmb_packet *nmb = &p->packet.nmb;
451 struct nmb_name *question = &nmb->question.question_name;
452 int name_type = question->name_type;
453 BOOL bcast = nmb->header.nm_flags.bcast;
454 int ttl=0;
455 int rcode = 0;
456 char *prdata = NULL;
457 char rdata[6];
458 BOOL success = False;
459 struct name_record *namerec = NULL;
460 int reply_data_len = 0;
461 int i;
463 DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n",
464 inet_ntoa(p->ip), subrec->subnet_name, namestr(question)));
466 /* Look up the name in the cache - if the request is a broadcast request that
467 came from a subnet we don't know about then search all the broadcast subnets
468 for a match (as we don't know what interface the request came in on). */
470 if(subrec == remote_broadcast_subnet)
471 namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
472 else
473 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
476 /* Check if it is a name that expired */
477 if( namerec
478 && ( (namerec->data.death_time != PERMANENT_TTL)
479 && (namerec->data.death_time < p->timestamp) ) )
481 DEBUG(5,("process_name_query_request: expired name %s\n", namestr(&namerec->name)));
482 namerec = NULL;
485 if (namerec)
489 * Always respond to unicast queries.
490 * Don't respond to broadcast queries unless the query is for
491 * a name we own, a Primary Domain Controller name, or a WINS_PROXY
492 * name with type 0 or 0x20. WINS_PROXY names are only ever added
493 * into the namelist if we were configured as a WINS proxy.
496 if( !bcast
497 || ( bcast
498 && ( (name_type == 0x1b)
499 || (namerec->data.source == SELF_NAME)
500 || (namerec->data.source == PERMANENT_NAME)
501 || ( (namerec->data.source == WINS_PROXY_NAME)
502 && ( (name_type == 0) || (name_type == 0x20) )
509 /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY,
510 or it's a Domain Master type. */
513 * If this is a WINS_PROXY_NAME, then ceck that none of the IP
514 * addresses we are returning is on the same broadcast subnet
515 * as the requesting packet. If it is then don't reply as the
516 * actual machine will be replying also and we don't want two
517 * replies to a broadcast query.
520 if( namerec->data.source == WINS_PROXY_NAME )
522 for( i = 0; i < namerec->data.num_ips; i++)
524 if(same_net( namerec->data.ip[i], subrec->myip, subrec->mask_ip ))
526 DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also \
527 on the same subnet (%s) as the requestor. Not replying.\n",
528 namestr(&namerec->name), subrec->subnet_name ));
529 return;
534 ttl = (namerec->data.death_time != PERMANENT_TTL) ?
535 namerec->data.death_time - p->timestamp : lp_max_ttl();
537 /* Copy all known ip addresses into the return data. */
538 /* Optimise for the common case of one IP address so
539 we don't need a malloc. */
541 if( namerec->data.num_ips == 1 )
542 prdata = rdata;
543 else
545 if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
547 DEBUG(0,("process_name_query_request: malloc fail !\n"));
548 return;
552 for( i = 0; i < namerec->data.num_ips; i++ )
554 set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
555 putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
557 reply_data_len = namerec->data.num_ips * 6;
558 success = True;
563 * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
564 * set we should initiate a WINS query here. On success we add the resolved name
565 * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
568 if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() &&
569 bcast && (subrec != remote_broadcast_subnet))
571 make_wins_proxy_name_query_request( subrec, p, question );
572 return;
575 if (!success && bcast)
577 if((prdata != rdata) && (prdata != NULL))
578 free(rdata);
579 return; /* Never reply with a negative response to broadcasts. */
583 * Final check. From observation, if a unicast packet is sent
584 * to a non-WINS server with the recursion desired bit set
585 * then never send a negative response.
588 if(!success && !bcast && nmb->header.nm_flags.recursion_desired)
590 if((prdata != rdata) && (prdata != NULL))
591 free(rdata);
592 return;
595 if (success)
597 rcode = 0;
598 DEBUG(3,("OK\n"));
600 else
602 rcode = NAM_ERR;
603 DEBUG(3,("UNKNOWN\n"));
606 /* See rfc1002.txt 4.2.13. */
608 reply_netbios_packet(p, /* Packet to reply to. */
609 rcode, /* Result code. */
610 NMB_QUERY, /* nmbd type code. */
611 NMB_NAME_QUERY_OPCODE, /* opcode. */
612 ttl, /* ttl. */
613 prdata, /* data to send. */
614 reply_data_len); /* data length. */
616 if((prdata != rdata) && (prdata != NULL))
617 free(prdata);