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