Removed global_myworkgroup, global_myname, global_myscope. Added liberal
[kai/samba.git] / source3 / nmbd / nmbd_incomingrequests.c
1 /* 
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
7    
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.
12    
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.
17    
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.
21    
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.
25
26 */
27
28 #include "includes.h"
29
30 /****************************************************************************
31 Send a name release response.
32 **************************************************************************/
33
34 static void send_name_release_response(int rcode, struct packet_struct *p)
35 {
36   struct nmb_packet *nmb = &p->packet.nmb;
37   char rdata[6];
38
39   memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
40   
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. */
45                        0,                            /* ttl. */
46                        rdata,                        /* data to send. */
47                        6);                           /* data length. */
48 }
49
50 /****************************************************************************
51 Process a name release packet on a broadcast subnet.
52 Ignore it if it's not one of our names.
53 ****************************************************************************/
54
55 void process_name_release_request(struct subnet_record *subrec, 
56                                   struct packet_struct *p)
57 {
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;
65   int rcode = 0;
66   
67   putip((char *)&owner_ip,&nmb->additional->rdata[2]);  
68   
69   if(!bcast)
70   {
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.
77      */
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));      
81
82     send_name_release_response(FMT_ERR, p);
83     return;
84   }
85
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)));
90   
91   /* If someone is releasing a broadcast group name, just ignore it. */
92   if( group && !ismyip(owner_ip) )
93     return;
94
95   /*
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* !!!!!
99    */
100
101   if( !group && !ismyip(owner_ip) && strequal(question->name, lp_workgroup()) && 
102       ((question->name_type == 0x0) || (question->name_type == 0x1e)))
103   {
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 ));
107     return;
108   }
109
110   namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_ANY_NAME);
111
112   /* We only care about someone trying to release one of our names. */
113   if( namerec
114    && ( (namerec->data.source == SELF_NAME)
115      || (namerec->data.source == PERMANENT_NAME) ) )
116   {
117     rcode = ACT_ERR;
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));
121   }
122
123   if(rcode == 0)
124     return;
125
126   /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
127   send_name_release_response(rcode, p);
128 }
129
130 /****************************************************************************
131 Send a name registration response.
132 **************************************************************************/
133
134 static void send_name_registration_response(int rcode, int ttl, struct packet_struct *p)
135 {
136   struct nmb_packet *nmb = &p->packet.nmb;
137   char rdata[6];
138
139   memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
140   
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. */
145                        ttl,                           /* ttl. */
146                        rdata,                         /* data to send. */
147                        6);                            /* data length. */
148 }
149
150 /****************************************************************************
151 Process a name refresh request on a broadcast subnet.
152 **************************************************************************/
153      
154 void process_name_refresh_request(struct subnet_record *subrec,
155                                   struct packet_struct *p)
156 {    
157      
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;
162   
163   putip((char *)&from_ip,&nmb->additional->rdata[2]);
164
165   if(!bcast)
166   { 
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.
173      */
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"));
178     
179     send_name_registration_response(FMT_ERR, 0, p);
180     return;
181   } 
182
183   /* Just log a message. We really don't care about broadcast name
184      refreshes. */
185      
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));
188      
189 }
190     
191 /****************************************************************************
192 Process a name registration request on a broadcast subnet.
193 **************************************************************************/
194
195 void process_name_registration_request(struct subnet_record *subrec, 
196                                        struct packet_struct *p)
197 {
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;
206   
207   putip((char *)&from_ip,&nmb->additional->rdata[2]);
208   
209   if(!bcast)
210   {
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.
217      */
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));      
221
222     send_name_registration_response(FMT_ERR, 0, p);
223     return;
224   }
225
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));
228   
229   /* See if the name already exists. */
230   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
231  
232   /* 
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
235    * later to queries.
236    */
237
238   if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
239   {
240     remove_name_from_namelist( subrec, namerec );
241     namerec = NULL;
242   }
243
244   if (!group)
245   {
246     /* Unique name. */
247
248     if( (namerec != NULL)
249      && ( (namerec->data.source == SELF_NAME)
250        || (namerec->data.source == PERMANENT_NAME)
251        || NAME_GROUP(namerec) ) )
252     {
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 */
255
256       send_name_registration_response(ACT_ERR, 0, p);
257       return;
258     }
259     else if(namerec != NULL)
260     {
261       /* Update the namelist record with the new information. */
262       namerec->data.ip[0] = from_ip;
263       update_name_ttl(namerec, ttl);
264
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));
267       return;
268     }
269   }
270   else
271   {
272     /* Group name. */
273
274     if( (namerec != NULL)
275      && !NAME_GROUP(namerec)
276      && ( (namerec->data.source == SELF_NAME)
277        || (namerec->data.source == PERMANENT_NAME) ) )
278     {
279       /* Disallow group names when we have a unique name. */
280       send_name_registration_response(ACT_ERR, 0, p);  
281       return;  
282     }  
283   }
284 }
285
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 **************************************************************************/
290
291 static int status_compare(char *n1,char *n2)
292 {
293   int l1,l2,l3;
294
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());
299
300   if ((l1==l3) && strncmp(n1,global_myname(),l3) == 0 && 
301       (l2!=l3 || strncmp(n2,global_myname(),l3) != 0))
302     return -1;
303
304   if ((l2==l3) && strncmp(n2,global_myname(),l3) == 0 && 
305       (l1!=l3 || strncmp(n1,global_myname(),l3) != 0))
306     return 1;
307
308   return memcmp(n1,n2,18);
309 }
310
311
312 /****************************************************************************
313   Process a node status query
314   ****************************************************************************/
315
316 void process_node_status_request(struct subnet_record *subrec, struct packet_struct *p)
317 {
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;
323   int names_added,i;
324   struct name_record *namerec;
325
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));
329
330   if((namerec = find_name_on_subnet(subrec, &nmb->question.question_name,
331                                     FIND_SELF_NAME)) == 0)
332   {
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));
336
337     return;
338   }
339  
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;
344   buf += 1;
345   buf0 = buf;
346
347   names_added = 0;
348
349   namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
350
351   while (buf < bufend) 
352   {
353     if( (namerec->data.source == SELF_NAME)
354      || (namerec->data.source == PERMANENT_NAME) )
355     {
356       int name_type = namerec->name.name_type;
357       
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)))
363       {
364         /* Start with the name. */
365         memset(buf,'\0',18);
366         slprintf(buf, 17, "%-15.15s",namerec->name.name);
367         strupper(buf);
368         
369         /* Put the name type and netbios flags in the buffer. */
370         buf[15] = name_type;
371         set_nb_flags( &buf[16],namerec->data.nb_flags );
372         buf[16] |= NB_ACTIVE; /* all our names are active */
373
374         buf += 18;
375
376         names_added++;
377       }
378     }
379
380     /* Remove duplicate names. */
381     if (names_added > 1) {
382             qsort( buf0, names_added, 18, QSORT_CAST status_compare );
383     }
384
385     for( i=1; i < names_added ; i++ )
386     {
387       if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0) 
388       {
389         names_added--;
390         if (names_added == i)
391           break;
392         memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
393         i--;
394       }
395     }
396
397     buf = buf0 + 18*names_added;
398
399     namerec = (struct name_record *)ubi_trNext( namerec );
400
401     if (!namerec)
402     {
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;
406
407       if (uni_subrec != subrec)
408       {
409         subrec = uni_subrec;
410         namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
411       }
412     }
413     if (!namerec)
414       break;
415
416   }
417   
418   SCVAL(countptr,0,names_added);
419   
420   /* We don't send any stats as they could be used to attack
421      the protocol. */
422   memset(buf,'\0',46);
423   
424   buf += 46;
425   
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. */
431                        0,                            /* ttl. */
432                        rdata,                        /* data to send. */
433                        PTR_DIFF(buf,rdata));         /* data length. */
434 }
435
436
437 /***************************************************************************
438 Process a name query.
439
440 For broadcast name queries:
441
442   - Only reply if the query is for one of YOUR names.
443   - NEVER send a negative response to a broadcast query.
444
445 ****************************************************************************/
446
447 void process_name_query_request(struct subnet_record *subrec, struct packet_struct *p)
448 {
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;
453         int ttl=0;
454         int rcode = 0;
455         char *prdata = NULL;
456         char rdata[6];
457         BOOL success = False;
458         struct name_record *namerec = NULL;
459         int reply_data_len = 0;
460         int i;
461         
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)));
464   
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). */
468
469         if(subrec == remote_broadcast_subnet)
470                 namerec = find_name_for_remote_broadcast_subnet( question, FIND_ANY_NAME);
471         else
472                 namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
473
474         /* Check if it is a name that expired */
475         if (namerec && 
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)));
479                 namerec = NULL;
480         }
481
482         if (namerec) {
483                 /* 
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.
489                  */
490                 
491                 if (!bcast || 
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. */
499
500                         /*
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.
506                          */
507                         
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 ));
513                                                 return;
514                                         }
515                                 }
516                         }
517
518                         ttl = (namerec->data.death_time != PERMANENT_TTL) ?
519                                 namerec->data.death_time - p->timestamp : lp_max_ttl();
520
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. */
524
525                         if (namerec->data.num_ips == 1) {
526                                 prdata = rdata;
527                         } else {
528                                 if ((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL) {
529                                         DEBUG(0,("process_name_query_request: malloc fail !\n"));
530                                         return;
531                                 }
532                         }
533
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]);
537                         }
538
539                         sort_query_replies(prdata, i, p->ip);
540                         
541                         reply_data_len = namerec->data.num_ips * 6;
542                         success = True;
543                 }
544         }
545
546         /*
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.
550          */
551         
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 );
555                 return;
556         }
557
558         if (!success && bcast) {
559                 if(prdata != rdata)
560                         SAFE_FREE(prdata);
561                 return; /* Never reply with a negative response to broadcasts. */
562         }
563
564         /* 
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.
568          */
569         
570         if(!success && !bcast && nmb->header.nm_flags.recursion_desired) {
571                 if(prdata != rdata)
572                         SAFE_FREE(prdata);
573                 return;
574         }
575
576         if (success) {
577                 rcode = 0;
578                 DEBUG(3,("OK\n"));
579         } else {
580                 rcode = NAM_ERR;
581                 DEBUG(3,("UNKNOWN\n"));      
582         }
583
584         /* See rfc1002.txt 4.2.13. */
585
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. */
590                              ttl,                            /* ttl. */
591                              prdata,                         /* data to send. */
592                              reply_data_len);                /* data length. */
593         
594         if(prdata != rdata)
595                 SAFE_FREE(prdata);
596 }