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