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