1/*
2   Unix SMB/CIFS implementation.
3   NBT netbios routines and daemon - version 2
4
5   Copyright (C) Jeremy Allison 1994-2003
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 2 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, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include "includes.h"
24
25#define WINS_LIST "wins.dat"
26#define WINS_VERSION 1
27
28/****************************************************************************
29 Change the wins owner address in the record.
30*****************************************************************************/
31
32static void update_wins_owner(struct name_record *namerec, struct in_addr wins_ip)
33{
34	if (namerec==NULL)
35		return;
36	namerec->data.wins_ip=wins_ip;
37}
38
39/****************************************************************************
40 Create the wins flags based on the nb flags and the input value.
41*****************************************************************************/
42
43static void update_wins_flag(struct name_record *namerec, int flags)
44{
45	if (namerec==NULL)
46		return;
47
48	namerec->data.wins_flags=0x0;
49
50	/* if it's a group, it can be a normal or a special one */
51	if (namerec->data.nb_flags & NB_GROUP) {
52		if (namerec->name.name_type==0x1C)
53			namerec->data.wins_flags|=WINS_SGROUP;
54		else
55			if (namerec->data.num_ips>1)
56				namerec->data.wins_flags|=WINS_SGROUP;
57			else
58				namerec->data.wins_flags|=WINS_NGROUP;
59	} else {
60		/* can be unique or multi-homed */
61		if (namerec->data.num_ips>1)
62			namerec->data.wins_flags|=WINS_MHOMED;
63		else
64			namerec->data.wins_flags|=WINS_UNIQUE;
65	}
66
67	/* the node type are the same bits */
68	namerec->data.wins_flags|=namerec->data.nb_flags&NB_NODETYPEMASK;
69
70	/* the static bit is elsewhere */
71	if (namerec->data.death_time == PERMANENT_TTL)
72		namerec->data.wins_flags|=WINS_STATIC;
73
74	/* and add the given bits */
75	namerec->data.wins_flags|=flags;
76
77	DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n",
78		 namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
79}
80
81/****************************************************************************
82 Return the general ID value and increase it if requested.
83*****************************************************************************/
84
85static void get_global_id_and_update(SMB_BIG_UINT *current_id, BOOL update)
86{
87	/*
88	 * it's kept as a static here, to prevent people from messing
89	 * with the value directly
90	 */
91
92	static SMB_BIG_UINT general_id = 1;
93
94	DEBUG(5,("get_global_id_and_update: updating version ID: %d\n", (int)general_id));
95
96	*current_id = general_id;
97
98	if (update)
99		general_id++;
100}
101
102/****************************************************************************
103 Possibly call the WINS hook external program when a WINS change is made.
104*****************************************************************************/
105
106static void wins_hook(const char *operation, struct name_record *namerec, int ttl)
107{
108	pstring command;
109	char *cmd = lp_wins_hook();
110	char *p, *namestr;
111	int i;
112
113	if (!cmd || !*cmd) return;
114
115	for (p=namerec->name.name; *p; p++) {
116		if (!(isalnum((int)*p) || strchr_m("._-",*p))) {
117			DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
118			return;
119		}
120	}
121
122	/* Use the name without the nametype (and scope) appended */
123
124	namestr = nmb_namestr(&namerec->name);
125	if ((p = strchr(namestr, '<')))
126		*p = 0;
127
128	p = command;
129	p += slprintf(p, sizeof(command)-1, "%s %s %s %02x %d",
130		      cmd,
131		      operation,
132		      namestr,
133		      namerec->name.name_type,
134		      ttl);
135
136	for (i=0;i<namerec->data.num_ips;i++) {
137		p += slprintf(p, sizeof(command) - (p-command) -1, " %s", inet_ntoa(namerec->data.ip[i]));
138	}
139
140	DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
141	smbrun(command, NULL);
142}
143
144
145/****************************************************************************
146Determine if this packet should be allocated to the WINS server.
147*****************************************************************************/
148
149BOOL packet_is_for_wins_server(struct packet_struct *packet)
150{
151	struct nmb_packet *nmb = &packet->packet.nmb;
152
153	/* Only unicast packets go to a WINS server. */
154	if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True)) {
155		DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
156		return False;
157	}
158
159	/* Check for node status requests. */
160	if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
161		return False;
162
163	switch(nmb->header.opcode) {
164		/*
165		 * A WINS server issues WACKS, not receives them.
166		 */
167		case NMB_WACK_OPCODE:
168			DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
169			return False;
170		/*
171		 * A WINS server only processes registration and
172		 * release requests, not responses.
173		 */
174		case NMB_NAME_REG_OPCODE:
175		case NMB_NAME_MULTIHOMED_REG_OPCODE:
176		case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
177		case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
178			if(nmb->header.response) {
179				DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
180				return False;
181			}
182			break;
183
184		case NMB_NAME_RELEASE_OPCODE:
185			if(nmb->header.response) {
186				DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
187				return False;
188			}
189			break;
190
191		/*
192		 * Only process unicast name queries with rd = 1.
193		 */
194		case NMB_NAME_QUERY_OPCODE:
195			if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired) {
196				DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
197				return False;
198			}
199			break;
200	}
201
202	return True;
203}
204
205/****************************************************************************
206Utility function to decide what ttl to give a register/refresh request.
207*****************************************************************************/
208
209static int get_ttl_from_packet(struct nmb_packet *nmb)
210{
211	int ttl = nmb->additional->ttl;
212
213	if(ttl < lp_min_wins_ttl() )
214		ttl = lp_min_wins_ttl();
215
216	if(ttl > lp_max_wins_ttl() )
217		ttl = lp_max_wins_ttl();
218
219	return ttl;
220}
221
222/****************************************************************************
223Load or create the WINS database.
224*****************************************************************************/
225
226BOOL initialise_wins(void)
227{
228	time_t time_now = time(NULL);
229	XFILE *fp;
230	pstring line;
231
232	if(!lp_we_are_a_wins_server())
233		return True;
234
235	add_samba_names_to_subnet(wins_server_subnet);
236
237	if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL) {
238		DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
239			WINS_LIST, strerror(errno) ));
240		return True;
241	}
242
243	while (!x_feof(fp)) {
244		pstring name_str, ip_str, ttl_str, nb_flags_str;
245		unsigned int num_ips;
246		pstring name;
247		struct in_addr *ip_list;
248		int type = 0;
249		int nb_flags;
250		int ttl;
251		const char *ptr;
252		char *p;
253		BOOL got_token;
254		BOOL was_ip;
255		int i;
256		unsigned int hash;
257		int version;
258
259		/* Read a line from the wins.dat file. Strips whitespace
260			from the beginning and end of the line.  */
261		if (!fgets_slash(line,sizeof(pstring),fp))
262			continue;
263
264		if (*line == '#')
265			continue;
266
267		if (strncmp(line,"VERSION ", 8) == 0) {
268			if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
269						version != WINS_VERSION) {
270				DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
271				x_fclose(fp);
272				return True;
273			}
274			continue;
275		}
276
277		ptr = line;
278
279		/*
280		 * Now we handle multiple IP addresses per name we need
281		 * to iterate over the line twice. The first time to
282		 * determine how many IP addresses there are, the second
283		 * time to actually parse them into the ip_list array.
284		 */
285
286		if (!next_token(&ptr,name_str,NULL,sizeof(name_str))) {
287			DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
288			continue;
289		}
290
291		if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str))) {
292			DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
293			continue;
294		}
295
296		/*
297		 * Determine the number of IP addresses per line.
298		 */
299		num_ips = 0;
300		do {
301			got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
302			was_ip = False;
303
304			if(got_token && strchr(ip_str, '.')) {
305				num_ips++;
306				was_ip = True;
307			}
308		} while( got_token && was_ip);
309
310		if(num_ips == 0) {
311			DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
312			continue;
313		}
314
315		if(!got_token) {
316			DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
317			continue;
318		}
319
320		/* Allocate the space for the ip_list. */
321		if((ip_list = SMB_MALLOC_ARRAY( struct in_addr, num_ips)) == NULL) {
322			DEBUG(0,("initialise_wins: Malloc fail !\n"));
323			return False;
324		}
325
326		/* Reset and re-parse the line. */
327		ptr = line;
328		next_token(&ptr,name_str,NULL,sizeof(name_str));
329		next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
330		for(i = 0; i < num_ips; i++) {
331			next_token(&ptr, ip_str, NULL, sizeof(ip_str));
332			ip_list[i] = *interpret_addr2(ip_str);
333		}
334		next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
335
336		/*
337		 * Deal with SELF or REGISTER name encoding. Default is REGISTER
338		 * for compatibility with old nmbds.
339		 */
340
341		if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') {
342			DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
343			SAFE_FREE(ip_list);
344			continue;
345		}
346
347		if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
348			nb_flags_str[strlen(nb_flags_str)-1] = '\0';
349
350		/* Netbios name. # divides the name from the type (hex): netbios#xx */
351		pstrcpy(name,name_str);
352
353		if((p = strchr(name,'#')) != NULL) {
354			*p = 0;
355			sscanf(p+1,"%x",&type);
356		}
357
358		/* Decode the netbios flags (hex) and the time-to-live (in seconds). */
359		sscanf(nb_flags_str,"%x",&nb_flags);
360		sscanf(ttl_str,"%d",&ttl);
361
362		/* add all entries that have 60 seconds or more to live */
363		if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
364			if(ttl != PERMANENT_TTL)
365				ttl -= time_now;
366
367			DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
368				name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
369
370			(void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
371					ttl, REGISTER_NAME, num_ips, ip_list );
372		} else {
373			DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
374				name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
375		}
376
377		SAFE_FREE(ip_list);
378	}
379
380	x_fclose(fp);
381	return True;
382}
383
384/****************************************************************************
385Send a WINS WACK (Wait ACKnowledgement) response.
386**************************************************************************/
387
388static void send_wins_wack_response(int ttl, struct packet_struct *p)
389{
390	struct nmb_packet *nmb = &p->packet.nmb;
391	unsigned char rdata[2];
392
393	rdata[0] = rdata[1] = 0;
394
395	/* Taken from nmblib.c - we need to send back almost
396		identical bytes from the requesting packet header. */
397
398	rdata[0] = (nmb->header.opcode & 0xF) << 3;
399	if (nmb->header.nm_flags.authoritative && nmb->header.response)
400		rdata[0] |= 0x4;
401	if (nmb->header.nm_flags.trunc)
402		rdata[0] |= 0x2;
403	if (nmb->header.nm_flags.recursion_desired)
404		rdata[0] |= 0x1;
405	if (nmb->header.nm_flags.recursion_available && nmb->header.response)
406		rdata[1] |= 0x80;
407	if (nmb->header.nm_flags.bcast)
408		rdata[1] |= 0x10;
409
410	reply_netbios_packet(p,                                /* Packet to reply to. */
411				0,                             /* Result code. */
412				NMB_WAIT_ACK,                  /* nmbd type code. */
413				NMB_WACK_OPCODE,               /* opcode. */
414				ttl,                           /* ttl. */
415				(char *)rdata,                 /* data to send. */
416				2);                            /* data length. */
417}
418
419/****************************************************************************
420Send a WINS name registration response.
421**************************************************************************/
422
423static void send_wins_name_registration_response(int rcode, int ttl, struct packet_struct *p)
424{
425	struct nmb_packet *nmb = &p->packet.nmb;
426	char rdata[6];
427
428	memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
429
430	reply_netbios_packet(p,                                /* Packet to reply to. */
431				rcode,                         /* Result code. */
432				WINS_REG,                      /* nmbd type code. */
433				NMB_NAME_REG_OPCODE,           /* opcode. */
434				ttl,                           /* ttl. */
435				rdata,                         /* data to send. */
436				6);                            /* data length. */
437}
438
439/***********************************************************************
440 Deal with a name refresh request to a WINS server.
441************************************************************************/
442
443void wins_process_name_refresh_request( struct subnet_record *subrec,
444                                        struct packet_struct *p )
445{
446	struct nmb_packet *nmb = &p->packet.nmb;
447	struct nmb_name *question = &nmb->question.question_name;
448	BOOL bcast = nmb->header.nm_flags.bcast;
449	uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
450	BOOL group = (nb_flags & NB_GROUP) ? True : False;
451	struct name_record *namerec = NULL;
452	int ttl = get_ttl_from_packet(nmb);
453	struct in_addr from_ip;
454	struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
455
456	putip( (char *)&from_ip, &nmb->additional->rdata[2] );
457
458	if(bcast) {
459		/*
460		 * We should only get unicast name refresh packets here.
461		 * Anyone trying to refresh broadcast should not be going
462		 * to a WINS server.  Log an error here.
463		 */
464		if( DEBUGLVL( 0 ) ) {
465			dbgtext( "wins_process_name_refresh_request: " );
466			dbgtext( "Broadcast name refresh request received " );
467			dbgtext( "for name %s ", nmb_namestr(question) );
468			dbgtext( "from IP %s ", inet_ntoa(from_ip) );
469			dbgtext( "on subnet %s.  ", subrec->subnet_name );
470			dbgtext( "Error - Broadcasts should not be sent " );
471			dbgtext( "to a WINS server\n" );
472		}
473		return;
474	}
475
476	if( DEBUGLVL( 3 ) ) {
477		dbgtext( "wins_process_name_refresh_request: " );
478		dbgtext( "Name refresh for name %s IP %s\n",
479			 nmb_namestr(question), inet_ntoa(from_ip) );
480	}
481
482	/*
483	 * See if the name already exists.
484	 * If not, handle it as a name registration and return.
485	 */
486	namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
487
488	/*
489	 * If this is a refresh request and the name doesn't exist then
490	 * treat it like a registration request. This allows us to recover
491	 * from errors (tridge)
492	 */
493	if(namerec == NULL) {
494		if( DEBUGLVL( 3 ) ) {
495			dbgtext( "wins_process_name_refresh_request: " );
496			dbgtext( "Name refresh for name %s ",
497				 nmb_namestr( question ) );
498			dbgtext( "and the name does not exist.  Treating " );
499			dbgtext( "as registration.\n" );
500		}
501		wins_process_name_registration_request(subrec,p);
502		return;
503	}
504
505	/*
506	 * if the name is present but not active, simply remove it
507	 * and treat the refresh request as a registration & return.
508	 */
509	if (namerec != NULL && !WINS_STATE_ACTIVE(namerec)) {
510		if( DEBUGLVL( 5 ) ) {
511			dbgtext( "wins_process_name_refresh_request: " );
512			dbgtext( "Name (%s) in WINS ", nmb_namestr(question) );
513			dbgtext( "was not active - removing it.\n" );
514		}
515		remove_name_from_namelist( subrec, namerec );
516		namerec = NULL;
517		wins_process_name_registration_request( subrec, p );
518		return;
519	}
520
521	/*
522	 * Check that the group bits for the refreshing name and the
523	 * name in our database match.  If not, refuse the refresh.
524	 * [crh:  Why RFS_ERR instead of ACT_ERR? Is this what MS does?]
525	 */
526	if( (namerec != NULL) &&
527	    ( (group && !NAME_GROUP(namerec))
528	   || (!group && NAME_GROUP(namerec)) ) ) {
529		if( DEBUGLVL( 3 ) ) {
530			dbgtext( "wins_process_name_refresh_request: " );
531			dbgtext( "Name %s ", nmb_namestr(question) );
532			dbgtext( "group bit = %s does not match ",
533				 group ? "True" : "False" );
534			dbgtext( "group bit in WINS for this name.\n" );
535		}
536		send_wins_name_registration_response(RFS_ERR, 0, p);
537		return;
538	}
539
540	/*
541	 * For a unique name check that the person refreshing the name is
542	 * one of the registered IP addresses. If not - fail the refresh.
543	 * Do the same for group names with a type of 0x1c.
544	 * Just return success for unique 0x1d refreshes. For normal group
545	 * names update the ttl and return success.
546	 */
547	if( (!group || (group && (question->name_type == 0x1c)))
548	 && find_ip_in_name_record(namerec, from_ip) ) {
549		/*
550		 * Update the ttl.
551		 */
552		update_name_ttl(namerec, ttl);
553
554		/*
555		 * if the record is a replica:
556		 * we take ownership and update the version ID.
557		 */
558		if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
559			update_wins_owner(namerec, our_fake_ip);
560			get_global_id_and_update(&namerec->data.id, True);
561		}
562
563		send_wins_name_registration_response(0, ttl, p);
564		wins_hook("refresh", namerec, ttl);
565		return;
566	} else if((group && (question->name_type == 0x1c))) {
567		/*
568		 * Added by crh for bug #1079.
569		 * Fix from Bert Driehuis
570		 */
571		if( DEBUGLVL( 3 ) ) {
572			dbgtext( "wins_process_name_refresh_request: " );
573			dbgtext( "Name refresh for name %s, ",
574				 nmb_namestr(question) );
575			dbgtext( "but IP address %s ", inet_ntoa(from_ip) );
576			dbgtext( "is not yet associated with " );
577			dbgtext( "that name. Treating as registration.\n" );
578		}
579		wins_process_name_registration_request(subrec,p);
580		return;
581	} else if(group) {
582		/*
583		 * Normal groups are all registered with an IP address of
584		 * 255.255.255.255  so we can't search for the IP address.
585	 	 */
586		update_name_ttl(namerec, ttl);
587		send_wins_name_registration_response(0, ttl, p);
588		return;
589	} else if(!group && (question->name_type == 0x1d)) {
590		/*
591		 * Special name type - just pretend the refresh succeeded.
592		 */
593		send_wins_name_registration_response(0, ttl, p);
594		return;
595	} else {
596		/*
597		 * Fail the refresh.
598		 */
599		if( DEBUGLVL( 3 ) ) {
600			dbgtext( "wins_process_name_refresh_request: " );
601			dbgtext( "Name refresh for name %s with IP %s ",
602				 nmb_namestr(question), inet_ntoa(from_ip) );
603			dbgtext( "and is IP is not known to the name.\n" );
604		}
605		send_wins_name_registration_response(RFS_ERR, 0, p);
606		return;
607	}
608}
609
610/***********************************************************************
611 Deal with a name registration request query success to a client that
612 owned the name.
613
614 We have a locked pointer to the original packet stashed away in the
615 userdata pointer. The success here is actually a failure as it means
616 the client we queried wants to keep the name, so we must return
617 a registration failure to the original requestor.
618************************************************************************/
619
620static void wins_register_query_success(struct subnet_record *subrec,
621                                             struct userdata_struct *userdata,
622                                             struct nmb_name *question_name,
623                                             struct in_addr ip,
624                                             struct res_rec *answers)
625{
626	struct packet_struct *orig_reg_packet;
627
628	memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
629
630	DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
631name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
632
633	send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
634
635	orig_reg_packet->locked = False;
636	free_packet(orig_reg_packet);
637}
638
639/***********************************************************************
640 Deal with a name registration request query failure to a client that
641 owned the name.
642
643 We have a locked pointer to the original packet stashed away in the
644 userdata pointer. The failure here is actually a success as it means
645 the client we queried didn't want to keep the name, so we can remove
646 the old name record and then successfully add the new name.
647************************************************************************/
648
649static void wins_register_query_fail(struct subnet_record *subrec,
650                                          struct response_record *rrec,
651                                          struct nmb_name *question_name,
652                                          int rcode)
653{
654	struct userdata_struct *userdata = rrec->userdata;
655	struct packet_struct *orig_reg_packet;
656	struct name_record *namerec = NULL;
657
658	memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
659
660	/*
661	 * We want to just add the name, as we now know the original owner
662	 * didn't want it. But we can't just do that as an arbitary
663	 * amount of time may have taken place between the name query
664	 * request and this timeout/error response. So we check that
665	 * the name still exists and is in the same state - if so
666	 * we remove it and call wins_process_name_registration_request()
667	 * as we know it will do the right thing now.
668	 */
669
670	namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
671
672	if( (namerec != NULL) && (namerec->data.source == REGISTER_NAME) && ip_equal(rrec->packet->ip, *namerec->data.ip) ) {
673		remove_name_from_namelist( subrec, namerec);
674		namerec = NULL;
675	}
676
677	if(namerec == NULL)
678		wins_process_name_registration_request(subrec, orig_reg_packet);
679	else
680		DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
681querying for name %s in order to replace it and this reply.\n", nmb_namestr(question_name) ));
682
683	orig_reg_packet->locked = False;
684	free_packet(orig_reg_packet);
685}
686
687/***********************************************************************
688 Deal with a name registration request to a WINS server.
689
690 Use the following pseudocode :
691
692 registering_group
693     |
694     |
695     +--------name exists
696     |                  |
697     |                  |
698     |                  +--- existing name is group
699     |                  |                      |
700     |                  |                      |
701     |                  |                      +--- add name (return).
702     |                  |
703     |                  |
704     |                  +--- exiting name is unique
705     |                                         |
706     |                                         |
707     |                                         +--- query existing owner (return).
708     |
709     |
710     +--------name doesn't exist
711                        |
712                        |
713                        +--- add name (return).
714
715 registering_unique
716     |
717     |
718     +--------name exists
719     |                  |
720     |                  |
721     |                  +--- existing name is group
722     |                  |                      |
723     |                  |                      |
724     |                  |                      +--- fail add (return).
725     |                  |
726     |                  |
727     |                  +--- exiting name is unique
728     |                                         |
729     |                                         |
730     |                                         +--- query existing owner (return).
731     |
732     |
733     +--------name doesn't exist
734                        |
735                        |
736                        +--- add name (return).
737
738 As can be seen from the above, the two cases may be collapsed onto each
739 other with the exception of the case where the name already exists and
740 is a group name. This case we handle with an if statement.
741
742************************************************************************/
743
744void wins_process_name_registration_request(struct subnet_record *subrec,
745                                            struct packet_struct *p)
746{
747	unstring name;
748	struct nmb_packet *nmb = &p->packet.nmb;
749	struct nmb_name *question = &nmb->question.question_name;
750	BOOL bcast = nmb->header.nm_flags.bcast;
751	uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
752	int ttl = get_ttl_from_packet(nmb);
753	struct name_record *namerec = NULL;
754	struct in_addr from_ip;
755	BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
756	struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
757
758	putip((char *)&from_ip,&nmb->additional->rdata[2]);
759
760	if(bcast) {
761		/*
762		 * We should only get unicast name registration packets here.
763		 * Anyone trying to register broadcast should not be going to a WINS
764		 * server. Log an error here.
765		 */
766
767		DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
768received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
769			nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
770		return;
771	}
772
773	DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
774IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
775
776	/*
777	 * See if the name already exists.
778	 */
779
780	namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
781
782	/*
783	 * if the record exists but NOT in active state,
784	 * consider it dead.
785	 */
786	if ( (namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
787		DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
788not active - removing it.\n", nmb_namestr(question) ));
789		remove_name_from_namelist( subrec, namerec );
790		namerec = NULL;
791	}
792
793	/*
794	 * Deal with the case where the name found was a dns entry.
795	 * Remove it as we now have a NetBIOS client registering the
796	 * name.
797	 */
798
799	if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
800		DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
801a dns lookup - removing it.\n", nmb_namestr(question) ));
802		remove_name_from_namelist( subrec, namerec );
803		namerec = NULL;
804	}
805
806	/*
807	 * Reject if the name exists and is not a REGISTER_NAME.
808	 * (ie. Don't allow any static names to be overwritten.
809	 */
810
811	if((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) {
812		DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
813to register name %s. Name already exists in WINS with source type %d.\n",
814			nmb_namestr(question), namerec->data.source ));
815		send_wins_name_registration_response(RFS_ERR, 0, p);
816		return;
817	}
818
819	/*
820	 * Special policy decisions based on MS documentation.
821	 * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
822	 * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
823	 */
824
825	/*
826	 * A group name is always added as the local broadcast address, except
827	 * for group names ending in 0x1c.
828	 * Group names with type 0x1c are registered with individual IP addresses.
829	 */
830
831	if(registering_group_name && (question->name_type != 0x1c))
832		from_ip = *interpret_addr2("255.255.255.255");
833
834	/*
835	 * Ignore all attempts to register a unique 0x1d name, although return success.
836	 */
837
838	if(!registering_group_name && (question->name_type == 0x1d)) {
839		DEBUG(3,("wins_process_name_registration_request: Ignoring request \
840to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
841		send_wins_name_registration_response(0, ttl, p);
842		return;
843	}
844
845	/*
846	 * Next two cases are the 'if statement' mentioned above.
847	 */
848
849	if((namerec != NULL) && NAME_GROUP(namerec)) {
850		if(registering_group_name) {
851			/*
852			 * If we are adding a group name, the name exists and is also a group entry just add this
853			 * IP address to it and update the ttl.
854			 */
855
856			DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
857				inet_ntoa(from_ip), nmb_namestr(question) ));
858
859			/*
860			 * Check the ip address is not already in the group.
861			 */
862
863			if(!find_ip_in_name_record(namerec, from_ip)) {
864				add_ip_to_name_record(namerec, from_ip);
865				/* we need to update the record for replication */
866				get_global_id_and_update(&namerec->data.id, True);
867
868				/*
869				 * if the record is a replica, we must change
870				 * the wins owner to us to make the replication updates
871				 * it on the other wins servers.
872				 * And when the partner will receive this record,
873				 * it will update its own record.
874				 */
875
876				update_wins_owner(namerec, our_fake_ip);
877			}
878			update_name_ttl(namerec, ttl);
879			send_wins_name_registration_response(0, ttl, p);
880			return;
881		} else {
882
883			/*
884			 * If we are adding a unique name, the name exists in the WINS db
885			 * and is a group name then reject the registration.
886			 *
887			 * explanation: groups have a higher priority than unique names.
888			 */
889
890			DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
891already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
892			send_wins_name_registration_response(RFS_ERR, 0, p);
893			return;
894		}
895	}
896
897	/*
898	 * From here on down we know that if the name exists in the WINS db it is
899	 * a unique name, not a group name.
900	 */
901
902	/*
903	 * If the name exists and is one of our names then check the
904	 * registering IP address. If it's not one of ours then automatically
905	 * reject without doing the query - we know we will reject it.
906	 */
907
908	if ( namerec != NULL )
909		pull_ascii_nstring(name, sizeof(name), namerec->name.name);
910
911	if( is_myname(name) ) {
912		if(!ismyip(from_ip)) {
913			DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
914is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
915			send_wins_name_registration_response(RFS_ERR, 0, p);
916			return;
917		} else {
918			/*
919			 * It's one of our names and one of our IP's - update the ttl.
920			 */
921			update_name_ttl(namerec, ttl);
922			send_wins_name_registration_response(0, ttl, p);
923			wins_hook("refresh", namerec, ttl);
924			return;
925		}
926	}
927
928	/*
929	 * If the name exists and it is a unique registration and the registering IP
930	 * is the same as the (single) already registered IP then just update the ttl.
931	 *
932	 * But not if the record is an active replica. IF it's a replica, it means it can be
933	 * the same client which has moved and not yet expired. So we don't update
934	 * the ttl in this case and go beyond to do a WACK and query the old client
935	 */
936
937	if( !registering_group_name
938			&& (namerec != NULL)
939			&& (namerec->data.num_ips == 1)
940			&& ip_equal( namerec->data.ip[0], from_ip )
941			&& ip_equal(namerec->data.wins_ip, our_fake_ip) ) {
942		update_name_ttl( namerec, ttl );
943		send_wins_name_registration_response( 0, ttl, p );
944		wins_hook("refresh", namerec, ttl);
945		return;
946	}
947
948	/*
949	 * Finally if the name exists do a query to the registering machine
950	 * to see if they still claim to have the name.
951	 */
952
953	if( namerec != NULL ) {
954		long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
955		struct userdata_struct *userdata = (struct userdata_struct *)ud;
956
957		/*
958		 * First send a WACK to the registering machine.
959		 */
960
961		send_wins_wack_response(60, p);
962
963		/*
964		 * When the reply comes back we need the original packet.
965		 * Lock this so it won't be freed and then put it into
966		 * the userdata structure.
967		 */
968
969		p->locked = True;
970
971		userdata = (struct userdata_struct *)ud;
972
973		userdata->copy_fn = NULL;
974		userdata->free_fn = NULL;
975		userdata->userdata_len = sizeof(struct packet_struct *);
976		memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
977
978		/*
979		 * Use the new call to send a query directly to an IP address.
980		 * This sends the query directly to the IP address, and ensures
981		 * the recursion desired flag is not set (you were right Luke :-).
982		 * This function should *only* be called from the WINS server
983		 * code. JRA.
984		 */
985
986		pull_ascii_nstring(name, sizeof(name), question->name);
987		query_name_from_wins_server( *namerec->data.ip,
988				name,
989				question->name_type,
990				wins_register_query_success,
991				wins_register_query_fail,
992				userdata );
993		return;
994	}
995
996	/*
997	 * Name did not exist - add it.
998	 */
999
1000	pull_ascii_nstring(name, sizeof(name), question->name);
1001	add_name_to_subnet( subrec, name, question->name_type,
1002			nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1003
1004	if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1005		get_global_id_and_update(&namerec->data.id, True);
1006		update_wins_owner(namerec, our_fake_ip);
1007		update_wins_flag(namerec, WINS_ACTIVE);
1008		wins_hook("add", namerec, ttl);
1009	}
1010
1011	send_wins_name_registration_response(0, ttl, p);
1012}
1013
1014/***********************************************************************
1015 Deal with a mutihomed name query success to the machine that
1016 requested the multihomed name registration.
1017
1018 We have a locked pointer to the original packet stashed away in the
1019 userdata pointer.
1020************************************************************************/
1021
1022static void wins_multihomed_register_query_success(struct subnet_record *subrec,
1023                                             struct userdata_struct *userdata,
1024                                             struct nmb_name *question_name,
1025                                             struct in_addr ip,
1026                                             struct res_rec *answers)
1027{
1028	struct packet_struct *orig_reg_packet;
1029	struct nmb_packet *nmb;
1030	struct name_record *namerec = NULL;
1031	struct in_addr from_ip;
1032	int ttl;
1033	struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
1034
1035	memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1036
1037	nmb = &orig_reg_packet->packet.nmb;
1038
1039	putip((char *)&from_ip,&nmb->additional->rdata[2]);
1040	ttl = get_ttl_from_packet(nmb);
1041
1042	/*
1043	 * We want to just add the new IP, as we now know the requesting
1044	 * machine claims to own it. But we can't just do that as an arbitary
1045	 * amount of time may have taken place between the name query
1046	 * request and this response. So we check that
1047	 * the name still exists and is in the same state - if so
1048	 * we just add the extra IP and update the ttl.
1049	 */
1050
1051	namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
1052
1053	if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) ) {
1054		DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
1055a subsequent IP address.\n", nmb_namestr(question_name) ));
1056		send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1057
1058		orig_reg_packet->locked = False;
1059		free_packet(orig_reg_packet);
1060
1061		return;
1062	}
1063
1064	if(!find_ip_in_name_record(namerec, from_ip))
1065		add_ip_to_name_record(namerec, from_ip);
1066
1067	get_global_id_and_update(&namerec->data.id, True);
1068	update_wins_owner(namerec, our_fake_ip);
1069	update_wins_flag(namerec, WINS_ACTIVE);
1070	update_name_ttl(namerec, ttl);
1071	send_wins_name_registration_response(0, ttl, orig_reg_packet);
1072	wins_hook("add", namerec, ttl);
1073
1074	orig_reg_packet->locked = False;
1075	free_packet(orig_reg_packet);
1076}
1077
1078/***********************************************************************
1079 Deal with a name registration request query failure to a client that
1080 owned the name.
1081
1082 We have a locked pointer to the original packet stashed away in the
1083 userdata pointer.
1084************************************************************************/
1085
1086static void wins_multihomed_register_query_fail(struct subnet_record *subrec,
1087                                          struct response_record *rrec,
1088                                          struct nmb_name *question_name,
1089                                          int rcode)
1090{
1091	struct userdata_struct *userdata = rrec->userdata;
1092	struct packet_struct *orig_reg_packet;
1093
1094	memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
1095
1096	DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
1097query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
1098	send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
1099
1100	orig_reg_packet->locked = False;
1101	free_packet(orig_reg_packet);
1102	return;
1103}
1104
1105/***********************************************************************
1106 Deal with a multihomed name registration request to a WINS server.
1107 These cannot be group name registrations.
1108***********************************************************************/
1109
1110void wins_process_multihomed_name_registration_request( struct subnet_record *subrec,
1111                                                        struct packet_struct *p)
1112{
1113	struct nmb_packet *nmb = &p->packet.nmb;
1114	struct nmb_name *question = &nmb->question.question_name;
1115	BOOL bcast = nmb->header.nm_flags.bcast;
1116	uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1117	int ttl = get_ttl_from_packet(nmb);
1118	struct name_record *namerec = NULL;
1119	struct in_addr from_ip;
1120	BOOL group = (nb_flags & NB_GROUP) ? True : False;
1121	struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
1122	unstring qname;
1123
1124	putip((char *)&from_ip,&nmb->additional->rdata[2]);
1125
1126	if(bcast) {
1127		/*
1128		 * We should only get unicast name registration packets here.
1129		 * Anyone trying to register broadcast should not be going to a WINS
1130		 * server. Log an error here.
1131		 */
1132
1133		DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
1134received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1135			nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1136		return;
1137	}
1138
1139	/*
1140	 * Only unique names should be registered multihomed.
1141	 */
1142
1143	if(group) {
1144		DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
1145received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
1146			nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1147		return;
1148	}
1149
1150	DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
1151IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
1152
1153	/*
1154	 * Deal with policy regarding 0x1d names.
1155	 */
1156
1157	if(question->name_type == 0x1d) {
1158		DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
1159to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1160		send_wins_name_registration_response(0, ttl, p);
1161		return;
1162	}
1163
1164	/*
1165	 * See if the name already exists.
1166	 */
1167
1168	namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1169
1170	/*
1171	 * if the record exists but NOT in active state,
1172	 * consider it dead.
1173	 */
1174
1175	if ((namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
1176		DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was not active - removing it.\n", nmb_namestr(question)));
1177		remove_name_from_namelist(subrec, namerec);
1178		namerec = NULL;
1179	}
1180
1181	/*
1182	 * Deal with the case where the name found was a dns entry.
1183	 * Remove it as we now have a NetBIOS client registering the
1184	 * name.
1185	 */
1186
1187	if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
1188		DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
1189- removing it.\n", nmb_namestr(question) ));
1190		remove_name_from_namelist( subrec, namerec);
1191		namerec = NULL;
1192	}
1193
1194	/*
1195	 * Reject if the name exists and is not a REGISTER_NAME.
1196	 * (ie. Don't allow any static names to be overwritten.
1197	 */
1198
1199	if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) ) {
1200		DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
1201to register name %s. Name already exists in WINS with source type %d.\n",
1202			nmb_namestr(question), namerec->data.source ));
1203		send_wins_name_registration_response(RFS_ERR, 0, p);
1204		return;
1205	}
1206
1207	/*
1208	 * Reject if the name exists and is a GROUP name and is active.
1209	 */
1210
1211	if((namerec != NULL) && NAME_GROUP(namerec) && WINS_STATE_ACTIVE(namerec)) {
1212		DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1213already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
1214		send_wins_name_registration_response(RFS_ERR, 0, p);
1215		return;
1216	}
1217
1218	/*
1219	 * From here on down we know that if the name exists in the WINS db it is
1220	 * a unique name, not a group name.
1221	 */
1222
1223	/*
1224	 * If the name exists and is one of our names then check the
1225	 * registering IP address. If it's not one of ours then automatically
1226	 * reject without doing the query - we know we will reject it.
1227	 */
1228
1229	if((namerec != NULL) && (is_myname(namerec->name.name)) ) {
1230		if(!ismyip(from_ip)) {
1231			DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
1232is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
1233			send_wins_name_registration_response(RFS_ERR, 0, p);
1234			return;
1235		} else {
1236			/*
1237			 * It's one of our names and one of our IP's. Ensure the IP is in the record and
1238			 *  update the ttl. Update the version ID to force replication.
1239			 */
1240			if(!find_ip_in_name_record(namerec, from_ip)) {
1241				get_global_id_and_update(&namerec->data.id, True);
1242				update_wins_owner(namerec, our_fake_ip);
1243				update_wins_flag(namerec, WINS_ACTIVE);
1244
1245				add_ip_to_name_record(namerec, from_ip);
1246				wins_hook("add", namerec, ttl);
1247			} else {
1248				wins_hook("refresh", namerec, ttl);
1249			}
1250
1251			update_name_ttl(namerec, ttl);
1252			send_wins_name_registration_response(0, ttl, p);
1253			return;
1254		}
1255	}
1256
1257	/*
1258	 * If the name exists and is active, check if the IP address is already registered
1259	 * to that name. If so then update the ttl and reply success.
1260	 */
1261
1262	if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip) && WINS_STATE_ACTIVE(namerec)) {
1263		update_name_ttl(namerec, ttl);
1264
1265		/*
1266		 * If it's a replica, we need to become the wins owner
1267		 * to force the replication
1268		 */
1269		if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
1270			get_global_id_and_update(&namerec->data.id, True);
1271			update_wins_owner(namerec, our_fake_ip);
1272			update_wins_flag(namerec, WINS_ACTIVE);
1273		}
1274
1275		send_wins_name_registration_response(0, ttl, p);
1276		wins_hook("refresh", namerec, ttl);
1277		return;
1278	}
1279
1280	/*
1281	 * If the name exists do a query to the owner
1282	 * to see if they still want the name.
1283	 */
1284
1285	if(namerec != NULL) {
1286		long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
1287		struct userdata_struct *userdata = (struct userdata_struct *)ud;
1288
1289		/*
1290		 * First send a WACK to the registering machine.
1291		 */
1292
1293		send_wins_wack_response(60, p);
1294
1295		/*
1296		 * When the reply comes back we need the original packet.
1297		 * Lock this so it won't be freed and then put it into
1298		 * the userdata structure.
1299		 */
1300
1301		p->locked = True;
1302
1303		userdata = (struct userdata_struct *)ud;
1304
1305		userdata->copy_fn = NULL;
1306		userdata->free_fn = NULL;
1307		userdata->userdata_len = sizeof(struct packet_struct *);
1308		memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
1309
1310		/*
1311		 * Use the new call to send a query directly to an IP address.
1312		 * This sends the query directly to the IP address, and ensures
1313		 * the recursion desired flag is not set (you were right Luke :-).
1314		 * This function should *only* be called from the WINS server
1315		 * code. JRA.
1316		 *
1317		 * Note that this packet is sent to the current owner of the name,
1318		 * not the person who sent the packet
1319		 */
1320
1321		pull_ascii_nstring( qname, sizeof(qname), question->name);
1322		query_name_from_wins_server( namerec->data.ip[0],
1323				qname,
1324				question->name_type,
1325				wins_multihomed_register_query_success,
1326				wins_multihomed_register_query_fail,
1327				userdata );
1328
1329		return;
1330	}
1331
1332	/*
1333	 * Name did not exist - add it.
1334	 */
1335
1336	pull_ascii_nstring( qname, sizeof(qname), question->name);
1337	add_name_to_subnet( subrec, qname, question->name_type,
1338			nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
1339
1340	if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
1341		get_global_id_and_update(&namerec->data.id, True);
1342		update_wins_owner(namerec, our_fake_ip);
1343		update_wins_flag(namerec, WINS_ACTIVE);
1344		wins_hook("add", namerec, ttl);
1345	}
1346
1347	send_wins_name_registration_response(0, ttl, p);
1348}
1349
1350/***********************************************************************
1351 Deal with the special name query for *<1b>.
1352***********************************************************************/
1353
1354static void process_wins_dmb_query_request(struct subnet_record *subrec,
1355                                           struct packet_struct *p)
1356{
1357	struct name_record *namerec = NULL;
1358	char *prdata;
1359	int num_ips;
1360
1361	/*
1362	 * Go through all the ACTIVE names in the WINS db looking for those
1363	 * ending in <1b>. Use this to calculate the number of IP
1364	 * addresses we need to return.
1365	 */
1366
1367	num_ips = 0;
1368	for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1369			namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
1370		if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b )
1371			num_ips += namerec->data.num_ips;
1372	}
1373
1374	if(num_ips == 0) {
1375		/*
1376		 * There are no 0x1b names registered. Return name query fail.
1377		 */
1378		send_wins_name_query_response(NAM_ERR, p, NULL);
1379		return;
1380	}
1381
1382	if((prdata = (char *)SMB_MALLOC( num_ips * 6 )) == NULL) {
1383		DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
1384		return;
1385	}
1386
1387	/*
1388	 * Go through all the names again in the WINS db looking for those
1389	 * ending in <1b>. Add their IP addresses into the list we will
1390	 * return.
1391	 */
1392
1393	num_ips = 0;
1394	for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
1395			namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
1396		if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
1397			int i;
1398			for(i = 0; i < namerec->data.num_ips; i++) {
1399				set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
1400				putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
1401				num_ips++;
1402			}
1403		}
1404	}
1405
1406	/*
1407	 * Send back the reply containing the IP list.
1408	 */
1409
1410	reply_netbios_packet(p,                                /* Packet to reply to. */
1411				0,                             /* Result code. */
1412				WINS_QUERY,                    /* nmbd type code. */
1413				NMB_NAME_QUERY_OPCODE,         /* opcode. */
1414				lp_min_wins_ttl(),             /* ttl. */
1415				prdata,                        /* data to send. */
1416				num_ips*6);                    /* data length. */
1417
1418	SAFE_FREE(prdata);
1419}
1420
1421/****************************************************************************
1422Send a WINS name query response.
1423**************************************************************************/
1424
1425void send_wins_name_query_response(int rcode, struct packet_struct *p,
1426                                          struct name_record *namerec)
1427{
1428	char rdata[6];
1429	char *prdata = rdata;
1430	int reply_data_len = 0;
1431	int ttl = 0;
1432	int i;
1433
1434	memset(rdata,'\0',6);
1435
1436	if(rcode == 0) {
1437		ttl = (namerec->data.death_time != PERMANENT_TTL) ?  namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
1438
1439		/* Copy all known ip addresses into the return data. */
1440		/* Optimise for the common case of one IP address so we don't need a malloc. */
1441
1442		if( namerec->data.num_ips == 1 ) {
1443			prdata = rdata;
1444		} else {
1445			if((prdata = (char *)SMB_MALLOC( namerec->data.num_ips * 6 )) == NULL) {
1446				DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
1447				return;
1448			}
1449		}
1450
1451		for(i = 0; i < namerec->data.num_ips; i++) {
1452			set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
1453			putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
1454		}
1455
1456		sort_query_replies(prdata, i, p->ip);
1457		reply_data_len = namerec->data.num_ips * 6;
1458	}
1459
1460	reply_netbios_packet(p,                                /* Packet to reply to. */
1461				rcode,                         /* Result code. */
1462				WINS_QUERY,                    /* nmbd type code. */
1463				NMB_NAME_QUERY_OPCODE,         /* opcode. */
1464				ttl,                           /* ttl. */
1465				prdata,                        /* data to send. */
1466				reply_data_len);               /* data length. */
1467
1468	if(prdata != rdata)
1469		SAFE_FREE(prdata);
1470}
1471
1472/***********************************************************************
1473 Deal with a name query.
1474***********************************************************************/
1475
1476void wins_process_name_query_request(struct subnet_record *subrec,
1477                                     struct packet_struct *p)
1478{
1479	struct nmb_packet *nmb = &p->packet.nmb;
1480	struct nmb_name *question = &nmb->question.question_name;
1481	struct name_record *namerec = NULL;
1482	unstring qname;
1483
1484	DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n",
1485		nmb_namestr(question), inet_ntoa(p->ip) ));
1486
1487	/*
1488	 * Special name code. If the queried name is *<1b> then search
1489	 * the entire WINS database and return a list of all the IP addresses
1490	 * registered to any <1b> name. This is to allow domain master browsers
1491	 * to discover other domains that may not have a presence on their subnet.
1492	 */
1493
1494	pull_ascii_nstring(qname, sizeof(qname), question->name);
1495	if(strequal( qname, "*") && (question->name_type == 0x1b)) {
1496		process_wins_dmb_query_request( subrec, p);
1497		return;
1498	}
1499
1500	namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1501
1502	if(namerec != NULL) {
1503		/*
1504		 * If the name is not anymore in active state then reply not found.
1505		 * it's fair even if we keep it in the cache for days.
1506		 */
1507		if (!WINS_STATE_ACTIVE(namerec)) {
1508			DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1509				nmb_namestr(question) ));
1510			send_wins_name_query_response(NAM_ERR, p, namerec);
1511			return;
1512		}
1513
1514		/*
1515		 * If it's a DNSFAIL_NAME then reply name not found.
1516		 */
1517
1518		if( namerec->data.source == DNSFAIL_NAME ) {
1519			DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
1520				nmb_namestr(question) ));
1521			send_wins_name_query_response(NAM_ERR, p, namerec);
1522			return;
1523		}
1524
1525		/*
1526		 * If the name has expired then reply name not found.
1527		 */
1528
1529		if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < p->timestamp) ) {
1530			DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
1531					nmb_namestr(question) ));
1532			send_wins_name_query_response(NAM_ERR, p, namerec);
1533			return;
1534		}
1535
1536		DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
1537				nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
1538
1539		send_wins_name_query_response(0, p, namerec);
1540		return;
1541	}
1542
1543	/*
1544	 * Name not found in WINS - try a dns query if it's a 0x20 name.
1545	 */
1546
1547	if(lp_dns_proxy() && ((question->name_type == 0x20) || question->name_type == 0)) {
1548		DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
1549				nmb_namestr(question) ));
1550
1551		queue_dns_query(p, question, &namerec);
1552		return;
1553	}
1554
1555	/*
1556	 * Name not found - return error.
1557	 */
1558
1559	send_wins_name_query_response(NAM_ERR, p, NULL);
1560}
1561
1562/****************************************************************************
1563Send a WINS name release response.
1564**************************************************************************/
1565
1566static void send_wins_name_release_response(int rcode, struct packet_struct *p)
1567{
1568	struct nmb_packet *nmb = &p->packet.nmb;
1569	char rdata[6];
1570
1571	memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
1572
1573	reply_netbios_packet(p,                               /* Packet to reply to. */
1574				rcode,                        /* Result code. */
1575				NMB_REL,                      /* nmbd type code. */
1576				NMB_NAME_RELEASE_OPCODE,      /* opcode. */
1577				0,                            /* ttl. */
1578				rdata,                        /* data to send. */
1579				6);                           /* data length. */
1580}
1581
1582/***********************************************************************
1583 Deal with a name release.
1584***********************************************************************/
1585
1586void wins_process_name_release_request(struct subnet_record *subrec,
1587                                       struct packet_struct *p)
1588{
1589	struct nmb_packet *nmb = &p->packet.nmb;
1590	struct nmb_name *question = &nmb->question.question_name;
1591	BOOL bcast = nmb->header.nm_flags.bcast;
1592	uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
1593	struct name_record *namerec = NULL;
1594	struct in_addr from_ip;
1595	BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
1596
1597	putip((char *)&from_ip,&nmb->additional->rdata[2]);
1598
1599	if(bcast) {
1600		/*
1601		 * We should only get unicast name registration packets here.
1602		 * Anyone trying to register broadcast should not be going to a WINS
1603		 * server. Log an error here.
1604		 */
1605
1606		DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
1607received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
1608			nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
1609		return;
1610	}
1611
1612	DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
1613IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
1614
1615	/*
1616	 * Deal with policy regarding 0x1d names.
1617	 */
1618
1619	if(!releasing_group_name && (question->name_type == 0x1d)) {
1620		DEBUG(3,("wins_process_name_release_request: Ignoring request \
1621to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
1622		send_wins_name_release_response(0, p);
1623		return;
1624	}
1625
1626	/*
1627	 * See if the name already exists.
1628	 */
1629
1630	namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
1631
1632	if( (namerec == NULL) || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) ) {
1633		send_wins_name_release_response(NAM_ERR, p);
1634		return;
1635	}
1636
1637	/*
1638	 * Check that the sending machine has permission to release this name.
1639	 * If it's a group name not ending in 0x1c then just say yes and let
1640	 * the group time out.
1641	 */
1642
1643	if(releasing_group_name && (question->name_type != 0x1c)) {
1644		send_wins_name_release_response(0, p);
1645		return;
1646	}
1647
1648	/*
1649	 * Check that the releasing node is on the list of IP addresses
1650	 * for this name. Disallow the release if not.
1651	 */
1652
1653	if(!find_ip_in_name_record(namerec, from_ip)) {
1654		DEBUG(3,("wins_process_name_release_request: Refusing request to \
1655release name %s as IP %s is not one of the known IP's for this name.\n",
1656			nmb_namestr(question), inet_ntoa(from_ip) ));
1657		send_wins_name_release_response(NAM_ERR, p);
1658		return;
1659	}
1660
1661	/*
1662	 * Check if the record is active. IF it's already released
1663	 * or tombstoned, refuse the release.
1664	 */
1665
1666	if (!WINS_STATE_ACTIVE(namerec)) {
1667		DEBUG(3,("wins_process_name_release_request: Refusing request to \
1668release name %s as this record is not active anymore.\n", nmb_namestr(question) ));
1669		send_wins_name_release_response(NAM_ERR, p);
1670		return;
1671	}
1672
1673	/*
1674	 * Check if the record is a 0x1c group
1675	 * and has more then one ip
1676	 * remove only this address.
1677	 */
1678
1679	if(releasing_group_name && (question->name_type == 0x1c) && (namerec->data.num_ips > 1)) {
1680		remove_ip_from_name_record(namerec, from_ip);
1681		DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
1682				inet_ntoa(from_ip),nmb_namestr(question)));
1683		send_wins_name_release_response(0, p);
1684		return;
1685	}
1686
1687	/*
1688	 * Send a release response.
1689	 * Flag the name as released and update the ttl
1690	 */
1691
1692	send_wins_name_release_response(0, p);
1693
1694	namerec->data.wins_flags |= WINS_RELEASED;
1695	update_name_ttl(namerec, EXTINCTION_INTERVAL);
1696
1697	wins_hook("delete", namerec, 0);
1698}
1699
1700/*******************************************************************
1701 WINS time dependent processing.
1702******************************************************************/
1703
1704void initiate_wins_processing(time_t t)
1705{
1706	static time_t lasttime = 0;
1707	struct name_record *namerec;
1708	struct name_record *next_namerec;
1709	struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
1710
1711	if (!lasttime)
1712		lasttime = t;
1713	if (t - lasttime < 20)
1714		return;
1715
1716	lasttime = t;
1717
1718	if(!lp_we_are_a_wins_server())
1719		return;
1720
1721	for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
1722	     namerec;
1723	     namerec = next_namerec ) {
1724		next_namerec = (struct name_record *)ubi_trNext( namerec );
1725
1726		if( (namerec->data.death_time != PERMANENT_TTL)
1727		     && (namerec->data.death_time < t) ) {
1728
1729			if( namerec->data.source == SELF_NAME ) {
1730				DEBUG( 3, ( "initiate_wins_processing: Subnet %s not expiring SELF name %s\n",
1731				           wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
1732				namerec->data.death_time += 300;
1733				namerec->subnet->namelist_changed = True;
1734				continue;
1735			} else if (namerec->data.source == DNS_NAME || namerec->data.source == DNSFAIL_NAME) {
1736				DEBUG(3,("initiate_wins_processing: deleting timed out DNS name %s\n",
1737						nmb_namestr(&namerec->name)));
1738				remove_name_from_namelist( wins_server_subnet, namerec );
1739				continue;
1740			}
1741
1742			/* handle records, samba is the wins owner */
1743			if (ip_equal(namerec->data.wins_ip, our_fake_ip)) {
1744				switch (namerec->data.wins_flags | WINS_STATE_MASK) {
1745					case WINS_ACTIVE:
1746						namerec->data.wins_flags&=~WINS_STATE_MASK;
1747						namerec->data.wins_flags|=WINS_RELEASED;
1748						namerec->data.death_time = t + EXTINCTION_INTERVAL;
1749						DEBUG(3,("initiate_wins_processing: expiring %s\n", nmb_namestr(&namerec->name)));
1750						break;
1751					case WINS_RELEASED:
1752						namerec->data.wins_flags&=~WINS_STATE_MASK;
1753						namerec->data.wins_flags|=WINS_TOMBSTONED;
1754						namerec->data.death_time = t + EXTINCTION_TIMEOUT;
1755						get_global_id_and_update(&namerec->data.id, True);
1756						DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
1757						break;
1758					case WINS_TOMBSTONED:
1759						DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
1760						remove_name_from_namelist( wins_server_subnet, namerec );
1761						break;
1762				}
1763			} else {
1764				switch (namerec->data.wins_flags | WINS_STATE_MASK) {
1765					case WINS_ACTIVE:
1766						/* that's not as MS says it should be */
1767						namerec->data.wins_flags&=~WINS_STATE_MASK;
1768						namerec->data.wins_flags|=WINS_TOMBSTONED;
1769						namerec->data.death_time = t + EXTINCTION_TIMEOUT;
1770						DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
1771					case WINS_TOMBSTONED:
1772						DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
1773						remove_name_from_namelist( wins_server_subnet, namerec );
1774						break;
1775					case WINS_RELEASED:
1776						DEBUG(0,("initiate_wins_processing: %s is in released state and\
1777we are not the wins owner !\n", nmb_namestr(&namerec->name)));
1778						break;
1779				}
1780			}
1781
1782		}
1783	}
1784
1785	if(wins_server_subnet->namelist_changed)
1786		wins_write_database(True);
1787
1788	wins_server_subnet->namelist_changed = False;
1789}
1790
1791/*******************************************************************
1792 Write out the current WINS database.
1793******************************************************************/
1794
1795void wins_write_database(BOOL background)
1796{
1797	struct name_record *namerec;
1798	pstring fname, fnamenew;
1799
1800	XFILE *fp;
1801
1802	if(!lp_we_are_a_wins_server())
1803		return;
1804
1805	/* We will do the writing in a child process to ensure that the parent doesn't block while this is done */
1806	if (background) {
1807		CatchChild();
1808		if (sys_fork()) {
1809			return;
1810		}
1811	}
1812
1813	slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
1814	all_string_sub(fname,"//", "/", 0);
1815	slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
1816
1817	if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) {
1818		DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
1819		if (background) {
1820			_exit(0);
1821		}
1822		return;
1823	}
1824
1825	DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
1826
1827	x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
1828
1829	for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist ); namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
1830		int i;
1831		struct tm *tm;
1832
1833		DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
1834
1835		if( namerec->data.death_time != PERMANENT_TTL ) {
1836			char *ts, *nl;
1837
1838			tm = LocalTime(&namerec->data.death_time);
1839			ts = asctime(tm);
1840			nl = strrchr( ts, '\n' );
1841			if( NULL != nl )
1842				*nl = '\0';
1843			DEBUGADD(4,("TTL = %s  ", ts ));
1844		} else {
1845			DEBUGADD(4,("TTL = PERMANENT                 "));
1846		}
1847
1848		for (i = 0; i < namerec->data.num_ips; i++)
1849			DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
1850		DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
1851
1852		if( namerec->data.source == REGISTER_NAME ) {
1853			unstring name;
1854			pull_ascii_nstring(name, sizeof(name), namerec->name.name);
1855			x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */
1856				(int)namerec->data.death_time);
1857
1858			for (i = 0; i < namerec->data.num_ips; i++)
1859				x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
1860			x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
1861		}
1862	}
1863
1864	x_fclose(fp);
1865	chmod(fnamenew,0644);
1866	unlink(fname);
1867	rename(fnamenew,fname);
1868	if (background) {
1869		_exit(0);
1870	}
1871}
1872
1873/****************************************************************************
1874 Process a internal Samba message receiving a wins record.
1875***************************************************************************/
1876
1877void nmbd_wins_new_entry(int msg_type, pid_t src, void *buf, size_t len)
1878{
1879	WINS_RECORD *record;
1880	struct name_record *namerec = NULL;
1881	struct name_record *new_namerec = NULL;
1882	struct nmb_name question;
1883	BOOL overwrite=False;
1884	struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
1885	int i;
1886
1887	if (buf==NULL)
1888		return;
1889
1890	/* Record should use UNIX codepage. Ensure this is so in the wrepld code. JRA. */
1891	record=(WINS_RECORD *)buf;
1892
1893	make_nmb_name(&question, record->name, record->type);
1894
1895	namerec = find_name_on_subnet(wins_server_subnet, &question, FIND_ANY_NAME);
1896
1897	/* record doesn't exist, add it */
1898	if (namerec == NULL) {
1899		DEBUG(3,("nmbd_wins_new_entry: adding new replicated record: %s<%02x> for wins server: %s\n",
1900			  record->name, record->type, inet_ntoa(record->wins_ip)));
1901
1902		new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
1903						EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
1904		if (new_namerec!=NULL) {
1905				update_wins_owner(new_namerec, record->wins_ip);
1906				update_wins_flag(new_namerec, record->wins_flags);
1907				new_namerec->data.id=record->id;
1908
1909				wins_server_subnet->namelist_changed = True;
1910			}
1911	}
1912
1913	/* check if we have a conflict */
1914	if (namerec != NULL) {
1915		/* both records are UNIQUE */
1916		if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
1917
1918			/* the database record is a replica */
1919			if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
1920				if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
1921					if (ip_equal(namerec->data.wins_ip, record->wins_ip))
1922						overwrite=True;
1923				} else
1924					overwrite=True;
1925			} else {
1926			/* we are the wins owner of the database record */
1927				/* the 2 records have the same IP address */
1928				if (ip_equal(namerec->data.ip[0], record->ip[0])) {
1929					if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
1930						get_global_id_and_update(&namerec->data.id, True);
1931					else
1932						overwrite=True;
1933
1934				} else {
1935				/* the 2 records have different IP address */
1936					if (namerec->data.wins_flags&WINS_ACTIVE) {
1937						if (record->wins_flags&WINS_TOMBSTONED)
1938							get_global_id_and_update(&namerec->data.id, True);
1939						if (record->wins_flags&WINS_ACTIVE)
1940							/* send conflict challenge to the replica node */
1941							;
1942					} else
1943						overwrite=True;
1944				}
1945
1946			}
1947		}
1948
1949		/* the replica is a standard group */
1950		if (record->wins_flags&WINS_NGROUP || record->wins_flags&WINS_SGROUP) {
1951			/* if the database record is unique and active force a name release */
1952			if (namerec->data.wins_flags&WINS_UNIQUE)
1953				/* send a release name to the unique node */
1954				;
1955			overwrite=True;
1956
1957		}
1958
1959		/* the replica is a special group */
1960		if (record->wins_flags&WINS_SGROUP && namerec->data.wins_flags&WINS_SGROUP) {
1961			if (namerec->data.wins_flags&WINS_ACTIVE) {
1962				for (i=0; i<record->num_ips; i++)
1963					if(!find_ip_in_name_record(namerec, record->ip[i]))
1964						add_ip_to_name_record(namerec, record->ip[i]);
1965			} else {
1966				overwrite=True;
1967			}
1968		}
1969
1970		/* the replica is a multihomed host */
1971
1972		/* I'm giving up on multi homed. Too much complex to understand */
1973
1974		if (record->wins_flags&WINS_MHOMED) {
1975			if (! (namerec->data.wins_flags&WINS_ACTIVE)) {
1976				if ( !(namerec->data.wins_flags&WINS_RELEASED) && !(namerec->data.wins_flags&WINS_NGROUP))
1977					overwrite=True;
1978			}
1979			else {
1980				if (ip_equal(record->wins_ip, namerec->data.wins_ip))
1981					overwrite=True;
1982
1983				if (ip_equal(namerec->data.wins_ip, our_fake_ip))
1984					if (namerec->data.wins_flags&WINS_UNIQUE)
1985						get_global_id_and_update(&namerec->data.id, True);
1986
1987			}
1988
1989			if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
1990				if (namerec->data.wins_flags&WINS_UNIQUE ||
1991				    namerec->data.wins_flags&WINS_MHOMED)
1992					if (ip_equal(record->wins_ip, namerec->data.wins_ip))
1993						overwrite=True;
1994
1995		}
1996
1997		if (overwrite == False)
1998			DEBUG(3, ("nmbd_wins_new_entry: conflict in adding record: %s<%02x> from wins server: %s\n",
1999				  record->name, record->type, inet_ntoa(record->wins_ip)));
2000		else {
2001			DEBUG(3, ("nmbd_wins_new_entry: replacing record: %s<%02x> from wins server: %s\n",
2002				  record->name, record->type, inet_ntoa(record->wins_ip)));
2003
2004			/* remove the old record and add a new one */
2005			remove_name_from_namelist( wins_server_subnet, namerec );
2006			new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
2007						EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
2008			if (new_namerec!=NULL) {
2009				update_wins_owner(new_namerec, record->wins_ip);
2010				update_wins_flag(new_namerec, record->wins_flags);
2011				new_namerec->data.id=record->id;
2012
2013				wins_server_subnet->namelist_changed = True;
2014			}
2015
2016			wins_server_subnet->namelist_changed = True;
2017		}
2018
2019	}
2020}
2021