d089686917a0b9a25e706aa1514a3f3ca471ed13
[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      * Use the new call to send a query directly to an IP address.
812      * This sends the query directly to the IP address, and ensures
813      * the recursion desired flag is not set (you were right Luke :-).
814      * This function should *only* be called from the WINS server
815      * code. JRA.
816      */
817
818     query_name_from_wins_server( *namerec->ip, question->name, question->name_type, 
819                 wins_register_query_success,
820                 wins_register_query_fail,
821                 userdata);
822     return;
823   }
824
825   /*
826    * Name did not exist - add it.
827    */
828
829   add_name_to_subnet(subrec, question->name, question->name_type,
830                      nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
831
832   send_wins_name_registration_response(0, ttl, p);
833 }
834
835 /***********************************************************************
836  Deal with a mutihomed name query success to the machine that
837  requested the multihomed name registration.
838
839  We have a locked pointer to the original packet stashed away in the
840  userdata pointer.
841 ************************************************************************/
842
843 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
844                                              struct userdata_struct *userdata,
845                                              struct nmb_name *question_name,
846                                              struct in_addr ip,
847                                              struct res_rec *answers)
848 {
849   struct packet_struct *orig_reg_packet;
850   struct nmb_packet *nmb;
851   struct name_record *namerec = NULL;
852   struct in_addr from_ip;
853   int ttl;
854
855   memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
856
857   nmb = &orig_reg_packet->packet.nmb;
858
859   putip((char *)&from_ip,&nmb->additional->rdata[2]);
860   ttl = get_ttl_from_packet(nmb);
861
862   /*
863    * We want to just add the new IP, as we now know the requesting
864    * machine claims to own it. But we can't just do that as an arbitary
865    * amount of time may have taken place between the name query
866    * request and this response. So we check that
867    * the name still exists and is in the same state - if so
868    * we just add the extra IP and update the ttl.
869    */
870
871   namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
872
873   if( (namerec == NULL) || (namerec->source != REGISTER_NAME) )
874   {
875     DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
876 a subsequent IP addess.\n", namestr(question_name) ));
877     send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
878     return;
879   }
880
881   if(!find_ip_in_name_record(namerec, from_ip))
882     add_ip_to_name_record(namerec, from_ip);
883   update_name_ttl(namerec, ttl);
884   send_wins_name_registration_response(0, ttl, orig_reg_packet);
885
886 }
887
888 /***********************************************************************
889  Deal with a name registration request query failure to a client that
890  owned the name.
891
892  We have a locked pointer to the original packet stashed away in the
893  userdata pointer.
894 ************************************************************************/
895
896 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
897                                           struct response_record *rrec,
898                                           struct nmb_name *question_name,
899                                           int rcode)
900 {
901   struct userdata_struct *userdata = rrec->userdata;
902   struct packet_struct *orig_reg_packet;
903
904   memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
905
906   DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
907 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), namestr(question_name) ));
908   send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
909   return;
910 }
911
912 /***********************************************************************
913  Deal with a multihomed name registration request to a WINS server.
914  These cannot be group name registrations.
915 ***********************************************************************/
916
917 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
918                                                         struct packet_struct *p)
919 {
920   struct nmb_packet *nmb = &p->packet.nmb;
921   struct nmb_name *question = &nmb->question.question_name;
922   BOOL bcast = nmb->header.nm_flags.bcast;
923   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
924   int ttl = get_ttl_from_packet(nmb);
925   struct name_record *namerec = NULL;
926   struct in_addr from_ip;
927   BOOL group = (nb_flags & NB_GROUP) ? True : False;;
928
929   putip((char *)&from_ip,&nmb->additional->rdata[2]);
930
931   if(bcast)
932   {
933     /*
934      * We should only get unicast name registration packets here.
935      * Anyone trying to register broadcast should not be going to a WINS
936      * server. Log an error here.
937      */
938
939     DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
940 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
941           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
942     return;
943   }
944
945   /*
946    * Only unique names should be registered multihomed.
947    */
948
949   if(group)
950   {
951     DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
952 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
953           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
954     return;
955   }
956
957   DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
958 IP %s\n", namestr(question), inet_ntoa(from_ip) ));
959
960   /*
961    * Deal with policy regarding 0x1d names.
962    */
963
964   if(question->name_type == 0x1d)
965   {
966     DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
967 to register name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
968     send_wins_name_registration_response(0, ttl, p);  
969     return;
970   }
971
972   /*
973    * See if the name already exists.
974    */
975
976   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
977
978   /*
979    * Deal with the case where the name found was a dns entry.
980    * Remove it as we now have a NetBIOS client registering the
981    * name.
982    */
983
984   if((namerec != NULL) && ((namerec->source == DNS_NAME) || (namerec->source == DNSFAIL_NAME)))
985   {
986     DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
987 - removing it.\n", namestr(question) ));
988     remove_name_from_namelist( subrec, namerec);
989     namerec = NULL;
990   }
991
992   /*
993    * Reject if the name exists and is not a REGISTER_NAME.
994    * (ie. Don't allow any static names to be overwritten.
995    */
996
997   if((namerec != NULL) && (namerec->source != REGISTER_NAME))
998   {
999     DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1000 already exists in WINS with source type %d.\n", namestr(question), namerec->source ));
1001     send_wins_name_registration_response(RFS_ERR, 0, p);
1002     return;
1003   }
1004
1005   /*
1006    * Reject if the name exists and is a GROUP name.
1007    */
1008
1009   if((namerec != NULL) && NAME_GROUP(namerec))
1010   {
1011     DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1012 already exists in WINS as a GROUP name.\n", namestr(question) ));
1013     send_wins_name_registration_response(RFS_ERR, 0, p);
1014     return;
1015   } 
1016
1017   /*
1018    * From here on down we know that if the name exists in the WINS db it is
1019    * a unique name, not a group name.
1020    */
1021
1022   /*
1023    * If the name exists and is one of our names then check the
1024    * registering IP address. If it's not one of ours then automatically
1025    * reject without doing the query - we know we will reject it.
1026    */
1027
1028   if((namerec != NULL) && (is_myname(namerec->name.name)) )
1029   {
1030     if(!ismyip(from_ip))
1031     {
1032       DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1033 is one of our (WINS server) names. Denying registration.\n", namestr(question) ));
1034       send_wins_name_registration_response(RFS_ERR, 0, p);
1035       return;
1036     }
1037     else
1038     {
1039       /*
1040        * It's one of our names and one of our IP's. Ensure the IP is in the record and
1041        *  update the ttl.
1042        */
1043       if(!find_ip_in_name_record(namerec, from_ip))
1044         add_ip_to_name_record(namerec, from_ip);
1045       update_name_ttl(namerec, ttl);
1046       send_wins_name_registration_response(0, ttl, p);
1047       return;
1048     }
1049   }
1050
1051   /*
1052    * If the name exists check if the IP address is already registered
1053    * to that name. If so then update the ttl and reply success.
1054    */
1055
1056   if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip))
1057   {
1058     update_name_ttl(namerec, ttl);
1059     send_wins_name_registration_response(0, ttl, p);
1060     return;
1061   }
1062
1063   /*
1064    * If the name exists do a query to the owner
1065    * to see if they still want the name.
1066    */
1067
1068   if(namerec != NULL)
1069   {
1070     char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
1071     struct userdata_struct *userdata = (struct userdata_struct *)ud;
1072
1073     /*
1074      * First send a WACK to the registering machine.
1075      */
1076
1077     send_wins_wack_response(60, p);
1078
1079     /*
1080      * When the reply comes back we need the original packet.
1081      * Lock this so it won't be freed and then put it into
1082      * the userdata structure.
1083      */
1084
1085     p->locked = True;
1086
1087     userdata = (struct userdata_struct *)ud;
1088
1089     userdata->copy_fn = NULL;
1090     userdata->free_fn = NULL;
1091     userdata->userdata_len = sizeof(struct packet_struct *);
1092     memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1093
1094     /*
1095      * As query_name uses the subnet broadcast address as the destination
1096      * of the packet we temporarily change the subnet broadcast address to
1097      * be the IP address of the requesting machine and send the packet. This
1098      * is a *horrible* hack but the alternative is to add the destination
1099      * address parameter to all query_name() calls. I hate this code :-).
1100      */
1101
1102     subrec->bcast_ip = p->ip;
1103     query_name( subrec, question->name, question->name_type,
1104                 wins_multihomed_register_query_success, 
1105                 wins_multihomed_register_query_fail,
1106                 userdata);
1107     subrec->bcast_ip = ipzero;
1108     return;
1109   }
1110
1111   /*
1112    * Name did not exist - add it.
1113    */
1114
1115   add_name_to_subnet(subrec, question->name, question->name_type,
1116                      nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1117
1118   send_wins_name_registration_response(0, ttl, p);
1119 }
1120
1121 /***********************************************************************
1122  Deal with the special name query for *<1b>.
1123 ***********************************************************************/
1124    
1125 static void process_wins_dmb_query_request(struct subnet_record *subrec,  
1126                                            struct packet_struct *p)
1127 {  
1128   struct name_record *namerec = NULL;
1129   char *prdata;
1130   int num_ips;
1131
1132   /*
1133    * Go through all the names in the WINS db looking for those
1134    * ending in <1b>. Use this to calculate the number of IP
1135    * addresses we need to return.
1136    */
1137
1138   num_ips = 0;
1139   for(namerec = subrec->namelist; namerec; namerec = namerec->next)
1140   {
1141     if(namerec->name.name_type == 0x1b)
1142       num_ips += namerec->num_ips;
1143   }
1144
1145   if(num_ips == 0)
1146   {
1147     /*
1148      * There are no 0x1b names registered. Return name query fail.
1149      */
1150     send_wins_name_query_response(NAM_ERR, p, NULL);
1151     return;
1152   }
1153
1154   if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
1155   {
1156     DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1157     return;
1158   }
1159
1160   /*
1161    * Go through all the names again in the WINS db looking for those
1162    * ending in <1b>. Add their IP addresses into the list we will
1163    * return.
1164    */ 
1165
1166   num_ips = 0;
1167   for(namerec = subrec->namelist; namerec; namerec = namerec->next)
1168   {
1169     if(namerec->name.name_type == 0x1b)
1170     {
1171       int i;
1172       for(i = 0; i < namerec->num_ips; i++)
1173       {
1174         set_nb_flags(&prdata[num_ips * 6],namerec->nb_flags);
1175         putip((char *)&prdata[(num_ips * 6) + 2], &namerec->ip[i]);
1176         num_ips++;
1177       }
1178     }
1179   }
1180
1181   /*
1182    * Send back the reply containing the IP list.
1183    */
1184
1185   reply_netbios_packet(p,                             /* Packet to reply to. */
1186                        0,                             /* Result code. */
1187                        WINS_QUERY,                    /* nmbd type code. */
1188                        NMB_NAME_QUERY_OPCODE,         /* opcode. */
1189                        lp_min_wins_ttl(),             /* ttl. */
1190                        prdata,                        /* data to send. */
1191                        num_ips*6);                    /* data length. */
1192
1193   free(prdata);
1194 }
1195
1196 /****************************************************************************
1197 Send a WINS name query response.
1198 **************************************************************************/
1199
1200 void send_wins_name_query_response(int rcode, struct packet_struct *p, 
1201                                           struct name_record *namerec)
1202 {
1203   char rdata[6];
1204   char *prdata = rdata;
1205   int reply_data_len = 0;
1206   int ttl = 0;
1207   int i = 0;
1208   int j;
1209
1210   bzero(rdata,6);
1211
1212   if(rcode == 0)
1213   {
1214     int same_net_index = -1;
1215
1216     ttl = (namerec->death_time != PERMANENT_TTL) ?
1217              namerec->death_time - p->timestamp : lp_max_wins_ttl();
1218
1219     /* Copy all known ip addresses into the return data. */
1220     /* Optimise for the common case of one IP address so
1221        we don't need a malloc. */
1222
1223     if(namerec->num_ips == 1 )
1224       prdata = rdata;
1225     else
1226     {
1227       if((prdata = (char *)malloc( namerec->num_ips * 6 )) == NULL)
1228       {
1229         DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1230         return;
1231       }
1232
1233       /* 
1234        * Look over the known IP addresses and see if one of them
1235        * is on the same (local) net as the requesting IP address. If so then
1236        * put that IP address into the packet as the first IP.
1237        * We can only do this for local nets as they're the only
1238        * ones we know the netmask for.
1239        */
1240
1241       i = 0;
1242
1243       if(is_local_net(p->ip))
1244       {
1245         struct in_addr *n_mask = iface_nmask(p->ip);
1246
1247         for( j = 0; j < namerec->num_ips; j++)
1248         {
1249           if(same_net( namerec->ip[j], p->ip, *n_mask))
1250           {
1251             set_nb_flags(&prdata[0],namerec->nb_flags);
1252             putip((char *)&prdata[2], &namerec->ip[j]);
1253             same_net_index = j;
1254             i = 1;
1255           }
1256         }
1257       }
1258     }
1259
1260     for(j = 0; j < namerec->num_ips; j++)
1261     {
1262       if(j == same_net_index)
1263         continue;
1264       set_nb_flags(&prdata[i*6],namerec->nb_flags);
1265       putip((char *)&prdata[2+(i*6)], &namerec->ip[j]);
1266       i++;
1267     }
1268     reply_data_len = namerec->num_ips * 6;
1269
1270   }
1271
1272   reply_netbios_packet(p,                             /* Packet to reply to. */
1273                        rcode,                         /* Result code. */
1274                        WINS_QUERY,                    /* nmbd type code. */
1275                        NMB_NAME_QUERY_OPCODE,         /* opcode. */
1276                        ttl,                           /* ttl. */
1277                        prdata,                        /* data to send. */
1278                        reply_data_len);               /* data length. */
1279
1280   if((prdata != rdata) && (prdata != NULL))
1281     free(prdata);
1282 }
1283
1284 /***********************************************************************
1285  Deal with a name query.
1286 ***********************************************************************/
1287
1288 void wins_process_name_query_request(struct subnet_record *subrec, 
1289                                      struct packet_struct *p)
1290 {
1291   struct nmb_packet *nmb = &p->packet.nmb;
1292   struct nmb_name *question = &nmb->question.question_name;
1293   struct name_record *namerec = NULL;
1294
1295   DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n", 
1296             namestr(question), inet_ntoa(p->ip) ));
1297
1298   /*
1299    * Special name code. If the queried name is *<1b> then search
1300    * the entire WINS database and return a list of all the IP addresses
1301    * registered to any <1b> name. This is to allow domain master browsers
1302    * to discover other domains that may not have a presence on their subnet.
1303    */
1304
1305   if(strequal( question->name, "*") && (question->name_type == 0x1b))
1306   {
1307     process_wins_dmb_query_request( subrec, p);
1308     return;
1309   }
1310
1311   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1312
1313   if(namerec != NULL)
1314   {
1315     /* 
1316      * If it's a DNSFAIL_NAME then reply name not found.
1317      */
1318
1319     if(namerec->source == DNSFAIL_NAME)
1320     {
1321       DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1322              namestr(question) ));
1323       send_wins_name_query_response(NAM_ERR, p, namerec);
1324       return;
1325     }
1326
1327     /*
1328      * If the name has expired then reply name not found.
1329      */
1330
1331     if((namerec->death_time != PERMANENT_TTL) && (namerec->death_time < p->timestamp))
1332     {
1333       DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1334                 namestr(question) ));
1335       send_wins_name_query_response(NAM_ERR, p, namerec);
1336       return;
1337     }
1338
1339     DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1340            namestr(question), inet_ntoa(namerec->ip[0]) ));
1341
1342     send_wins_name_query_response(0, p, namerec);
1343     return;
1344   }
1345
1346   /* 
1347    * Name not found in WINS - try a dns query if it's a 0x20 name.
1348    */
1349
1350   if(lp_dns_proxy() && 
1351      ((question->name_type == 0x20) || question->name_type == 0))
1352   {
1353
1354     DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1355               namestr(question) ));
1356
1357     queue_dns_query(p, question, &namerec);
1358     return;
1359   }
1360
1361   /*
1362    * Name not found - return error.
1363    */
1364
1365   send_wins_name_query_response(NAM_ERR, p, NULL);
1366 }
1367
1368 /****************************************************************************
1369 Send a WINS name release response.
1370 **************************************************************************/
1371
1372 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1373 {
1374   struct nmb_packet *nmb = &p->packet.nmb;
1375   char rdata[6];
1376
1377   memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1378
1379   reply_netbios_packet(p,                            /* Packet to reply to. */
1380                        rcode,                        /* Result code. */
1381                        NMB_REL,                      /* nmbd type code. */
1382                        NMB_NAME_RELEASE_OPCODE,      /* opcode. */
1383                        0,                            /* ttl. */
1384                        rdata,                        /* data to send. */
1385                        6);                           /* data length. */
1386 }
1387
1388 /***********************************************************************
1389  Deal with a name release.
1390 ***********************************************************************/
1391
1392 void wins_process_name_release_request(struct subnet_record *subrec,
1393                                        struct packet_struct *p)
1394 {
1395   struct nmb_packet *nmb = &p->packet.nmb;
1396   struct nmb_name *question = &nmb->question.question_name;
1397   BOOL bcast = nmb->header.nm_flags.bcast;
1398   uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1399   struct name_record *namerec = NULL;
1400   struct in_addr from_ip;
1401   BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1402
1403   putip((char *)&from_ip,&nmb->additional->rdata[2]);
1404
1405   if(bcast)
1406   {
1407     /*
1408      * We should only get unicast name registration packets here.
1409      * Anyone trying to register broadcast should not be going to a WINS
1410      * server. Log an error here.
1411      */
1412
1413     DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1414 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1415           namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1416     return;
1417   }
1418   
1419   DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1420 IP %s\n", releasing_group_name ? "Group" : "Unique", namestr(question), inet_ntoa(from_ip) ));
1421     
1422   /*
1423    * Deal with policy regarding 0x1d names.
1424    */
1425
1426   if(!releasing_group_name && (question->name_type == 0x1d))
1427   {
1428     DEBUG(3,("wins_process_name_release_request: Ignoring request \
1429 to release name %s from IP %s.", namestr(question), inet_ntoa(p->ip) ));
1430     send_wins_name_release_response(0, p);
1431     return;
1432   }
1433
1434   /*
1435    * See if the name already exists.
1436    */
1437     
1438   namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1439
1440   if((namerec == NULL) || ((namerec != NULL) && (namerec->source != REGISTER_NAME)) )
1441   {
1442     send_wins_name_release_response(NAM_ERR, p);
1443     return;
1444   }
1445
1446   /* 
1447    * Check that the sending machine has permission to release this name.
1448    * If it's a group name not ending in 0x1c then just say yes and let
1449    * the group time out.
1450    */
1451
1452   if(releasing_group_name && (question->name_type != 0x1c))
1453   {
1454     send_wins_name_release_response(0, p);
1455     return;
1456   }
1457
1458   /* 
1459    * Check that the releasing node is on the list of IP addresses
1460    * for this name. Disallow the release if not.
1461    */
1462
1463   if(!find_ip_in_name_record(namerec, from_ip))
1464   {
1465     DEBUG(3,("wins_process_name_release_request: Refusing request to \
1466 release name %s as IP %s is not one of the known IP's for this name.\n",
1467            namestr(question), inet_ntoa(from_ip) ));
1468     send_wins_name_release_response(NAM_ERR, p);
1469     return;
1470   }    
1471
1472   /* 
1473    * Release the name and then remove the IP from the known list.
1474    */
1475
1476   send_wins_name_release_response(0, p);
1477   remove_ip_from_name_record(namerec, from_ip);
1478
1479   /* 
1480    * Remove the name entirely if no IP addresses left.
1481    */
1482   if (namerec->num_ips == 0)
1483     remove_name_from_namelist(subrec, namerec);
1484
1485 }
1486
1487 /*******************************************************************
1488  WINS time dependent processing.
1489 ******************************************************************/
1490
1491 void initiate_wins_processing(time_t t)
1492 {
1493   static time_t lasttime = 0;
1494
1495   if (!lasttime)
1496     lasttime = t;
1497   if (t - lasttime < 5)
1498     return;
1499
1500   if(!lp_we_are_a_wins_server())
1501     return;
1502
1503   expire_names_on_subnet(wins_server_subnet, t);
1504
1505   if(wins_server_subnet->namelist_changed)
1506     wins_write_database();
1507
1508   wins_server_subnet->namelist_changed = False;
1509 }
1510
1511 /*******************************************************************
1512  Write out the current WINS database.
1513 ******************************************************************/
1514
1515 void wins_write_database(void)
1516 {
1517   struct name_record *namerec;
1518   fstring fname, fnamenew;
1519    
1520   FILE *fp;
1521    
1522   if(!lp_we_are_a_wins_server())
1523     return;
1524
1525   fstrcpy(fname,lp_lockdir());
1526   trim_string(fname,NULL,"/");
1527   strcat(fname,"/");
1528   strcat(fname,WINS_LIST);
1529   fstrcpy(fnamenew,fname);
1530   strcat(fnamenew,".");
1531
1532   if((fp = fopen(fnamenew,"w")) == NULL)
1533   {
1534     DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1535     return;
1536   }
1537
1538   DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1539  
1540   for (namerec = wins_server_subnet->namelist; namerec; namerec = namerec->next)
1541   {
1542     int i;
1543     struct tm *tm;
1544
1545     DEBUG(4,("%-19s ", namestr(&namerec->name) ));
1546
1547     if(namerec->death_time != PERMANENT_TTL)
1548     {
1549       tm = LocalTime(&namerec->death_time);
1550       DEBUG(4,("TTL = %s", asctime(tm) ));
1551     }
1552     else
1553       DEBUG(4,("TTL = PERMANENT\t"));
1554
1555     for (i = 0; i < namerec->num_ips; i++)
1556       DEBUG(4,("%15s ", inet_ntoa(namerec->ip[i]) ));
1557     DEBUG(4,("%2x\n", namerec->nb_flags ));
1558
1559     if (namerec->source == REGISTER_NAME)
1560     {
1561       fprintf(fp, "\"%s#%02x\" %d ",
1562               namerec->name.name,namerec->name.name_type, /* Ignore scope. */
1563               (int)namerec->death_time);
1564
1565       for (i = 0; i < namerec->num_ips; i++)
1566         fprintf(fp, "%s ", inet_ntoa(namerec->ip[i]));
1567       fprintf(fp, "%2xR\n", namerec->nb_flags);
1568     }
1569   }
1570   
1571   fclose(fp);
1572   unlink(fname);
1573   chmod(fnamenew,0644);
1574   rename(fnamenew,fname);
1575 }