move to SAFE_FREE()
[samba.git] / source3 / nmbd / nmbd_incomingrequests.c
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
8    
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.
13    
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.
18    
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.
22    
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.
26
27 */
28
29 #include "includes.h"
30
31 extern int DEBUGLEVEL;
32 extern fstring global_myworkgroup;
33
34 /****************************************************************************
35 Send a name release response.
36 **************************************************************************/
37
38 static void send_name_release_response(int rcode, struct packet_struct *p)
39 {
40   struct nmb_packet *nmb = &p->packet.nmb;
41   char rdata[6];
42
43   memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
44   
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. */
52 }
53
54 /****************************************************************************
55 Process a name release packet on a broadcast subnet.
56 Ignore it if it's not one of our names.
57 ****************************************************************************/
58
59 void process_name_release_request(struct subnet_record *subrec, 
60                                   struct packet_struct *p)
61 {
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;
70   
71   putip((char *)&owner_ip,&nmb->additional->rdata[2]);  
72   
73   if(!bcast)
74   {
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.
81      */
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));      
85
86     send_name_release_response(FMT_ERR, p);
87     return;
88   }
89
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)));
94   
95   /* If someone is releasing a broadcast group name, just ignore it. */
96   if( group && !ismyip(owner_ip) )
97     return;
98
99   /*
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* !!!!!
103    */
104
105   if( !group && !ismyip(owner_ip) && strequal(question->name, global_myworkgroup) && 
106       ((question->name_type == 0x0) || (question->name_type == 0x1e)))
107   {
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 ));
111     return;
112   }
113
114   namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_ANY_NAME);
115
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) ) )
120   {
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           nmb_namestr(&nmb->question.question_name), inet_ntoa(owner_ip), subrec->subnet_name));
125   }
126
127   if(rcode == 0)
128     return;
129
130   /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
131   send_name_release_response(rcode, p);
132 }
133
134 /****************************************************************************
135 Send a name registration response.
136 **************************************************************************/
137
138 static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p)
139 {
140   struct nmb_packet *nmb = &p->packet.nmb;
141   char rdata[6];
142
143   memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
144   
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. */
152 }
153
154 /****************************************************************************
155 Process a name refresh request on a broadcast subnet.
156 **************************************************************************/
157      
158 void process_name_refresh_request(struct subnet_record *subrec,
159                                   struct packet_struct *p)
160 {    
161      
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;
166   
167   putip((char *)&from_ip,&nmb->additional->rdata[2]);
168
169   if(!bcast)
170   { 
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.
177      */
178     DEBUG(0,("process_name_refresh_request: unicast name registration request \
179 received for name %s from IP %s on subnet %s.\n",
180           nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
181     DEBUG(0,("Error - should be sent to WINS server\n"));
182     
183     send_name_registration_response(FMT_ERR, 0, p);
184     return;
185   } 
186
187   /* Just log a message. We really don't care about broadcast name
188      refreshes. */
189      
190   DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
191 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
192      
193 }
194     
195 /****************************************************************************
196 Process a name registration request on a broadcast subnet.
197 **************************************************************************/
198
199 void process_name_registration_request(struct subnet_record *subrec, 
200                                        struct packet_struct *p)
201 {
202   struct nmb_packet *nmb = &p->packet.nmb;
203   struct nmb_name *question = &nmb->question.question_name;
204   BOOL bcast = nmb->header.nm_flags.bcast;
205   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
206   BOOL group = (nb_flags & NB_GROUP) ? True : False;
207   struct name_record *namerec = NULL;
208   int ttl = nmb->additional->ttl;
209   struct in_addr from_ip;
210   
211   putip((char *)&from_ip,&nmb->additional->rdata[2]);
212   
213   if(!bcast)
214   {
215     /* We should only get broadcast name registration packets here.
216        Anyone trying to register unicast should be going to a WINS
217        server. If the code gets here, then either we are not a wins
218        server and they sent it anyway, or we are a WINS server and
219        the request was malformed. Either way, log an error here.
220        and send an error reply back.
221      */
222     DEBUG(0,("process_name_registration_request: unicast name registration request \
223 received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
224           nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));      
225
226     send_name_registration_response(FMT_ERR, 0, p);
227     return;
228   }
229
230   DEBUG(3,("process_name_registration_request: Name registration for name %s \
231 IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
232   
233   /* See if the name already exists. */
234   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
235  
236   /* 
237    * If the name being registered exists and is a WINS_PROXY_NAME 
238    * then delete the WINS proxy name entry so we don't reply erroneously
239    * later to queries.
240    */
241
242   if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
243   {
244     remove_name_from_namelist( subrec, namerec );
245     namerec = NULL;
246   }
247
248   if (!group)
249   {
250     /* Unique name. */
251
252     if( (namerec != NULL)
253      && ( (namerec->data.source == SELF_NAME)
254        || (namerec->data.source == PERMANENT_NAME)
255        || NAME_GROUP(namerec) ) )
256     {
257       /* No-one can register one of Samba's names, nor can they
258          register a name that's a group name as a unique name */
259
260       send_name_registration_response(ACT_ERR, 0, p);
261       return;
262     }
263     else if(namerec != NULL)
264     {
265       /* Update the namelist record with the new information. */
266       namerec->data.ip[0] = from_ip;
267       update_name_ttl(namerec, ttl);
268
269       DEBUG(3,("process_name_registration_request: Updated name record %s \
270 with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
271       return;
272     }
273   }
274   else
275   {
276     /* Group name. */
277
278     if( (namerec != NULL)
279      && !NAME_GROUP(namerec)
280      && ( (namerec->data.source == SELF_NAME)
281        || (namerec->data.source == PERMANENT_NAME) ) )
282     {
283       /* Disallow group names when we have a unique name. */
284       send_name_registration_response(ACT_ERR, 0, p);  
285       return;  
286     }  
287   }
288 }
289
290 /****************************************************************************
291 This is used to sort names for a name status into a sensible order.
292 We put our own names first, then in alphabetical order.
293 **************************************************************************/
294
295 static int status_compare(char *n1,char *n2)
296 {
297   extern pstring global_myname;
298   int l1,l2,l3;
299
300   /* It's a bit tricky because the names are space padded */
301   for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) ;
302   for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) ;
303   l3 = strlen(global_myname);
304
305   if ((l1==l3) && strncmp(n1,global_myname,l3) == 0 && 
306       (l2!=l3 || strncmp(n2,global_myname,l3) != 0))
307     return -1;
308
309   if ((l2==l3) && strncmp(n2,global_myname,l3) == 0 && 
310       (l1!=l3 || strncmp(n1,global_myname,l3) != 0))
311     return 1;
312
313   return memcmp(n1,n2,18);
314 }
315
316
317 /****************************************************************************
318   Process a node status query
319   ****************************************************************************/
320
321 void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p)
322 {
323   struct nmb_packet *nmb = &p->packet.nmb;
324   char *qname   = nmb->question.question_name.name;
325   int ques_type = nmb->question.question_name.name_type;
326   char rdata[MAX_DGRAM_SIZE];
327   char *countptr, *buf, *bufend, *buf0;
328   int names_added,i;
329   struct name_record *namerec;
330
331   DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
332 subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip),
333           subrec->subnet_name));
334
335   if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name,
336                                     FIND_SELF_NAME)) == 0)
337   {
338     DEBUG(1,("process_node_status_request: status request for name %s from IP %s on \
339 subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
340           inet_ntoa(p->ip), subrec->subnet_name));
341
342     return;
343   }
344  
345   /* this is not an exact calculation. the 46 is for the stats buffer
346      and the 60 is to leave room for the header etc */
347   bufend = &rdata[MAX_DGRAM_SIZE] - (18 + 46 + 60);
348   countptr = buf = rdata;
349   buf += 1;
350   buf0 = buf;
351
352   names_added = 0;
353
354   namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
355
356   while (buf < bufend) 
357   {
358     if( (namerec->data.source == SELF_NAME)
359      || (namerec->data.source == PERMANENT_NAME) )
360     {
361       int name_type = namerec->name.name_type;
362       
363       if (!strequal(namerec->name.name,"*") &&
364           !strequal(namerec->name.name,"__SAMBA__") &&
365           (name_type < 0x1b || name_type >= 0x20 || 
366            ques_type < 0x1b || ques_type >= 0x20 ||
367            strequal(qname, namerec->name.name)))
368       {
369         /* Start with the name. */
370         memset(buf,'\0',18);
371         slprintf(buf, 17, "%-15.15s",namerec->name.name);
372         strupper(buf);
373         
374         /* Put the name type and netbios flags in the buffer. */
375         buf[15] = name_type;
376         set_nb_flags( &buf[16],namerec->data.nb_flags );
377         buf[16] |= NB_ACTIVE; /* all our names are active */
378
379         buf += 18;
380
381         names_added++;
382       }
383     }
384
385     /* Remove duplicate names. */
386     if (names_added > 1) {
387             qsort( buf0, names_added, 18, QSORT_CAST status_compare );
388     }
389
390     for( i=1; i < names_added ; i++ )
391     {
392       if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0) 
393       {
394         names_added--;
395         if (names_added == i)
396           break;
397         memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
398         i--;
399       }
400     }
401
402     buf = buf0 + 18*names_added;
403
404     namerec = (struct name_record *)ubi_trNext( namerec );
405
406     if (!namerec)
407     {
408       /* End of the subnet specific name list. Now 
409          add the names on the unicast subnet . */
410       struct subnet_record *uni_subrec = unicast_subnet;
411
412       if (uni_subrec != subrec)
413       {
414         subrec = uni_subrec;
415         namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
416       }
417     }
418     if (!namerec)
419       break;
420
421   }
422   
423   SCVAL(countptr,0,names_added);
424   
425   /* We don't send any stats as they could be used to attack
426      the protocol. */
427   memset(buf,'\0',46);
428   
429   buf += 46;
430   
431   /* Send a NODE STATUS RESPONSE */
432   reply_netbios_packet(p,                            /* Packet to reply to. */
433                        0,                            /* Result code. */
434                        NMB_STATUS,                   /* nmbd type code. */
435                        NMB_NAME_QUERY_OPCODE,        /* opcode. */
436                        0,                            /* ttl. */
437                        rdata,                        /* data to send. */
438                        PTR_DIFF(buf,rdata));         /* data length. */
439 }
440
441
442 /***************************************************************************
443 Process a name query.
444
445 For broadcast name queries:
446
447   - Only reply if the query is for one of YOUR names.
448   - NEVER send a negative response to a broadcast query.
449
450 ****************************************************************************/
451
452 void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
453 {
454   struct nmb_packet *nmb = &p->packet.nmb;
455   struct nmb_name *question = &nmb->question.question_name;
456   int name_type = question->name_type;
457   BOOL bcast = nmb->header.nm_flags.bcast;
458   int ttl=0;
459   int rcode = 0;
460   char *prdata = NULL;
461   char rdata[6];
462   BOOL success = False;
463   struct name_record *namerec = NULL;
464   int reply_data_len = 0;
465   int i;
466  
467   DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n", 
468             inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
469   
470   /* Look up the name in the cache - if the request is a broadcast request that
471      came from a subnet we don't know about then search all the broadcast subnets
472      for a match (as we don't know what interface the request came in on). */
473
474   if(subrec == remote_broadcast_subnet)
475     namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
476   else
477     namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
478
479
480   /* Check if it is a name that expired */
481   if( namerec
482    && ( (namerec->data.death_time != PERMANENT_TTL)
483      && (namerec->data.death_time < p->timestamp) ) )
484   {
485     DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
486     namerec = NULL;
487   }
488
489   if (namerec)
490   {
491
492     /* 
493      * Always respond to unicast queries.
494      * Don't respond to broadcast queries unless the query is for
495      * a name we own, a Primary Domain Controller name, or a WINS_PROXY 
496      * name with type 0 or 0x20. WINS_PROXY names are only ever added
497      * into the namelist if we were configured as a WINS proxy.
498      */
499
500     if( !bcast
501      || ( bcast
502        && ( (name_type == 0x1b)
503          || (namerec->data.source == SELF_NAME)
504          || (namerec->data.source == PERMANENT_NAME)
505          || ( (namerec->data.source == WINS_PROXY_NAME)
506            && ( (name_type == 0) || (name_type == 0x20) ) 
507             )
508           )
509         )
510       )
511     {
512       
513       /* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY, 
514          or it's a Domain Master type. */
515
516       /*
517        * If this is a WINS_PROXY_NAME, then ceck that none of the IP 
518        * addresses we are returning is on the same broadcast subnet 
519        * as the requesting packet. If it is then don't reply as the 
520        * actual machine will be replying also and we don't want two 
521        * replies to a broadcast query.
522        */
523
524       if( namerec->data.source == WINS_PROXY_NAME )
525       {
526         for( i = 0; i < namerec->data.num_ips; i++)
527         {
528           if(same_net( namerec->data.ip[i], subrec->myip, subrec->mask_ip ))    
529           {
530             DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also \
531 on the same subnet (%s) as the requestor. Not replying.\n", 
532                    nmb_namestr(&namerec->name), subrec->subnet_name ));
533             return;
534           }
535         }   
536       }     
537
538       ttl = (namerec->data.death_time != PERMANENT_TTL) ?
539                      namerec->data.death_time - p->timestamp : lp_max_ttl();
540
541       /* Copy all known ip addresses into the return data. */
542       /* Optimise for the common case of one IP address so 
543          we don't need a malloc. */
544
545       if( namerec->data.num_ips == 1 )
546         prdata = rdata;
547       else
548       {
549         if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
550         {
551           DEBUG(0,("process_name_query_request: malloc fail !\n"));
552           return;
553         }
554       }
555
556       for( i = 0; i < namerec->data.num_ips; i++ )
557       {
558         set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
559         putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
560       }
561
562       sort_query_replies(prdata, i, p->ip);
563       
564       reply_data_len = namerec->data.num_ips * 6;
565       success = True;
566     }
567   }
568
569   /*
570    * If a machine is broadcasting a name lookup request and we have lp_wins_proxy()
571    * set we should initiate a WINS query here. On success we add the resolved name 
572    * into our namelist with a type of WINS_PROXY_NAME and then reply to the query.
573    */
574
575   if(!success && (namerec == NULL) && we_are_a_wins_client() && lp_wins_proxy() && 
576      bcast && (subrec != remote_broadcast_subnet))
577   {
578     make_wins_proxy_name_query_request( subrec, p, question );
579     return;
580   }
581
582   if (!success && bcast)
583   {
584     if(prdata != rdata)
585       SAFE_FREE(prdata);
586     return; /* Never reply with a negative response to broadcasts. */
587   }
588
589   /* 
590    * Final check. From observation, if a unicast packet is sent
591    * to a non-WINS server with the recursion desired bit set
592    * then never send a negative response.
593    */
594
595   if(!success && !bcast && nmb->header.nm_flags.recursion_desired)
596   {
597     if(prdata != rdata)
598       SAFE_FREE(prdata);
599     return;
600   }
601
602   if (success)
603   {
604       rcode = 0;
605       DEBUG(3,("OK\n"));
606   }
607   else
608   {
609       rcode = NAM_ERR;
610       DEBUG(3,("UNKNOWN\n"));      
611   }
612
613   /* See rfc1002.txt 4.2.13. */
614
615   reply_netbios_packet(p,                              /* Packet to reply to. */
616                        rcode,                          /* Result code. */
617                        NMB_QUERY,                      /* nmbd type code. */
618                        NMB_NAME_QUERY_OPCODE,          /* opcode. */
619                        ttl,                            /* ttl. */
620                        prdata,                         /* data to send. */
621                        reply_data_len);                /* data length. */
622
623   if(prdata != rdata)
624     SAFE_FREE(prdata);
625 }