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