• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source3/nmbd/
1/*
2   Unix SMB/CIFS implementation.
3   NBT netbios routines and daemon - version 2
4   Copyright (C) Andrew Tridgell 1994-1998
5   Copyright (C) Luke Kenneth Casson Leighton 1994-1998
6   Copyright (C) Jeremy Allison 1994-2003
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21*/
22
23#include "includes.h"
24
25/* forward declarations */
26static void wins_next_registration(struct response_record *rrec);
27
28
29/****************************************************************************
30 Deal with a response packet when registering one of our names.
31****************************************************************************/
32
33static void register_name_response(struct subnet_record *subrec,
34                       struct response_record *rrec, struct packet_struct *p)
35{
36	/*
37	 * If we are registering broadcast, then getting a response is an
38	 * error - we do not have the name. If we are registering unicast,
39	 * then we expect to get a response.
40	 */
41
42	struct nmb_packet *nmb = &p->packet.nmb;
43	bool bcast = nmb->header.nm_flags.bcast;
44	bool success = True;
45	struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
46	struct nmb_name *answer_name = &nmb->answers->rr_name;
47	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
48	int ttl = 0;
49	uint16 nb_flags = 0;
50	struct in_addr register_ip;
51	fstring reg_name;
52
53	putip(&register_ip,&sent_nmb->additional->rdata[2]);
54	fstrcpy(reg_name, inet_ntoa(register_ip));
55
56	if (subrec == unicast_subnet) {
57		/* we know that this wins server is definately alive - for the moment! */
58		wins_srv_alive(rrec->packet->ip, register_ip);
59	}
60
61	/* Sanity check. Ensure that the answer name in the incoming packet is the
62	   same as the requested name in the outgoing packet. */
63
64	if(!question_name || !answer_name) {
65		DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
66			 question_name ? "question_name" : "answer_name" ));
67		return;
68	}
69
70	if(!nmb_name_equal(question_name, answer_name)) {
71		DEBUG(0,("register_name_response: Answer name %s differs from question name %s.\n",
72			 nmb_namestr(answer_name), nmb_namestr(question_name)));
73		return;
74	}
75
76	if(bcast) {
77		/*
78		 * Special hack to cope with old Samba nmbd's.
79		 * Earlier versions of Samba (up to 1.9.16p11) respond
80		 * to a broadcast name registration of WORKGROUP<1b> when
81		 * they should not. Hence, until these versions are gone,
82		 * we should treat such errors as success for this particular
83		 * case only. jallison@whistle.com.
84		 */
85
86#if 1 /* OLD_SAMBA_SERVER_HACK */
87		unstring ans_name;
88		pull_ascii_nstring(ans_name, sizeof(ans_name), answer_name->name);
89		if((nmb->header.rcode == ACT_ERR) && strequal(lp_workgroup(), ans_name) &&
90		   (answer_name->name_type == 0x1b)) {
91			/* Pretend we did not get this. */
92			rrec->num_msgs--;
93
94			DEBUG(5,("register_name_response: Ignoring broadcast response to registration of name %s due to old Samba server bug.\n",
95				 nmb_namestr(answer_name)));
96			return;
97		}
98#endif /* OLD_SAMBA_SERVER_HACK */
99
100		/* Someone else has the name. Log the problem. */
101		DEBUG(1,("register_name_response: Failed to register name %s IP %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n",
102			 nmb_namestr(answer_name),
103			 reg_name,
104			 subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
105		success = False;
106	} else {
107		if (!ip_equal_v4(rrec->packet->ip, p->ip)) {
108			DEBUG(5,("register_name_response: Ignoring WINS server response "
109				"from IP %s, for name %s. We sent to IP %s\n",
110				inet_ntoa(p->ip),
111				nmb_namestr(answer_name),
112				inet_ntoa(rrec->packet->ip)));
113			return;
114		}
115		/* Unicast - check to see if the response allows us to have the name. */
116		if (nmb->header.opcode == NMB_WACK_OPCODE) {
117			/* WINS server is telling us to wait. Pretend we didn't get
118			   the response but don't send out any more register requests. */
119
120			DEBUG(5,("register_name_response: WACK from WINS server %s in registering name %s IP %s\n",
121				 inet_ntoa(p->ip), nmb_namestr(answer_name), reg_name));
122
123			rrec->repeat_count = 0;
124			/* How long we should wait for. */
125			rrec->repeat_time = p->timestamp + nmb->answers->ttl;
126			rrec->num_msgs--;
127			return;
128		} else if (nmb->header.rcode != 0) {
129			/* Error code - we didn't get the name. */
130			success = False;
131
132			DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n",
133				 subrec==unicast_subnet?"WINS ":"",
134				 inet_ntoa(p->ip),
135				 nmb_namestr(answer_name),
136				 reg_name,
137				 nmb->header.rcode));
138		} else {
139			success = True;
140			/* Get the data we need to pass to the success function. */
141			nb_flags = get_nb_flags(nmb->answers->rdata);
142			ttl = nmb->answers->ttl;
143
144			/* send off a registration for the next IP, if any */
145			wins_next_registration(rrec);
146		}
147	}
148
149	DEBUG(5,("register_name_response: %s in registering %sname %s IP %s with %s.\n",
150		 success ? "success" : "failure",
151		 subrec==unicast_subnet?"WINS ":"",
152		 nmb_namestr(answer_name),
153		 reg_name,
154		 inet_ntoa(rrec->packet->ip)));
155
156	if(success) {
157		/* Enter the registered name into the subnet name database before calling
158		   the success function. */
159		standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
160		if( rrec->success_fn)
161			(*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
162	} else {
163		struct nmb_name qname = *question_name;
164		if( rrec->fail_fn)
165			(*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
166		/* Remove the name. */
167		standard_fail_register( subrec, &qname);
168	}
169
170	/* Ensure we don't retry. */
171	remove_response_record(subrec, rrec);
172}
173
174/****************************************************************************
175 Deal with a timeout of a WINS registration request
176****************************************************************************/
177
178static void wins_registration_timeout(struct subnet_record *subrec,
179				      struct response_record *rrec)
180{
181	struct userdata_struct *userdata = rrec->userdata;
182	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
183	struct nmb_name *nmbname = &sent_nmb->question.question_name;
184	struct in_addr register_ip;
185	fstring src_addr;
186
187	putip(&register_ip,&sent_nmb->additional->rdata[2]);
188
189	fstrcpy(src_addr, inet_ntoa(register_ip));
190
191	DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n",
192		 inet_ntoa(rrec->packet->ip), src_addr));
193
194	/* mark it temporarily dead for this source address */
195	wins_srv_died(rrec->packet->ip, register_ip);
196
197	/* if we have some userdata then use that to work out what
198	   wins server to try next */
199	if (userdata) {
200		const char *tag = (const char *)userdata->data;
201
202		/* try the next wins server in our failover list for
203		   this tag */
204		rrec->packet->ip = wins_srv_ip_tag(tag, register_ip);
205	}
206
207	/* if we have run out of wins servers for this tag then they
208	   must all have timed out. We treat this as *success*, not
209	   failure, and go into our standard name refresh mode. This
210	   copes with all the wins servers being down */
211	if (wins_srv_is_dead(rrec->packet->ip, register_ip)) {
212		uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
213		int ttl = sent_nmb->additional->ttl;
214
215		standard_success_register(subrec, userdata, nmbname, nb_flags, ttl, register_ip);
216		if(rrec->success_fn) {
217			(*(register_name_success_function)rrec->success_fn)(subrec,
218									    rrec->userdata,
219									    nmbname,
220									    nb_flags,
221									    ttl,
222									    register_ip);
223		}
224
225		/* send off a registration for the next IP, if any */
226		wins_next_registration(rrec);
227
228		/* don't need to send this packet any more */
229		remove_response_record(subrec, rrec);
230		return;
231	}
232
233	/* we will be moving to the next WINS server for this group,
234	   send it immediately */
235	rrec->repeat_count = 2;
236	rrec->repeat_time = time(NULL) + 1;
237	rrec->in_expiration_processing = False;
238
239	DEBUG(6,("Retrying register of name %s IP %s with WINS server %s\n",
240		 nmb_namestr(nmbname), src_addr, inet_ntoa(rrec->packet->ip)));
241
242	/* notice that we don't remove the response record. This keeps
243	   us trying to register with each of our failover wins servers */
244}
245
246/****************************************************************************
247 Deal with a timeout when registering one of our names.
248****************************************************************************/
249
250static void register_name_timeout_response(struct subnet_record *subrec,
251					   struct response_record *rrec)
252{
253	/*
254	 * If we are registering unicast, then NOT getting a response is an
255	 * error - we do not have the name. If we are registering broadcast,
256	 * then we don't expect to get a response.
257	 */
258
259	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
260	bool bcast = sent_nmb->header.nm_flags.bcast;
261	bool success = False;
262	struct nmb_name *question_name = &sent_nmb->question.question_name;
263	uint16 nb_flags = 0;
264	int ttl = 0;
265	struct in_addr registered_ip;
266
267	if (bcast) {
268		if(rrec->num_msgs == 0) {
269			/* Not receiving a message is success for broadcast registration. */
270			success = True;
271
272			/* Pull the success values from the original request packet. */
273			nb_flags = get_nb_flags(sent_nmb->additional->rdata);
274			ttl = sent_nmb->additional->ttl;
275			putip(&registered_ip,&sent_nmb->additional->rdata[2]);
276		}
277	} else {
278		/* wins timeouts are special */
279		wins_registration_timeout(subrec, rrec);
280		return;
281	}
282
283	DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
284		 success ? "success" : "failure", nmb_namestr(question_name), subrec->subnet_name));
285	if(success) {
286		/* Enter the registered name into the subnet name database before calling
287		   the success function. */
288		standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
289		if( rrec->success_fn)
290			(*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
291	} else {
292		struct nmb_name qname = *question_name;
293		if( rrec->fail_fn)
294			(*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
295		/* Remove the name. */
296		standard_fail_register( subrec, &qname);
297	}
298
299	/* Ensure we don't retry. */
300	remove_response_record(subrec, rrec);
301}
302
303/****************************************************************************
304 Initiate one multi-homed name registration packet.
305****************************************************************************/
306
307static void multihomed_register_one(struct nmb_name *nmbname,
308				    uint16 nb_flags,
309				    register_name_success_function success_fn,
310				    register_name_fail_function fail_fn,
311				    struct in_addr ip,
312				    const char *tag)
313{
314	struct userdata_struct *userdata;
315	struct in_addr wins_ip = wins_srv_ip_tag(tag, ip);
316	fstring ip_str;
317
318	userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
319	if (!userdata) {
320		DEBUG(0,("Failed to allocate userdata structure!\n"));
321		return;
322	}
323	ZERO_STRUCTP(userdata);
324	userdata->userdata_len = strlen(tag) + 1;
325	strlcpy(userdata->data, tag, userdata->userdata_len);
326
327	fstrcpy(ip_str, inet_ntoa(ip));
328
329	DEBUG(6,("Registering name %s IP %s with WINS server %s using tag '%s'\n",
330		 nmb_namestr(nmbname), ip_str, inet_ntoa(wins_ip), tag));
331
332	if (queue_register_multihomed_name(unicast_subnet,
333					   register_name_response,
334					   register_name_timeout_response,
335					   success_fn,
336					   fail_fn,
337					   userdata,
338					   nmbname,
339					   nb_flags,
340					   ip,
341					   wins_ip) == NULL) {
342		DEBUG(0,("multihomed_register_one: Failed to send packet trying to register name %s IP %s\n",
343			 nmb_namestr(nmbname), inet_ntoa(ip)));
344	}
345
346	free(userdata);
347}
348
349/****************************************************************************
350 We have finished the registration of one IP and need to see if we have
351 any more IPs left to register with this group of wins server for this name.
352****************************************************************************/
353
354static void wins_next_registration(struct response_record *rrec)
355{
356	struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
357	struct nmb_name *nmbname = &sent_nmb->question.question_name;
358	uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
359	struct userdata_struct *userdata = rrec->userdata;
360	const char *tag;
361	struct in_addr last_ip;
362	struct subnet_record *subrec;
363
364	putip(&last_ip,&sent_nmb->additional->rdata[2]);
365
366	if (!userdata) {
367		/* it wasn't multi-homed */
368		return;
369	}
370
371	tag = (const char *)userdata->data;
372
373	for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
374		if (ip_equal_v4(last_ip, subrec->myip)) {
375			subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec);
376			break;
377		}
378	}
379
380	if (!subrec) {
381		/* no more to do! */
382		return;
383	}
384
385	switch (sent_nmb->header.opcode) {
386	case NMB_NAME_MULTIHOMED_REG_OPCODE:
387		multihomed_register_one(nmbname, nb_flags, NULL, NULL, subrec->myip, tag);
388		break;
389	case NMB_NAME_REFRESH_OPCODE_8:
390		queue_wins_refresh(nmbname,
391				   register_name_response,
392				   register_name_timeout_response,
393				   nb_flags, subrec->myip, tag);
394		break;
395	}
396}
397
398/****************************************************************************
399 Try and register one of our names on the unicast subnet - multihomed.
400****************************************************************************/
401
402static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags,
403				     register_name_success_function success_fn,
404				     register_name_fail_function fail_fn)
405{
406	/*
407	  If we are adding a group name, we just send multiple
408	  register name packets to the WINS server (this is an
409	  internet group name.
410
411	  If we are adding a unique name, We need first to add
412	  our names to the unicast subnet namelist. This is
413	  because when a WINS server receives a multihomed
414	  registration request, the first thing it does is to
415	  send a name query to the registering machine, to see
416	  if it has put the name in it's local namelist.
417	  We need the name there so the query response code in
418	  nmbd_incomingrequests.c will find it.
419
420	  We are adding this name prematurely (we don't really
421	  have it yet), but as this is on the unicast subnet
422	  only we will get away with this (only the WINS server
423	  will ever query names from us on this subnet).
424	*/
425	int num_ips=0;
426	int i, t;
427	struct subnet_record *subrec;
428	char **wins_tags;
429	struct in_addr *ip_list;
430	unstring name;
431
432	for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
433		num_ips++;
434
435	if((ip_list = SMB_MALLOC_ARRAY(struct in_addr, num_ips))==NULL) {
436		DEBUG(0,("multihomed_register_name: malloc fail !\n"));
437		return;
438	}
439
440	for (subrec = FIRST_SUBNET, i = 0;
441	     subrec;
442	     subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ ) {
443		ip_list[i] = subrec->myip;
444	}
445
446	pull_ascii_nstring(name, sizeof(name), nmbname->name);
447	add_name_to_subnet(unicast_subnet, name, nmbname->name_type,
448			   nb_flags, lp_max_ttl(), SELF_NAME,
449			   num_ips, ip_list);
450
451	/* get the list of wins tags - we try to register for each of them */
452	wins_tags = wins_srv_tags();
453
454	/* Now try and register the name for each wins tag.  Note that
455	   at this point we only register our first IP with each wins
456	   group. We will register the rest from
457	   wins_next_registration() when we get the reply for this
458	   one. That follows the way W2K does things (tridge)
459	*/
460	for (t=0; wins_tags && wins_tags[t]; t++) {
461		multihomed_register_one(nmbname, nb_flags,
462					success_fn, fail_fn,
463					ip_list[0],
464					wins_tags[t]);
465	}
466
467	wins_srv_tags_free(wins_tags);
468
469	SAFE_FREE(ip_list);
470}
471
472/****************************************************************************
473 Try and register one of our names.
474****************************************************************************/
475
476void register_name(struct subnet_record *subrec,
477                   const char *name, int type, uint16 nb_flags,
478                   register_name_success_function success_fn,
479                   register_name_fail_function fail_fn,
480                   struct userdata_struct *userdata)
481{
482	struct nmb_name nmbname;
483	nstring nname;
484
485	errno = 0;
486	push_ascii_nstring(nname, name);
487        if (errno == E2BIG) {
488		unstring tname;
489		pull_ascii_nstring(tname, sizeof(tname), nname);
490		DEBUG(0,("register_name: NetBIOS name %s is too long. Truncating to %s\n",
491			name, tname));
492		make_nmb_name(&nmbname, tname, type);
493	} else {
494		make_nmb_name(&nmbname, name, type);
495	}
496
497	/* Always set the NB_ACTIVE flag on the name we are
498	   registering. Doesn't make sense without it.
499	*/
500
501	nb_flags |= NB_ACTIVE;
502
503	if (subrec == unicast_subnet) {
504		/* we now always do multi-homed registration if we are
505		   registering to a WINS server. This copes much
506		   better with complex WINS setups */
507		multihomed_register_name(&nmbname, nb_flags,
508					 success_fn, fail_fn);
509		return;
510	}
511
512	if (queue_register_name(subrec,
513				register_name_response,
514				register_name_timeout_response,
515				success_fn,
516				fail_fn,
517				userdata,
518				&nmbname,
519				nb_flags) == NULL) {
520		DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
521			 nmb_namestr(&nmbname)));
522	}
523}
524
525/****************************************************************************
526 Try and refresh one of our names. This is *only* called for WINS refresh
527****************************************************************************/
528
529void wins_refresh_name(struct name_record *namerec)
530{
531	int t;
532	char **wins_tags;
533
534	/* get the list of wins tags - we try to refresh for each of them */
535	wins_tags = wins_srv_tags();
536
537	for (t=0; wins_tags && wins_tags[t]; t++) {
538		queue_wins_refresh(&namerec->name,
539				   register_name_response,
540				   register_name_timeout_response,
541				   namerec->data.nb_flags,
542				   namerec->data.ip[0], wins_tags[t]);
543	}
544
545	wins_srv_tags_free(wins_tags);
546}
547