"For I have laboured mightily on Luke's code, and hath broken
[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   fstring 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   fstrcpy(fname,lp_lockdir());
135   trim_string(fname,NULL,"/");
136   strcat(fname,"/");
137   strcat(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) && (namerec->source == REGISTER_NAME) && 
533             ip_equal(rrec->packet->ip, *namerec->ip) )
534   {
535     remove_name_from_namelist( subrec, namerec);
536     namerec = NULL;
537   }
538
539   if(namerec == NULL)
540     wins_process_name_registration_request(subrec, orig_reg_packet);
541   else
542     DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
543 querying for name %s in order to replace it and this reply.\n", namestr(question_name) ));
544
545   orig_reg_packet->locked = False;
546   free_packet(orig_reg_packet);
547 }
548
549 /***********************************************************************
550  Deal with a name registration request to a WINS server.
551
552  Use the following pseudocode :
553
554  registering_group
555      |
556      |
557      +--------name exists
558      |                  |
559      |                  |
560      |                  +--- existing name is group
561      |                  |                      |
562      |                  |                      |
563      |                  |                      +--- add name (return).
564      |                  |
565      |                  |
566      |                  +--- exiting name is unique
567      |                                         |
568      |                                         |
569      |                                         +--- query existing owner (return).
570      |
571      |
572      +--------name doesn't exist
573                         |
574                         |
575                         +--- add name (return).
576
577  registering_unique
578      |
579      |
580      +--------name exists
581      |                  |
582      |                  |
583      |                  +--- existing name is group 
584      |                  |                      |
585      |                  |                      |
586      |                  |                      +--- fail add (return).
587      |                  | 
588      |                  |
589      |                  +--- exiting name is unique
590      |                                         |
591      |                                         |
592      |                                         +--- query existing owner (return).
593      |
594      |
595      +--------name doesn't exist
596                         |
597                         |
598                         +--- add name (return).
599
600  As can be seen from the above, the two cases may be collapsed onto each
601  other with the exception of the case where the name already exists and
602  is a group name. This case we handle with an if statement.
603  
604 ************************************************************************/
605
606 void wins_process_name_registration_request(struct subnet_record *subrec,
607                                             struct packet_struct *p)
608 {
609   struct nmb_packet *nmb = &p->packet.nmb;
610   struct nmb_name *question = &nmb->question.question_name;
611   BOOL bcast = nmb->header.nm_flags.bcast;
612   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
613   int ttl = get_ttl_from_packet(nmb);
614   struct name_record *namerec = NULL;
615   struct in_addr from_ip;
616   BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;;
617
618   putip((char *)&from_ip,&nmb->additional->rdata[2]);
619
620   if(bcast)
621   {
622     /*
623      * We should only get unicast name registration packets here.
624      * Anyone trying to register broadcast should not be going to a WINS
625      * server. Log an error here.
626      */
627
628     DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
629 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
630           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
631     return;
632   }
633
634   DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
635 IP %s\n", registering_group_name ? "Group" : "Unique", namestr(question), inet_ntoa(from_ip) ));
636
637   /*
638    * See if the name already exists.
639    */
640
641   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
642
643   /*
644    * Deal with the case where the name found was a dns entry.
645    * Remove it as we now have a NetBIOS client registering the
646    * name.
647    */
648
649   if((namerec != NULL) && ((namerec->source == DNS_NAME) || (namerec->source == DNSFAIL_NAME)))
650   {
651     DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was a dns lookup \
652 - removing it.\n", namestr(question) ));
653     remove_name_from_namelist( subrec, namerec);
654     namerec = NULL;
655   }
656
657   /*
658    * Reject if the name exists and is not a REGISTER_NAME.
659    * (ie. Don't allow any static names to be overwritten.
660    */
661
662   if((namerec != NULL) && (namerec->source != REGISTER_NAME))
663   {
664     DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
665 already exists in WINS with source type %d.\n", namestr(question), namerec->source ));
666     send_wins_name_registration_response(RFS_ERR, 0, p);
667     return;
668   }
669
670   /*
671    * Special policy decisions based on MS documentation.
672    * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
673    * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
674    */
675
676   /*
677    * A group name is always added as the local broadcast address, except
678    * for group names ending in 0x1c.
679    * Group names with type 0x1c are registered with individual IP addresses.
680    */
681
682   if(registering_group_name && (question->name_type != 0x1c))
683     from_ip = *interpret_addr2("255.255.255.255");
684
685   /*
686    * Ignore all attempts to register a unique 0x1d name, although return success.
687    */
688
689   if(!registering_group_name && (question->name_type == 0x1d))
690   {
691     DEBUG(3,("wins_process_name_registration_request: Ignoring request \
692 to register name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
693     send_wins_name_registration_response(0, ttl, p);
694     return;
695   }
696
697   /*
698    * Next two cases are the 'if statement' mentioned above.
699    */
700
701   if((namerec != NULL) && NAME_GROUP(namerec))
702   {
703     if(registering_group_name)
704     {
705       /*
706        * If we are adding a group name, the name exists and is also a group entry just add this
707        * IP address to it and update the ttl.
708        */
709
710       DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
711             inet_ntoa(from_ip), namestr(question) ));
712       /* 
713        * Check the ip address is not already in the group.
714        */
715       if(!find_ip_in_name_record(namerec, from_ip))
716         add_ip_to_name_record(namerec, from_ip);
717       update_name_ttl(namerec, ttl);
718       send_wins_name_registration_response(0, ttl, p);
719       return;
720     }
721     else
722     {
723       /*
724        * If we are adding a unique name, the name exists in the WINS db 
725        * and is a group name then reject the registration.
726        */
727
728       DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
729 already exists in WINS as a GROUP name.\n", namestr(question) ));
730       send_wins_name_registration_response(RFS_ERR, 0, p);
731       return;
732     } 
733   }
734
735   /*
736    * From here on down we know that if the name exists in the WINS db it is
737    * a unique name, not a group name.
738    */
739
740   /* 
741    * If the name exists and is one of our names then check the
742    * registering IP address. If it's not one of ours then automatically
743    * reject without doing the query - we know we will reject it.
744    */
745
746   if((namerec != NULL) && (is_myname(namerec->name.name)) )
747   {
748     if(!ismyip(from_ip))
749     {
750       DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
751 is one of our (WINS server) names. Denying registration.\n", namestr(question) ));
752       send_wins_name_registration_response(RFS_ERR, 0, p);
753       return;
754     }
755     else
756     {
757       /*
758        * It's one of our names and one of our IP's - update the ttl.
759        */
760       update_name_ttl(namerec, ttl);
761       send_wins_name_registration_response(0, ttl, p);
762       return;
763     }
764   }
765
766   /*
767    * If the name exists and it is a unique registration and the registering IP 
768    * is the same as the the (single) already registered IP then just update the ttl.
769    */
770
771   if(!registering_group_name && (namerec != NULL) && (namerec->num_ips == 1) && 
772            ip_equal(namerec->ip[0], from_ip))
773   {
774     update_name_ttl(namerec, ttl);
775     send_wins_name_registration_response(0, ttl, p);
776     return;
777   }
778
779   /*
780    * Finally if the name exists do a query to the registering machine 
781    * to see if they still claim to have the name.
782    */
783
784   if(namerec != NULL)
785   {
786     char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
787     struct userdata_struct *userdata = (struct userdata_struct *)ud;
788
789     /*
790      * First send a WACK to the registering machine.
791      */
792
793     send_wins_wack_response(60, p);
794
795     /*
796      * When the reply comes back we need the original packet.
797      * Lock this so it won't be freed and then put it into
798      * the userdata structure.
799      */
800
801     p->locked = True;
802
803     userdata = (struct userdata_struct *)ud;
804
805     userdata->copy_fn = NULL;
806     userdata->free_fn = NULL;
807     userdata->userdata_len = sizeof(struct packet_struct *);
808     memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
809
810     /*
811      * As query_name uses the subnet broadcast address as the destination
812      * of the packet we temporarily change the subnet broadcast address to
813      * be the first IP address of the name owner and send the packet. This
814      * is a *horrible* hack but the alternative is to add the destination
815      * address parameter to all query_name() calls. I hate this code :-).
816      */
817
818     subrec->bcast_ip = *namerec->ip;
819
820     query_name( subrec, question->name, question->name_type, 
821                 wins_register_query_success,
822                 wins_register_query_fail,
823                 userdata);
824     subrec->bcast_ip = ipzero;
825     return;
826   }
827
828   /*
829    * Name did not exist - add it.
830    */
831
832   add_name_to_subnet(subrec, question->name, question->name_type,
833                      nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
834
835   send_wins_name_registration_response(0, ttl, p);
836 }
837
838 /***********************************************************************
839  Deal with a mutihomed name query success to the machine that
840  requested the multihomed name registration.
841
842  We have a locked pointer to the original packet stashed away in the
843  userdata pointer.
844 ************************************************************************/
845
846 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
847                                              struct userdata_struct *userdata,
848                                              struct nmb_name *question_name,
849                                              struct in_addr ip,
850                                              struct res_rec *answers)
851 {
852   struct packet_struct *orig_reg_packet;
853   struct nmb_packet *nmb;
854   struct name_record *namerec = NULL;
855   struct in_addr from_ip;
856   int ttl;
857
858   memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
859
860   nmb = &orig_reg_packet->packet.nmb;
861
862   putip((char *)&from_ip,&nmb->additional->rdata[2]);
863   ttl = get_ttl_from_packet(nmb);
864
865   /*
866    * We want to just add the new IP, as we now know the requesting
867    * machine claims to own it. But we can't just do that as an arbitary
868    * amount of time may have taken place between the name query
869    * request and this response. So we check that
870    * the name still exists and is in the same state - if so
871    * we just add the extra IP and update the ttl.
872    */
873
874   namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
875
876   if( (namerec == NULL) || (namerec->source != REGISTER_NAME) )
877   {
878     DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
879 a subsequent IP addess.\n", namestr(question_name) ));
880     send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
881     return;
882   }
883
884   if(!find_ip_in_name_record(namerec, from_ip))
885     add_ip_to_name_record(namerec, from_ip);
886   update_name_ttl(namerec, ttl);
887   send_wins_name_registration_response(0, ttl, orig_reg_packet);
888
889 }
890
891 /***********************************************************************
892  Deal with a name registration request query failure to a client that
893  owned the name.
894
895  We have a locked pointer to the original packet stashed away in the
896  userdata pointer.
897 ************************************************************************/
898
899 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
900                                           struct response_record *rrec,
901                                           struct nmb_name *question_name,
902                                           int rcode)
903 {
904   struct userdata_struct *userdata = rrec->userdata;
905   struct packet_struct *orig_reg_packet;
906
907   memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
908
909   DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
910 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), namestr(question_name) ));
911   send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
912   return;
913 }
914
915 /***********************************************************************
916  Deal with a multihomed name registration request to a WINS server.
917  These cannot be group name registrations.
918 ***********************************************************************/
919
920 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
921                                                         struct packet_struct *p)
922 {
923   struct nmb_packet *nmb = &p->packet.nmb;
924   struct nmb_name *question = &nmb->question.question_name;
925   BOOL bcast = nmb->header.nm_flags.bcast;
926   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
927   int ttl = get_ttl_from_packet(nmb);
928   struct name_record *namerec = NULL;
929   struct in_addr from_ip;
930   BOOL group = (nb_flags & NB_GROUP) ? True : False;;
931
932   putip((char *)&from_ip,&nmb->additional->rdata[2]);
933
934   if(bcast)
935   {
936     /*
937      * We should only get unicast name registration packets here.
938      * Anyone trying to register broadcast should not be going to a WINS
939      * server. Log an error here.
940      */
941
942     DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
943 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
944           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
945     return;
946   }
947
948   /*
949    * Only unique names should be registered multihomed.
950    */
951
952   if(group)
953   {
954     DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
955 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
956           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
957     return;
958   }
959
960   DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
961 IP %s\n", namestr(question), inet_ntoa(from_ip) ));
962
963   /*
964    * Deal with policy regarding 0x1d names.
965    */
966
967   if(question->name_type == 0x1d)
968   {
969     DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
970 to register name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
971     send_wins_name_registration_response(0, ttl, p);  
972     return;
973   }
974
975   /*
976    * See if the name already exists.
977    */
978
979   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
980
981   /*
982    * Deal with the case where the name found was a dns entry.
983    * Remove it as we now have a NetBIOS client registering the
984    * name.
985    */
986
987   if((namerec != NULL) && ((namerec->source == DNS_NAME) || (namerec->source == DNSFAIL_NAME)))
988   {
989     DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
990 - removing it.\n", namestr(question) ));
991     remove_name_from_namelist( subrec, namerec);
992     namerec = NULL;
993   }
994
995   /*
996    * Reject if the name exists and is not a REGISTER_NAME.
997    * (ie. Don't allow any static names to be overwritten.
998    */
999
1000   if((namerec != NULL) && (namerec->source != REGISTER_NAME))
1001   {
1002     DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1003 already exists in WINS with source type %d.\n", namestr(question), namerec->source ));
1004     send_wins_name_registration_response(RFS_ERR, 0, p);
1005     return;
1006   }
1007
1008   /*
1009    * Reject if the name exists and is a GROUP name.
1010    */
1011
1012   if((namerec != NULL) && NAME_GROUP(namerec))
1013   {
1014     DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1015 already exists in WINS as a GROUP name.\n", namestr(question) ));
1016     send_wins_name_registration_response(RFS_ERR, 0, p);
1017     return;
1018   } 
1019
1020   /*
1021    * From here on down we know that if the name exists in the WINS db it is
1022    * a unique name, not a group name.
1023    */
1024
1025   /*
1026    * If the name exists and is one of our names then check the
1027    * registering IP address. If it's not one of ours then automatically
1028    * reject without doing the query - we know we will reject it.
1029    */
1030
1031   if((namerec != NULL) && (is_myname(namerec->name.name)) )
1032   {
1033     if(!ismyip(from_ip))
1034     {
1035       DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1036 is one of our (WINS server) names. Denying registration.\n", namestr(question) ));
1037       send_wins_name_registration_response(RFS_ERR, 0, p);
1038       return;
1039     }
1040     else
1041     {
1042       /*
1043        * It's one of our names and one of our IP's. Ensure the IP is in the record and
1044        *  update the ttl.
1045        */
1046       if(!find_ip_in_name_record(namerec, from_ip))
1047         add_ip_to_name_record(namerec, from_ip);
1048       update_name_ttl(namerec, ttl);
1049       send_wins_name_registration_response(0, ttl, p);
1050       return;
1051     }
1052   }
1053
1054   /*
1055    * If the name exists check if the IP address is already registered
1056    * to that name. If so then update the ttl and reply success.
1057    */
1058
1059   if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip))
1060   {
1061     update_name_ttl(namerec, ttl);
1062     send_wins_name_registration_response(0, ttl, p);
1063     return;
1064   }
1065
1066   /*
1067    * If the name exists do a query to the owner
1068    * to see if they still want the name.
1069    */
1070
1071   if(namerec != NULL)
1072   {
1073     char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
1074     struct userdata_struct *userdata = (struct userdata_struct *)ud;
1075
1076     /*
1077      * First send a WACK to the registering machine.
1078      */
1079
1080     send_wins_wack_response(60, p);
1081
1082     /*
1083      * When the reply comes back we need the original packet.
1084      * Lock this so it won't be freed and then put it into
1085      * the userdata structure.
1086      */
1087
1088     p->locked = True;
1089
1090     userdata = (struct userdata_struct *)ud;
1091
1092     userdata->copy_fn = NULL;
1093     userdata->free_fn = NULL;
1094     userdata->userdata_len = sizeof(struct packet_struct *);
1095     memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1096
1097     /*
1098      * As query_name uses the subnet broadcast address as the destination
1099      * of the packet we temporarily change the subnet broadcast address to
1100      * be the IP address of the requesting machine and send the packet. This
1101      * is a *horrible* hack but the alternative is to add the destination
1102      * address parameter to all query_name() calls. I hate this code :-).
1103      */
1104
1105     subrec->bcast_ip = p->ip;
1106     query_name( subrec, question->name, question->name_type,
1107                 wins_multihomed_register_query_success, 
1108                 wins_multihomed_register_query_fail,
1109                 userdata);
1110     subrec->bcast_ip = ipzero;
1111     return;
1112   }
1113
1114   /*
1115    * Name did not exist - add it.
1116    */
1117
1118   add_name_to_subnet(subrec, question->name, question->name_type,
1119                      nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1120
1121   send_wins_name_registration_response(0, ttl, p);
1122 }
1123
1124 /***********************************************************************
1125  Deal with the special name query for *<1b>.
1126 ***********************************************************************/
1127    
1128 static void process_wins_dmb_query_request(struct subnet_record *subrec,  
1129                                            struct packet_struct *p)
1130 {  
1131   struct name_record *namerec = NULL;
1132   char *prdata;
1133   int num_ips;
1134
1135   /*
1136    * Go through all the names in the WINS db looking for those
1137    * ending in <1b>. Use this to calculate the number of IP
1138    * addresses we need to return.
1139    */
1140
1141   num_ips = 0;
1142   for(namerec = subrec->namelist; namerec; namerec = namerec->next)
1143   {
1144     if(namerec->name.name_type == 0x1b)
1145       num_ips += namerec->num_ips;
1146   }
1147
1148   if(num_ips == 0)
1149   {
1150     /*
1151      * There are no 0x1b names registered. Return name query fail.
1152      */
1153     send_wins_name_query_response(NAM_ERR, p, NULL);
1154     return;
1155   }
1156
1157   if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
1158   {
1159     DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1160     return;
1161   }
1162
1163   /*
1164    * Go through all the names again in the WINS db looking for those
1165    * ending in <1b>. Add their IP addresses into the list we will
1166    * return.
1167    */ 
1168
1169   num_ips = 0;
1170   for(namerec = subrec->namelist; namerec; namerec = namerec->next)
1171   {
1172     if(namerec->name.name_type == 0x1b)
1173     {
1174       int i;
1175       for(i = 0; i < namerec->num_ips; i++)
1176       {
1177         set_nb_flags(&prdata[num_ips * 6],namerec->nb_flags);
1178         putip((char *)&prdata[(num_ips * 6) + 2], &namerec->ip[i]);
1179         num_ips++;
1180       }
1181     }
1182   }
1183
1184   /*
1185    * Send back the reply containing the IP list.
1186    */
1187
1188   reply_netbios_packet(p,                             /* Packet to reply to. */
1189                        0,                             /* Result code. */
1190                        WINS_QUERY,                    /* nmbd type code. */
1191                        NMB_NAME_QUERY_OPCODE,         /* opcode. */
1192                        lp_min_wins_ttl(),             /* ttl. */
1193                        prdata,                        /* data to send. */
1194                        num_ips*6);                    /* data length. */
1195
1196   free(prdata);
1197 }
1198
1199 /****************************************************************************
1200 Send a WINS name query response.
1201 **************************************************************************/
1202
1203 void send_wins_name_query_response(int rcode, struct packet_struct *p, 
1204                                           struct name_record *namerec)
1205 {
1206   char rdata[6];
1207   char *prdata = rdata;
1208   int reply_data_len = 0;
1209   int ttl = 0;
1210   int i = 0;
1211   int j;
1212
1213   bzero(rdata,6);
1214
1215   if(rcode == 0)
1216   {
1217     int same_net_index = -1;
1218
1219     ttl = (namerec->death_time != PERMANENT_TTL) ?
1220              namerec->death_time - p->timestamp : lp_max_wins_ttl();
1221
1222     /* Copy all known ip addresses into the return data. */
1223     /* Optimise for the common case of one IP address so
1224        we don't need a malloc. */
1225
1226     if(namerec->num_ips == 1 )
1227       prdata = rdata;
1228     else
1229     {
1230       if((prdata = (char *)malloc( namerec->num_ips * 6 )) == NULL)
1231       {
1232         DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1233         return;
1234       }
1235
1236       /* 
1237        * Look over the known IP addresses and see if one of them
1238        * is on the same (local) net as the requesting IP address. If so then
1239        * put that IP address into the packet as the first IP.
1240        * We can only do this for local nets as they're the only
1241        * ones we know the netmask for.
1242        */
1243
1244       i = 0;
1245
1246       if(is_local_net(p->ip))
1247       {
1248         struct in_addr *n_mask = iface_nmask(p->ip);
1249
1250         for( j = 0; j < namerec->num_ips; j++)
1251         {
1252           if(same_net( namerec->ip[j], p->ip, *n_mask))
1253           {
1254             set_nb_flags(&prdata[0],namerec->nb_flags);
1255             putip((char *)&prdata[2], &namerec->ip[j]);
1256             same_net_index = j;
1257             i = 1;
1258           }
1259         }
1260       }
1261     }
1262
1263     for(j = 0; j < namerec->num_ips; j++)
1264     {
1265       if(j == same_net_index)
1266         continue;
1267       set_nb_flags(&prdata[i*6],namerec->nb_flags);
1268       putip((char *)&prdata[2+(i*6)], &namerec->ip[j]);
1269       i++;
1270     }
1271     reply_data_len = namerec->num_ips * 6;
1272
1273   }
1274
1275   reply_netbios_packet(p,                             /* Packet to reply to. */
1276                        rcode,                         /* Result code. */
1277                        WINS_QUERY,                    /* nmbd type code. */
1278                        NMB_NAME_QUERY_OPCODE,         /* opcode. */
1279                        ttl,                           /* ttl. */
1280                        prdata,                        /* data to send. */
1281                        reply_data_len);               /* data length. */
1282
1283   if((prdata != rdata) && (prdata != NULL))
1284     free(prdata);
1285 }
1286
1287 /***********************************************************************
1288  Deal with a name query.
1289 ***********************************************************************/
1290
1291 void wins_process_name_query_request(struct subnet_record *subrec, 
1292                                      struct packet_struct *p)
1293 {
1294   struct nmb_packet *nmb = &p->packet.nmb;
1295   struct nmb_name *question = &nmb->question.question_name;
1296   struct name_record *namerec = NULL;
1297
1298   DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n", 
1299             namestr(question), inet_ntoa(p->ip) ));
1300
1301   /*
1302    * Special name code. If the queried name is *<1b> then search
1303    * the entire WINS database and return a list of all the IP addresses
1304    * registered to any <1b> name. This is to allow domain master browsers
1305    * to discover other domains that may not have a presence on their subnet.
1306    */
1307
1308   if(strequal( question->name, "*") && (question->name_type == 0x1b))
1309   {
1310     process_wins_dmb_query_request( subrec, p);
1311     return;
1312   }
1313
1314   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1315
1316   if(namerec != NULL)
1317   {
1318     /* 
1319      * If it's a DNSFAIL_NAME then reply name not found.
1320      */
1321
1322     if(namerec->source == DNSFAIL_NAME)
1323     {
1324       DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1325              namestr(question) ));
1326       send_wins_name_query_response(NAM_ERR, p, namerec);
1327       return;
1328     }
1329
1330     /*
1331      * If the name has expired then reply name not found.
1332      */
1333
1334     if((namerec->death_time != PERMANENT_TTL) && (namerec->death_time < p->timestamp))
1335     {
1336       DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1337                 namestr(question) ));
1338       send_wins_name_query_response(NAM_ERR, p, namerec);
1339       return;
1340     }
1341
1342     DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1343            namestr(question), inet_ntoa(namerec->ip[0]) ));
1344
1345     send_wins_name_query_response(0, p, namerec);
1346     return;
1347   }
1348
1349   /* 
1350    * Name not found in WINS - try a dns query if it's a 0x20 name.
1351    */
1352
1353   if(lp_dns_proxy() && 
1354      ((question->name_type == 0x20) || question->name_type == 0))
1355   {
1356
1357     DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1358               namestr(question) ));
1359
1360     queue_dns_query(p, question, &namerec);
1361     return;
1362   }
1363
1364   /*
1365    * Name not found - return error.
1366    */
1367
1368   send_wins_name_query_response(NAM_ERR, p, NULL);
1369 }
1370
1371 /****************************************************************************
1372 Send a WINS name release response.
1373 **************************************************************************/
1374
1375 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1376 {
1377   struct nmb_packet *nmb = &p->packet.nmb;
1378   char rdata[6];
1379
1380   memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1381
1382   reply_netbios_packet(p,                            /* Packet to reply to. */
1383                        rcode,                        /* Result code. */
1384                        NMB_REL,                      /* nmbd type code. */
1385                        NMB_NAME_RELEASE_OPCODE,      /* opcode. */
1386                        0,                            /* ttl. */
1387                        rdata,                        /* data to send. */
1388                        6);                           /* data length. */
1389 }
1390
1391 /***********************************************************************
1392  Deal with a name release.
1393 ***********************************************************************/
1394
1395 void wins_process_name_release_request(struct subnet_record *subrec,
1396                                        struct packet_struct *p)
1397 {
1398   struct nmb_packet *nmb = &p->packet.nmb;
1399   struct nmb_name *question = &nmb->question.question_name;
1400   BOOL bcast = nmb->header.nm_flags.bcast;
1401   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1402   struct name_record *namerec = NULL;
1403   struct in_addr from_ip;
1404   BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1405
1406   putip((char *)&from_ip,&nmb->additional->rdata[2]);
1407
1408   if(bcast)
1409   {
1410     /*
1411      * We should only get unicast name registration packets here.
1412      * Anyone trying to register broadcast should not be going to a WINS
1413      * server. Log an error here.
1414      */
1415
1416     DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1417 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1418           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1419     return;
1420   }
1421   
1422   DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1423 IP %s\n", releasing_group_name ? "Group" : "Unique", namestr(question), inet_ntoa(from_ip) ));
1424     
1425   /*
1426    * Deal with policy regarding 0x1d names.
1427    */
1428
1429   if(!releasing_group_name && (question->name_type == 0x1d))
1430   {
1431     DEBUG(3,("wins_process_name_release_request: Ignoring request \
1432 to release name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
1433     send_wins_name_release_response(0, p);
1434     return;
1435   }
1436
1437   /*
1438    * See if the name already exists.
1439    */
1440     
1441   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1442
1443   if((namerec == NULL) || ((namerec != NULL) && (namerec->source != REGISTER_NAME)) )
1444   {
1445     send_wins_name_release_response(NAM_ERR, p);
1446     return;
1447   }
1448
1449   /* 
1450    * Check that the sending machine has permission to release this name.
1451    * If it's a group name not ending in 0x1c then just say yes and let
1452    * the group time out.
1453    */
1454
1455   if(releasing_group_name && (question->name_type != 0x1c))
1456   {
1457     send_wins_name_release_response(0, p);
1458     return;
1459   }
1460
1461   /* 
1462    * Check that the releasing node is on the list of IP addresses
1463    * for this name. Disallow the release if not.
1464    */
1465
1466   if(!find_ip_in_name_record(namerec, from_ip))
1467   {
1468     DEBUG(3,("wins_process_name_release_request: Refusing request to \
1469 release name %s as IP %s is not one of the known IP's for this name.\n",
1470            namestr(question), inet_ntoa(from_ip) ));
1471     send_wins_name_release_response(NAM_ERR, p);
1472     return;
1473   }    
1474
1475   /* 
1476    * Release the name and then remove the IP from the known list.
1477    */
1478
1479   send_wins_name_release_response(0, p);
1480   remove_ip_from_name_record(namerec, from_ip);
1481
1482   /* 
1483    * Remove the name entirely if no IP addresses left.
1484    */
1485   if (namerec->num_ips == 0)
1486     remove_name_from_namelist(subrec, namerec);
1487
1488 }
1489
1490 /*******************************************************************
1491  WINS time dependent processing.
1492 ******************************************************************/
1493
1494 void initiate_wins_processing(time_t t)
1495 {
1496   static time_t lasttime = 0;
1497
1498   if (!lasttime)
1499     lasttime = t;
1500   if (t - lasttime < 5)
1501     return;
1502
1503   if(!lp_we_are_a_wins_server())
1504     return;
1505
1506   expire_names_on_subnet(wins_server_subnet, t);
1507
1508   if(wins_server_subnet->namelist_changed)
1509     wins_write_database();
1510
1511   wins_server_subnet->namelist_changed = False;
1512 }
1513
1514 /*******************************************************************
1515  Write out the current WINS database.
1516 ******************************************************************/
1517
1518 void wins_write_database(void)
1519 {
1520   struct name_record *namerec;
1521   fstring fname, fnamenew;
1522    
1523   FILE *fp;
1524    
1525   if(!lp_we_are_a_wins_server())
1526     return;
1527
1528   fstrcpy(fname,lp_lockdir());
1529   trim_string(fname,NULL,"/");
1530   strcat(fname,"/");
1531   strcat(fname,WINS_LIST);
1532   fstrcpy(fnamenew,fname);
1533   strcat(fnamenew,".");
1534
1535   if((fp = fopen(fnamenew,"w")) == NULL)
1536   {
1537     DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1538     return;
1539   }
1540
1541   DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1542  
1543   for (namerec = wins_server_subnet->namelist; namerec; namerec = namerec->next)
1544   {
1545     int i;
1546     struct tm *tm;
1547
1548     DEBUG(4,("%-19s ", namestr(&namerec->name) ));
1549
1550     if(namerec->death_time != PERMANENT_TTL)
1551     {
1552       tm = LocalTime(&namerec->death_time);
1553       DEBUG(4,("TTL = %s", asctime(tm) ));
1554     }
1555     else
1556       DEBUG(4,("TTL = PERMANENT\t"));
1557
1558     for (i = 0; i < namerec->num_ips; i++)
1559       DEBUG(4,("%15s ", inet_ntoa(namerec->ip[i]) ));
1560     DEBUG(4,("%2x\n", namerec->nb_flags ));
1561
1562     if (namerec->source == REGISTER_NAME)
1563     {
1564       fprintf(fp, "\"%s#%02x\" %d ",
1565               namerec->name.name,namerec->name.name_type, /* Ignore scope. */
1566               (int)namerec->death_time);
1567
1568       for (i = 0; i < namerec->num_ips; i++)
1569         fprintf(fp, "%s ", inet_ntoa(namerec->ip[i]));
1570       fprintf(fp, "%2xR\n", namerec->nb_flags);
1571     }
1572   }
1573   
1574   fclose(fp);
1575   unlink(fname);
1576   chmod(fnamenew,0644);
1577   rename(fnamenew,fname);
1578 }