be2c6a24438129d6a1fe93ed0ade91368727b31b
[metze/samba/wip.git] / source3 / nmbd / nmbd_winsserver.c
1 /* 
2    Unix SMB/CIFS implementation.
3    NBT netbios routines and daemon - version 2
4
5    Copyright (C) Jeremy Allison 1994-2005
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 3 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, see <http://www.gnu.org/licenses/>.
19    
20    Converted to store WINS data in a tdb. Dec 2005. JRA.
21 */
22
23 #include "includes.h"
24
25 #define WINS_LIST "wins.dat"
26 #define WINS_VERSION 1
27 #define WINSDB_VERSION 1
28
29 /****************************************************************************
30  We don't store the NetBIOS scope in the wins.tdb. We key off the (utf8) netbios
31  name (65 bytes with the last byte being the name type).
32 *****************************************************************************/
33
34 TDB_CONTEXT *wins_tdb;
35
36 /****************************************************************************
37  Delete all the temporary name records on the in-memory linked list.
38 *****************************************************************************/
39
40 static void wins_delete_all_tmp_in_memory_records(void)
41 {
42         struct name_record *nr = NULL;
43         struct name_record *nrnext = NULL;
44
45         /* Delete all temporary name records on the wins subnet linked list. */
46         for( nr = wins_server_subnet->namelist; nr; nr = nrnext) {
47                 nrnext = nr->next;
48                 DLIST_REMOVE(wins_server_subnet->namelist, nr);
49                 SAFE_FREE(nr->data.ip);
50                 SAFE_FREE(nr);
51         }
52 }
53
54 /****************************************************************************
55  Delete all the temporary 1b name records on the in-memory linked list.
56 *****************************************************************************/
57
58 static void wins_delete_all_1b_in_memory_records(void)
59 {
60         struct name_record *nr = NULL;
61         struct name_record *nrnext = NULL;
62
63         /* Delete all temporary 1b name records on the wins subnet linked list. */
64         for( nr = wins_server_subnet->namelist; nr; nr = nrnext) {
65                 nrnext = nr->next;
66                 if (nr->name.name_type == 0x1b) {
67                         DLIST_REMOVE(wins_server_subnet->namelist, nr);
68                         SAFE_FREE(nr->data.ip);
69                         SAFE_FREE(nr);
70                 }
71         }
72 }
73
74 /****************************************************************************
75  Convert a wins.tdb record to a struct name_record. Add in our global_scope().
76 *****************************************************************************/
77
78 static struct name_record *wins_record_to_name_record(TDB_DATA key, TDB_DATA data)
79 {
80         struct name_record *namerec = NULL;
81         uint16 nb_flags;
82         unsigned char nr_src;
83         uint32 death_time, refresh_time;
84         uint32 id_low, id_high;
85         uint32 saddr;
86         uint32 wins_flags;
87         uint32 num_ips;
88         size_t len;
89         int i;
90
91         if (data.dptr == NULL || data.dsize == 0) {
92                 return NULL;
93         }
94
95         /* Min size is "wbddddddd" + 1 ip address (4). */
96         if (data.dsize < 2 + 1 + (7*4) + 4) {
97                 return NULL;
98         }
99
100         len = tdb_unpack(data.dptr, data.dsize,
101                         "wbddddddd",
102                         &nb_flags,
103                         &nr_src,
104                         &death_time,
105                         &refresh_time,
106                         &id_low,
107                         &id_high,
108                         &saddr,
109                         &wins_flags,
110                         &num_ips );
111
112         namerec = SMB_MALLOC_P(struct name_record);
113         if (!namerec) {
114                 return NULL;
115         }
116         ZERO_STRUCTP(namerec);
117
118         namerec->data.ip = SMB_MALLOC_ARRAY(struct in_addr, num_ips);
119         if (!namerec->data.ip) {
120                 SAFE_FREE(namerec);
121                 return NULL;
122         }
123
124         namerec->subnet = wins_server_subnet;
125         push_ascii_nstring(namerec->name.name, (const char *)key.dptr);
126         namerec->name.name_type = key.dptr[sizeof(unstring)];
127         /* Add the scope. */
128         push_ascii(namerec->name.scope, global_scope(), 64, STR_TERMINATE);
129
130         /* We're using a byte-by-byte compare, so we must be sure that
131          * unused space doesn't have garbage in it.
132          */
133                                                                                                                                
134         for( i = strlen( namerec->name.name ); i < sizeof( namerec->name.name ); i++ ) {
135                 namerec->name.name[i] = '\0';
136         }
137         for( i = strlen( namerec->name.scope ); i < sizeof( namerec->name.scope ); i++ ) {
138                 namerec->name.scope[i] = '\0';
139         }
140
141         namerec->data.nb_flags = nb_flags;
142         namerec->data.source = (enum name_source)nr_src;
143         namerec->data.death_time = (time_t)death_time;
144         namerec->data.refresh_time = (time_t)refresh_time;
145         namerec->data.id = id_low;
146 #if defined(HAVE_LONGLONG)
147         namerec->data.id |= ((uint64_t)id_high << 32);
148 #endif
149         namerec->data.wins_ip.s_addr = saddr;
150         namerec->data.wins_flags = wins_flags,
151         namerec->data.num_ips = num_ips;
152
153         for (i = 0; i < num_ips; i++) {
154                 namerec->data.ip[i].s_addr = IVAL(data.dptr, len + (i*4));
155         }
156
157         return namerec;
158 }
159
160 /****************************************************************************
161  Convert a struct name_record to a wins.tdb record. Ignore the scope.
162 *****************************************************************************/
163
164 static TDB_DATA name_record_to_wins_record(const struct name_record *namerec)
165 {
166         TDB_DATA data;
167         size_t len = 0;
168         int i;
169         uint32 id_low = (namerec->data.id & 0xFFFFFFFF);
170 #if defined(HAVE_LONGLONG)
171         uint32 id_high = (namerec->data.id >> 32) & 0xFFFFFFFF;
172 #else
173         uint32 id_high = 0;
174 #endif
175
176         ZERO_STRUCT(data);
177
178         len = (2 + 1 + (7*4)); /* "wbddddddd" */
179         len += (namerec->data.num_ips * 4);
180
181         data.dptr = (uint8 *)SMB_MALLOC(len);
182         if (!data.dptr) {
183                 return data;
184         }
185         data.dsize = len;
186
187         len = tdb_pack(data.dptr, data.dsize, "wbddddddd",
188                         namerec->data.nb_flags,
189                         (unsigned char)namerec->data.source,
190                         (uint32)namerec->data.death_time,
191                         (uint32)namerec->data.refresh_time,
192                         id_low,
193                         id_high,
194                         (uint32)namerec->data.wins_ip.s_addr,
195                         (uint32)namerec->data.wins_flags,
196                         (uint32)namerec->data.num_ips );
197
198         for (i = 0; i < namerec->data.num_ips; i++) {
199                 SIVAL(data.dptr, len + (i*4), namerec->data.ip[i].s_addr);
200         }
201
202         return data;
203 }
204
205 /****************************************************************************
206  Create key. Key is UNIX codepage namestring (usually utf8 64 byte len) with 1 byte type.
207 *****************************************************************************/
208
209 static TDB_DATA name_to_key(const struct nmb_name *nmbname)
210 {
211         static char keydata[sizeof(unstring) + 1];
212         TDB_DATA key;
213
214         memset(keydata, '\0', sizeof(keydata));
215
216         pull_ascii_nstring(keydata, sizeof(unstring), nmbname->name);
217         strupper_m(keydata);
218         keydata[sizeof(unstring)] = nmbname->name_type;
219         key.dptr = (uint8 *)keydata;
220         key.dsize = sizeof(keydata);
221
222         return key;
223 }
224
225 /****************************************************************************
226  Lookup a given name in the wins.tdb and create a temporary malloc'ed data struct
227  on the linked list. We will free this later in XXXX().
228 *****************************************************************************/
229
230 struct name_record *find_name_on_wins_subnet(const struct nmb_name *nmbname, bool self_only)
231 {
232         TDB_DATA data, key;
233         struct name_record *nr = NULL;
234         struct name_record *namerec = NULL;
235
236         if (!wins_tdb) {
237                 return NULL;
238         }
239
240         key = name_to_key(nmbname);
241         data = tdb_fetch(wins_tdb, key);
242
243         if (data.dsize == 0) {
244                 return NULL;
245         }
246
247         namerec = wins_record_to_name_record(key, data);
248
249         /* done with the this */
250
251         SAFE_FREE( data.dptr );
252
253         if (!namerec) {
254                 return NULL;
255         }
256
257         /* Self names only - these include permanent names. */
258         if( self_only && (namerec->data.source != SELF_NAME) && (namerec->data.source != PERMANENT_NAME) ) {
259                 DEBUG( 9, ( "find_name_on_wins_subnet: self name %s NOT FOUND\n", nmb_namestr(nmbname) ) );
260                 SAFE_FREE(namerec->data.ip);
261                 SAFE_FREE(namerec);
262                 return NULL;
263         }
264
265         /* Search for this name record on the list. Replace it if found. */
266
267         for( nr = wins_server_subnet->namelist; nr; nr = nr->next) {
268                 if (memcmp(nmbname->name, nr->name.name, 16) == 0) {
269                         /* Delete it. */
270                         DLIST_REMOVE(wins_server_subnet->namelist, nr);
271                         SAFE_FREE(nr->data.ip);
272                         SAFE_FREE(nr);
273                         break;
274                 }
275         }
276         
277         DLIST_ADD(wins_server_subnet->namelist, namerec);
278         return namerec;
279 }
280
281 /****************************************************************************
282  Overwrite or add a given name in the wins.tdb.
283 *****************************************************************************/
284
285 static bool store_or_replace_wins_namerec(const struct name_record *namerec, int tdb_flag)
286 {
287         TDB_DATA key, data;
288         int ret;
289
290         if (!wins_tdb) {
291                 return False;
292         }
293
294         key = name_to_key(&namerec->name);
295         data = name_record_to_wins_record(namerec);
296
297         if (data.dptr == NULL) {
298                 return False;
299         }
300
301         ret = tdb_store(wins_tdb, key, data, tdb_flag);
302
303         SAFE_FREE(data.dptr);
304         return (ret == 0) ? True : False;
305 }
306
307 /****************************************************************************
308  Overwrite a given name in the wins.tdb.
309 *****************************************************************************/
310
311 bool wins_store_changed_namerec(const struct name_record *namerec)
312 {
313         return store_or_replace_wins_namerec(namerec, TDB_REPLACE);
314 }
315
316 /****************************************************************************
317  Primary interface into creating and overwriting records in the wins.tdb.
318 *****************************************************************************/
319
320 bool add_name_to_wins_subnet(const struct name_record *namerec)
321 {
322         return store_or_replace_wins_namerec(namerec, TDB_INSERT);
323 }
324
325 /****************************************************************************
326  Delete a given name in the tdb and remove the temporary malloc'ed data struct
327  on the linked list.
328 *****************************************************************************/
329
330 bool remove_name_from_wins_namelist(struct name_record *namerec)
331 {
332         TDB_DATA key;
333         int ret;
334
335         if (!wins_tdb) {
336                 return False;
337         }
338
339         key = name_to_key(&namerec->name);
340         ret = tdb_delete(wins_tdb, key);
341
342         DLIST_REMOVE(wins_server_subnet->namelist, namerec);
343
344         /* namerec must be freed by the caller */
345
346         return (ret == 0) ? True : False;
347 }
348
349 /****************************************************************************
350  Dump out the complete namelist.
351 *****************************************************************************/
352
353 static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
354 {
355         struct name_record *namerec = NULL;
356         XFILE *fp = (XFILE *)state;
357
358         if (kbuf.dsize != sizeof(unstring) + 1) {
359                 return 0;
360         }
361
362         namerec = wins_record_to_name_record(kbuf, dbuf);
363         if (!namerec) {
364                 return 0;
365         }
366
367         dump_name_record(namerec, fp);
368
369         SAFE_FREE(namerec->data.ip);
370         SAFE_FREE(namerec);
371         return 0;
372 }
373
374 void dump_wins_subnet_namelist(XFILE *fp)
375 {
376         tdb_traverse(wins_tdb, traverse_fn, (void *)fp);
377 }
378
379 /****************************************************************************
380  Change the wins owner address in the record.
381 *****************************************************************************/
382
383 static void update_wins_owner(struct name_record *namerec, struct in_addr wins_ip)
384 {
385         namerec->data.wins_ip=wins_ip;
386 }
387
388 /****************************************************************************
389  Create the wins flags based on the nb flags and the input value.
390 *****************************************************************************/
391
392 static void update_wins_flag(struct name_record *namerec, int flags)
393 {
394         namerec->data.wins_flags=0x0;
395
396         /* if it's a group, it can be a normal or a special one */
397         if (namerec->data.nb_flags & NB_GROUP) {
398                 if (namerec->name.name_type==0x1C) {
399                         namerec->data.wins_flags|=WINS_SGROUP;
400                 } else {
401                         if (namerec->data.num_ips>1) {
402                                 namerec->data.wins_flags|=WINS_SGROUP;
403                         } else {
404                                 namerec->data.wins_flags|=WINS_NGROUP;
405                         }
406                 }
407         } else {
408                 /* can be unique or multi-homed */
409                 if (namerec->data.num_ips>1) {
410                         namerec->data.wins_flags|=WINS_MHOMED;
411                 } else {
412                         namerec->data.wins_flags|=WINS_UNIQUE;
413                 }
414         }
415
416         /* the node type are the same bits */
417         namerec->data.wins_flags|=namerec->data.nb_flags&NB_NODETYPEMASK;
418
419         /* the static bit is elsewhere */
420         if (namerec->data.death_time == PERMANENT_TTL) {
421                 namerec->data.wins_flags|=WINS_STATIC;
422         }
423
424         /* and add the given bits */
425         namerec->data.wins_flags|=flags;
426
427         DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n", 
428                  namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
429 }
430
431 /****************************************************************************
432  Return the general ID value and increase it if requested.
433 *****************************************************************************/
434
435 static void get_global_id_and_update(uint64_t *current_id, bool update)
436 {
437         /*
438          * it's kept as a static here, to prevent people from messing
439          * with the value directly
440          */
441
442         static uint64_t general_id = 1;
443
444         DEBUG(5,("get_global_id_and_update: updating version ID: %d\n", (int)general_id));
445         
446         *current_id = general_id;
447         
448         if (update) {
449                 general_id++;
450         }
451 }
452
453 /****************************************************************************
454  Possibly call the WINS hook external program when a WINS change is made.
455  Also stores the changed record back in the wins_tdb.
456 *****************************************************************************/
457
458 static void wins_hook(const char *operation, struct name_record *namerec, int ttl)
459 {
460         char *command = NULL;
461         char *cmd = lp_wins_hook();
462         char *p, *namestr;
463         int i;
464         TALLOC_CTX *ctx = talloc_tos();
465
466         wins_store_changed_namerec(namerec);
467
468         if (!cmd || !*cmd) {
469                 return;
470         }
471
472         for (p=namerec->name.name; *p; p++) {
473                 if (!(isalnum((int)*p) || strchr_m("._-",*p))) {
474                         DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
475                         return;
476                 }
477         }
478         
479         /* Use the name without the nametype (and scope) appended */
480
481         namestr = nmb_namestr(&namerec->name);
482         if ((p = strchr(namestr, '<'))) {
483                 *p = 0;
484         }
485
486         command = talloc_asprintf(ctx,
487                                 "%s %s %s %02x %d",
488                                 cmd,
489                                 operation,
490                                 namestr,
491                                 namerec->name.name_type,
492                                 ttl);
493         if (!command) {
494                 return;
495         }
496
497         for (i=0;i<namerec->data.num_ips;i++) {
498                 command = talloc_asprintf_append(command,
499                                                 " %s",
500                                                 inet_ntoa(namerec->data.ip[i]));
501                 if (!command) {
502                         return;
503                 }
504         }
505
506         DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
507         smbrun(command, NULL);
508         TALLOC_FREE(command);
509 }
510
511 /****************************************************************************
512 Determine if this packet should be allocated to the WINS server.
513 *****************************************************************************/
514
515 bool packet_is_for_wins_server(struct packet_struct *packet)
516 {
517         struct nmb_packet *nmb = &packet->packet.nmb;
518
519         /* Only unicast packets go to a WINS server. */
520         if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True)) {
521                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
522                 return False;
523         }
524
525         /* Check for node status requests. */
526         if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY) {
527                 return False;
528         }
529
530         switch(nmb->header.opcode) { 
531                 /*
532                  * A WINS server issues WACKS, not receives them.
533                  */
534                 case NMB_WACK_OPCODE:
535                         DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
536                         return False;
537                 /*
538                  * A WINS server only processes registration and
539                  * release requests, not responses.
540                  */
541                 case NMB_NAME_REG_OPCODE:
542                 case NMB_NAME_MULTIHOMED_REG_OPCODE:
543                 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
544                 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
545                         if(nmb->header.response) {
546                                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
547                                 return False;
548                         }
549                         break;
550
551                 case NMB_NAME_RELEASE_OPCODE:
552                         if(nmb->header.response) {
553                                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
554                                 return False;
555                         }
556                         break;
557
558                 /*
559                  * Only process unicast name queries with rd = 1.
560                  */
561                 case NMB_NAME_QUERY_OPCODE:
562                         if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired) {
563                                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
564                                 return False;
565                         }
566                         break;
567         }
568
569         return True;
570 }
571
572 /****************************************************************************
573 Utility function to decide what ttl to give a register/refresh request.
574 *****************************************************************************/
575
576 static int get_ttl_from_packet(struct nmb_packet *nmb)
577 {
578         int ttl = nmb->additional->ttl;
579
580         if (ttl < lp_min_wins_ttl()) {
581                 ttl = lp_min_wins_ttl();
582         }
583
584         if (ttl > lp_max_wins_ttl()) {
585                 ttl = lp_max_wins_ttl();
586         }
587
588         return ttl;
589 }
590
591 /****************************************************************************
592 Load or create the WINS database.
593 *****************************************************************************/
594
595 bool initialise_wins(void)
596 {
597         time_t time_now = time(NULL);
598         XFILE *fp;
599         char line[1024];
600
601         if(!lp_we_are_a_wins_server()) {
602                 return True;
603         }
604
605         /* Open the wins.tdb. */
606         wins_tdb = tdb_open_log(state_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, O_CREAT|O_RDWR, 0600);
607         if (!wins_tdb) {
608                 DEBUG(0,("initialise_wins: failed to open wins.tdb. Error was %s\n",
609                         strerror(errno) ));
610                 return False;
611         }
612
613         tdb_store_int32(wins_tdb, "WINSDB_VERSION", WINSDB_VERSION);
614
615         add_samba_names_to_subnet(wins_server_subnet);
616
617         if((fp = x_fopen(state_path(WINS_LIST),O_RDONLY,0)) == NULL) {
618                 DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
619                         WINS_LIST, strerror(errno) ));
620                 return True;
621         }
622
623         while (!x_feof(fp)) {
624                 char *name_str = NULL;
625                 char *ip_str = NULL;
626                 char *ttl_str = NULL, *nb_flags_str = NULL;
627                 unsigned int num_ips;
628                 char *name = NULL;
629                 struct in_addr *ip_list = NULL;
630                 int type = 0;
631                 int nb_flags;
632                 int ttl;
633                 const char *ptr;
634                 char *p = NULL;
635                 bool got_token;
636                 bool was_ip;
637                 int i;
638                 unsigned int hash;
639                 int version;
640                 TALLOC_CTX *frame = NULL;
641
642                 /* Read a line from the wins.dat file. Strips whitespace
643                         from the beginning and end of the line.  */
644                 if (!fgets_slash(line,sizeof(line),fp)) {
645                         continue;
646                 }
647
648                 if (*line == '#') {
649                         continue;
650                 }
651
652                 if (strncmp(line,"VERSION ", 8) == 0) {
653                         if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
654                                                 version != WINS_VERSION) {
655                                 DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
656                                 x_fclose(fp);
657                                 return True;
658                         }
659                         continue;
660                 }
661
662                 ptr = line;
663
664                 /*
665                  * Now we handle multiple IP addresses per name we need
666                  * to iterate over the line twice. The first time to
667                  * determine how many IP addresses there are, the second
668                  * time to actually parse them into the ip_list array.
669                  */
670
671                 frame = talloc_stackframe();
672                 if (!next_token_talloc(frame,&ptr,&name_str,NULL)) {
673                         DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
674                         TALLOC_FREE(frame);
675                         continue;
676                 }
677
678                 if (!next_token_talloc(frame,&ptr,&ttl_str,NULL)) {
679                         DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
680                         TALLOC_FREE(frame);
681                         continue;
682                 }
683
684                 /*
685                  * Determine the number of IP addresses per line.
686                  */
687                 num_ips = 0;
688                 do {
689                         got_token = next_token_talloc(frame,&ptr,&ip_str,NULL);
690                         was_ip = False;
691
692                         if(got_token && strchr(ip_str, '.')) {
693                                 num_ips++;
694                                 was_ip = True;
695                         }
696                 } while(got_token && was_ip);
697
698                 if(num_ips == 0) {
699                         DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
700                         TALLOC_FREE(frame);
701                         continue;
702                 }
703
704                 if(!got_token) {
705                         DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
706                         TALLOC_FREE(frame);
707                         continue;
708                 }
709
710                 /* Allocate the space for the ip_list. */
711                 if((ip_list = SMB_MALLOC_ARRAY( struct in_addr, num_ips)) == NULL) {
712                         DEBUG(0,("initialise_wins: Malloc fail !\n"));
713                         x_fclose(fp);
714                         TALLOC_FREE(frame);
715                         return False;
716                 }
717
718                 /* Reset and re-parse the line. */
719                 ptr = line;
720                 next_token_talloc(frame,&ptr,&name_str,NULL);
721                 next_token_talloc(frame,&ptr,&ttl_str,NULL);
722                 for(i = 0; i < num_ips; i++) {
723                         next_token_talloc(frame,&ptr, &ip_str, NULL);
724                         ip_list[i] = interpret_addr2(ip_str);
725                 }
726                 next_token_talloc(frame,&ptr,&nb_flags_str,NULL);
727
728                 /*
729                  * Deal with SELF or REGISTER name encoding. Default is REGISTER
730                  * for compatibility with old nmbds.
731                  */
732
733                 if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') {
734                         DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
735                         SAFE_FREE(ip_list);
736                         TALLOC_FREE(frame);
737                         continue;
738                 }
739
740                 if(nb_flags_str[strlen(nb_flags_str)-1] == 'R') {
741                         nb_flags_str[strlen(nb_flags_str)-1] = '\0';
742                 }
743
744                 /* Netbios name. # divides the name from the type (hex): netbios#xx */
745                 name = name_str;
746
747                 if((p = strchr(name,'#')) != NULL) {
748                         *p = 0;
749                         sscanf(p+1,"%x",&type);
750                 }
751
752                 /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
753                 sscanf(nb_flags_str,"%x",&nb_flags);
754                 sscanf(ttl_str,"%d",&ttl);
755
756                 /* add all entries that have 60 seconds or more to live */
757                 if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
758                         if(ttl != PERMANENT_TTL) {
759                                 ttl -= time_now;
760                         }
761
762                         DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
763                                 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
764
765                         (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags, 
766                                         ttl, REGISTER_NAME, num_ips, ip_list );
767                 } else {
768                         DEBUG(4, ("initialise_wins: not adding name (ttl problem) "
769                                 "%s#%02x ttl = %d first IP %s flags = %2x\n",
770                                 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
771                 }
772
773                 TALLOC_FREE(frame);
774                 SAFE_FREE(ip_list);
775         }
776
777         x_fclose(fp);
778         return True;
779 }
780
781 /****************************************************************************
782 Send a WINS WACK (Wait ACKnowledgement) response.
783 **************************************************************************/
784
785 static void send_wins_wack_response(int ttl, struct packet_struct *p)
786 {
787         struct nmb_packet *nmb = &p->packet.nmb;
788         unsigned char rdata[2];
789
790         rdata[0] = rdata[1] = 0;
791
792         /* Taken from nmblib.c - we need to send back almost
793                 identical bytes from the requesting packet header. */
794
795         rdata[0] = (nmb->header.opcode & 0xF) << 3;
796         if (nmb->header.nm_flags.authoritative && nmb->header.response) {
797                 rdata[0] |= 0x4;
798         }
799         if (nmb->header.nm_flags.trunc) {
800                 rdata[0] |= 0x2;
801         }
802         if (nmb->header.nm_flags.recursion_desired) {
803                 rdata[0] |= 0x1;
804         }
805         if (nmb->header.nm_flags.recursion_available && nmb->header.response) {
806                 rdata[1] |= 0x80;
807         }
808         if (nmb->header.nm_flags.bcast) {
809                 rdata[1] |= 0x10;
810         }
811
812         reply_netbios_packet(p,                                /* Packet to reply to. */
813                                 0,                             /* Result code. */
814                                 NMB_WAIT_ACK,                  /* nmbd type code. */
815                                 NMB_WACK_OPCODE,               /* opcode. */
816                                 ttl,                           /* ttl. */
817                                 (char *)rdata,                 /* data to send. */
818                                 2);                            /* data length. */
819 }
820
821 /****************************************************************************
822 Send a WINS name registration response.
823 **************************************************************************/
824
825 static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
826 {
827         struct nmb_packet *nmb = &p->packet.nmb;
828         char rdata[6];
829
830         memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
831
832         reply_netbios_packet(p,                                /* Packet to reply to. */
833                                 rcode,                         /* Result code. */
834                                 WINS_REG,                      /* nmbd type code. */
835                                 NMB_NAME_REG_OPCODE,           /* opcode. */
836                                 ttl,                           /* ttl. */
837                                 rdata,                         /* data to send. */
838                                 6);                            /* data length. */
839 }
840
841 /***********************************************************************
842  Deal with a name refresh request to a WINS server.
843 ************************************************************************/
844
845 void wins_process_name_refresh_request( struct subnet_record *subrec,
846                                         struct packet_struct *p )
847 {
848         struct nmb_packet *nmb = &p->packet.nmb;
849         struct nmb_name *question = &nmb->question.question_name;
850         bool bcast = nmb->header.nm_flags.bcast;
851         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
852         bool group = (nb_flags & NB_GROUP) ? True : False;
853         struct name_record *namerec = NULL;
854         int ttl = get_ttl_from_packet(nmb);
855         struct in_addr from_ip;
856         struct in_addr our_fake_ip;
857
858         our_fake_ip = interpret_addr2("0.0.0.0");
859         putip( (char *)&from_ip, &nmb->additional->rdata[2] );
860
861         if(bcast) {
862                 /*
863                  * We should only get unicast name refresh packets here.
864                  * Anyone trying to refresh broadcast should not be going
865                  * to a WINS server.  Log an error here.
866                  */
867                 if( DEBUGLVL( 0 ) ) {
868                         dbgtext( "wins_process_name_refresh_request: " );
869                         dbgtext( "Broadcast name refresh request received " );
870                         dbgtext( "for name %s ", nmb_namestr(question) );
871                         dbgtext( "from IP %s ", inet_ntoa(from_ip) );
872                         dbgtext( "on subnet %s.  ", subrec->subnet_name );
873                         dbgtext( "Error - Broadcasts should not be sent " );
874                         dbgtext( "to a WINS server\n" );
875                 }
876                 return;
877         }
878
879         if( DEBUGLVL( 3 ) ) {
880                 dbgtext( "wins_process_name_refresh_request: " );
881                 dbgtext( "Name refresh for name %s IP %s\n",
882                          nmb_namestr(question), inet_ntoa(from_ip) );
883         }
884
885         /* 
886          * See if the name already exists.
887          * If not, handle it as a name registration and return.
888          */
889         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
890
891         /*
892          * If this is a refresh request and the name doesn't exist then
893          * treat it like a registration request. This allows us to recover 
894          * from errors (tridge)
895          */
896         if(namerec == NULL) {
897                 if( DEBUGLVL( 3 ) ) {
898                         dbgtext( "wins_process_name_refresh_request: " );
899                         dbgtext( "Name refresh for name %s ",
900                                  nmb_namestr( question ) );
901                         dbgtext( "and the name does not exist.  Treating " );
902                         dbgtext( "as registration.\n" );
903                 }
904                 wins_process_name_registration_request(subrec,p);
905                 return;
906         }
907
908         /*
909          * if the name is present but not active, simply remove it
910          * and treat the refresh request as a registration & return.
911          */
912         if (namerec != NULL && !WINS_STATE_ACTIVE(namerec)) {
913                 if( DEBUGLVL( 5 ) ) {
914                         dbgtext( "wins_process_name_refresh_request: " );
915                         dbgtext( "Name (%s) in WINS ", nmb_namestr(question) );
916                         dbgtext( "was not active - removing it.\n" );
917                 }
918                 remove_name_from_namelist( subrec, namerec );
919                 namerec = NULL;
920                 wins_process_name_registration_request( subrec, p );
921                 return;
922         }
923
924         /*
925          * Check that the group bits for the refreshing name and the
926          * name in our database match.  If not, refuse the refresh.
927          * [crh:  Why RFS_ERR instead of ACT_ERR? Is this what MS does?]
928          */
929         if( (namerec != NULL) &&
930             ( (group && !NAME_GROUP(namerec))
931            || (!group && NAME_GROUP(namerec)) ) ) {
932                 if( DEBUGLVL( 3 ) ) {
933                         dbgtext( "wins_process_name_refresh_request: " );
934                         dbgtext( "Name %s ", nmb_namestr(question) );
935                         dbgtext( "group bit = %s does not match ",
936                                  group ? "True" : "False" );
937                         dbgtext( "group bit in WINS for this name.\n" );
938                 }
939                 send_wins_name_registration_response(RFS_ERR, 0, p);
940                 return;
941         }
942
943         /*
944          * For a unique name check that the person refreshing the name is
945          * one of the registered IP addresses. If not - fail the refresh.
946          * Do the same for group names with a type of 0x1c.
947          * Just return success for unique 0x1d refreshes. For normal group
948          * names update the ttl and return success.
949          */
950         if( (!group || (group && (question->name_type == 0x1c)))
951                         && find_ip_in_name_record(namerec, from_ip) ) {
952                 /*
953                  * Update the ttl.
954                  */
955                 update_name_ttl(namerec, ttl);
956
957                 /*
958                  * if the record is a replica:
959                  * we take ownership and update the version ID.
960                  */
961                 if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
962                         update_wins_owner(namerec, our_fake_ip);
963                         get_global_id_and_update(&namerec->data.id, True);
964                 }
965
966                 send_wins_name_registration_response(0, ttl, p);
967                 wins_hook("refresh", namerec, ttl);
968                 return;
969         } else if((group && (question->name_type == 0x1c))) {
970                 /*
971                  * Added by crh for bug #1079.
972                  * Fix from Bert Driehuis
973                  */
974                 if( DEBUGLVL( 3 ) ) {
975                         dbgtext( "wins_process_name_refresh_request: " );
976                         dbgtext( "Name refresh for name %s, ",
977                                  nmb_namestr(question) );
978                         dbgtext( "but IP address %s ", inet_ntoa(from_ip) );
979                         dbgtext( "is not yet associated with " );
980                         dbgtext( "that name. Treating as registration.\n" );
981                 }
982                 wins_process_name_registration_request(subrec,p);
983                 return;
984         } else if(group) {
985                 /* 
986                  * Normal groups are all registered with an IP address of
987                  * 255.255.255.255  so we can't search for the IP address.
988                  */
989                 update_name_ttl(namerec, ttl);
990                 wins_hook("refresh", namerec, ttl);
991                 send_wins_name_registration_response(0, ttl, p);
992                 return;
993         } else if(!group && (question->name_type == 0x1d)) {
994                 /*
995                  * Special name type - just pretend the refresh succeeded.
996                  */
997                 send_wins_name_registration_response(0, ttl, p);
998                 return;
999         } else {
1000                 /*
1001                  * Fail the refresh.
1002                  */
1003                 if( DEBUGLVL( 3 ) ) {
1004                         dbgtext( "wins_process_name_refresh_request: " );
1005                         dbgtext( "Name refresh for name %s with IP %s ",
1006                                  nmb_namestr(question), inet_ntoa(from_ip) );
1007                         dbgtext( "and is IP is not known to the name.\n" );
1008                 }
1009                 send_wins_name_registration_response(RFS_ERR, 0, p);
1010                 return;
1011         }
1012 }
1013
1014 /***********************************************************************
1015  Deal with a name registration request query success to a client that
1016  owned the name.
1017
1018  We have a locked pointer to the original packet stashed away in the
1019  userdata pointer. The success here is actually a failure as it means
1020  the client we queried wants to keep the name, so we must return
1021  a registration failure to the original requestor.
1022 ************************************************************************/
1023
1024 static void wins_register_query_success(struct subnet_record *subrec,
1025                                              struct userdata_struct *userdata,
1026                                              struct nmb_name *question_name,
1027                                              struct in_addr ip,
1028                                              struct res_rec *answers)
1029 {
1030         struct packet_struct *orig_reg_packet;
1031
1032         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1033
1034         DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
1035 name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
1036
1037         send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1038
1039         orig_reg_packet->locked = False;
1040         free_packet(orig_reg_packet);
1041 }
1042
1043 /***********************************************************************
1044  Deal with a name registration request query failure to a client that
1045  owned the name.
1046
1047  We have a locked pointer to the original packet stashed away in the
1048  userdata pointer. The failure here is actually a success as it means
1049  the client we queried didn't want to keep the name, so we can remove
1050  the old name record and then successfully add the new name.
1051 ************************************************************************/
1052
1053 static void wins_register_query_fail(struct subnet_record *subrec,
1054                                           struct response_record *rrec,
1055                                           struct nmb_name *question_name,
1056                                           int rcode)
1057 {
1058         struct userdata_struct *userdata = rrec->userdata;
1059         struct packet_struct *orig_reg_packet;
1060         struct name_record *namerec = NULL;
1061
1062         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1063
1064         /*
1065          * We want to just add the name, as we now know the original owner
1066          * didn't want it. But we can't just do that as an arbitary
1067          * amount of time may have taken place between the name query
1068          * request and this timeout/error response. So we check that
1069          * the name still exists and is in the same state - if so
1070          * we remove it and call wins_process_name_registration_request()
1071          * as we know it will do the right thing now.
1072          */
1073
1074         namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
1075
1076         if ((namerec != NULL) && (namerec->data.source == REGISTER_NAME) &&
1077                         ip_equal_v4(rrec->packet->ip, *namerec->data.ip)) {
1078                 remove_name_from_namelist( subrec, namerec);
1079                 namerec = NULL;
1080         }
1081
1082         if(namerec == NULL) {
1083                 wins_process_name_registration_request(subrec, orig_reg_packet);
1084         } else {
1085                 DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between "
1086                         "querying for name %s in order to replace it and this reply.\n",
1087                         nmb_namestr(question_name) ));
1088         }
1089
1090         orig_reg_packet->locked = False;
1091         free_packet(orig_reg_packet);
1092 }
1093
1094 /***********************************************************************
1095  Deal with a name registration request to a WINS server.
1096
1097  Use the following pseudocode :
1098
1099  registering_group
1100      |
1101      |
1102      +--------name exists
1103      |                  |
1104      |                  |
1105      |                  +--- existing name is group
1106      |                  |                      |
1107      |                  |                      |
1108      |                  |                      +--- add name (return).
1109      |                  |
1110      |                  |
1111      |                  +--- exiting name is unique
1112      |                                         |
1113      |                                         |
1114      |                                         +--- query existing owner (return).
1115      |
1116      |
1117      +--------name doesn't exist
1118                         |
1119                         |
1120                         +--- add name (return).
1121
1122  registering_unique
1123      |
1124      |
1125      +--------name exists
1126      |                  |
1127      |                  |
1128      |                  +--- existing name is group 
1129      |                  |                      |
1130      |                  |                      |
1131      |                  |                      +--- fail add (return).
1132      |                  | 
1133      |                  |
1134      |                  +--- exiting name is unique
1135      |                                         |
1136      |                                         |
1137      |                                         +--- query existing owner (return).
1138      |
1139      |
1140      +--------name doesn't exist
1141                         |
1142                         |
1143                         +--- add name (return).
1144
1145  As can be seen from the above, the two cases may be collapsed onto each
1146  other with the exception of the case where the name already exists and
1147  is a group name. This case we handle with an if statement.
1148  
1149 ************************************************************************/
1150
1151 void wins_process_name_registration_request(struct subnet_record *subrec,
1152                                             struct packet_struct *p)
1153 {
1154         unstring name;
1155         struct nmb_packet *nmb = &p->packet.nmb;
1156         struct nmb_name *question = &nmb->question.question_name;
1157         bool bcast = nmb->header.nm_flags.bcast;
1158         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1159         int ttl = get_ttl_from_packet(nmb);
1160         struct name_record *namerec = NULL;
1161         struct in_addr from_ip;
1162         bool registering_group_name = (nb_flags & NB_GROUP) ? True : False;
1163         struct in_addr our_fake_ip;
1164
1165         our_fake_ip = interpret_addr2("0.0.0.0");
1166         putip((char *)&from_ip,&nmb->additional->rdata[2]);
1167
1168         if(bcast) {
1169                 /*
1170                  * We should only get unicast name registration packets here.
1171                  * Anyone trying to register broadcast should not be going to a WINS
1172                  * server. Log an error here.
1173                  */
1174
1175                 DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
1176 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1177                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1178                 return;
1179         }
1180
1181         DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
1182 IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
1183
1184         /*
1185          * See if the name already exists.
1186          */
1187
1188         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1189
1190         /*
1191          * if the record exists but NOT in active state,
1192          * consider it dead.
1193          */
1194         if ( (namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
1195                 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
1196 not active - removing it.\n", nmb_namestr(question) ));
1197                 remove_name_from_namelist( subrec, namerec );
1198                 namerec = NULL;
1199         }
1200
1201         /*
1202          * Deal with the case where the name found was a dns entry.
1203          * Remove it as we now have a NetBIOS client registering the
1204          * name.
1205          */
1206
1207         if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
1208                 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
1209 a dns lookup - removing it.\n", nmb_namestr(question) ));
1210                 remove_name_from_namelist( subrec, namerec );
1211                 namerec = NULL;
1212         }
1213
1214         /*
1215          * Reject if the name exists and is not a REGISTER_NAME.
1216          * (ie. Don't allow any static names to be overwritten.
1217          */
1218
1219         if((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) {
1220                 DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
1221 to register name %s. Name already exists in WINS with source type %d.\n",
1222                         nmb_namestr(question), namerec->data.source ));
1223                 send_wins_name_registration_response(RFS_ERR, 0, p);
1224                 return;
1225         }
1226
1227         /*
1228          * Special policy decisions based on MS documentation.
1229          * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
1230          * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
1231          */
1232
1233         /*
1234          * A group name is always added as the local broadcast address, except
1235          * for group names ending in 0x1c.
1236          * Group names with type 0x1c are registered with individual IP addresses.
1237          */
1238
1239         if(registering_group_name && (question->name_type != 0x1c)) {
1240                 from_ip = interpret_addr2("255.255.255.255");
1241         }
1242
1243         /*
1244          * Ignore all attempts to register a unique 0x1d name, although return success.
1245          */
1246
1247         if(!registering_group_name && (question->name_type == 0x1d)) {
1248                 DEBUG(3,("wins_process_name_registration_request: Ignoring request \
1249 to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
1250                 send_wins_name_registration_response(0, ttl, p);
1251                 return;
1252         }
1253
1254         /*
1255          * Next two cases are the 'if statement' mentioned above.
1256          */
1257
1258         if((namerec != NULL) && NAME_GROUP(namerec)) {
1259                 if(registering_group_name) {
1260                         /*
1261                          * If we are adding a group name, the name exists and is also a group entry just add this
1262                          * IP address to it and update the ttl.
1263                          */
1264
1265                         DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
1266                                 inet_ntoa(from_ip), nmb_namestr(question) ));
1267
1268                         /* 
1269                          * Check the ip address is not already in the group.
1270                          */
1271
1272                         if(!find_ip_in_name_record(namerec, from_ip)) {
1273                                 /*
1274                                  * Need to emulate the behaviour of Windows, as
1275                                  * described in:
1276                                  * http://lists.samba.org/archive/samba-technical/2001-October/016236.html
1277                                  * (is there an MS reference for this
1278                                  * somewhere?) because if the 1c list gets over
1279                                  * 86 entries, the reply packet is too big
1280                                  * (rdata>576 bytes) so no reply is sent.
1281                                  *
1282                                  * Keep only the "latest" 25 records, while
1283                                  * ensuring that the PDC (0x1b) is never removed
1284                                  * We do this by removing the first entry that
1285                                  * isn't the 1b entry for the same name,
1286                                  * on the grounds that insertion is at the end
1287                                  * of the list, so the oldest entries are at
1288                                  * the start.
1289                                  *
1290                                  */
1291                                 while(namerec->data.num_ips>=25) {
1292                                         struct name_record *name1brec = NULL;
1293
1294                                         /* We only do this for 1c types. */
1295                                         if (namerec->name.name_type != 0x1c) {
1296                                                 break;
1297                                         }
1298                                         DEBUG(3,("wins_process_name_registration_request: "
1299                                                 "More than 25 IPs already in "
1300                                                 "the list. Looking for a 1b "
1301                                                 "record\n"));
1302
1303                                         /* Ensure we have all the active 1b
1304                                          * names on the list. */
1305                                         wins_delete_all_1b_in_memory_records();
1306                                         fetch_all_active_wins_1b_names();
1307
1308                                         /* Per the above, find the 1b record,
1309                                            and then remove the first IP that isn't the same */
1310                                         for(name1brec = subrec->namelist;
1311                                                         name1brec;
1312                                                         name1brec = name1brec->next ) {
1313                                                 if( WINS_STATE_ACTIVE(name1brec) &&
1314                                                                 name1brec->name.name_type == 0x1b) {
1315                                                         DEBUG(3,("wins_process_name_registration_request: "
1316                                                                 "Found the #1b record "
1317                                                                 "with ip %s\n",
1318                                                                 inet_ntoa(name1brec->data.ip[0])));
1319                                                         break;
1320                                                 }
1321                                         }
1322                                         if(!name1brec) {
1323                                                 DEBUG(3,("wins_process_name_registration_request: "
1324                                                         "Didn't find a #1b name record. "
1325                                                         "Removing the first available "
1326                                                         "entry %s\n",
1327                                                         inet_ntoa(namerec->data.ip[0])));
1328                                                 remove_ip_from_name_record(namerec, namerec->data.ip[0]);
1329                                                 wins_hook("delete", namerec, 0);
1330                                         } else {
1331                                                 int i;
1332                                                 for(i=0; i<namerec->data.num_ips; i++) {
1333                                                         /* The name1brec should only have
1334                                                          * the single IP address in it,
1335                                                          * so we only check against the first one*/
1336                                                         if(!ip_equal_v4( namerec->data.ip[i], name1brec->data.ip[0])) {
1337                                                                 /* The i'th entry isn't the 1b address; delete it  */
1338                                                                 DEBUG(3,("wins_process_name_registration_request: "
1339                                                                         "Entry at %d is not the #1b address. "
1340                                                                         "About to remove it\n",
1341                                                                         i));
1342                                                                 remove_ip_from_name_record(namerec, namerec->data.ip[i]);
1343                                                                 wins_hook("delete", namerec, 0);
1344                                                                 break;
1345                                                         }
1346                                                 }
1347                                         }
1348                                 }
1349                                 /* The list is guaranteed to be < 25 entries now
1350                                  * - safe to add a new one  */
1351                                 add_ip_to_name_record(namerec, from_ip);
1352                                 /* we need to update the record for replication */
1353                                 get_global_id_and_update(&namerec->data.id, True);
1354
1355                                 /*
1356                                  * if the record is a replica, we must change
1357                                  * the wins owner to us to make the replication updates
1358                                  * it on the other wins servers.
1359                                  * And when the partner will receive this record,
1360                                  * it will update its own record.
1361                                  */
1362
1363                                 update_wins_owner(namerec, our_fake_ip);
1364                         }
1365                         update_name_ttl(namerec, ttl);
1366                         wins_hook("refresh", namerec, ttl);
1367                         send_wins_name_registration_response(0, ttl, p);
1368                         return;
1369                 } else {
1370
1371                         /*
1372                          * If we are adding a unique name, the name exists in the WINS db 
1373                          * and is a group name then reject the registration.
1374                          *
1375                          * explanation: groups have a higher priority than unique names.
1376                          */
1377
1378                         DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
1379 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
1380                         send_wins_name_registration_response(RFS_ERR, 0, p);
1381                         return;
1382                 } 
1383         }
1384
1385         /*
1386          * From here on down we know that if the name exists in the WINS db it is
1387          * a unique name, not a group name.
1388          */
1389
1390         /* 
1391          * If the name exists and is one of our names then check the
1392          * registering IP address. If it's not one of ours then automatically
1393          * reject without doing the query - we know we will reject it.
1394          */
1395
1396         if ( namerec != NULL ) {
1397                 pull_ascii_nstring(name, sizeof(name), namerec->name.name);
1398                 if( is_myname(name) ) {
1399                         if(!ismyip_v4(from_ip)) {
1400                                 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
1401 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
1402                                 send_wins_name_registration_response(RFS_ERR, 0, p);
1403                                 return;
1404                         } else {
1405                                 /*
1406                                  * It's one of our names and one of our IP's - update the ttl.
1407                                  */
1408                                 update_name_ttl(namerec, ttl);
1409                                 wins_hook("refresh", namerec, ttl);
1410                                 send_wins_name_registration_response(0, ttl, p);
1411                                 return;
1412                         }
1413                 }
1414         } else {
1415                 name[0] = '\0';
1416         }
1417
1418         /*
1419          * If the name exists and it is a unique registration and the registering IP 
1420          * is the same as the (single) already registered IP then just update the ttl.
1421          *
1422          * But not if the record is an active replica. IF it's a replica, it means it can be
1423          * the same client which has moved and not yet expired. So we don't update
1424          * the ttl in this case and go beyond to do a WACK and query the old client
1425          */
1426
1427         if( !registering_group_name
1428                         && (namerec != NULL)
1429                         && (namerec->data.num_ips == 1)
1430                         && ip_equal_v4( namerec->data.ip[0], from_ip )
1431                         && ip_equal_v4(namerec->data.wins_ip, our_fake_ip) ) {
1432                 update_name_ttl( namerec, ttl );
1433                 wins_hook("refresh", namerec, ttl);
1434                 send_wins_name_registration_response( 0, ttl, p );
1435                 return;
1436         }
1437
1438         /*
1439          * Finally if the name exists do a query to the registering machine 
1440          * to see if they still claim to have the name.
1441          */
1442
1443         if( namerec != NULL ) {
1444                 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
1445                 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1446
1447                 /*
1448                  * First send a WACK to the registering machine.
1449                  */
1450
1451                 send_wins_wack_response(60, p);
1452
1453                 /*
1454                  * When the reply comes back we need the original packet.
1455                  * Lock this so it won't be freed and then put it into
1456                  * the userdata structure.
1457                  */
1458
1459                 p->locked = True;
1460
1461                 userdata = (struct userdata_struct *)ud;
1462
1463                 userdata->copy_fn = NULL;
1464                 userdata->free_fn = NULL;
1465                 userdata->userdata_len = sizeof(struct packet_struct *);
1466                 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1467
1468                 /*
1469                  * Use the new call to send a query directly to an IP address.
1470                  * This sends the query directly to the IP address, and ensures
1471                  * the recursion desired flag is not set (you were right Luke :-).
1472                  * This function should *only* be called from the WINS server
1473                  * code. JRA.
1474                  */
1475
1476                 pull_ascii_nstring(name, sizeof(name), question->name);
1477                 query_name_from_wins_server( *namerec->data.ip,
1478                                 name,
1479                                 question->name_type, 
1480                                 wins_register_query_success,
1481                                 wins_register_query_fail,
1482                                 userdata );
1483                 return;
1484         }
1485
1486         /*
1487          * Name did not exist - add it.
1488          */
1489
1490         pull_ascii_nstring(name, sizeof(name), question->name);
1491         add_name_to_subnet( subrec, name, question->name_type,
1492                         nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1493
1494         if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1495                 get_global_id_and_update(&namerec->data.id, True);
1496                 update_wins_owner(namerec, our_fake_ip);
1497                 update_wins_flag(namerec, WINS_ACTIVE);
1498                 wins_hook("add", namerec, ttl);
1499         }
1500
1501         send_wins_name_registration_response(0, ttl, p);
1502 }
1503
1504 /***********************************************************************
1505  Deal with a mutihomed name query success to the machine that
1506  requested the multihomed name registration.
1507
1508  We have a locked pointer to the original packet stashed away in the
1509  userdata pointer.
1510 ************************************************************************/
1511
1512 static void wins_multihomed_register_query_success(struct subnet_record *subrec,
1513                                              struct userdata_struct *userdata,
1514                                              struct nmb_name *question_name,
1515                                              struct in_addr ip,
1516                                              struct res_rec *answers)
1517 {
1518         struct packet_struct *orig_reg_packet;
1519         struct nmb_packet *nmb;
1520         struct name_record *namerec = NULL;
1521         struct in_addr from_ip;
1522         int ttl;
1523         struct in_addr our_fake_ip;
1524
1525         our_fake_ip = interpret_addr2("0.0.0.0");
1526         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1527
1528         nmb = &orig_reg_packet->packet.nmb;
1529
1530         putip((char *)&from_ip,&nmb->additional->rdata[2]);
1531         ttl = get_ttl_from_packet(nmb);
1532
1533         /*
1534          * We want to just add the new IP, as we now know the requesting
1535          * machine claims to own it. But we can't just do that as an arbitary
1536          * amount of time may have taken place between the name query
1537          * request and this response. So we check that
1538          * the name still exists and is in the same state - if so
1539          * we just add the extra IP and update the ttl.
1540          */
1541
1542         namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
1543
1544         if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) ) {
1545                 DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
1546 a subsequent IP address.\n", nmb_namestr(question_name) ));
1547                 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1548
1549                 orig_reg_packet->locked = False;
1550                 free_packet(orig_reg_packet);
1551
1552                 return;
1553         }
1554
1555         if(!find_ip_in_name_record(namerec, from_ip)) {
1556                 add_ip_to_name_record(namerec, from_ip);
1557         }
1558
1559         get_global_id_and_update(&namerec->data.id, True);
1560         update_wins_owner(namerec, our_fake_ip);
1561         update_wins_flag(namerec, WINS_ACTIVE);
1562         update_name_ttl(namerec, ttl);
1563         wins_hook("add", namerec, ttl);
1564         send_wins_name_registration_response(0, ttl, orig_reg_packet);
1565
1566         orig_reg_packet->locked = False;
1567         free_packet(orig_reg_packet);
1568 }
1569
1570 /***********************************************************************
1571  Deal with a name registration request query failure to a client that
1572  owned the name.
1573
1574  We have a locked pointer to the original packet stashed away in the
1575  userdata pointer.
1576 ************************************************************************/
1577
1578 static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
1579                                           struct response_record *rrec,
1580                                           struct nmb_name *question_name,
1581                                           int rcode)
1582 {
1583         struct userdata_struct *userdata = rrec->userdata;
1584         struct packet_struct *orig_reg_packet;
1585
1586         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1587
1588         DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
1589 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
1590         send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1591
1592         orig_reg_packet->locked = False;
1593         free_packet(orig_reg_packet);
1594         return;
1595 }
1596
1597 /***********************************************************************
1598  Deal with a multihomed name registration request to a WINS server.
1599  These cannot be group name registrations.
1600 ***********************************************************************/
1601
1602 void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
1603                                                         struct packet_struct *p)
1604 {
1605         struct nmb_packet *nmb = &p->packet.nmb;
1606         struct nmb_name *question = &nmb->question.question_name;
1607         bool bcast = nmb->header.nm_flags.bcast;
1608         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1609         int ttl = get_ttl_from_packet(nmb);
1610         struct name_record *namerec = NULL;
1611         struct in_addr from_ip;
1612         bool group = (nb_flags & NB_GROUP) ? True : False;
1613         struct in_addr our_fake_ip;
1614         unstring qname;
1615
1616         our_fake_ip = interpret_addr2("0.0.0.0");
1617         putip((char *)&from_ip,&nmb->additional->rdata[2]);
1618
1619         if(bcast) {
1620                 /*
1621                  * We should only get unicast name registration packets here.
1622                  * Anyone trying to register broadcast should not be going to a WINS
1623                  * server. Log an error here.
1624                  */
1625
1626                 DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
1627 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1628                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1629                 return;
1630         }
1631
1632         /*
1633          * Only unique names should be registered multihomed.
1634          */
1635
1636         if(group) {
1637                 DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
1638 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
1639                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1640                 return;
1641         }
1642
1643         DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
1644 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
1645
1646         /*
1647          * Deal with policy regarding 0x1d names.
1648          */
1649
1650         if(question->name_type == 0x1d) {
1651                 DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
1652 to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1653                 send_wins_name_registration_response(0, ttl, p);  
1654                 return;
1655         }
1656
1657         /*
1658          * See if the name already exists.
1659          */
1660
1661         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1662
1663         /*
1664          * if the record exists but NOT in active state,
1665          * consider it dead.
1666          */
1667
1668         if ((namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
1669                 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was not active - removing it.\n", nmb_namestr(question)));
1670                 remove_name_from_namelist(subrec, namerec);
1671                 namerec = NULL;
1672         }
1673   
1674         /*
1675          * Deal with the case where the name found was a dns entry.
1676          * Remove it as we now have a NetBIOS client registering the
1677          * name.
1678          */
1679
1680         if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
1681                 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
1682 - removing it.\n", nmb_namestr(question) ));
1683                 remove_name_from_namelist( subrec, namerec);
1684                 namerec = NULL;
1685         }
1686
1687         /*
1688          * Reject if the name exists and is not a REGISTER_NAME.
1689          * (ie. Don't allow any static names to be overwritten.
1690          */
1691
1692         if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) ) {
1693                 DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1694 to register name %s. Name already exists in WINS with source type %d.\n",
1695                         nmb_namestr(question), namerec->data.source ));
1696                 send_wins_name_registration_response(RFS_ERR, 0, p);
1697                 return;
1698         }
1699
1700         /*
1701          * Reject if the name exists and is a GROUP name and is active.
1702          */
1703
1704         if((namerec != NULL) && NAME_GROUP(namerec) && WINS_STATE_ACTIVE(namerec)) {
1705                 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1706 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
1707                 send_wins_name_registration_response(RFS_ERR, 0, p);
1708                 return;
1709         } 
1710
1711         /*
1712          * From here on down we know that if the name exists in the WINS db it is
1713          * a unique name, not a group name.
1714          */
1715
1716         /*
1717          * If the name exists and is one of our names then check the
1718          * registering IP address. If it's not one of ours then automatically
1719          * reject without doing the query - we know we will reject it.
1720          */
1721
1722         if((namerec != NULL) && (is_myname(namerec->name.name)) ) {
1723                 if(!ismyip_v4(from_ip)) {
1724                         DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1725 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
1726                         send_wins_name_registration_response(RFS_ERR, 0, p);
1727                         return;
1728                 } else {
1729                         /*
1730                          * It's one of our names and one of our IP's. Ensure the IP is in the record and
1731                          *  update the ttl. Update the version ID to force replication.
1732                          */
1733                         update_name_ttl(namerec, ttl);
1734
1735                         if(!find_ip_in_name_record(namerec, from_ip)) {
1736                                 get_global_id_and_update(&namerec->data.id, True);
1737                                 update_wins_owner(namerec, our_fake_ip);
1738                                 update_wins_flag(namerec, WINS_ACTIVE);
1739
1740                                 add_ip_to_name_record(namerec, from_ip);
1741                         }
1742
1743                         wins_hook("refresh", namerec, ttl);
1744                         send_wins_name_registration_response(0, ttl, p);
1745                         return;
1746                 }
1747         }
1748
1749         /*
1750          * If the name exists and is active, check if the IP address is already registered
1751          * to that name. If so then update the ttl and reply success.
1752          */
1753
1754         if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip) && WINS_STATE_ACTIVE(namerec)) {
1755                 update_name_ttl(namerec, ttl);
1756
1757                 /*
1758                  * If it's a replica, we need to become the wins owner
1759                  * to force the replication
1760                  */
1761                 if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
1762                         get_global_id_and_update(&namerec->data.id, True);
1763                         update_wins_owner(namerec, our_fake_ip);
1764                         update_wins_flag(namerec, WINS_ACTIVE);
1765                 }
1766     
1767                 wins_hook("refresh", namerec, ttl);
1768                 send_wins_name_registration_response(0, ttl, p);
1769                 return;
1770         }
1771
1772         /*
1773          * If the name exists do a query to the owner
1774          * to see if they still want the name.
1775          */
1776
1777         if(namerec != NULL) {
1778                 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
1779                 struct userdata_struct *userdata = (struct userdata_struct *)ud;
1780
1781                 /*
1782                  * First send a WACK to the registering machine.
1783                  */
1784
1785                 send_wins_wack_response(60, p);
1786
1787                 /*
1788                  * When the reply comes back we need the original packet.
1789                  * Lock this so it won't be freed and then put it into
1790                  * the userdata structure.
1791                  */
1792
1793                 p->locked = True;
1794
1795                 userdata = (struct userdata_struct *)ud;
1796
1797                 userdata->copy_fn = NULL;
1798                 userdata->free_fn = NULL;
1799                 userdata->userdata_len = sizeof(struct packet_struct *);
1800                 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1801
1802                 /* 
1803                  * Use the new call to send a query directly to an IP address.
1804                  * This sends the query directly to the IP address, and ensures
1805                  * the recursion desired flag is not set (you were right Luke :-).
1806                  * This function should *only* be called from the WINS server
1807                  * code. JRA.
1808                  *
1809                  * Note that this packet is sent to the current owner of the name,
1810                  * not the person who sent the packet 
1811                  */
1812
1813                 pull_ascii_nstring( qname, sizeof(qname), question->name);
1814                 query_name_from_wins_server( namerec->data.ip[0],
1815                                 qname,
1816                                 question->name_type, 
1817                                 wins_multihomed_register_query_success,
1818                                 wins_multihomed_register_query_fail,
1819                                 userdata );
1820
1821                 return;
1822         }
1823
1824         /*
1825          * Name did not exist - add it.
1826          */
1827
1828         pull_ascii_nstring( qname, sizeof(qname), question->name);
1829         add_name_to_subnet( subrec, qname, question->name_type,
1830                         nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1831
1832         if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1833                 get_global_id_and_update(&namerec->data.id, True);
1834                 update_wins_owner(namerec, our_fake_ip);
1835                 update_wins_flag(namerec, WINS_ACTIVE);
1836                 wins_hook("add", namerec, ttl);
1837         }
1838
1839         send_wins_name_registration_response(0, ttl, p);
1840 }
1841
1842 /***********************************************************************
1843  Fetch all *<1b> names from the WINS db and store on the namelist.
1844 ***********************************************************************/
1845
1846 static int fetch_1b_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
1847 {
1848         struct name_record *namerec = NULL;
1849
1850         if (kbuf.dsize != sizeof(unstring) + 1) {
1851                 return 0;
1852         }
1853
1854         /* Filter out all non-1b names. */
1855         if (kbuf.dptr[sizeof(unstring)] != 0x1b) {
1856                 return 0;
1857         }
1858
1859         namerec = wins_record_to_name_record(kbuf, dbuf);
1860         if (!namerec) {
1861                 return 0;
1862         }
1863
1864         DLIST_ADD(wins_server_subnet->namelist, namerec);
1865         return 0;
1866 }
1867
1868 void fetch_all_active_wins_1b_names(void)
1869 {
1870         tdb_traverse(wins_tdb, fetch_1b_traverse_fn, NULL);
1871 }
1872
1873 /***********************************************************************
1874  Deal with the special name query for *<1b>.
1875 ***********************************************************************/
1876    
1877 static void process_wins_dmb_query_request(struct subnet_record *subrec,  
1878                                            struct packet_struct *p)
1879 {  
1880         struct name_record *namerec = NULL;
1881         char *prdata;
1882         int num_ips;
1883
1884         /*
1885          * Go through all the ACTIVE names in the WINS db looking for those
1886          * ending in <1b>. Use this to calculate the number of IP
1887          * addresses we need to return.
1888          */
1889
1890         num_ips = 0;
1891
1892         /* First, clear the in memory list - we're going to re-populate
1893            it with the tdb_traversal in fetch_all_active_wins_1b_names. */
1894
1895         wins_delete_all_tmp_in_memory_records();
1896
1897         fetch_all_active_wins_1b_names();
1898
1899         for( namerec = subrec->namelist; namerec; namerec = namerec->next ) {
1900                 if( WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
1901                         num_ips += namerec->data.num_ips;
1902                 }
1903         }
1904
1905         if(num_ips == 0) {
1906                 /*
1907                  * There are no 0x1b names registered. Return name query fail.
1908                  */
1909                 send_wins_name_query_response(NAM_ERR, p, NULL);
1910                 return;
1911         }
1912
1913         if((prdata = (char *)SMB_MALLOC( num_ips * 6 )) == NULL) {
1914                 DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1915                 return;
1916         }
1917
1918         /*
1919          * Go through all the names again in the WINS db looking for those
1920          * ending in <1b>. Add their IP addresses into the list we will
1921          * return.
1922          */ 
1923
1924         num_ips = 0;
1925         for( namerec = subrec->namelist; namerec; namerec = namerec->next ) {
1926                 if( WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
1927                         int i;
1928                         for(i = 0; i < namerec->data.num_ips; i++) {
1929                                 set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1930                                 putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1931                                 num_ips++;
1932                         }
1933                 }
1934         }
1935
1936         /*
1937          * Send back the reply containing the IP list.
1938          */
1939
1940         reply_netbios_packet(p,                                /* Packet to reply to. */
1941                                 0,                             /* Result code. */
1942                                 WINS_QUERY,                    /* nmbd type code. */
1943                                 NMB_NAME_QUERY_OPCODE,         /* opcode. */
1944                                 lp_min_wins_ttl(),             /* ttl. */
1945                                 prdata,                        /* data to send. */
1946                                 num_ips*6);                    /* data length. */
1947
1948         SAFE_FREE(prdata);
1949 }
1950
1951 /****************************************************************************
1952 Send a WINS name query response.
1953 **************************************************************************/
1954
1955 void send_wins_name_query_response(int rcode, struct packet_struct *p, 
1956                                           struct name_record *namerec)
1957 {
1958         char rdata[6];
1959         char *prdata = rdata;
1960         int reply_data_len = 0;
1961         int ttl = 0;
1962         int i;
1963
1964         memset(rdata,'\0',6);
1965
1966         if(rcode == 0) {
1967
1968                 int ip_count;
1969
1970                 ttl = (namerec->data.death_time != PERMANENT_TTL) ?  namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1971
1972                 /* The netbios reply packet data section is limited to 576 bytes.  In theory 
1973                  * this should give us space for 96 addresses, but in practice, 86 appears 
1974                  * to be the max (don't know why).  If we send any more than that, 
1975                  * reply_netbios_packet will fail to send a reply to avoid a memcpy buffer 
1976                  * overflow.  Keep the count to 85 and it will be ok */
1977                 ip_count=namerec->data.num_ips;
1978                 if(ip_count>85) {
1979                         ip_count=85;    
1980                 }
1981
1982                 /* Copy all known ip addresses into the return data. */
1983                 /* Optimise for the common case of one IP address so we don't need a malloc. */
1984
1985                 if( ip_count == 1 ) {
1986                         prdata = rdata;
1987                 } else {
1988                         if((prdata = (char *)SMB_MALLOC( ip_count * 6 )) == NULL) {
1989                                 DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1990                                 return;
1991                         }
1992                 }
1993
1994                 for(i = 0; i < ip_count; i++) {
1995                         set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1996                         putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
1997                 }
1998
1999                 sort_query_replies(prdata, i, p->ip);
2000                 reply_data_len = ip_count * 6;
2001         }
2002
2003         reply_netbios_packet(p,                                /* Packet to reply to. */
2004                                 rcode,                         /* Result code. */
2005                                 WINS_QUERY,                    /* nmbd type code. */
2006                                 NMB_NAME_QUERY_OPCODE,         /* opcode. */
2007                                 ttl,                           /* ttl. */
2008                                 prdata,                        /* data to send. */
2009                                 reply_data_len);               /* data length. */
2010
2011         if(prdata != rdata) {
2012                 SAFE_FREE(prdata);
2013         }
2014 }
2015
2016 /***********************************************************************
2017  Deal with a name query.
2018 ***********************************************************************/
2019
2020 void wins_process_name_query_request(struct subnet_record *subrec, 
2021                                      struct packet_struct *p)
2022 {
2023         struct nmb_packet *nmb = &p->packet.nmb;
2024         struct nmb_name *question = &nmb->question.question_name;
2025         struct name_record *namerec = NULL;
2026         unstring qname;
2027
2028         DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n", 
2029                 nmb_namestr(question), inet_ntoa(p->ip) ));
2030
2031         /*
2032          * Special name code. If the queried name is *<1b> then search
2033          * the entire WINS database and return a list of all the IP addresses
2034          * registered to any <1b> name. This is to allow domain master browsers
2035          * to discover other domains that may not have a presence on their subnet.
2036          */
2037
2038         pull_ascii_nstring(qname, sizeof(qname), question->name);
2039         if(strequal( qname, "*") && (question->name_type == 0x1b)) {
2040                 process_wins_dmb_query_request( subrec, p);
2041                 return;
2042         }
2043
2044         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
2045
2046         if(namerec != NULL) {
2047                 /*
2048                  * If the name is not anymore in active state then reply not found.
2049                  * it's fair even if we keep it in the cache for days.
2050                  */
2051                 if (!WINS_STATE_ACTIVE(namerec)) {
2052                         DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
2053                                 nmb_namestr(question) ));
2054                         send_wins_name_query_response(NAM_ERR, p, namerec);
2055                         return;
2056                 }
2057
2058                 /* 
2059                  * If it's a DNSFAIL_NAME then reply name not found.
2060                  */
2061
2062                 if( namerec->data.source == DNSFAIL_NAME ) {
2063                         DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
2064                                 nmb_namestr(question) ));
2065                         send_wins_name_query_response(NAM_ERR, p, namerec);
2066                         return;
2067                 }
2068
2069                 /*
2070                  * If the name has expired then reply name not found.
2071                  */
2072
2073                 if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < p->timestamp) ) {
2074                         DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
2075                                         nmb_namestr(question) ));
2076                         send_wins_name_query_response(NAM_ERR, p, namerec);
2077                         return;
2078                 }
2079
2080                 DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
2081                                 nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
2082
2083                 send_wins_name_query_response(0, p, namerec);
2084                 return;
2085         }
2086
2087         /* 
2088          * Name not found in WINS - try a dns query if it's a 0x20 name.
2089          */
2090
2091         if(lp_dns_proxy() && ((question->name_type == 0x20) || question->name_type == 0)) {
2092                 DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
2093                                 nmb_namestr(question) ));
2094
2095                 queue_dns_query(p, question);
2096                 return;
2097         }
2098
2099         /*
2100          * Name not found - return error.
2101          */
2102
2103         send_wins_name_query_response(NAM_ERR, p, NULL);
2104 }
2105
2106 /****************************************************************************
2107 Send a WINS name release response.
2108 **************************************************************************/
2109
2110 static void send_wins_name_release_response(int rcode, struct packet_struct *p)
2111 {
2112         struct nmb_packet *nmb = &p->packet.nmb;
2113         char rdata[6];
2114
2115         memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
2116
2117         reply_netbios_packet(p,                               /* Packet to reply to. */
2118                                 rcode,                        /* Result code. */
2119                                 NMB_REL,                      /* nmbd type code. */
2120                                 NMB_NAME_RELEASE_OPCODE,      /* opcode. */
2121                                 0,                            /* ttl. */
2122                                 rdata,                        /* data to send. */
2123                                 6);                           /* data length. */
2124 }
2125
2126 /***********************************************************************
2127  Deal with a name release.
2128 ***********************************************************************/
2129
2130 void wins_process_name_release_request(struct subnet_record *subrec,
2131                                        struct packet_struct *p)
2132 {
2133         struct nmb_packet *nmb = &p->packet.nmb;
2134         struct nmb_name *question = &nmb->question.question_name;
2135         bool bcast = nmb->header.nm_flags.bcast;
2136         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
2137         struct name_record *namerec = NULL;
2138         struct in_addr from_ip;
2139         bool releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
2140
2141         putip((char *)&from_ip,&nmb->additional->rdata[2]);
2142
2143         if(bcast) {
2144                 /*
2145                  * We should only get unicast name registration packets here.
2146                  * Anyone trying to register broadcast should not be going to a WINS
2147                  * server. Log an error here.
2148                  */
2149
2150                 DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
2151 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
2152                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
2153                 return;
2154         }
2155   
2156         DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
2157 IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
2158     
2159         /*
2160          * Deal with policy regarding 0x1d names.
2161          */
2162
2163         if(!releasing_group_name && (question->name_type == 0x1d)) {
2164                 DEBUG(3,("wins_process_name_release_request: Ignoring request \
2165 to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
2166                 send_wins_name_release_response(0, p);
2167                 return;
2168         }
2169
2170         /*
2171          * See if the name already exists.
2172          */
2173     
2174         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
2175
2176         if( (namerec == NULL) || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) ) {
2177                 send_wins_name_release_response(NAM_ERR, p);
2178                 return;
2179         }
2180
2181         /* 
2182          * Check that the sending machine has permission to release this name.
2183          * If it's a group name not ending in 0x1c then just say yes and let
2184          * the group time out.
2185          */
2186
2187         if(releasing_group_name && (question->name_type != 0x1c)) {
2188                 send_wins_name_release_response(0, p);
2189                 return;
2190         }
2191
2192         /* 
2193          * Check that the releasing node is on the list of IP addresses
2194          * for this name. Disallow the release if not.
2195          */
2196
2197         if(!find_ip_in_name_record(namerec, from_ip)) {
2198                 DEBUG(3,("wins_process_name_release_request: Refusing request to \
2199 release name %s as IP %s is not one of the known IP's for this name.\n",
2200                         nmb_namestr(question), inet_ntoa(from_ip) ));
2201                 send_wins_name_release_response(NAM_ERR, p);
2202                 return;
2203         }
2204
2205         /*
2206          * Check if the record is active. IF it's already released
2207          * or tombstoned, refuse the release.
2208          */
2209
2210         if (!WINS_STATE_ACTIVE(namerec)) {
2211                 DEBUG(3,("wins_process_name_release_request: Refusing request to \
2212 release name %s as this record is not active anymore.\n", nmb_namestr(question) ));
2213                 send_wins_name_release_response(NAM_ERR, p);
2214                 return;
2215         }    
2216
2217         /*
2218          * Check if the record is a 0x1c group
2219          * and has more then one ip
2220          * remove only this address.
2221          */
2222
2223         if(releasing_group_name && (question->name_type == 0x1c) && (namerec->data.num_ips > 1)) {
2224                 remove_ip_from_name_record(namerec, from_ip);
2225                 DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
2226                                 inet_ntoa(from_ip),nmb_namestr(question)));
2227                 wins_hook("delete", namerec, 0);
2228                 send_wins_name_release_response(0, p);
2229                 return;
2230         }
2231
2232         /* 
2233          * Send a release response.
2234          * Flag the name as released and update the ttl
2235          */
2236
2237         namerec->data.wins_flags |= WINS_RELEASED;
2238         update_name_ttl(namerec, EXTINCTION_INTERVAL);
2239
2240         wins_hook("delete", namerec, 0);
2241         send_wins_name_release_response(0, p);
2242 }
2243
2244 /*******************************************************************
2245  WINS time dependent processing.
2246 ******************************************************************/
2247
2248 static int wins_processing_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
2249 {
2250         time_t t = *(time_t *)state;
2251         bool store_record = False;
2252         struct name_record *namerec = NULL;
2253         struct in_addr our_fake_ip;
2254
2255         our_fake_ip = interpret_addr2("0.0.0.0");
2256         if (kbuf.dsize != sizeof(unstring) + 1) {
2257                 return 0;
2258         }
2259
2260         namerec = wins_record_to_name_record(kbuf, dbuf);
2261         if (!namerec) {
2262                 return 0;
2263         }
2264
2265         if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < t) ) {
2266                 if( namerec->data.source == SELF_NAME ) {
2267                         DEBUG( 3, ( "wins_processing_traverse_fn: Subnet %s not expiring SELF name %s\n", 
2268                                    wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
2269                         namerec->data.death_time += 300;
2270                         store_record = True;
2271                         goto done;
2272                 } else if (namerec->data.source == DNS_NAME || namerec->data.source == DNSFAIL_NAME) {
2273                         DEBUG(3,("wins_processing_traverse_fn: deleting timed out DNS name %s\n",
2274                                         nmb_namestr(&namerec->name)));
2275                         remove_name_from_wins_namelist(namerec );
2276                         goto done;
2277                 }
2278
2279                 /* handle records, samba is the wins owner */
2280                 if (ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
2281                         switch (namerec->data.wins_flags & WINS_STATE_MASK) {
2282                                 case WINS_ACTIVE:
2283                                         namerec->data.wins_flags&=~WINS_STATE_MASK;
2284                                         namerec->data.wins_flags|=WINS_RELEASED;
2285                                         namerec->data.death_time = t + EXTINCTION_INTERVAL;
2286                                         DEBUG(3,("wins_processing_traverse_fn: expiring %s\n",
2287                                                 nmb_namestr(&namerec->name)));
2288                                         store_record = True;
2289                                         goto done;
2290                                 case WINS_RELEASED:
2291                                         namerec->data.wins_flags&=~WINS_STATE_MASK;
2292                                         namerec->data.wins_flags|=WINS_TOMBSTONED;
2293                                         namerec->data.death_time = t + EXTINCTION_TIMEOUT;
2294                                         get_global_id_and_update(&namerec->data.id, True);
2295                                         DEBUG(3,("wins_processing_traverse_fn: tombstoning %s\n",
2296                                                 nmb_namestr(&namerec->name)));
2297                                         store_record = True;
2298                                         goto done;
2299                                 case WINS_TOMBSTONED:
2300                                         DEBUG(3,("wins_processing_traverse_fn: deleting %s\n",
2301                                                 nmb_namestr(&namerec->name)));
2302                                         remove_name_from_wins_namelist(namerec );
2303                                         goto done;
2304                         }
2305                 } else {
2306                         switch (namerec->data.wins_flags & WINS_STATE_MASK) {
2307                                 case WINS_ACTIVE:
2308                                         /* that's not as MS says it should be */
2309                                         namerec->data.wins_flags&=~WINS_STATE_MASK;
2310                                         namerec->data.wins_flags|=WINS_TOMBSTONED;
2311                                         namerec->data.death_time = t + EXTINCTION_TIMEOUT;
2312                                         DEBUG(3,("wins_processing_traverse_fn: tombstoning %s\n",
2313                                                 nmb_namestr(&namerec->name)));
2314                                         store_record = True;
2315                                         goto done;
2316                                 case WINS_TOMBSTONED:
2317                                         DEBUG(3,("wins_processing_traverse_fn: deleting %s\n",
2318                                                 nmb_namestr(&namerec->name)));
2319                                         remove_name_from_wins_namelist(namerec );
2320                                         goto done;
2321                                 case WINS_RELEASED:
2322                                         DEBUG(0,("wins_processing_traverse_fn: %s is in released state and\
2323 we are not the wins owner !\n", nmb_namestr(&namerec->name)));
2324                                         goto done;
2325                         }
2326                 }
2327         }
2328
2329   done:
2330
2331         if (store_record) {
2332                 wins_store_changed_namerec(namerec);
2333         }
2334
2335         SAFE_FREE(namerec->data.ip);
2336         SAFE_FREE(namerec);
2337
2338         return 0;
2339 }
2340
2341 /*******************************************************************
2342  Time dependent wins processing.
2343 ******************************************************************/
2344
2345 void initiate_wins_processing(time_t t)
2346 {
2347         static time_t lasttime = 0;
2348
2349         if (!lasttime) {
2350                 lasttime = t;
2351         }
2352         if (t - lasttime < 20) {
2353                 return;
2354         }
2355
2356         if(!lp_we_are_a_wins_server()) {
2357                 lasttime = t;
2358                 return;
2359         }
2360
2361         tdb_traverse(wins_tdb, wins_processing_traverse_fn, &t);
2362
2363         wins_delete_all_tmp_in_memory_records();
2364
2365         wins_write_database(t, True);
2366
2367         lasttime = t;
2368 }
2369
2370 /*******************************************************************
2371  Write out one record.
2372 ******************************************************************/
2373
2374 void wins_write_name_record(struct name_record *namerec, XFILE *fp)
2375 {
2376         int i;
2377         struct tm *tm;
2378
2379         DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
2380
2381         if( namerec->data.death_time != PERMANENT_TTL ) {
2382                 char *ts, *nl;
2383
2384                 tm = localtime(&namerec->data.death_time);
2385                 if (!tm) {
2386                         return;
2387                 }
2388                 ts = asctime(tm);
2389                 if (!ts) {
2390                         return;
2391                 }
2392                 nl = strrchr( ts, '\n' );
2393                 if( NULL != nl ) {
2394                         *nl = '\0';
2395                 }
2396                 DEBUGADD(4,("TTL = %s  ", ts ));
2397         } else {
2398                 DEBUGADD(4,("TTL = PERMANENT                 "));
2399         }
2400
2401         for (i = 0; i < namerec->data.num_ips; i++) {
2402                 DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
2403         }
2404         DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
2405
2406         if( namerec->data.source == REGISTER_NAME ) {
2407                 unstring name;
2408                 pull_ascii_nstring(name, sizeof(name), namerec->name.name);
2409                 x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */
2410                         (int)namerec->data.death_time);
2411
2412                 for (i = 0; i < namerec->data.num_ips; i++)
2413                         x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
2414                 x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
2415         }
2416 }
2417
2418 /*******************************************************************
2419  Write out the current WINS database.
2420 ******************************************************************/
2421
2422 static int wins_writedb_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
2423 {
2424         struct name_record *namerec = NULL;
2425         XFILE *fp = (XFILE *)state;
2426
2427         if (kbuf.dsize != sizeof(unstring) + 1) {
2428                 return 0;
2429         }
2430
2431         namerec = wins_record_to_name_record(kbuf, dbuf);
2432         if (!namerec) {
2433                 return 0;
2434         }
2435
2436         wins_write_name_record(namerec, fp);
2437
2438         SAFE_FREE(namerec->data.ip);
2439         SAFE_FREE(namerec);
2440         return 0;
2441 }
2442
2443
2444 void wins_write_database(time_t t, bool background)
2445 {
2446         static time_t last_write_time = 0;
2447         char *fname = NULL;
2448         char *fnamenew = NULL;
2449
2450         XFILE *fp;
2451
2452         if (background) {
2453                 if (!last_write_time) {
2454                         last_write_time = t;
2455                 }
2456                 if (t - last_write_time < 120) {
2457                         return;
2458                 }
2459
2460         }
2461
2462         if(!lp_we_are_a_wins_server()) {
2463                 return;
2464         }
2465
2466         /* We will do the writing in a child process to ensure that the parent doesn't block while this is done */
2467         if (background) {
2468                 CatchChild();
2469                 if (sys_fork()) {
2470                         return;
2471                 }
2472                 if (tdb_reopen(wins_tdb)) {
2473                         DEBUG(0,("wins_write_database: tdb_reopen failed. Error was %s\n",
2474                                 strerror(errno)));
2475                         _exit(0);
2476                         return;
2477                 }
2478         }
2479
2480         if (!(fname = state_path(WINS_LIST))) {
2481                 goto err_exit;
2482         }
2483         /* This is safe as the 0 length means "don't expand". */
2484         all_string_sub(fname,"//", "/", 0);
2485
2486         if (asprintf(&fnamenew, "%s.%u", fname, (unsigned int)sys_getpid()) < 0) {
2487                 goto err_exit;
2488         }
2489
2490         if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) {
2491                 DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
2492                 goto err_exit;
2493         }
2494
2495         DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
2496
2497         x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
2498
2499         tdb_traverse(wins_tdb, wins_writedb_traverse_fn, fp);
2500
2501         x_fclose(fp);
2502         chmod(fnamenew,0644);
2503         unlink(fname);
2504         rename(fnamenew,fname);
2505
2506   err_exit:
2507
2508         SAFE_FREE(fnamenew);
2509         TALLOC_FREE(fname);
2510
2511         if (background) {
2512                 _exit(0);
2513         }
2514 }
2515
2516 #if 0
2517         Until winsrepl is done.
2518 /****************************************************************************
2519  Process a internal Samba message receiving a wins record.
2520 ***************************************************************************/
2521
2522 void nmbd_wins_new_entry(struct messaging_context *msg,
2523                                        void *private_data,
2524                                        uint32_t msg_type,
2525                                        struct server_id server_id,
2526                                        DATA_BLOB *data)
2527 {
2528         WINS_RECORD *record;
2529         struct name_record *namerec = NULL;
2530         struct name_record *new_namerec = NULL;
2531         struct nmb_name question;
2532         bool overwrite=False;
2533         struct in_addr our_fake_ip;
2534         int i;
2535
2536         our_fake_ip = interpret_addr2("0.0.0.0");
2537         if (buf==NULL) {
2538                 return;
2539         }
2540         
2541         /* Record should use UNIX codepage. Ensure this is so in the wrepld code. JRA. */
2542         record=(WINS_RECORD *)buf;
2543         
2544         make_nmb_name(&question, record->name, record->type);
2545
2546         namerec = find_name_on_subnet(wins_server_subnet, &question, FIND_ANY_NAME);
2547
2548         /* record doesn't exist, add it */
2549         if (namerec == NULL) {
2550                 DEBUG(3,("nmbd_wins_new_entry: adding new replicated record: %s<%02x> for wins server: %s\n", 
2551                           record->name, record->type, inet_ntoa(record->wins_ip)));
2552
2553                 new_namerec=add_name_to_subnet( wins_server_subnet,
2554                                                 record->name,
2555                                                 record->type,
2556                                                 record->nb_flags, 
2557                                                 EXTINCTION_INTERVAL,
2558                                                 REGISTER_NAME,
2559                                                 record->num_ips,
2560                                                 record->ip);
2561
2562                 if (new_namerec!=NULL) {
2563                                 update_wins_owner(new_namerec, record->wins_ip);
2564                                 update_wins_flag(new_namerec, record->wins_flags);
2565                                 new_namerec->data.id=record->id;
2566
2567                                 wins_server_subnet->namelist_changed = True;
2568                         }
2569         }
2570
2571         /* check if we have a conflict */
2572         if (namerec != NULL) {
2573                 /* both records are UNIQUE */
2574                 if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
2575
2576                         /* the database record is a replica */
2577                         if (!ip_equal_v4(namerec->data.wins_ip, our_fake_ip)) {
2578                                 if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
2579                                         if (ip_equal_v4(namerec->data.wins_ip, record->wins_ip))
2580                                                 overwrite=True;
2581                                 } else
2582                                         overwrite=True;
2583                         } else {
2584                         /* we are the wins owner of the database record */
2585                                 /* the 2 records have the same IP address */
2586                                 if (ip_equal_v4(namerec->data.ip[0], record->ip[0])) {
2587                                         if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
2588                                                 get_global_id_and_update(&namerec->data.id, True);
2589                                         else
2590                                                 overwrite=True;
2591                                 
2592                                 } else {
2593                                 /* the 2 records have different IP address */
2594                                         if (namerec->data.wins_flags&WINS_ACTIVE) {
2595                                                 if (record->wins_flags&WINS_TOMBSTONED)
2596                                                         get_global_id_and_update(&namerec->data.id, True);
2597                                                 if (record->wins_flags&WINS_ACTIVE)
2598                                                         /* send conflict challenge to the replica node */
2599                                                         ;
2600                                         } else
2601                                                 overwrite=True;
2602                                 }
2603
2604                         }
2605                 }
2606                 
2607                 /* the replica is a standard group */
2608                 if (record->wins_flags&WINS_NGROUP || record->wins_flags&WINS_SGROUP) {
2609                         /* if the database record is unique and active force a name release */
2610                         if (namerec->data.wins_flags&WINS_UNIQUE)
2611                                 /* send a release name to the unique node */
2612                                 ;
2613                         overwrite=True;
2614                 
2615                 }
2616         
2617                 /* the replica is a special group */
2618                 if (record->wins_flags&WINS_SGROUP && namerec->data.wins_flags&WINS_SGROUP) {
2619                         if (namerec->data.wins_flags&WINS_ACTIVE) {
2620                                 for (i=0; i<record->num_ips; i++)
2621                                         if(!find_ip_in_name_record(namerec, record->ip[i]))
2622                                                 add_ip_to_name_record(namerec, record->ip[i]);
2623                         } else {
2624                                 overwrite=True;
2625                         }
2626                 }
2627                 
2628                 /* the replica is a multihomed host */
2629                 
2630                 /* I'm giving up on multi homed. Too much complex to understand */
2631                 
2632                 if (record->wins_flags&WINS_MHOMED) {
2633                         if (! (namerec->data.wins_flags&WINS_ACTIVE)) {
2634                                 if ( !(namerec->data.wins_flags&WINS_RELEASED) && !(namerec->data.wins_flags&WINS_NGROUP))
2635                                         overwrite=True;
2636                         }
2637                         else {
2638                                 if (ip_equal_v4(record->wins_ip, namerec->data.wins_ip))
2639                                         overwrite=True;
2640                                 
2641                                 if (ip_equal_v4(namerec->data.wins_ip, our_fake_ip))
2642                                         if (namerec->data.wins_flags&WINS_UNIQUE)
2643                                                 get_global_id_and_update(&namerec->data.id, True);
2644                                 
2645                         }
2646                         
2647                         if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
2648                                 if (namerec->data.wins_flags&WINS_UNIQUE ||
2649                                     namerec->data.wins_flags&WINS_MHOMED)
2650                                         if (ip_equal_v4(record->wins_ip, namerec->data.wins_ip))
2651                                                 overwrite=True;
2652                                 
2653                 }
2654
2655                 if (overwrite == False)
2656                         DEBUG(3, ("nmbd_wins_new_entry: conflict in adding record: %s<%02x> from wins server: %s\n", 
2657                                   record->name, record->type, inet_ntoa(record->wins_ip)));
2658                 else {
2659                         DEBUG(3, ("nmbd_wins_new_entry: replacing record: %s<%02x> from wins server: %s\n", 
2660                                   record->name, record->type, inet_ntoa(record->wins_ip)));
2661
2662                         /* remove the old record and add a new one */
2663                         remove_name_from_namelist( wins_server_subnet, namerec );
2664                         new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags, 
2665                                                 EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
2666                         if (new_namerec!=NULL) {
2667                                 update_wins_owner(new_namerec, record->wins_ip);
2668                                 update_wins_flag(new_namerec, record->wins_flags);
2669                                 new_namerec->data.id=record->id;
2670
2671                                 wins_server_subnet->namelist_changed = True;
2672                         }
2673
2674                         wins_server_subnet->namelist_changed = True;
2675                 }
2676
2677         }
2678 }
2679 #endif