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