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