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