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