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