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