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