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