Modified fix for bugid #784. Based on a patch from moriyama@miraclelinux.com (MORIYAM...
[samba.git] / source3 / nmbd / nmbd_winsserver.c
1 /* 
2    Unix SMB/CIFS implementation.
3    NBT netbios routines and daemon - version 2
4
5    Copyright (C) Jeremy Allison 1994-2003
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21 */
22
23 #include "includes.h"
24
25 #define WINS_LIST "wins.dat"
26 #define WINS_VERSION 1
27
28 /****************************************************************************
29  Change the wins owner address in the record.
30 *****************************************************************************/
31
32 static void update_wins_owner(struct name_record *namerec, struct in_addr wins_ip)
33 {
34         if (namerec==NULL)
35                 return;
36         namerec->data.wins_ip=wins_ip;
37 }
38
39 /****************************************************************************
40  Create the wins flags based on the nb flags and the input value.
41 *****************************************************************************/
42
43 static void update_wins_flag(struct name_record *namerec, int flags)
44 {
45         if (namerec==NULL)
46                 return;
47
48         namerec->data.wins_flags=0x0;
49
50         /* if it's a group, it can be a normal or a special one */
51         if (namerec->data.nb_flags & NB_GROUP) {
52                 if (namerec->name.name_type==0x1C)
53                         namerec->data.wins_flags|=WINS_SGROUP;
54                 else
55                         if (namerec->data.num_ips>1)
56                                 namerec->data.wins_flags|=WINS_SGROUP;
57                         else
58                                 namerec->data.wins_flags|=WINS_NGROUP;
59         } else {
60                 /* can be unique or multi-homed */
61                 if (namerec->data.num_ips>1)
62                         namerec->data.wins_flags|=WINS_MHOMED;
63                 else
64                         namerec->data.wins_flags|=WINS_UNIQUE;
65         }
66
67         /* the node type are the same bits */
68         namerec->data.wins_flags|=namerec->data.nb_flags&NB_NODETYPEMASK;
69
70         /* the static bit is elsewhere */
71         if (namerec->data.death_time == PERMANENT_TTL)
72                 namerec->data.wins_flags|=WINS_STATIC;
73
74         /* and add the given bits */
75         namerec->data.wins_flags|=flags;
76
77         DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n", 
78                  namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
79 }
80
81 /****************************************************************************
82  Return the general ID value and increase it if requested.
83 *****************************************************************************/
84
85 static void get_global_id_and_update(SMB_BIG_UINT *current_id, BOOL update)
86 {
87         /*
88          * it's kept as a static here, to prevent people from messing
89          * with the value directly
90          */
91
92         static SMB_BIG_UINT general_id = 1;
93
94         DEBUG(5,("get_global_id_and_update: updating version ID: %d\n", (int)general_id));
95         
96         *current_id = general_id;
97         
98         if (update)
99                 general_id++;
100 }
101
102 /****************************************************************************
103  Possibly call the WINS hook external program when a WINS change is made.
104 *****************************************************************************/
105
106 static void wins_hook(const char *operation, struct name_record *namerec, int ttl)
107 {
108         pstring command;
109         char *cmd = lp_wins_hook();
110         char *p, *namestr;
111         int i;
112
113         if (!cmd || !*cmd) return;
114
115         for (p=namerec->name.name; *p; p++) {
116                 if (!(isalnum((int)*p) || strchr_m("._-",*p))) {
117                         DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
118                         return;
119                 }
120         }
121         
122         /* Use the name without the nametype (and scope) appended */
123
124         namestr = nmb_namestr(&namerec->name);
125         if ((p = strchr(namestr, '<')))
126                 *p = 0;
127
128         p = command;
129         p += slprintf(p, sizeof(command)-1, "%s %s %s %02x %d", 
130                       cmd,
131                       operation, 
132                       namestr,
133                       namerec->name.name_type,
134                       ttl);
135
136         for (i=0;i<namerec->data.num_ips;i++) {
137                 p += slprintf(p, sizeof(command) - (p-command) -1, " %s", inet_ntoa(namerec->data.ip[i]));
138         }
139
140         DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
141         smbrun(command, NULL);
142 }
143
144
145 /****************************************************************************
146 Determine if this packet should be allocated to the WINS server.
147 *****************************************************************************/
148
149 BOOL packet_is_for_wins_server(struct packet_struct *packet)
150 {
151         struct nmb_packet *nmb = &packet->packet.nmb;
152
153         /* Only unicast packets go to a WINS server. */
154         if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True)) {
155                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
156                 return False;
157         }
158
159         /* Check for node status requests. */
160         if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
161                 return False;
162
163         switch(nmb->header.opcode) { 
164                 /*
165                  * A WINS server issues WACKS, not receives them.
166                  */
167                 case NMB_WACK_OPCODE:
168                         DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
169                         return False;
170                 /*
171                  * A WINS server only processes registration and
172                  * release requests, not responses.
173                  */
174                 case NMB_NAME_REG_OPCODE:
175                 case NMB_NAME_MULTIHOMED_REG_OPCODE:
176                 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
177                 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
178                         if(nmb->header.response) {
179                                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
180                                 return False;
181                         }
182                         break;
183
184                 case NMB_NAME_RELEASE_OPCODE:
185                         if(nmb->header.response) {
186                                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
187                                 return False;
188                         }
189                         break;
190
191                 /*
192                  * Only process unicast name queries with rd = 1.
193                  */
194                 case NMB_NAME_QUERY_OPCODE:
195                         if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired) {
196                                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
197                                 return False;
198                         }
199                         break;
200         }
201
202         return True;
203 }
204
205 /****************************************************************************
206 Utility function to decide what ttl to give a register/refresh request.
207 *****************************************************************************/
208
209 static int get_ttl_from_packet(struct nmb_packet *nmb)
210 {
211         int ttl = nmb->additional->ttl;
212
213         if(ttl < lp_min_wins_ttl() )
214                 ttl = lp_min_wins_ttl();
215
216         if(ttl > lp_max_wins_ttl() )
217                 ttl = lp_max_wins_ttl();
218
219         return ttl;
220 }
221
222 /****************************************************************************
223 Load or create the WINS database.
224 *****************************************************************************/
225
226 BOOL initialise_wins(void)
227 {
228         time_t time_now = time(NULL);
229         XFILE *fp;
230         pstring line;
231
232         if(!lp_we_are_a_wins_server())
233                 return True;
234
235         add_samba_names_to_subnet(wins_server_subnet);
236
237         if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL) {
238                 DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
239                         WINS_LIST, strerror(errno) ));
240                 return True;
241         }
242
243         while (!x_feof(fp)) {
244                 pstring name_str, ip_str, ttl_str, nb_flags_str;
245                 unsigned int num_ips;
246                 pstring name;
247                 struct in_addr *ip_list;
248                 int type = 0;
249                 int nb_flags;
250                 int ttl;
251                 const char *ptr;
252                 char *p;
253                 BOOL got_token;
254                 BOOL was_ip;
255                 int i;
256                 unsigned int hash;
257                 int version;
258
259                 /* Read a line from the wins.dat file. Strips whitespace
260                         from the beginning and end of the line.  */
261                 if (!fgets_slash(line,sizeof(pstring),fp))
262                         continue;
263       
264                 if (*line == '#')
265                         continue;
266
267                 if (strncmp(line,"VERSION ", 8) == 0) {
268                         if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
269                                                 version != WINS_VERSION) {
270                                 DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
271                                 x_fclose(fp);
272                                 return True;
273                         }
274                         continue;
275                 }
276
277                 ptr = line;
278
279                 /* 
280                  * Now we handle multiple IP addresses per name we need
281                  * to iterate over the line twice. The first time to
282                  * determine how many IP addresses there are, the second
283                  * time to actually parse them into the ip_list array.
284                  */
285
286                 if (!next_token(&ptr,name_str,NULL,sizeof(name_str))) {
287                         DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
288                         continue;
289                 }
290
291                 if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str))) {
292                         DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
293                         continue;
294                 }
295
296                 /*
297                  * Determine the number of IP addresses per line.
298                  */
299                 num_ips = 0;
300                 do {
301                         got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
302                         was_ip = False;
303
304                         if(got_token && strchr(ip_str, '.')) {
305                                 num_ips++;
306                                 was_ip = True;
307                         }
308                 } while( got_token && was_ip);
309
310                 if(num_ips == 0) {
311                         DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
312                         continue;
313                 }
314
315                 if(!got_token) {
316                         DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
317                         continue;
318                 }
319
320                 /* Allocate the space for the ip_list. */
321                 if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) {
322                         DEBUG(0,("initialise_wins: Malloc fail !\n"));
323                         return False;
324                 }
325  
326                 /* Reset and re-parse the line. */
327                 ptr = line;
328                 next_token(&ptr,name_str,NULL,sizeof(name_str)); 
329                 next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
330                 for(i = 0; i < num_ips; i++) {
331                         next_token(&ptr, ip_str, NULL, sizeof(ip_str));
332                         ip_list[i] = *interpret_addr2(ip_str);
333                 }
334                 next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
335
336                 /* 
337                  * Deal with SELF or REGISTER name encoding. Default is REGISTER
338                  * for compatibility with old nmbds.
339                  */
340
341                 if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') {
342                         DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
343                         SAFE_FREE(ip_list);
344                         continue;
345                 }
346       
347                 if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
348                         nb_flags_str[strlen(nb_flags_str)-1] = '\0';
349       
350                 /* Netbios name. # divides the name from the type (hex): netbios#xx */
351                 pstrcpy(name,name_str);
352       
353                 if((p = strchr(name,'#')) != NULL) {
354                         *p = 0;
355                         sscanf(p+1,"%x",&type);
356                 }
357       
358                 /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
359                 sscanf(nb_flags_str,"%x",&nb_flags);
360                 sscanf(ttl_str,"%d",&ttl);
361
362                 /* add all entries that have 60 seconds or more to live */
363                 if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
364                         if(ttl != PERMANENT_TTL)
365                                 ttl -= time_now;
366     
367                         DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
368                                 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
369
370                         (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags, 
371                                         ttl, REGISTER_NAME, num_ips, ip_list );
372                 } else {
373                         DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
374                                 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
375                 }
376
377                 SAFE_FREE(ip_list);
378         } 
379     
380         x_fclose(fp);
381         return True;
382 }
383
384 /****************************************************************************
385 Send a WINS WACK (Wait ACKnowledgement) response.
386 **************************************************************************/
387
388 static void send_wins_wack_response(int ttl, struct packet_struct *p)
389 {
390         struct nmb_packet *nmb = &p->packet.nmb;
391         unsigned char rdata[2];
392
393         rdata[0] = rdata[1] = 0;
394
395         /* Taken from nmblib.c - we need to send back almost
396                 identical bytes from the requesting packet header. */
397
398         rdata[0] = (nmb->header.opcode & 0xF) << 3;
399         if (nmb->header.nm_flags.authoritative && nmb->header.response)
400                 rdata[0] |= 0x4;
401         if (nmb->header.nm_flags.trunc)
402                 rdata[0] |= 0x2;
403         if (nmb->header.nm_flags.recursion_desired)
404                 rdata[0] |= 0x1;
405         if (nmb->header.nm_flags.recursion_available && nmb->header.response)
406                 rdata[1] |= 0x80;
407         if (nmb->header.nm_flags.bcast)
408                 rdata[1] |= 0x10;
409
410         reply_netbios_packet(p,                                /* Packet to reply to. */
411                                 0,                             /* Result code. */
412                                 NMB_WAIT_ACK,                  /* nmbd type code. */
413                                 NMB_WACK_OPCODE,               /* opcode. */
414                                 ttl,                           /* ttl. */
415                                 (char *)rdata,                 /* data to send. */
416                                 2);                            /* data length. */
417 }
418
419 /****************************************************************************
420 Send a WINS name registration response.
421 **************************************************************************/
422
423 static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
424 {
425         struct nmb_packet *nmb = &p->packet.nmb;
426         char rdata[6];
427
428         memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
429
430         reply_netbios_packet(p,                                /* Packet to reply to. */
431                                 rcode,                         /* Result code. */
432                                 WINS_REG,                      /* nmbd type code. */
433                                 NMB_NAME_REG_OPCODE,           /* opcode. */
434                                 ttl,                           /* ttl. */
435                                 rdata,                         /* data to send. */
436                                 6);                            /* data length. */
437 }
438
439 /***********************************************************************
440  Deal with a name refresh request to a WINS server.
441 ************************************************************************/
442
443 void wins_process_name_refresh_request( struct subnet_record *subrec,
444                                         struct packet_struct *p )
445 {
446         struct nmb_packet *nmb = &p->packet.nmb;
447         struct nmb_name *question = &nmb->question.question_name;
448         BOOL bcast = nmb->header.nm_flags.bcast;
449         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
450         BOOL group = (nb_flags & NB_GROUP) ? True : False;
451         struct name_record *namerec = NULL;
452         int ttl = get_ttl_from_packet(nmb);
453         struct in_addr from_ip;
454         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
455
456         putip( (char *)&from_ip, &nmb->additional->rdata[2] );
457
458         if(bcast) {
459                 /*
460                  * We should only get unicast name refresh packets here.
461                  * Anyone trying to refresh broadcast should not be going
462                  * to a WINS server.  Log an error here.
463                  */
464                 if( DEBUGLVL( 0 ) ) {
465                         dbgtext( "wins_process_name_refresh_request: " );
466                         dbgtext( "Broadcast name refresh request received " );
467                         dbgtext( "for name %s ", nmb_namestr(question) );
468                         dbgtext( "from IP %s ", inet_ntoa(from_ip) );
469                         dbgtext( "on subnet %s.  ", subrec->subnet_name );
470                         dbgtext( "Error - Broadcasts should not be sent " );
471                         dbgtext( "to a WINS server\n" );
472                 }
473                 return;
474         }
475
476         if( DEBUGLVL( 3 ) ) {
477                 dbgtext( "wins_process_name_refresh_request: " );
478                 dbgtext( "Name refresh for name %s IP %s\n",
479                          nmb_namestr(question), inet_ntoa(from_ip) );
480         }
481
482         /* 
483          * See if the name already exists.
484          * If not, handle it as a name registration and return.
485          */
486         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
487
488         /*
489          * If this is a refresh request and the name doesn't exist then
490          * treat it like a registration request. This allows us to recover 
491          * from errors (tridge)
492          */
493         if(namerec == NULL) {
494                 if( DEBUGLVL( 3 ) ) {
495                         dbgtext( "wins_process_name_refresh_request: " );
496                         dbgtext( "Name refresh for name %s ",
497                                  nmb_namestr( question ) );
498                         dbgtext( "and the name does not exist.  Treating " );
499                         dbgtext( "as registration.\n" );
500                 }
501                 wins_process_name_registration_request(subrec,p);
502                 return;
503         }
504
505         /*
506          * if the name is present but not active, simply remove it
507          * and treat the refresh request as a registration & return.
508          */
509         if (namerec != NULL && !WINS_STATE_ACTIVE(namerec)) {
510                 if( DEBUGLVL( 5 ) ) {
511                         dbgtext( "wins_process_name_refresh_request: " );
512                         dbgtext( "Name (%s) in WINS ", nmb_namestr(question) );
513                         dbgtext( "was not active - removing it.\n" );
514                 }
515                 remove_name_from_namelist( subrec, namerec );
516                 namerec = NULL;
517                 wins_process_name_registration_request( subrec, p );
518                 return;
519         }
520
521         /*
522          * Check that the group bits for the refreshing name and the
523          * name in our database match.  If not, refuse the refresh.
524          * [crh:  Why RFS_ERR instead of ACT_ERR? Is this what MS does?]
525          */
526         if( (namerec != NULL) &&
527             ( (group && !NAME_GROUP(namerec))
528            || (!group && NAME_GROUP(namerec)) ) ) {
529                 if( DEBUGLVL( 3 ) ) {
530                         dbgtext( "wins_process_name_refresh_request: " );
531                         dbgtext( "Name %s ", nmb_namestr(question) );
532                         dbgtext( "group bit = %s does not match ",
533                                  group ? "True" : "False" );
534                         dbgtext( "group bit in WINS for this name.\n" );
535                 }
536                 send_wins_name_registration_response(RFS_ERR, 0, p);
537                 return;
538         }
539
540         /*
541          * For a unique name check that the person refreshing the name is
542          * one of the registered IP addresses. If not - fail the refresh.
543          * Do the same for group names with a type of 0x1c.
544          * Just return success for unique 0x1d refreshes. For normal group
545          * names update the ttl and return success.
546          */
547         if( (!group || (group && (question->name_type == 0x1c)))
548          && find_ip_in_name_record(namerec, from_ip) ) {
549                 /*
550                  * Update the ttl.
551                  */
552                 update_name_ttl(namerec, ttl);
553
554                 /*
555                  * if the record is a replica:
556                  * we take ownership and update the version ID.
557                  */
558                 if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
559                         update_wins_owner(namerec, our_fake_ip);
560                         get_global_id_and_update(&namerec->data.id, True);
561                 }
562
563                 send_wins_name_registration_response(0, ttl, p);
564                 wins_hook("refresh", namerec, ttl);
565                 return;
566         } else if((group && (question->name_type == 0x1c))) {
567                 /*
568                  * Added by crh for bug #1079.
569                  * Fix from Bert Driehuis
570                  */
571                 if( DEBUGLVL( 3 ) ) {
572                         dbgtext( "wins_process_name_refresh_request: " );
573                         dbgtext( "Name refresh for name %s, ",
574                                  nmb_namestr(question) );
575                         dbgtext( "but IP address %s ", inet_ntoa(from_ip) );
576                         dbgtext( "is not yet associated with " );
577                         dbgtext( "that name. Treating as registration.\n" );
578                 }
579                 wins_process_name_registration_request(subrec,p);
580                 return;
581         } else if(group) {
582                 /* 
583                  * Normal groups are all registered with an IP address of
584                  * 255.255.255.255  so we can't search for the IP address.
585                  */
586                 update_name_ttl(namerec, ttl);
587                 send_wins_name_registration_response(0, ttl, p);
588                 return;
589         } else if(!group && (question->name_type == 0x1d)) {
590                 /*
591                  * Special name type - just pretend the refresh succeeded.
592                  */
593                 send_wins_name_registration_response(0, ttl, p);
594                 return;
595         } else {
596                 /*
597                  * Fail the refresh.
598                  */
599                 if( DEBUGLVL( 3 ) ) {
600                         dbgtext( "wins_process_name_refresh_request: " );
601                         dbgtext( "Name refresh for name %s with IP %s ",
602                                  nmb_namestr(question), inet_ntoa(from_ip) );
603                         dbgtext( "and is IP is not known to the name.\n" );
604                 }
605                 send_wins_name_registration_response(RFS_ERR, 0, p);
606                 return;
607         }
608 }
609
610 /***********************************************************************
611  Deal with a name registration request query success to a client that
612  owned the name.
613
614  We have a locked pointer to the original packet stashed away in the
615  userdata pointer. The success here is actually a failure as it means
616  the client we queried wants to keep the name, so we must return
617  a registration failure to the original requestor.
618 ************************************************************************/
619
620 static void wins_register_query_success(struct subnet_record *subrec,
621                                              struct userdata_struct *userdata,
622                                              struct nmb_name *question_name,
623                                              struct in_addr ip,
624                                              struct res_rec *answers)
625 {
626         struct packet_struct *orig_reg_packet;
627
628         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
629
630         DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
631 name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
632
633         send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
634
635         orig_reg_packet->locked = False;
636         free_packet(orig_reg_packet);
637 }
638
639 /***********************************************************************
640  Deal with a name registration request query failure to a client that
641  owned the name.
642
643  We have a locked pointer to the original packet stashed away in the
644  userdata pointer. The failure here is actually a success as it means
645  the client we queried didn't want to keep the name, so we can remove
646  the old name record and then successfully add the new name.
647 ************************************************************************/
648
649 static void wins_register_query_fail(struct subnet_record *subrec,
650                                           struct response_record *rrec,
651                                           struct nmb_name *question_name,
652                                           int rcode)
653 {
654         struct userdata_struct *userdata = rrec->userdata;
655         struct packet_struct *orig_reg_packet;
656         struct name_record *namerec = NULL;
657
658         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
659
660         /*
661          * We want to just add the name, as we now know the original owner
662          * didn't want it. But we can't just do that as an arbitary
663          * amount of time may have taken place between the name query
664          * request and this timeout/error response. So we check that
665          * the name still exists and is in the same state - if so
666          * we remove it and call wins_process_name_registration_request()
667          * as we know it will do the right thing now.
668          */
669
670         namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
671
672         if( (namerec != NULL) && (namerec->data.source == REGISTER_NAME) && ip_equal(rrec->packet->ip, *namerec->data.ip) ) {
673                 remove_name_from_namelist( subrec, namerec);
674                 namerec = NULL;
675         }
676
677         if(namerec == NULL)
678                 wins_process_name_registration_request(subrec, orig_reg_packet);
679         else
680                 DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
681 querying for name %s in order to replace it and this reply.\n", nmb_namestr(question_name) ));
682
683         orig_reg_packet->locked = False;
684         free_packet(orig_reg_packet);
685 }
686
687 /***********************************************************************
688  Deal with a name registration request to a WINS server.
689
690  Use the following pseudocode :
691
692  registering_group
693      |
694      |
695      +--------name exists
696      |                  |
697      |                  |
698      |                  +--- existing name is group
699      |                  |                      |
700      |                  |                      |
701      |                  |                      +--- add name (return).
702      |                  |
703      |                  |
704      |                  +--- exiting name is unique
705      |                                         |
706      |                                         |
707      |                                         +--- query existing owner (return).
708      |
709      |
710      +--------name doesn't exist
711                         |
712                         |
713                         +--- add name (return).
714
715  registering_unique
716      |
717      |
718      +--------name exists
719      |                  |
720      |                  |
721      |                  +--- existing name is group 
722      |                  |                      |
723      |                  |                      |
724      |                  |                      +--- fail add (return).
725      |                  | 
726      |                  |
727      |                  +--- exiting name is unique
728      |                                         |
729      |                                         |
730      |                                         +--- query existing owner (return).
731      |
732      |
733      +--------name doesn't exist
734                         |
735                         |
736                         +--- add name (return).
737
738  As can be seen from the above, the two cases may be collapsed onto each
739  other with the exception of the case where the name already exists and
740  is a group name. This case we handle with an if statement.
741  
742 ************************************************************************/
743
744 void wins_process_name_registration_request(struct subnet_record *subrec,
745                                             struct packet_struct *p)
746 {
747         fstring name;
748         struct nmb_packet *nmb = &p->packet.nmb;
749         struct nmb_name *question = &nmb->question.question_name;
750         BOOL bcast = nmb->header.nm_flags.bcast;
751         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
752         int ttl = get_ttl_from_packet(nmb);
753         struct name_record *namerec = NULL;
754         struct in_addr from_ip;
755         BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
756         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
757
758         putip((char *)&from_ip,&nmb->additional->rdata[2]);
759
760         if(bcast) {
761                 /*
762                  * We should only get unicast name registration packets here.
763                  * Anyone trying to register broadcast should not be going to a WINS
764                  * server. Log an error here.
765                  */
766
767                 DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
768 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
769                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
770                 return;
771         }
772
773         DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
774 IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
775
776         /*
777          * See if the name already exists.
778          */
779
780         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
781
782         /*
783          * if the record exists but NOT in active state,
784          * consider it dead.
785          */
786         if ( (namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
787                 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
788 not active - removing it.\n", nmb_namestr(question) ));
789                 remove_name_from_namelist( subrec, namerec );
790                 namerec = NULL;
791         }
792
793         /*
794          * Deal with the case where the name found was a dns entry.
795          * Remove it as we now have a NetBIOS client registering the
796          * name.
797          */
798
799         if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
800                 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
801 a dns lookup - removing it.\n", nmb_namestr(question) ));
802                 remove_name_from_namelist( subrec, namerec );
803                 namerec = NULL;
804         }
805
806         /*
807          * Reject if the name exists and is not a REGISTER_NAME.
808          * (ie. Don't allow any static names to be overwritten.
809          */
810
811         if((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) {
812                 DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
813 to register name %s. Name already exists in WINS with source type %d.\n",
814                         nmb_namestr(question), namerec->data.source ));
815                 send_wins_name_registration_response(RFS_ERR, 0, p);
816                 return;
817         }
818
819         /*
820          * Special policy decisions based on MS documentation.
821          * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
822          * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
823          */
824
825         /*
826          * A group name is always added as the local broadcast address, except
827          * for group names ending in 0x1c.
828          * Group names with type 0x1c are registered with individual IP addresses.
829          */
830
831         if(registering_group_name && (question->name_type != 0x1c))
832                 from_ip = *interpret_addr2("255.255.255.255");
833
834         /*
835          * Ignore all attempts to register a unique 0x1d name, although return success.
836          */
837
838         if(!registering_group_name && (question->name_type == 0x1d)) {
839                 DEBUG(3,("wins_process_name_registration_request: Ignoring request \
840 to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
841                 send_wins_name_registration_response(0, ttl, p);
842                 return;
843         }
844
845         /*
846          * Next two cases are the 'if statement' mentioned above.
847          */
848
849         if((namerec != NULL) && NAME_GROUP(namerec)) {
850                 if(registering_group_name) {
851                         /*
852                          * If we are adding a group name, the name exists and is also a group entry just add this
853                          * IP address to it and update the ttl.
854                          */
855
856                         DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
857                                 inet_ntoa(from_ip), nmb_namestr(question) ));
858
859                         /* 
860                          * Check the ip address is not already in the group.
861                          */
862
863                         if(!find_ip_in_name_record(namerec, from_ip)) {
864                                 add_ip_to_name_record(namerec, from_ip);
865                                 /* we need to update the record for replication */
866                                 get_global_id_and_update(&namerec->data.id, True);
867
868                                 /*
869                                  * if the record is a replica, we must change
870                                  * the wins owner to us to make the replication updates
871                                  * it on the other wins servers.
872                                  * And when the partner will receive this record,
873                                  * it will update its own record.
874                                  */
875
876                                 update_wins_owner(namerec, our_fake_ip);
877                         }
878                         update_name_ttl(namerec, ttl);
879                         send_wins_name_registration_response(0, ttl, p);
880                         return;
881                 } else {
882
883                         /*
884                          * If we are adding a unique name, the name exists in the WINS db 
885                          * and is a group name then reject the registration.
886                          *
887                          * explanation: groups have a higher priority than unique names.
888                          */
889
890                         DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
891 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
892                         send_wins_name_registration_response(RFS_ERR, 0, p);
893                         return;
894                 } 
895         }
896
897         /*
898          * From here on down we know that if the name exists in the WINS db it is
899          * a unique name, not a group name.
900          */
901
902         /* 
903          * If the name exists and is one of our names then check the
904          * registering IP address. If it's not one of ours then automatically
905          * reject without doing the query - we know we will reject it.
906          */
907
908         if ( namerec != NULL )
909                 pull_ascii_nstring(name, sizeof(name), namerec->name.name);
910                 
911         if( is_myname(name) ) {
912                 if(!ismyip(from_ip)) {
913                         DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
914 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
915                         send_wins_name_registration_response(RFS_ERR, 0, p);
916                         return;
917                 } else {
918                         /*
919                          * It's one of our names and one of our IP's - update the ttl.
920                          */
921                         update_name_ttl(namerec, ttl);
922                         send_wins_name_registration_response(0, ttl, p);
923                         wins_hook("refresh", namerec, ttl);
924                         return;
925                 }
926         }
927
928         /*
929          * If the name exists and it is a unique registration and the registering IP 
930          * is the same as the (single) already registered IP then just update the ttl.
931          *
932          * But not if the record is an active replica. IF it's a replica, it means it can be
933          * the same client which has moved and not yet expired. So we don't update
934          * the ttl in this case and go beyond to do a WACK and query the old client
935          */
936
937         if( !registering_group_name
938                         && (namerec != NULL)
939                         && (namerec->data.num_ips == 1)
940                         && ip_equal( namerec->data.ip[0], from_ip )
941                         && ip_equal(namerec->data.wins_ip, our_fake_ip) ) {
942                 update_name_ttl( namerec, ttl );
943                 send_wins_name_registration_response( 0, ttl, p );
944                 wins_hook("refresh", namerec, ttl);
945                 return;
946         }
947
948         /*
949          * Finally if the name exists do a query to the registering machine 
950          * to see if they still claim to have the name.
951          */
952
953         if( namerec != NULL ) {
954                 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
955                 struct userdata_struct *userdata = (struct userdata_struct *)ud;
956
957                 /*
958                  * First send a WACK to the registering machine.
959                  */
960
961                 send_wins_wack_response(60, p);
962
963                 /*
964                  * When the reply comes back we need the original packet.
965                  * Lock this so it won't be freed and then put it into
966                  * the userdata structure.
967                  */
968
969                 p->locked = True;
970
971                 userdata = (struct userdata_struct *)ud;
972
973                 userdata->copy_fn = NULL;
974                 userdata->free_fn = NULL;
975                 userdata->userdata_len = sizeof(struct packet_struct *);
976                 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
977
978                 /*
979                  * Use the new call to send a query directly to an IP address.
980                  * This sends the query directly to the IP address, and ensures
981                  * the recursion desired flag is not set (you were right Luke :-).
982                  * This function should *only* be called from the WINS server
983                  * code. JRA.
984                  */
985
986                 pull_ascii_nstring(name, sizeof(name), question->name);
987                 query_name_from_wins_server( *namerec->data.ip,
988                                 name,
989                                 question->name_type, 
990                                 wins_register_query_success,
991                                 wins_register_query_fail,
992                                 userdata );
993                 return;
994         }
995
996         /*
997          * Name did not exist - add it.
998          */
999
1000         pull_ascii_nstring(name, sizeof(name), question->name);
1001         add_name_to_subnet( subrec, name, question->name_type,
1002                         nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1003
1004         if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1005                 get_global_id_and_update(&namerec->data.id, True);
1006                 update_wins_owner(namerec, our_fake_ip);
1007                 update_wins_flag(namerec, WINS_ACTIVE);
1008                 wins_hook("add", namerec, ttl);
1009         }
1010
1011         send_wins_name_registration_response(0, ttl, p);
1012 }
1013
1014 /***********************************************************************
1015  Deal with a mutihomed name query success to the machine that
1016  requested the multihomed name registration.
1017
1018  We have a locked pointer to the original packet stashed away in the
1019  userdata pointer.
1020 ************************************************************************/
1021
1022 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
1023                                              struct userdata_struct *userdata,
1024                                              struct nmb_name *question_name,
1025                                              struct in_addr ip,
1026                                              struct res_rec *answers)
1027 {
1028         struct packet_struct *orig_reg_packet;
1029         struct nmb_packet *nmb;
1030         struct name_record *namerec = NULL;
1031         struct in_addr from_ip;
1032         int ttl;
1033         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
1034
1035         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1036
1037         nmb = &orig_reg_packet->packet.nmb;
1038
1039         putip((char *)&from_ip,&nmb->additional->rdata[2]);
1040         ttl = get_ttl_from_packet(nmb);
1041
1042         /*
1043          * We want to just add the new IP, as we now know the requesting
1044          * machine claims to own it. But we can't just do that as an arbitary
1045          * amount of time may have taken place between the name query
1046          * request and this response. So we check that
1047          * the name still exists and is in the same state - if so
1048          * we just add the extra IP and update the ttl.
1049          */
1050
1051         namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
1052
1053         if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) ) {
1054                 DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
1055 a subsequent IP address.\n", nmb_namestr(question_name) ));
1056                 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1057
1058                 orig_reg_packet->locked = False;
1059                 free_packet(orig_reg_packet);
1060
1061                 return;
1062         }
1063
1064         if(!find_ip_in_name_record(namerec, from_ip))
1065                 add_ip_to_name_record(namerec, from_ip);
1066
1067         get_global_id_and_update(&namerec->data.id, True);
1068         update_wins_owner(namerec, our_fake_ip);
1069         update_wins_flag(namerec, WINS_ACTIVE);
1070         update_name_ttl(namerec, ttl);
1071         send_wins_name_registration_response(0, ttl, orig_reg_packet);
1072         wins_hook("add", namerec, ttl);
1073
1074         orig_reg_packet->locked = False;
1075         free_packet(orig_reg_packet);
1076 }
1077
1078 /***********************************************************************
1079  Deal with a name registration request query failure to a client that
1080  owned the name.
1081
1082  We have a locked pointer to the original packet stashed away in the
1083  userdata pointer.
1084 ************************************************************************/
1085
1086 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
1087                                           struct response_record *rrec,
1088                                           struct nmb_name *question_name,
1089                                           int rcode)
1090 {
1091         struct userdata_struct *userdata = rrec->userdata;
1092         struct packet_struct *orig_reg_packet;
1093
1094         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1095
1096         DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
1097 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
1098         send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1099
1100         orig_reg_packet->locked = False;
1101         free_packet(orig_reg_packet);
1102         return;
1103 }
1104
1105 /***********************************************************************
1106  Deal with a multihomed name registration request to a WINS server.
1107  These cannot be group name registrations.
1108 ***********************************************************************/
1109
1110 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
1111                                                         struct packet_struct *p)
1112 {
1113         struct nmb_packet *nmb = &p->packet.nmb;
1114         struct nmb_name *question = &nmb->question.question_name;
1115         BOOL bcast = nmb->header.nm_flags.bcast;
1116         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1117         int ttl = get_ttl_from_packet(nmb);
1118         struct name_record *namerec = NULL;
1119         struct in_addr from_ip;
1120         BOOL group = (nb_flags & NB_GROUP) ? True : False;
1121         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
1122         fstring qname;
1123
1124         putip((char *)&from_ip,&nmb->additional->rdata[2]);
1125
1126         if(bcast) {
1127                 /*
1128                  * We should only get unicast name registration packets here.
1129                  * Anyone trying to register broadcast should not be going to a WINS
1130                  * server. Log an error here.
1131                  */
1132
1133                 DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
1134 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1135                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1136                 return;
1137         }
1138
1139         /*
1140          * Only unique names should be registered multihomed.
1141          */
1142
1143         if(group) {
1144                 DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
1145 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
1146                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1147                 return;
1148         }
1149
1150         DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
1151 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
1152
1153         /*
1154          * Deal with policy regarding 0x1d names.
1155          */
1156
1157         if(question->name_type == 0x1d) {
1158                 DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
1159 to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1160                 send_wins_name_registration_response(0, ttl, p);  
1161                 return;
1162         }
1163
1164         /*
1165          * See if the name already exists.
1166          */
1167
1168         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1169
1170         /*
1171          * if the record exists but NOT in active state,
1172          * consider it dead.
1173          */
1174
1175         if ((namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
1176                 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was not active - removing it.\n", nmb_namestr(question)));
1177                 remove_name_from_namelist(subrec, namerec);
1178                 namerec = NULL;
1179         }
1180   
1181         /*
1182          * Deal with the case where the name found was a dns entry.
1183          * Remove it as we now have a NetBIOS client registering the
1184          * name.
1185          */
1186
1187         if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
1188                 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
1189 - removing it.\n", nmb_namestr(question) ));
1190                 remove_name_from_namelist( subrec, namerec);
1191                 namerec = NULL;
1192         }
1193
1194         /*
1195          * Reject if the name exists and is not a REGISTER_NAME.
1196          * (ie. Don't allow any static names to be overwritten.
1197          */
1198
1199         if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) ) {
1200                 DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1201 to register name %s. Name already exists in WINS with source type %d.\n",
1202                         nmb_namestr(question), namerec->data.source ));
1203                 send_wins_name_registration_response(RFS_ERR, 0, p);
1204                 return;
1205         }
1206
1207         /*
1208          * Reject if the name exists and is a GROUP name and is active.
1209          */
1210
1211         if((namerec != NULL) && NAME_GROUP(namerec) && WINS_STATE_ACTIVE(namerec)) {
1212                 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1213 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
1214                 send_wins_name_registration_response(RFS_ERR, 0, p);
1215                 return;
1216         } 
1217
1218         /*
1219          * From here on down we know that if the name exists in the WINS db it is
1220          * a unique name, not a group name.
1221          */
1222
1223         /*
1224          * If the name exists and is one of our names then check the
1225          * registering IP address. If it's not one of ours then automatically
1226          * reject without doing the query - we know we will reject it.
1227          */
1228
1229         if((namerec != NULL) && (is_myname(namerec->name.name)) ) {
1230                 if(!ismyip(from_ip)) {
1231                         DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1232 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
1233                         send_wins_name_registration_response(RFS_ERR, 0, p);
1234                         return;
1235                 } else {
1236                         /*
1237                          * It's one of our names and one of our IP's. Ensure the IP is in the record and
1238                          *  update the ttl. Update the version ID to force replication.
1239                          */
1240                         if(!find_ip_in_name_record(namerec, from_ip)) {
1241                                 get_global_id_and_update(&namerec->data.id, True);
1242                                 update_wins_owner(namerec, our_fake_ip);
1243                                 update_wins_flag(namerec, WINS_ACTIVE);
1244
1245                                 add_ip_to_name_record(namerec, from_ip);
1246                                 wins_hook("add", namerec, ttl);
1247                         } else {
1248                                 wins_hook("refresh", namerec, ttl);
1249                         }
1250
1251                         update_name_ttl(namerec, ttl);
1252                         send_wins_name_registration_response(0, ttl, p);
1253                         return;
1254                 }
1255         }
1256
1257         /*
1258          * If the name exists and is active, check if the IP address is already registered
1259          * to that name. If so then update the ttl and reply success.
1260          */
1261
1262         if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip) && WINS_STATE_ACTIVE(namerec)) {
1263                 update_name_ttl(namerec, ttl);
1264
1265                 /*
1266                  * If it's a replica, we need to become the wins owner
1267                  * to force the replication
1268                  */
1269                 if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
1270                         get_global_id_and_update(&namerec->data.id, True);
1271                         update_wins_owner(namerec, our_fake_ip);
1272                         update_wins_flag(namerec, WINS_ACTIVE);
1273                 }
1274     
1275                 send_wins_name_registration_response(0, ttl, p);
1276                 wins_hook("refresh", namerec, ttl);
1277                 return;
1278         }
1279
1280         /*
1281          * If the name exists do a query to the owner
1282          * to see if they still want the name.
1283          */
1284
1285         if(namerec != NULL) {
1286                 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
1287                 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1288
1289                 /*
1290                  * First send a WACK to the registering machine.
1291                  */
1292
1293                 send_wins_wack_response(60, p);
1294
1295                 /*
1296                  * When the reply comes back we need the original packet.
1297                  * Lock this so it won't be freed and then put it into
1298                  * the userdata structure.
1299                  */
1300
1301                 p->locked = True;
1302
1303                 userdata = (struct userdata_struct *)ud;
1304
1305                 userdata->copy_fn = NULL;
1306                 userdata->free_fn = NULL;
1307                 userdata->userdata_len = sizeof(struct packet_struct *);
1308                 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1309
1310                 /* 
1311                  * Use the new call to send a query directly to an IP address.
1312                  * This sends the query directly to the IP address, and ensures
1313                  * the recursion desired flag is not set (you were right Luke :-).
1314                  * This function should *only* be called from the WINS server
1315                  * code. JRA.
1316                  *
1317                  * Note that this packet is sent to the current owner of the name,
1318                  * not the person who sent the packet 
1319                  */
1320
1321                 pull_ascii_nstring( qname, sizeof(qname), question->name);
1322                 query_name_from_wins_server( namerec->data.ip[0],
1323                                 qname,
1324                                 question->name_type, 
1325                                 wins_multihomed_register_query_success,
1326                                 wins_multihomed_register_query_fail,
1327                                 userdata );
1328
1329                 return;
1330         }
1331
1332         /*
1333          * Name did not exist - add it.
1334          */
1335
1336         pull_ascii_nstring( qname, sizeof(qname), question->name);
1337         add_name_to_subnet( subrec, qname, question->name_type,
1338                         nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1339
1340         if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1341                 get_global_id_and_update(&namerec->data.id, True);
1342                 update_wins_owner(namerec, our_fake_ip);
1343                 update_wins_flag(namerec, WINS_ACTIVE);
1344                 wins_hook("add", namerec, ttl);
1345         }
1346
1347         send_wins_name_registration_response(0, ttl, p);
1348 }
1349
1350 /***********************************************************************
1351  Deal with the special name query for *<1b>.
1352 ***********************************************************************/
1353    
1354 static void process_wins_dmb_query_request(struct subnet_record *subrec,  
1355                                            struct packet_struct *p)
1356 {  
1357         struct name_record *namerec = NULL;
1358         char *prdata;
1359         int num_ips;
1360
1361         /*
1362          * Go through all the ACTIVE names in the WINS db looking for those
1363          * ending in <1b>. Use this to calculate the number of IP
1364          * addresses we need to return.
1365          */
1366
1367         num_ips = 0;
1368         for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1369                         namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
1370                 if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b )
1371                         num_ips += namerec->data.num_ips;
1372         }
1373
1374         if(num_ips == 0) {
1375                 /*
1376                  * There are no 0x1b names registered. Return name query fail.
1377                  */
1378                 send_wins_name_query_response(NAM_ERR, p, NULL);
1379                 return;
1380         }
1381
1382         if((prdata = (char *)malloc( num_ips * 6 )) == NULL) {
1383                 DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1384                 return;
1385         }
1386
1387         /*
1388          * Go through all the names again in the WINS db looking for those
1389          * ending in <1b>. Add their IP addresses into the list we will
1390          * return.
1391          */ 
1392
1393         num_ips = 0;
1394         for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1395                         namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
1396                 if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
1397                         int i;
1398                         for(i = 0; i < namerec->data.num_ips; i++) {
1399                                 set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1400                                 putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1401                                 num_ips++;
1402                         }
1403                 }
1404         }
1405
1406         /*
1407          * Send back the reply containing the IP list.
1408          */
1409
1410         reply_netbios_packet(p,                                /* Packet to reply to. */
1411                                 0,                             /* Result code. */
1412                                 WINS_QUERY,                    /* nmbd type code. */
1413                                 NMB_NAME_QUERY_OPCODE,         /* opcode. */
1414                                 lp_min_wins_ttl(),             /* ttl. */
1415                                 prdata,                        /* data to send. */
1416                                 num_ips*6);                    /* data length. */
1417
1418         SAFE_FREE(prdata);
1419 }
1420
1421 /****************************************************************************
1422 Send a WINS name query response.
1423 **************************************************************************/
1424
1425 void send_wins_name_query_response(int rcode, struct packet_struct *p, 
1426                                           struct name_record *namerec)
1427 {
1428         char rdata[6];
1429         char *prdata = rdata;
1430         int reply_data_len = 0;
1431         int ttl = 0;
1432         int i;
1433
1434         memset(rdata,'\0',6);
1435
1436         if(rcode == 0) {
1437                 ttl = (namerec->data.death_time != PERMANENT_TTL) ?  namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1438
1439                 /* Copy all known ip addresses into the return data. */
1440                 /* Optimise for the common case of one IP address so we don't need a malloc. */
1441
1442                 if( namerec->data.num_ips == 1 ) {
1443                         prdata = rdata;
1444                 } else {
1445                         if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL) {
1446                                 DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1447                                 return;
1448                         }
1449                 }
1450
1451                 for(i = 0; i < namerec->data.num_ips; i++) {
1452                         set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1453                         putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
1454                 }
1455
1456                 sort_query_replies(prdata, i, p->ip);
1457                 reply_data_len = namerec->data.num_ips * 6;
1458         }
1459
1460         reply_netbios_packet(p,                                /* Packet to reply to. */
1461                                 rcode,                         /* Result code. */
1462                                 WINS_QUERY,                    /* nmbd type code. */
1463                                 NMB_NAME_QUERY_OPCODE,         /* opcode. */
1464                                 ttl,                           /* ttl. */
1465                                 prdata,                        /* data to send. */
1466                                 reply_data_len);               /* data length. */
1467
1468         if(prdata != rdata)
1469                 SAFE_FREE(prdata);
1470 }
1471
1472 /***********************************************************************
1473  Deal with a name query.
1474 ***********************************************************************/
1475
1476 void wins_process_name_query_request(struct subnet_record *subrec, 
1477                                      struct packet_struct *p)
1478 {
1479         struct nmb_packet *nmb = &p->packet.nmb;
1480         struct nmb_name *question = &nmb->question.question_name;
1481         struct name_record *namerec = NULL;
1482         fstring qname;
1483
1484         DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n", 
1485                 nmb_namestr(question), inet_ntoa(p->ip) ));
1486
1487         /*
1488          * Special name code. If the queried name is *<1b> then search
1489          * the entire WINS database and return a list of all the IP addresses
1490          * registered to any <1b> name. This is to allow domain master browsers
1491          * to discover other domains that may not have a presence on their subnet.
1492          */
1493
1494         pull_ascii_nstring(qname, sizeof(qname), question->name);
1495         if(strequal( qname, "*") && (question->name_type == 0x1b)) {
1496                 process_wins_dmb_query_request( subrec, p);
1497                 return;
1498         }
1499
1500         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1501
1502         if(namerec != NULL) {
1503                 /*
1504                  * If the name is not anymore in active state then reply not found.
1505                  * it's fair even if we keep it in the cache for days.
1506                  */
1507                 if (!WINS_STATE_ACTIVE(namerec)) {
1508                         DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1509                                 nmb_namestr(question) ));
1510                         send_wins_name_query_response(NAM_ERR, p, namerec);
1511                         return;
1512                 }
1513
1514                 /* 
1515                  * If it's a DNSFAIL_NAME then reply name not found.
1516                  */
1517
1518                 if( namerec->data.source == DNSFAIL_NAME ) {
1519                         DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1520                                 nmb_namestr(question) ));
1521                         send_wins_name_query_response(NAM_ERR, p, namerec);
1522                         return;
1523                 }
1524
1525                 /*
1526                  * If the name has expired then reply name not found.
1527                  */
1528
1529                 if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < p->timestamp) ) {
1530                         DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1531                                         nmb_namestr(question) ));
1532                         send_wins_name_query_response(NAM_ERR, p, namerec);
1533                         return;
1534                 }
1535
1536                 DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1537                                 nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
1538
1539                 send_wins_name_query_response(0, p, namerec);
1540                 return;
1541         }
1542
1543         /* 
1544          * Name not found in WINS - try a dns query if it's a 0x20 name.
1545          */
1546
1547         if(lp_dns_proxy() && ((question->name_type == 0x20) || question->name_type == 0)) {
1548                 DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1549                                 nmb_namestr(question) ));
1550
1551                 queue_dns_query(p, question, &namerec);
1552                 return;
1553         }
1554
1555         /*
1556          * Name not found - return error.
1557          */
1558
1559         send_wins_name_query_response(NAM_ERR, p, NULL);
1560 }
1561
1562 /****************************************************************************
1563 Send a WINS name release response.
1564 **************************************************************************/
1565
1566 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1567 {
1568         struct nmb_packet *nmb = &p->packet.nmb;
1569         char rdata[6];
1570
1571         memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1572
1573         reply_netbios_packet(p,                               /* Packet to reply to. */
1574                                 rcode,                        /* Result code. */
1575                                 NMB_REL,                      /* nmbd type code. */
1576                                 NMB_NAME_RELEASE_OPCODE,      /* opcode. */
1577                                 0,                            /* ttl. */
1578                                 rdata,                        /* data to send. */
1579                                 6);                           /* data length. */
1580 }
1581
1582 /***********************************************************************
1583  Deal with a name release.
1584 ***********************************************************************/
1585
1586 void wins_process_name_release_request(struct subnet_record *subrec,
1587                                        struct packet_struct *p)
1588 {
1589         struct nmb_packet *nmb = &p->packet.nmb;
1590         struct nmb_name *question = &nmb->question.question_name;
1591         BOOL bcast = nmb->header.nm_flags.bcast;
1592         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1593         struct name_record *namerec = NULL;
1594         struct in_addr from_ip;
1595         BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1596
1597         putip((char *)&from_ip,&nmb->additional->rdata[2]);
1598
1599         if(bcast) {
1600                 /*
1601                  * We should only get unicast name registration packets here.
1602                  * Anyone trying to register broadcast should not be going to a WINS
1603                  * server. Log an error here.
1604                  */
1605
1606                 DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1607 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1608                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1609                 return;
1610         }
1611   
1612         DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1613 IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
1614     
1615         /*
1616          * Deal with policy regarding 0x1d names.
1617          */
1618
1619         if(!releasing_group_name && (question->name_type == 0x1d)) {
1620                 DEBUG(3,("wins_process_name_release_request: Ignoring request \
1621 to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1622                 send_wins_name_release_response(0, p);
1623                 return;
1624         }
1625
1626         /*
1627          * See if the name already exists.
1628          */
1629     
1630         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1631
1632         if( (namerec == NULL) || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) ) {
1633                 send_wins_name_release_response(NAM_ERR, p);
1634                 return;
1635         }
1636
1637         /* 
1638          * Check that the sending machine has permission to release this name.
1639          * If it's a group name not ending in 0x1c then just say yes and let
1640          * the group time out.
1641          */
1642
1643         if(releasing_group_name && (question->name_type != 0x1c)) {
1644                 send_wins_name_release_response(0, p);
1645                 return;
1646         }
1647
1648         /* 
1649          * Check that the releasing node is on the list of IP addresses
1650          * for this name. Disallow the release if not.
1651          */
1652
1653         if(!find_ip_in_name_record(namerec, from_ip)) {
1654                 DEBUG(3,("wins_process_name_release_request: Refusing request to \
1655 release name %s as IP %s is not one of the known IP's for this name.\n",
1656                         nmb_namestr(question), inet_ntoa(from_ip) ));
1657                 send_wins_name_release_response(NAM_ERR, p);
1658                 return;
1659         }
1660
1661         /*
1662          * Check if the record is active. IF it's already released
1663          * or tombstoned, refuse the release.
1664          */
1665
1666         if (!WINS_STATE_ACTIVE(namerec)) {
1667                 DEBUG(3,("wins_process_name_release_request: Refusing request to \
1668 release name %s as this record is not active anymore.\n", nmb_namestr(question) ));
1669                 send_wins_name_release_response(NAM_ERR, p);
1670                 return;
1671         }    
1672
1673         /*
1674          * Check if the record is a 0x1c group
1675          * and has more then one ip
1676          * remove only this address.
1677          */
1678
1679         if(releasing_group_name && (question->name_type == 0x1c) && (namerec->data.num_ips > 1)) {
1680                 remove_ip_from_name_record(namerec, from_ip);
1681                 DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
1682                                 inet_ntoa(from_ip),nmb_namestr(question)));
1683                 send_wins_name_release_response(0, p);
1684                 return;
1685         }
1686
1687         /* 
1688          * Send a release response.
1689          * Flag the name as released and update the ttl
1690          */
1691
1692         send_wins_name_release_response(0, p);
1693   
1694         namerec->data.wins_flags |= WINS_RELEASED;
1695         update_name_ttl(namerec, EXTINCTION_INTERVAL);
1696
1697         wins_hook("delete", namerec, 0);
1698 }
1699
1700 /*******************************************************************
1701  WINS time dependent processing.
1702 ******************************************************************/
1703
1704 void initiate_wins_processing(time_t t)
1705 {
1706         static time_t lasttime = 0;
1707         struct name_record *namerec;
1708         struct name_record *next_namerec;
1709         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
1710
1711         if (!lasttime)
1712                 lasttime = t;
1713         if (t - lasttime < 20)
1714                 return;
1715
1716         lasttime = t;
1717
1718         if(!lp_we_are_a_wins_server())
1719                 return;
1720
1721         for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
1722              namerec;
1723              namerec = next_namerec ) {
1724                 next_namerec = (struct name_record *)ubi_trNext( namerec );
1725
1726                 if( (namerec->data.death_time != PERMANENT_TTL)
1727                      && (namerec->data.death_time < t) ) {
1728
1729                         if( namerec->data.source == SELF_NAME ) {
1730                                 DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF name %s\n", 
1731                                            wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
1732                                 namerec->data.death_time += 300;
1733                                 namerec->subnet->namelist_changed = True;
1734                                 continue;
1735                         }
1736
1737                         /* handle records, samba is the wins owner */
1738                         if (ip_equal(namerec->data.wins_ip, our_fake_ip)) {
1739                                 switch (namerec->data.wins_flags | WINS_STATE_MASK) {
1740                                         case WINS_ACTIVE:
1741                                                 namerec->data.wins_flags&=~WINS_STATE_MASK;
1742                                                 namerec->data.wins_flags|=WINS_RELEASED;
1743                                                 namerec->data.death_time = t + EXTINCTION_INTERVAL;
1744                                                 DEBUG(3,("initiate_wins_processing: expiring %s\n", nmb_namestr(&namerec->name)));
1745                                                 break;
1746                                         case WINS_RELEASED:
1747                                                 namerec->data.wins_flags&=~WINS_STATE_MASK;
1748                                                 namerec->data.wins_flags|=WINS_TOMBSTONED;
1749                                                 namerec->data.death_time = t + EXTINCTION_TIMEOUT;
1750                                                 get_global_id_and_update(&namerec->data.id, True);
1751                                                 DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
1752                                                 break;
1753                                         case WINS_TOMBSTONED:
1754                                                 DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
1755                                                 remove_name_from_namelist( wins_server_subnet, namerec );
1756                                                 break;
1757                                 }
1758                         } else {
1759                                 switch (namerec->data.wins_flags | WINS_STATE_MASK) {
1760                                         case WINS_ACTIVE:
1761                                                 /* that's not as MS says it should be */
1762                                                 namerec->data.wins_flags&=~WINS_STATE_MASK;
1763                                                 namerec->data.wins_flags|=WINS_TOMBSTONED;
1764                                                 namerec->data.death_time = t + EXTINCTION_TIMEOUT;
1765                                                 DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
1766                                         case WINS_TOMBSTONED:
1767                                                 DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
1768                                                 remove_name_from_namelist( wins_server_subnet, namerec );
1769                                                 break;
1770                                         case WINS_RELEASED:
1771                                                 DEBUG(0,("initiate_wins_processing: %s is in released state and\
1772 we are not the wins owner !\n", nmb_namestr(&namerec->name)));
1773                                                 break;
1774                                 }
1775                         }
1776
1777                 }
1778         }
1779
1780         if(wins_server_subnet->namelist_changed)
1781                 wins_write_database(True);
1782
1783         wins_server_subnet->namelist_changed = False;
1784 }
1785
1786 /*******************************************************************
1787  Write out the current WINS database.
1788 ******************************************************************/
1789
1790 void wins_write_database(BOOL background)
1791 {
1792         struct name_record *namerec;
1793         pstring fname, fnamenew;
1794
1795         XFILE *fp;
1796    
1797         if(!lp_we_are_a_wins_server())
1798                 return;
1799
1800         /* We will do the writing in a child process to ensure that the parent doesn't block while this is done */
1801         if (background) {
1802                 CatchChild();
1803                 if (sys_fork()) {
1804                         return;
1805                 }
1806         }
1807
1808         slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
1809         all_string_sub(fname,"//", "/", 0);
1810         slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
1811
1812         if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) {
1813                 DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1814                 if (background) {
1815                         _exit(0);
1816                 }
1817                 return;
1818         }
1819
1820         DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1821
1822         x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
1823  
1824         for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist ); namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
1825                 int i;
1826                 struct tm *tm;
1827
1828                 DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
1829
1830                 if( namerec->data.death_time != PERMANENT_TTL ) {
1831                         char *ts, *nl;
1832
1833                         tm = LocalTime(&namerec->data.death_time);
1834                         ts = asctime(tm);
1835                         nl = strrchr( ts, '\n' );
1836                         if( NULL != nl )
1837                                 *nl = '\0';
1838                         DEBUGADD(4,("TTL = %s  ", ts ));
1839                 } else {
1840                         DEBUGADD(4,("TTL = PERMANENT                 "));
1841                 }
1842
1843                 for (i = 0; i < namerec->data.num_ips; i++)
1844                         DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
1845                 DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
1846
1847                 if( namerec->data.source == REGISTER_NAME ) {
1848                         fstring name;
1849                         pull_ascii_nstring(name, sizeof(name), namerec->name.name);
1850                         x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */
1851                                 (int)namerec->data.death_time);
1852
1853                         for (i = 0; i < namerec->data.num_ips; i++)
1854                                 x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
1855                         x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
1856                 }
1857         }
1858   
1859         x_fclose(fp);
1860         chmod(fnamenew,0644);
1861         unlink(fname);
1862         rename(fnamenew,fname);
1863         if (background) {
1864                 _exit(0);
1865         }
1866 }
1867
1868 /****************************************************************************
1869  Process a internal Samba message receiving a wins record.
1870 ***************************************************************************/
1871
1872 void nmbd_wins_new_entry(int msg_type, pid_t src, void *buf, size_t len)
1873 {
1874         WINS_RECORD *record;
1875         struct name_record *namerec = NULL;
1876         struct name_record *new_namerec = NULL;
1877         struct nmb_name question;
1878         BOOL overwrite=False;
1879         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
1880         int i;
1881
1882         if (buf==NULL)
1883                 return;
1884         
1885         /* Record should use UNIX codepage. Ensure this is so in the wrepld code. JRA. */
1886         record=(WINS_RECORD *)buf;
1887         
1888         make_nmb_name(&question, record->name, record->type);
1889
1890         namerec = find_name_on_subnet(wins_server_subnet, &question, FIND_ANY_NAME);
1891
1892         /* record doesn't exist, add it */
1893         if (namerec == NULL) {
1894                 DEBUG(3,("nmbd_wins_new_entry: adding new replicated record: %s<%02x> for wins server: %s\n", 
1895                           record->name, record->type, inet_ntoa(record->wins_ip)));
1896
1897                 new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags, 
1898                                                 EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
1899                 if (new_namerec!=NULL) {
1900                                 update_wins_owner(new_namerec, record->wins_ip);
1901                                 update_wins_flag(new_namerec, record->wins_flags);
1902                                 new_namerec->data.id=record->id;
1903
1904                                 wins_server_subnet->namelist_changed = True;
1905                         }
1906         }
1907
1908         /* check if we have a conflict */
1909         if (namerec != NULL) {
1910                 /* both records are UNIQUE */
1911                 if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
1912
1913                         /* the database record is a replica */
1914                         if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
1915                                 if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
1916                                         if (ip_equal(namerec->data.wins_ip, record->wins_ip))
1917                                                 overwrite=True;
1918                                 } else
1919                                         overwrite=True;
1920                         } else {
1921                         /* we are the wins owner of the database record */
1922                                 /* the 2 records have the same IP address */
1923                                 if (ip_equal(namerec->data.ip[0], record->ip[0])) {
1924                                         if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
1925                                                 get_global_id_and_update(&namerec->data.id, True);
1926                                         else
1927                                                 overwrite=True;
1928                                 
1929                                 } else {
1930                                 /* the 2 records have different IP address */
1931                                         if (namerec->data.wins_flags&WINS_ACTIVE) {
1932                                                 if (record->wins_flags&WINS_TOMBSTONED)
1933                                                         get_global_id_and_update(&namerec->data.id, True);
1934                                                 if (record->wins_flags&WINS_ACTIVE)
1935                                                         /* send conflict challenge to the replica node */
1936                                                         ;
1937                                         } else
1938                                                 overwrite=True;
1939                                 }
1940
1941                         }
1942                 }
1943                 
1944                 /* the replica is a standard group */
1945                 if (record->wins_flags&WINS_NGROUP || record->wins_flags&WINS_SGROUP) {
1946                         /* if the database record is unique and active force a name release */
1947                         if (namerec->data.wins_flags&WINS_UNIQUE)
1948                                 /* send a release name to the unique node */
1949                                 ;
1950                         overwrite=True;
1951                 
1952                 }
1953         
1954                 /* the replica is a special group */
1955                 if (record->wins_flags&WINS_SGROUP && namerec->data.wins_flags&WINS_SGROUP) {
1956                         if (namerec->data.wins_flags&WINS_ACTIVE) {
1957                                 for (i=0; i<record->num_ips; i++)
1958                                         if(!find_ip_in_name_record(namerec, record->ip[i]))
1959                                                 add_ip_to_name_record(namerec, record->ip[i]);
1960                         } else {
1961                                 overwrite=True;
1962                         }
1963                 }
1964                 
1965                 /* the replica is a multihomed host */
1966                 
1967                 /* I'm giving up on multi homed. Too much complex to understand */
1968                 
1969                 if (record->wins_flags&WINS_MHOMED) {
1970                         if (! (namerec->data.wins_flags&WINS_ACTIVE)) {
1971                                 if ( !(namerec->data.wins_flags&WINS_RELEASED) && !(namerec->data.wins_flags&WINS_NGROUP))
1972                                         overwrite=True;
1973                         }
1974                         else {
1975                                 if (ip_equal(record->wins_ip, namerec->data.wins_ip))
1976                                         overwrite=True;
1977                                 
1978                                 if (ip_equal(namerec->data.wins_ip, our_fake_ip))
1979                                         if (namerec->data.wins_flags&WINS_UNIQUE)
1980                                                 get_global_id_and_update(&namerec->data.id, True);
1981                                 
1982                         }
1983                         
1984                         if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
1985                                 if (namerec->data.wins_flags&WINS_UNIQUE ||
1986                                     namerec->data.wins_flags&WINS_MHOMED)
1987                                         if (ip_equal(record->wins_ip, namerec->data.wins_ip))
1988                                                 overwrite=True;
1989                                 
1990                 }
1991
1992                 if (overwrite == False)
1993                         DEBUG(3, ("nmbd_wins_new_entry: conflict in adding record: %s<%02x> from wins server: %s\n", 
1994                                   record->name, record->type, inet_ntoa(record->wins_ip)));
1995                 else {
1996                         DEBUG(3, ("nmbd_wins_new_entry: replacing record: %s<%02x> from wins server: %s\n", 
1997                                   record->name, record->type, inet_ntoa(record->wins_ip)));
1998
1999                         /* remove the old record and add a new one */
2000                         remove_name_from_namelist( wins_server_subnet, namerec );
2001                         new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags, 
2002                                                 EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
2003                         if (new_namerec!=NULL) {
2004                                 update_wins_owner(new_namerec, record->wins_ip);
2005                                 update_wins_flag(new_namerec, record->wins_flags);
2006                                 new_namerec->data.id=record->id;
2007
2008                                 wins_server_subnet->namelist_changed = True;
2009                         }
2010
2011                         wins_server_subnet->namelist_changed = True;
2012                 }
2013
2014         }
2015 }