304e9f4dba6ba492fd4c7577cca8a3d5ba0bdda9
[samba.git] / source3 / nmbd / nmbd_winsserver.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5
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 */
23
24 #include "includes.h"
25
26 #define WINS_LIST "wins.dat"
27
28 extern int DEBUGLEVEL;
29 extern struct in_addr ipzero;
30
31 /****************************************************************************
32 Determine if this packet should be allocated to the WINS server.
33 *****************************************************************************/
34
35 BOOL packet_is_for_wins_server(struct packet_struct *packet)
36 {
37   struct nmb_packet *nmb = &packet->packet.nmb;
38
39   /* Only unicast packets go to a WINS server. */
40   if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True))
41   {
42     DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
43     return False;
44   }
45
46   /* Check for node status requests. */
47   if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
48     return False;
49
50   switch(nmb->header.opcode)
51   { 
52     /*
53      * A WINS server issues WACKS, not receives them.
54      */
55     case NMB_WACK_OPCODE:
56       DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
57       return False;
58     /*
59      * A WINS server only processes registration and
60      * release requests, not responses.
61      */
62     case NMB_NAME_REG_OPCODE:
63     case NMB_NAME_MULTIHOMED_REG_OPCODE:
64     case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
65     case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
66       if(nmb->header.response)
67       {
68         DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
69         return False;
70       }
71       break;
72
73     case NMB_NAME_RELEASE_OPCODE:
74       if(nmb->header.response)
75       {
76         DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
77         return False;
78       }
79       break;
80
81     /*
82      * Only process unicast name queries with rd = 1.
83      */
84     case NMB_NAME_QUERY_OPCODE:
85       if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired)
86       {
87         DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
88         return False;
89       }
90       break;
91   }
92
93   return True;
94 }
95
96 /****************************************************************************
97 Utility function to decide what ttl to give a register/refresh request.
98 *****************************************************************************/
99
100 static int get_ttl_from_packet(struct nmb_packet *nmb)
101 {
102   int ttl = nmb->additional->ttl;
103
104   if(ttl < lp_min_wins_ttl() )
105     ttl = lp_min_wins_ttl();
106
107   if(ttl > lp_max_wins_ttl() )
108     ttl = lp_max_wins_ttl();
109
110   return ttl;
111 }
112
113 /****************************************************************************
114 Load or create the WINS database.
115 *****************************************************************************/
116
117 BOOL initialise_wins(void)
118 {
119   pstring fname;
120   time_t time_now = time(NULL);
121   FILE *fp;
122   pstring line;
123
124   if(!lp_we_are_a_wins_server())
125     return True;
126
127   add_samba_names_to_subnet(wins_server_subnet);
128
129 #ifndef SYNC_DNS
130   /* Setup the async dns. */
131   start_async_dns();
132 #endif
133
134   pstrcpy(fname,lp_lockdir());
135   trim_string(fname,NULL,"/");
136   pstrcat(fname,"/");
137   pstrcat(fname,WINS_LIST);
138
139   if((fp = fopen(fname,"r")) == NULL)
140   {
141     DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
142            fname, strerror(errno) ));
143     return True;
144   }
145
146   while (!feof(fp))
147   {
148     pstring name_str, ip_str, ttl_str, nb_flags_str;
149     unsigned int num_ips;
150     pstring name;
151     struct in_addr *ip_list;
152     int type = 0;
153     int nb_flags;
154     int ttl;
155     enum name_source source;
156     char *ptr;
157     char *p;
158     BOOL got_token;
159     BOOL was_ip;
160     int i;
161
162     /* Read a line from the wins.dat file. Strips whitespace
163        from the beginning and end of the line.
164      */
165     if (!fgets_slash(line,sizeof(pstring),fp))
166       continue;
167       
168     if (*line == '#')
169       continue;
170
171     ptr = line;
172
173     /* 
174      * Now we handle multiple IP addresses per name we need
175      * to iterate over the line twice. The first time to
176      * determine how many IP addresses there are, the second
177      * time to actually parse them into the ip_list array.
178      */
179
180     if (!next_token(&ptr,name_str,NULL)) 
181     {
182       DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
183       continue;
184     }
185
186     if (!next_token(&ptr,ttl_str,NULL))
187     {
188       DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
189       continue;
190     }
191
192     /*
193      * Determine the number of IP addresses per line.
194      */
195     num_ips = 0;
196     do
197     {
198       got_token = next_token(&ptr,ip_str,NULL);
199       was_ip = False;
200
201       if(got_token && strchr(ip_str, '.'))
202       {
203         num_ips++;
204         was_ip = True;
205       }
206     } while( got_token && was_ip);
207
208     if(num_ips == 0)
209     {
210       DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
211       continue;
212     }
213
214     if(!got_token)
215     {
216       DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
217       continue;
218     }
219
220     /* Allocate the space for the ip_list. */
221     if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL)
222     {
223       DEBUG(0,("initialise_wins: Malloc fail !\n"));
224       return False;
225     }
226  
227     /* Reset and re-parse the line. */
228     ptr = line;
229     next_token(&ptr,name_str,NULL); 
230     next_token(&ptr,ttl_str,NULL);
231     for(i = 0; i < num_ips; i++)
232     {
233       next_token(&ptr, ip_str, NULL);
234       ip_list[i] = *interpret_addr2(ip_str);
235       if (ip_equal(ip_list[i], ipzero)) 
236          source = SELF_NAME;
237     }
238     next_token(&ptr,nb_flags_str,NULL);
239
240     /* 
241      * Deal with SELF or REGISTER name encoding. Default is REGISTER
242      * for compatibility with old nmbds.
243      */
244
245     if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
246     {
247       DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
248       free((char *)ip_list);
249       continue;
250     }
251       
252     if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
253       nb_flags_str[strlen(nb_flags_str)-1] = '\0';
254       
255     /* Netbios name. # divides the name from the type (hex): netbios#xx */
256     pstrcpy(name,name_str);
257       
258     if((p = strchr(name,'#')) != NULL)
259     {
260       *p = 0;
261       sscanf(p+1,"%x",&type);
262     }
263       
264     /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
265     sscanf(nb_flags_str,"%x",&nb_flags);
266     sscanf(ttl_str,"%d",&ttl);
267
268     /* add all entries that have 60 seconds or more to live */
269     if ((ttl - 60) > time_now || ttl == PERMANENT_TTL)
270     {
271       struct name_record *namerec;
272
273       if(ttl != PERMANENT_TTL)
274         ttl -= time_now;
275     
276       DEBUG(4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
277            name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
278
279       namerec = add_name_to_subnet(wins_server_subnet, name, type, nb_flags, 
280                                    ttl, REGISTER_NAME, num_ips, ip_list);
281
282     }
283     else
284     {
285       DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
286              name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
287     }
288
289     free((char *)ip_list);
290   } 
291     
292   fclose(fp);
293   return True;
294 }
295
296 /****************************************************************************
297 Send a WINS WACK (Wait ACKnowledgement) response.
298 **************************************************************************/
299
300 static void send_wins_wack_response(int ttl, struct packet_struct *p)
301 {
302   struct nmb_packet *nmb = &p->packet.nmb;
303   unsigned char rdata[2];
304
305   rdata[0] = rdata[1] = 0;
306
307   /* Taken from nmblib.c - we need to send back almost
308      identical bytes from the requesting packet header. */
309
310   rdata[0] = (nmb->header.opcode & 0xF) << 3;
311   if (nmb->header.nm_flags.authoritative &&
312       nmb->header.response) rdata[0] |= 0x4;
313   if (nmb->header.nm_flags.trunc) rdata[0] |= 0x2;
314   if (nmb->header.nm_flags.recursion_desired) rdata[0] |= 0x1;
315   if (nmb->header.nm_flags.recursion_available &&
316       nmb->header.response) rdata[1] |= 0x80;
317   if (nmb->header.nm_flags.bcast) rdata[1] |= 0x10;
318
319   reply_netbios_packet(p,                             /* Packet to reply to. */
320                        0,                             /* Result code. */
321                        NMB_WAIT_ACK,                  /* nmbd type code. */
322                        NMB_WACK_OPCODE,               /* opcode. */
323                        ttl,                           /* ttl. */
324                        (char *)rdata,                 /* data to send. */
325                        2);                            /* data length. */
326 }
327
328 /****************************************************************************
329 Send a WINS name registration response.
330 **************************************************************************/
331
332 static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
333 {
334   struct nmb_packet *nmb = &p->packet.nmb;
335   char rdata[6];
336
337   memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
338
339   reply_netbios_packet(p,                             /* Packet to reply to. */
340                        rcode,                         /* Result code. */
341                        WINS_REG,                      /* nmbd type code. */
342                        NMB_NAME_REG_OPCODE,           /* opcode. */
343                        ttl,                           /* ttl. */
344                        rdata,                         /* data to send. */
345                        6);                            /* data length. */
346 }
347
348 /***********************************************************************
349  Deal with a name refresh request to a WINS server.
350 ************************************************************************/
351
352 void wins_process_name_refresh_request(struct subnet_record *subrec,
353                                             struct packet_struct *p)
354 {
355   struct nmb_packet *nmb = &p->packet.nmb;
356   struct nmb_name *question = &nmb->question.question_name;
357   BOOL bcast = nmb->header.nm_flags.bcast;
358   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
359   BOOL group = (nb_flags & NB_GROUP) ? True : False;
360   struct name_record *namerec = NULL;
361   int ttl = get_ttl_from_packet(nmb);
362   struct in_addr from_ip;
363
364   putip((char *)&from_ip,&nmb->additional->rdata[2]);
365
366   if(bcast)
367   {
368     /*
369      * We should only get unicast name refresh packets here.
370      * Anyone trying to refresh broadcast should not be going to a WINS
371      * server. Log an error here.
372      */
373
374     DEBUG(0,("wins_process_name_refresh_request: broadcast name refresh request \
375 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
376           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
377     return;
378   }
379
380   DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s \
381 IP %s\n", namestr(question), inet_ntoa(from_ip) ));
382
383   /* 
384    * See if the name already exists.
385    */
386
387   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
388
389   /*
390    * If this is a refresh request and the name doesn't exist then
391    * fail it.
392    */
393
394   if(namerec == NULL)
395   {
396     DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s and \
397 the name does not exist.\n", namestr(question) ));
398     send_wins_name_registration_response(NAM_ERR, 0, p);
399     return;
400   }
401
402   /*
403    * Check that the group bits for the refreshing name and the
404    * name in our database match.
405    */
406
407   if((namerec != NULL) && ((group && !NAME_GROUP(namerec)) || (!group && NAME_GROUP(namerec))) )
408   {
409     DEBUG(3,("wins_process_name_refresh_request: Name %s group bit = %s \
410 does not match group bit in WINS for this name.\n", namestr(question), group ? "True" : "False" ));
411     send_wins_name_registration_response(RFS_ERR, 0, p);
412     return;
413   }
414
415   /*
416    * For a unique name check that the person refreshing the name is one of the registered IP
417    * addresses. If not - fail the refresh. Do the same for group names with a type of 0x1c.
418    * Just return success for unique 0x1d refreshes. For normal group names update the ttl
419    * and return success.
420    */
421
422   if((!group || (group && (question->name_type == 0x1c))) && find_ip_in_name_record(namerec, from_ip ))
423   {
424     /*
425      * Update the ttl.
426      */
427     update_name_ttl(namerec, ttl);
428     send_wins_name_registration_response(0, ttl, p);
429     return;
430   }
431   else if(group)
432   {
433     /* 
434      * Normal groups are all registered with an IP address of 255.255.255.255 
435      * so we can't search for the IP address.
436      */
437     update_name_ttl(namerec, ttl);
438     send_wins_name_registration_response(0, ttl, p);
439     return;
440   }
441   else if(!group && (question->name_type == 0x1d))
442   {
443     /*
444      * Special name type - just pretend the refresh succeeded.
445      */
446     send_wins_name_registration_response(0, ttl, p);
447     return;
448   }
449   else
450   {
451     /*
452      * Fail the refresh.
453      */
454
455     DEBUG(3,("wins_process_name_refresh_request: Name refresh for name %s with IP %s and \
456 is IP is not known to the name.\n", namestr(question), inet_ntoa(from_ip) ));
457     send_wins_name_registration_response(RFS_ERR, 0, p);
458     return;
459   }
460 }
461
462 /***********************************************************************
463  Deal with a name registration request query success to a client that
464  owned the name.
465
466  We have a locked pointer to the original packet stashed away in the
467  userdata pointer. The success here is actually a failure as it means
468  the client we queried wants to keep the name, so we must return
469  a registration failure to the original requestor.
470 ************************************************************************/
471
472 static void wins_register_query_success(struct subnet_record *subrec,
473                                              struct userdata_struct *userdata,
474                                              struct nmb_name *question_name,
475                                              struct in_addr ip,
476                                              struct res_rec *answers)
477 {
478   struct packet_struct *orig_reg_packet;
479
480   memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
481
482   DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
483 name %s. Rejecting registration request.\n", inet_ntoa(ip), namestr(question_name) ));
484
485   send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
486
487   orig_reg_packet->locked = False;
488   free_packet(orig_reg_packet);
489 }
490
491 /***********************************************************************
492  Deal with a name registration request query failure to a client that
493  owned the name.
494
495  We have a locked pointer to the original packet stashed away in the
496  userdata pointer. The failure here is actually a success as it means
497  the client we queried didn't want to keep the name, so we can remove
498  the old name record and then successfully add the new name.
499 ************************************************************************/
500
501 static void wins_register_query_fail(struct subnet_record *subrec,
502                                           struct response_record *rrec,
503                                           struct nmb_name *question_name,
504                                           int rcode)
505 {
506   struct userdata_struct *userdata = rrec->userdata;
507   struct packet_struct *orig_reg_packet;
508   struct nmb_packet *nmb;
509   struct name_record *namerec = NULL;
510   uint16 nb_flags;
511   BOOL group;
512
513   memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
514
515   nmb = &orig_reg_packet->packet.nmb;
516
517   nb_flags = get_nb_flags(nmb->additional->rdata);
518   group = (nb_flags & NB_GROUP) ? True : False;
519
520   /*
521    * We want to just add the name, as we now know the original owner
522    * didn't want it. But we can't just do that as an arbitary
523    * amount of time may have taken place between the name query
524    * request and this timeout/error response. So we check that
525    * the name still exists and is in the same state - if so
526    * we remove it and call wins_process_name_registration_request()
527    * as we know it will do the right thing now.
528    */
529
530   namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
531
532   if( (namerec != NULL)
533    && (namerec->data.source == REGISTER_NAME)
534    && ip_equal(rrec->packet->ip, *namerec->data.ip) )
535   {
536     remove_name_from_namelist( subrec, namerec);
537     namerec = NULL;
538   }
539
540   if(namerec == NULL)
541     wins_process_name_registration_request(subrec, orig_reg_packet);
542   else
543     DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
544 querying for name %s in order to replace it and this reply.\n", namestr(question_name) ));
545
546   orig_reg_packet->locked = False;
547   free_packet(orig_reg_packet);
548 }
549
550 /***********************************************************************
551  Deal with a name registration request to a WINS server.
552
553  Use the following pseudocode :
554
555  registering_group
556      |
557      |
558      +--------name exists
559      |                  |
560      |                  |
561      |                  +--- existing name is group
562      |                  |                      |
563      |                  |                      |
564      |                  |                      +--- add name (return).
565      |                  |
566      |                  |
567      |                  +--- exiting name is unique
568      |                                         |
569      |                                         |
570      |                                         +--- query existing owner (return).
571      |
572      |
573      +--------name doesn't exist
574                         |
575                         |
576                         +--- add name (return).
577
578  registering_unique
579      |
580      |
581      +--------name exists
582      |                  |
583      |                  |
584      |                  +--- existing name is group 
585      |                  |                      |
586      |                  |                      |
587      |                  |                      +--- fail add (return).
588      |                  | 
589      |                  |
590      |                  +--- exiting name is unique
591      |                                         |
592      |                                         |
593      |                                         +--- query existing owner (return).
594      |
595      |
596      +--------name doesn't exist
597                         |
598                         |
599                         +--- add name (return).
600
601  As can be seen from the above, the two cases may be collapsed onto each
602  other with the exception of the case where the name already exists and
603  is a group name. This case we handle with an if statement.
604  
605 ************************************************************************/
606
607 void wins_process_name_registration_request(struct subnet_record *subrec,
608                                             struct packet_struct *p)
609 {
610   struct nmb_packet *nmb = &p->packet.nmb;
611   struct nmb_name *question = &nmb->question.question_name;
612   BOOL bcast = nmb->header.nm_flags.bcast;
613   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
614   int ttl = get_ttl_from_packet(nmb);
615   struct name_record *namerec = NULL;
616   struct in_addr from_ip;
617   BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;;
618
619   putip((char *)&from_ip,&nmb->additional->rdata[2]);
620
621   if(bcast)
622   {
623     /*
624      * We should only get unicast name registration packets here.
625      * Anyone trying to register broadcast should not be going to a WINS
626      * server. Log an error here.
627      */
628
629     DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
630 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
631           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
632     return;
633   }
634
635   DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
636 IP %s\n", registering_group_name ? "Group" : "Unique", namestr(question), inet_ntoa(from_ip) ));
637
638   /*
639    * See if the name already exists.
640    */
641
642   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
643
644   /*
645    * Deal with the case where the name found was a dns entry.
646    * Remove it as we now have a NetBIOS client registering the
647    * name.
648    */
649
650   if( (namerec != NULL)
651    && ( (namerec->data.source == DNS_NAME)
652      || (namerec->data.source == DNSFAIL_NAME) ) )
653   {
654     DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
655 a dns lookup - removing it.\n", namestr(question) ));
656     remove_name_from_namelist( subrec, namerec );
657     namerec = NULL;
658   }
659
660   /*
661    * Reject if the name exists and is not a REGISTER_NAME.
662    * (ie. Don't allow any static names to be overwritten.
663    */
664
665   if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
666   {
667     DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
668 to register name %s. Name already exists in WINS with source type %d.\n",
669                 namestr(question), namerec->data.source ));
670     send_wins_name_registration_response(RFS_ERR, 0, p);
671     return;
672   }
673
674   /*
675    * Special policy decisions based on MS documentation.
676    * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
677    * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
678    */
679
680   /*
681    * A group name is always added as the local broadcast address, except
682    * for group names ending in 0x1c.
683    * Group names with type 0x1c are registered with individual IP addresses.
684    */
685
686   if(registering_group_name && (question->name_type != 0x1c))
687     from_ip = *interpret_addr2("255.255.255.255");
688
689   /*
690    * Ignore all attempts to register a unique 0x1d name, although return success.
691    */
692
693   if(!registering_group_name && (question->name_type == 0x1d))
694   {
695     DEBUG(3,("wins_process_name_registration_request: Ignoring request \
696 to register name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
697     send_wins_name_registration_response(0, ttl, p);
698     return;
699   }
700
701   /*
702    * Next two cases are the 'if statement' mentioned above.
703    */
704
705   if((namerec != NULL) && NAME_GROUP(namerec))
706   {
707     if(registering_group_name)
708     {
709       /*
710        * If we are adding a group name, the name exists and is also a group entry just add this
711        * IP address to it and update the ttl.
712        */
713
714       DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
715             inet_ntoa(from_ip), namestr(question) ));
716       /* 
717        * Check the ip address is not already in the group.
718        */
719       if(!find_ip_in_name_record(namerec, from_ip))
720         add_ip_to_name_record(namerec, from_ip);
721       update_name_ttl(namerec, ttl);
722       send_wins_name_registration_response(0, ttl, p);
723       return;
724     }
725     else
726     {
727       /*
728        * If we are adding a unique name, the name exists in the WINS db 
729        * and is a group name then reject the registration.
730        */
731
732       DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
733 already exists in WINS as a GROUP name.\n", namestr(question) ));
734       send_wins_name_registration_response(RFS_ERR, 0, p);
735       return;
736     } 
737   }
738
739   /*
740    * From here on down we know that if the name exists in the WINS db it is
741    * a unique name, not a group name.
742    */
743
744   /* 
745    * If the name exists and is one of our names then check the
746    * registering IP address. If it's not one of ours then automatically
747    * reject without doing the query - we know we will reject it.
748    */
749
750   if((namerec != NULL) && (is_myname(namerec->name.name)) )
751   {
752     if(!ismyip(from_ip))
753     {
754       DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
755 is one of our (WINS server) names. Denying registration.\n", namestr(question) ));
756       send_wins_name_registration_response(RFS_ERR, 0, p);
757       return;
758     }
759     else
760     {
761       /*
762        * It's one of our names and one of our IP's - update the ttl.
763        */
764       update_name_ttl(namerec, ttl);
765       send_wins_name_registration_response(0, ttl, p);
766       return;
767     }
768   }
769
770   /*
771    * If the name exists and it is a unique registration and the registering IP 
772    * is the same as the the (single) already registered IP then just update the ttl.
773    */
774
775   if( !registering_group_name
776    && (namerec != NULL)
777    && (namerec->data.num_ips == 1)
778    && ip_equal( namerec->data.ip[0], from_ip ) )
779   {
780     update_name_ttl( namerec, ttl );
781     send_wins_name_registration_response( 0, ttl, p );
782     return;
783   }
784
785   /*
786    * Finally if the name exists do a query to the registering machine 
787    * to see if they still claim to have the name.
788    */
789
790   if( namerec != NULL )
791   {
792     char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
793     struct userdata_struct *userdata = (struct userdata_struct *)ud;
794
795     /*
796      * First send a WACK to the registering machine.
797      */
798
799     send_wins_wack_response(60, p);
800
801     /*
802      * When the reply comes back we need the original packet.
803      * Lock this so it won't be freed and then put it into
804      * the userdata structure.
805      */
806
807     p->locked = True;
808
809     userdata = (struct userdata_struct *)ud;
810
811     userdata->copy_fn = NULL;
812     userdata->free_fn = NULL;
813     userdata->userdata_len = sizeof(struct packet_struct *);
814     memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
815
816     /*
817      * Use the new call to send a query directly to an IP address.
818      * This sends the query directly to the IP address, and ensures
819      * the recursion desired flag is not set (you were right Luke :-).
820      * This function should *only* be called from the WINS server
821      * code. JRA.
822      */
823
824     query_name_from_wins_server( *namerec->data.ip,
825                                   question->name,
826                                   question->name_type, 
827                                   wins_register_query_success,
828                                   wins_register_query_fail,
829                                   userdata );
830     return;
831   }
832
833   /*
834    * Name did not exist - add it.
835    */
836
837   add_name_to_subnet(subrec, question->name, question->name_type,
838                      nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
839
840   send_wins_name_registration_response(0, ttl, p);
841 }
842
843 /***********************************************************************
844  Deal with a mutihomed name query success to the machine that
845  requested the multihomed name registration.
846
847  We have a locked pointer to the original packet stashed away in the
848  userdata pointer.
849 ************************************************************************/
850
851 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
852                                              struct userdata_struct *userdata,
853                                              struct nmb_name *question_name,
854                                              struct in_addr ip,
855                                              struct res_rec *answers)
856 {
857   struct packet_struct *orig_reg_packet;
858   struct nmb_packet *nmb;
859   struct name_record *namerec = NULL;
860   struct in_addr from_ip;
861   int ttl;
862
863   memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
864
865   nmb = &orig_reg_packet->packet.nmb;
866
867   putip((char *)&from_ip,&nmb->additional->rdata[2]);
868   ttl = get_ttl_from_packet(nmb);
869
870   /*
871    * We want to just add the new IP, as we now know the requesting
872    * machine claims to own it. But we can't just do that as an arbitary
873    * amount of time may have taken place between the name query
874    * request and this response. So we check that
875    * the name still exists and is in the same state - if so
876    * we just add the extra IP and update the ttl.
877    */
878
879   namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
880
881   if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) )
882   {
883     DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
884 a subsequent IP addess.\n", namestr(question_name) ));
885     send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
886     return;
887   }
888
889   if(!find_ip_in_name_record(namerec, from_ip))
890     add_ip_to_name_record(namerec, from_ip);
891   update_name_ttl(namerec, ttl);
892   send_wins_name_registration_response(0, ttl, orig_reg_packet);
893
894 }
895
896 /***********************************************************************
897  Deal with a name registration request query failure to a client that
898  owned the name.
899
900  We have a locked pointer to the original packet stashed away in the
901  userdata pointer.
902 ************************************************************************/
903
904 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
905                                           struct response_record *rrec,
906                                           struct nmb_name *question_name,
907                                           int rcode)
908 {
909   struct userdata_struct *userdata = rrec->userdata;
910   struct packet_struct *orig_reg_packet;
911
912   memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
913
914   DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
915 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), namestr(question_name) ));
916   send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
917   return;
918 }
919
920 /***********************************************************************
921  Deal with a multihomed name registration request to a WINS server.
922  These cannot be group name registrations.
923 ***********************************************************************/
924
925 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
926                                                         struct packet_struct *p)
927 {
928   struct nmb_packet *nmb = &p->packet.nmb;
929   struct nmb_name *question = &nmb->question.question_name;
930   BOOL bcast = nmb->header.nm_flags.bcast;
931   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
932   int ttl = get_ttl_from_packet(nmb);
933   struct name_record *namerec = NULL;
934   struct in_addr from_ip;
935   BOOL group = (nb_flags & NB_GROUP) ? True : False;;
936
937   putip((char *)&from_ip,&nmb->additional->rdata[2]);
938
939   if(bcast)
940   {
941     /*
942      * We should only get unicast name registration packets here.
943      * Anyone trying to register broadcast should not be going to a WINS
944      * server. Log an error here.
945      */
946
947     DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
948 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
949           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
950     return;
951   }
952
953   /*
954    * Only unique names should be registered multihomed.
955    */
956
957   if(group)
958   {
959     DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
960 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
961           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
962     return;
963   }
964
965   DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
966 IP %s\n", namestr(question), inet_ntoa(from_ip) ));
967
968   /*
969    * Deal with policy regarding 0x1d names.
970    */
971
972   if(question->name_type == 0x1d)
973   {
974     DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
975 to register name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
976     send_wins_name_registration_response(0, ttl, p);  
977     return;
978   }
979
980   /*
981    * See if the name already exists.
982    */
983
984   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
985
986   /*
987    * Deal with the case where the name found was a dns entry.
988    * Remove it as we now have a NetBIOS client registering the
989    * name.
990    */
991
992   if( (namerec != NULL)
993    && ( (namerec->data.source == DNS_NAME)
994      || (namerec->data.source == DNSFAIL_NAME) ) )
995   {
996     DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
997 - removing it.\n", namestr(question) ));
998     remove_name_from_namelist( subrec, namerec);
999     namerec = NULL;
1000   }
1001
1002   /*
1003    * Reject if the name exists and is not a REGISTER_NAME.
1004    * (ie. Don't allow any static names to be overwritten.
1005    */
1006
1007   if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
1008   {
1009     DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1010 to register name %s. Name already exists in WINS with source type %d.\n",
1011     namestr(question), namerec->data.source ));
1012     send_wins_name_registration_response(RFS_ERR, 0, p);
1013     return;
1014   }
1015
1016   /*
1017    * Reject if the name exists and is a GROUP name.
1018    */
1019
1020   if((namerec != NULL) && NAME_GROUP(namerec))
1021   {
1022     DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1023 already exists in WINS as a GROUP name.\n", namestr(question) ));
1024     send_wins_name_registration_response(RFS_ERR, 0, p);
1025     return;
1026   } 
1027
1028   /*
1029    * From here on down we know that if the name exists in the WINS db it is
1030    * a unique name, not a group name.
1031    */
1032
1033   /*
1034    * If the name exists and is one of our names then check the
1035    * registering IP address. If it's not one of ours then automatically
1036    * reject without doing the query - we know we will reject it.
1037    */
1038
1039   if((namerec != NULL) && (is_myname(namerec->name.name)) )
1040   {
1041     if(!ismyip(from_ip))
1042     {
1043       DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1044 is one of our (WINS server) names. Denying registration.\n", namestr(question) ));
1045       send_wins_name_registration_response(RFS_ERR, 0, p);
1046       return;
1047     }
1048     else
1049     {
1050       /*
1051        * It's one of our names and one of our IP's. Ensure the IP is in the record and
1052        *  update the ttl.
1053        */
1054       if(!find_ip_in_name_record(namerec, from_ip))
1055         add_ip_to_name_record(namerec, from_ip);
1056       update_name_ttl(namerec, ttl);
1057       send_wins_name_registration_response(0, ttl, p);
1058       return;
1059     }
1060   }
1061
1062   /*
1063    * If the name exists check if the IP address is already registered
1064    * to that name. If so then update the ttl and reply success.
1065    */
1066
1067   if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip))
1068   {
1069     update_name_ttl(namerec, ttl);
1070     send_wins_name_registration_response(0, ttl, p);
1071     return;
1072   }
1073
1074   /*
1075    * If the name exists do a query to the owner
1076    * to see if they still want the name.
1077    */
1078
1079   if(namerec != NULL)
1080   {
1081     char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
1082     struct userdata_struct *userdata = (struct userdata_struct *)ud;
1083
1084     /*
1085      * First send a WACK to the registering machine.
1086      */
1087
1088     send_wins_wack_response(60, p);
1089
1090     /*
1091      * When the reply comes back we need the original packet.
1092      * Lock this so it won't be freed and then put it into
1093      * the userdata structure.
1094      */
1095
1096     p->locked = True;
1097
1098     userdata = (struct userdata_struct *)ud;
1099
1100     userdata->copy_fn = NULL;
1101     userdata->free_fn = NULL;
1102     userdata->userdata_len = sizeof(struct packet_struct *);
1103     memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1104
1105     /*
1106      * As query_name uses the subnet broadcast address as the destination
1107      * of the packet we temporarily change the subnet broadcast address to
1108      * be the IP address of the requesting machine and send the packet. This
1109      * is a *horrible* hack but the alternative is to add the destination
1110      * address parameter to all query_name() calls. I hate this code :-).
1111      */
1112
1113     subrec->bcast_ip = p->ip;
1114     query_name( subrec, question->name, question->name_type,
1115                 wins_multihomed_register_query_success, 
1116                 wins_multihomed_register_query_fail,
1117                 userdata);
1118     subrec->bcast_ip = ipzero;
1119     return;
1120   }
1121
1122   /*
1123    * Name did not exist - add it.
1124    */
1125
1126   add_name_to_subnet(subrec, question->name, question->name_type,
1127                      nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1128
1129   send_wins_name_registration_response(0, ttl, p);
1130 }
1131
1132 /***********************************************************************
1133  Deal with the special name query for *<1b>.
1134 ***********************************************************************/
1135    
1136 static void process_wins_dmb_query_request(struct subnet_record *subrec,  
1137                                            struct packet_struct *p)
1138 {  
1139   struct name_record *namerec = NULL;
1140   char *prdata;
1141   int num_ips;
1142
1143   /*
1144    * Go through all the names in the WINS db looking for those
1145    * ending in <1b>. Use this to calculate the number of IP
1146    * addresses we need to return.
1147    */
1148
1149   num_ips = 0;
1150   for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1151        namerec;
1152        namerec = (struct name_record *)ubi_trNext( namerec ) )
1153   {
1154     if( namerec->name.name_type == 0x1b )
1155       num_ips += namerec->data.num_ips;
1156   }
1157
1158   if(num_ips == 0)
1159   {
1160     /*
1161      * There are no 0x1b names registered. Return name query fail.
1162      */
1163     send_wins_name_query_response(NAM_ERR, p, NULL);
1164     return;
1165   }
1166
1167   if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
1168   {
1169     DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1170     return;
1171   }
1172
1173   /*
1174    * Go through all the names again in the WINS db looking for those
1175    * ending in <1b>. Add their IP addresses into the list we will
1176    * return.
1177    */ 
1178
1179   num_ips = 0;
1180   for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1181        namerec;
1182        namerec = (struct name_record *)ubi_trNext( namerec ) )
1183   {
1184     if(namerec->name.name_type == 0x1b)
1185     {
1186       int i;
1187       for(i = 0; i < namerec->data.num_ips; i++)
1188       {
1189         set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1190         putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1191         num_ips++;
1192       }
1193     }
1194   }
1195
1196   /*
1197    * Send back the reply containing the IP list.
1198    */
1199
1200   reply_netbios_packet(p,                             /* Packet to reply to. */
1201                        0,                             /* Result code. */
1202                        WINS_QUERY,                    /* nmbd type code. */
1203                        NMB_NAME_QUERY_OPCODE,         /* opcode. */
1204                        lp_min_wins_ttl(),             /* ttl. */
1205                        prdata,                        /* data to send. */
1206                        num_ips*6);                    /* data length. */
1207
1208   free(prdata);
1209 }
1210
1211 /****************************************************************************
1212 Send a WINS name query response.
1213 **************************************************************************/
1214
1215 void send_wins_name_query_response(int rcode, struct packet_struct *p, 
1216                                           struct name_record *namerec)
1217 {
1218   char rdata[6];
1219   char *prdata = rdata;
1220   int reply_data_len = 0;
1221   int ttl = 0;
1222   int i = 0;
1223   int j;
1224
1225   bzero(rdata,6);
1226
1227   if(rcode == 0)
1228   {
1229     int same_net_index = -1;
1230
1231     ttl = (namerec->data.death_time != PERMANENT_TTL) ?
1232              namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1233
1234     /* Copy all known ip addresses into the return data. */
1235     /* Optimise for the common case of one IP address so
1236        we don't need a malloc. */
1237
1238     if( namerec->data.num_ips == 1 )
1239       prdata = rdata;
1240     else
1241     {
1242       if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
1243       {
1244         DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1245         return;
1246       }
1247
1248       /* 
1249        * Look over the known IP addresses and see if one of them
1250        * is on the same (local) net as the requesting IP address. If so then
1251        * put that IP address into the packet as the first IP.
1252        * We can only do this for local nets as they're the only
1253        * ones we know the netmask for.
1254        */
1255
1256       i = 0;
1257
1258       if(is_local_net(p->ip))
1259       {
1260         struct in_addr *n_mask = iface_nmask(p->ip);
1261
1262         for( j = 0; j < namerec->data.num_ips; j++)
1263         {
1264           if(same_net( namerec->data.ip[j], p->ip, *n_mask))
1265           {
1266             set_nb_flags(&prdata[0],namerec->data.nb_flags);
1267             putip((char *)&prdata[2], &namerec->data.ip[j]);
1268             same_net_index = j;
1269             i = 1;
1270           }
1271         }
1272       }
1273     }
1274
1275     for(j = 0; j < namerec->data.num_ips; j++)
1276     {
1277       if(j == same_net_index)
1278         continue;
1279       set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1280       putip((char *)&prdata[2+(i*6)], &namerec->data.ip[j]);
1281       i++;
1282     }
1283     reply_data_len = namerec->data.num_ips * 6;
1284
1285   }
1286
1287   reply_netbios_packet(p,                             /* Packet to reply to. */
1288                        rcode,                         /* Result code. */
1289                        WINS_QUERY,                    /* nmbd type code. */
1290                        NMB_NAME_QUERY_OPCODE,         /* opcode. */
1291                        ttl,                           /* ttl. */
1292                        prdata,                        /* data to send. */
1293                        reply_data_len);               /* data length. */
1294
1295   if((prdata != rdata) && (prdata != NULL))
1296     free(prdata);
1297 }
1298
1299 /***********************************************************************
1300  Deal with a name query.
1301 ***********************************************************************/
1302
1303 void wins_process_name_query_request(struct subnet_record *subrec, 
1304                                      struct packet_struct *p)
1305 {
1306   struct nmb_packet *nmb = &p->packet.nmb;
1307   struct nmb_name *question = &nmb->question.question_name;
1308   struct name_record *namerec = NULL;
1309
1310   DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n", 
1311             namestr(question), inet_ntoa(p->ip) ));
1312
1313   /*
1314    * Special name code. If the queried name is *<1b> then search
1315    * the entire WINS database and return a list of all the IP addresses
1316    * registered to any <1b> name. This is to allow domain master browsers
1317    * to discover other domains that may not have a presence on their subnet.
1318    */
1319
1320   if(strequal( question->name, "*") && (question->name_type == 0x1b))
1321   {
1322     process_wins_dmb_query_request( subrec, p);
1323     return;
1324   }
1325
1326   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1327
1328   if(namerec != NULL)
1329   {
1330     /* 
1331      * If it's a DNSFAIL_NAME then reply name not found.
1332      */
1333
1334     if( namerec->data.source == DNSFAIL_NAME )
1335     {
1336       DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1337              namestr(question) ));
1338       send_wins_name_query_response(NAM_ERR, p, namerec);
1339       return;
1340     }
1341
1342     /*
1343      * If the name has expired then reply name not found.
1344      */
1345
1346     if( (namerec->data.death_time != PERMANENT_TTL)
1347      && (namerec->data.death_time < p->timestamp) )
1348     {
1349       DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1350                 namestr(question) ));
1351       send_wins_name_query_response(NAM_ERR, p, namerec);
1352       return;
1353     }
1354
1355     DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1356            namestr(question), inet_ntoa(namerec->data.ip[0]) ));
1357
1358     send_wins_name_query_response(0, p, namerec);
1359     return;
1360   }
1361
1362   /* 
1363    * Name not found in WINS - try a dns query if it's a 0x20 name.
1364    */
1365
1366   if(lp_dns_proxy() && 
1367      ((question->name_type == 0x20) || question->name_type == 0))
1368   {
1369
1370     DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1371               namestr(question) ));
1372
1373     queue_dns_query(p, question, &namerec);
1374     return;
1375   }
1376
1377   /*
1378    * Name not found - return error.
1379    */
1380
1381   send_wins_name_query_response(NAM_ERR, p, NULL);
1382 }
1383
1384 /****************************************************************************
1385 Send a WINS name release response.
1386 **************************************************************************/
1387
1388 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1389 {
1390   struct nmb_packet *nmb = &p->packet.nmb;
1391   char rdata[6];
1392
1393   memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1394
1395   reply_netbios_packet(p,                            /* Packet to reply to. */
1396                        rcode,                        /* Result code. */
1397                        NMB_REL,                      /* nmbd type code. */
1398                        NMB_NAME_RELEASE_OPCODE,      /* opcode. */
1399                        0,                            /* ttl. */
1400                        rdata,                        /* data to send. */
1401                        6);                           /* data length. */
1402 }
1403
1404 /***********************************************************************
1405  Deal with a name release.
1406 ***********************************************************************/
1407
1408 void wins_process_name_release_request(struct subnet_record *subrec,
1409                                        struct packet_struct *p)
1410 {
1411   struct nmb_packet *nmb = &p->packet.nmb;
1412   struct nmb_name *question = &nmb->question.question_name;
1413   BOOL bcast = nmb->header.nm_flags.bcast;
1414   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1415   struct name_record *namerec = NULL;
1416   struct in_addr from_ip;
1417   BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1418
1419   putip((char *)&from_ip,&nmb->additional->rdata[2]);
1420
1421   if(bcast)
1422   {
1423     /*
1424      * We should only get unicast name registration packets here.
1425      * Anyone trying to register broadcast should not be going to a WINS
1426      * server. Log an error here.
1427      */
1428
1429     DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1430 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1431           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1432     return;
1433   }
1434   
1435   DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1436 IP %s\n", releasing_group_name ? "Group" : "Unique", namestr(question), inet_ntoa(from_ip) ));
1437     
1438   /*
1439    * Deal with policy regarding 0x1d names.
1440    */
1441
1442   if(!releasing_group_name && (question->name_type == 0x1d))
1443   {
1444     DEBUG(3,("wins_process_name_release_request: Ignoring request \
1445 to release name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
1446     send_wins_name_release_response(0, p);
1447     return;
1448   }
1449
1450   /*
1451    * See if the name already exists.
1452    */
1453     
1454   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1455
1456   if( (namerec == NULL)
1457    || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
1458   {
1459     send_wins_name_release_response(NAM_ERR, p);
1460     return;
1461   }
1462
1463   /* 
1464    * Check that the sending machine has permission to release this name.
1465    * If it's a group name not ending in 0x1c then just say yes and let
1466    * the group time out.
1467    */
1468
1469   if(releasing_group_name && (question->name_type != 0x1c))
1470   {
1471     send_wins_name_release_response(0, p);
1472     return;
1473   }
1474
1475   /* 
1476    * Check that the releasing node is on the list of IP addresses
1477    * for this name. Disallow the release if not.
1478    */
1479
1480   if(!find_ip_in_name_record(namerec, from_ip))
1481   {
1482     DEBUG(3,("wins_process_name_release_request: Refusing request to \
1483 release name %s as IP %s is not one of the known IP's for this name.\n",
1484            namestr(question), inet_ntoa(from_ip) ));
1485     send_wins_name_release_response(NAM_ERR, p);
1486     return;
1487   }    
1488
1489   /* 
1490    * Release the name and then remove the IP from the known list.
1491    */
1492
1493   send_wins_name_release_response(0, p);
1494   remove_ip_from_name_record(namerec, from_ip);
1495
1496   /* 
1497    * Remove the name entirely if no IP addresses left.
1498    */
1499   if (namerec->data.num_ips == 0)
1500     remove_name_from_namelist(subrec, namerec);
1501
1502 }
1503
1504 /*******************************************************************
1505  WINS time dependent processing.
1506 ******************************************************************/
1507
1508 void initiate_wins_processing(time_t t)
1509 {
1510   static time_t lasttime = 0;
1511
1512   if (!lasttime)
1513     lasttime = t;
1514   if (t - lasttime < 5)
1515     return;
1516
1517   if(!lp_we_are_a_wins_server())
1518     return;
1519
1520   expire_names_on_subnet(wins_server_subnet, t);
1521
1522   if(wins_server_subnet->namelist_changed)
1523     wins_write_database();
1524
1525   wins_server_subnet->namelist_changed = False;
1526 }
1527
1528 /*******************************************************************
1529  Write out the current WINS database.
1530 ******************************************************************/
1531
1532 void wins_write_database(void)
1533 {
1534   struct name_record *namerec;
1535   pstring fname, fnamenew;
1536    
1537   FILE *fp;
1538    
1539   if(!lp_we_are_a_wins_server())
1540     return;
1541
1542   pstrcpy(fname,lp_lockdir());
1543   trim_string(fname,NULL,"/");
1544   pstrcat(fname,"/");
1545   pstrcat(fname,WINS_LIST);
1546   pstrcpy(fnamenew,fname);
1547   pstrcat(fnamenew,".");
1548
1549   if((fp = fopen(fnamenew,"w")) == NULL)
1550   {
1551     DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1552     return;
1553   }
1554
1555   DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1556  
1557   for( namerec 
1558            = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
1559        namerec;
1560        namerec = (struct name_record *)ubi_trNext( namerec ) )
1561   {
1562     int i;
1563     struct tm *tm;
1564
1565     DEBUG(4,("%-19s ", namestr(&namerec->name) ));
1566
1567     if( namerec->data.death_time != PERMANENT_TTL )
1568     {
1569       tm = LocalTime(&namerec->data.death_time);
1570       DEBUG(4,("TTL = %s", asctime(tm) ));
1571     }
1572     else
1573       DEBUG(4,("TTL = PERMANENT\t"));
1574
1575     for (i = 0; i < namerec->data.num_ips; i++)
1576       DEBUG(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
1577     DEBUG(4,("%2x\n", namerec->data.nb_flags ));
1578
1579     if( namerec->data.source == REGISTER_NAME )
1580     {
1581       fprintf(fp, "\"%s#%02x\" %d ",
1582               namerec->name.name,namerec->name.name_type, /* Ignore scope. */
1583               (int)namerec->data.death_time);
1584
1585       for (i = 0; i < namerec->data.num_ips; i++)
1586         fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
1587       fprintf( fp, "%2xR\n", namerec->data.nb_flags );
1588     }
1589   }
1590   
1591   fclose(fp);
1592   unlink(fname);
1593   chmod(fnamenew,0644);
1594   rename(fnamenew,fname);
1595 }