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