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