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