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