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-1998
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 2 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* forward declarations */
27 static void wins_next_registration(struct response_record
*rrec
);
30 /****************************************************************************
31 Deal with a response packet when registering one of our names.
32 ****************************************************************************/
34 static void register_name_response(struct subnet_record
*subrec
,
35 struct response_record
*rrec
, struct packet_struct
*p
)
38 * If we are registering broadcast, then getting a response is an
39 * error - we do not have the name. If we are registering unicast,
40 * then we expect to get a response.
43 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
44 BOOL bcast
= nmb
->header
.nm_flags
.bcast
;
46 struct nmb_name
*question_name
= &rrec
->packet
->packet
.nmb
.question
.question_name
;
47 struct nmb_name
*answer_name
= &nmb
->answers
->rr_name
;
48 struct nmb_packet
*sent_nmb
= &rrec
->packet
->packet
.nmb
;
51 struct in_addr register_ip
;
54 putip(®ister_ip
,&sent_nmb
->additional
->rdata
[2]);
55 fstrcpy(reg_name
, inet_ntoa(register_ip
));
57 if (subrec
== unicast_subnet
) {
58 /* we know that this wins server is definately alive - for the moment! */
59 wins_srv_alive(rrec
->packet
->ip
, register_ip
);
62 /* Sanity check. Ensure that the answer name in the incoming packet is the
63 same as the requested name in the outgoing packet. */
65 if(!question_name
|| !answer_name
) {
66 DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
67 question_name
? "question_name" : "answer_name" ));
71 if(!nmb_name_equal(question_name
, answer_name
)) {
72 DEBUG(0,("register_name_response: Answer name %s differs from question name %s.\n",
73 nmb_namestr(answer_name
), nmb_namestr(question_name
)));
79 * Special hack to cope with old Samba nmbd's.
80 * Earlier versions of Samba (up to 1.9.16p11) respond
81 * to a broadcast name registration of WORKGROUP<1b> when
82 * they should not. Hence, until these versions are gone,
83 * we should treat such errors as success for this particular
84 * case only. jallison@whistle.com.
87 #if 1 /* OLD_SAMBA_SERVER_HACK */
88 if((nmb
->header
.rcode
== ACT_ERR
) && strequal(lp_workgroup(), answer_name
->name
) &&
89 (answer_name
->name_type
== 0x1b)) {
90 /* Pretend we did not get this. */
93 DEBUG(5,("register_name_response: Ignoring broadcast response to registration of name %s due to old Samba server bug.\n",
94 nmb_namestr(answer_name
)));
97 #endif /* OLD_SAMBA_SERVER_HACK */
99 /* Someone else has the name. Log the problem. */
100 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",
101 nmb_namestr(answer_name
),
103 subrec
->subnet_name
, nmb
->header
.rcode
, inet_ntoa(p
->ip
)));
106 /* Unicast - check to see if the response allows us to have the name. */
107 if (nmb
->header
.opcode
== NMB_WACK_OPCODE
) {
108 /* WINS server is telling us to wait. Pretend we didn't get
109 the response but don't send out any more register requests. */
111 DEBUG(5,("register_name_response: WACK from WINS server %s in registering name %s IP %s\n",
112 inet_ntoa(p
->ip
), nmb_namestr(answer_name
), reg_name
));
114 rrec
->repeat_count
= 0;
115 /* How long we should wait for. */
116 rrec
->repeat_time
= p
->timestamp
+ nmb
->answers
->ttl
;
119 } else if (nmb
->header
.rcode
!= 0) {
120 /* Error code - we didn't get the name. */
123 DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n",
124 subrec
==unicast_subnet
?"WINS ":"",
126 nmb_namestr(answer_name
),
131 /* Get the data we need to pass to the success function. */
132 nb_flags
= get_nb_flags(nmb
->answers
->rdata
);
133 ttl
= nmb
->answers
->ttl
;
135 /* send off a registration for the next IP, if any */
136 wins_next_registration(rrec
);
140 DEBUG(5,("register_name_response: %s in registering %sname %s IP %s with %s.\n",
141 success
? "success" : "failure",
142 subrec
==unicast_subnet
?"WINS ":"",
143 nmb_namestr(answer_name
),
145 inet_ntoa(rrec
->packet
->ip
)));
148 /* Enter the registered name into the subnet name database before calling
149 the success function. */
150 standard_success_register(subrec
, rrec
->userdata
, answer_name
, nb_flags
, ttl
, register_ip
);
151 if( rrec
->success_fn
)
152 (*(register_name_success_function
)rrec
->success_fn
)(subrec
, rrec
->userdata
, answer_name
, nb_flags
, ttl
, register_ip
);
155 (*(register_name_fail_function
)rrec
->fail_fn
)(subrec
, rrec
, question_name
);
156 /* Remove the name. */
157 standard_fail_register( subrec
, rrec
, question_name
);
160 /* Ensure we don't retry. */
161 remove_response_record(subrec
, rrec
);
165 /****************************************************************************
166 Deal with a timeout of a WINS registration request
167 ****************************************************************************/
168 static void wins_registration_timeout(struct subnet_record
*subrec
,
169 struct response_record
*rrec
)
171 struct userdata_struct
*userdata
= rrec
->userdata
;
172 struct nmb_packet
*sent_nmb
= &rrec
->packet
->packet
.nmb
;
173 struct nmb_name
*nmbname
= &sent_nmb
->question
.question_name
;
174 struct in_addr register_ip
;
177 putip(®ister_ip
,&sent_nmb
->additional
->rdata
[2]);
179 fstrcpy(src_addr
, inet_ntoa(register_ip
));
181 DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n",
182 inet_ntoa(rrec
->packet
->ip
), src_addr
));
184 /* mark it temporarily dead for this source address */
185 wins_srv_died(rrec
->packet
->ip
, register_ip
);
187 /* if we have some userdata then use that to work out what
188 wins server to try next */
190 const char *tag
= (const char *)userdata
->data
;
192 /* try the next wins server in our failover list for
194 rrec
->packet
->ip
= wins_srv_ip_tag(tag
, register_ip
);
197 /* if we have run out of wins servers for this tag then they
198 must all have timed out. We treat this as *success*, not
199 failure, and go into our standard name refresh mode. This
200 copes with all the wins servers being down */
201 if (wins_srv_is_dead(rrec
->packet
->ip
, register_ip
)) {
202 uint16 nb_flags
= get_nb_flags(sent_nmb
->additional
->rdata
);
203 int ttl
= sent_nmb
->additional
->ttl
;
205 standard_success_register(subrec
, userdata
, nmbname
, nb_flags
, ttl
, register_ip
);
206 if(rrec
->success_fn
) {
207 (*(register_name_success_function
)rrec
->success_fn
)(subrec
,
215 /* send off a registration for the next IP, if any */
216 wins_next_registration(rrec
);
218 /* don't need to send this packet any more */
219 remove_response_record(subrec
, rrec
);
223 /* we will be moving to the next WINS server for this group,
224 send it immediately */
225 rrec
->repeat_count
= 2;
226 rrec
->repeat_time
= time(NULL
) + 1;
227 rrec
->in_expiration_processing
= False
;
229 DEBUG(6,("Retrying register of name %s IP %s with WINS server %s\n",
230 nmb_namestr(nmbname
), src_addr
, inet_ntoa(rrec
->packet
->ip
)));
232 /* notice that we don't remove the response record. This keeps
233 us trying to register with each of our failover wins servers */
237 /****************************************************************************
238 Deal with a timeout when registering one of our names.
239 ****************************************************************************/
241 static void register_name_timeout_response(struct subnet_record
*subrec
,
242 struct response_record
*rrec
)
245 * If we are registering unicast, then NOT getting a response is an
246 * error - we do not have the name. If we are registering broadcast,
247 * then we don't expect to get a response.
250 struct nmb_packet
*sent_nmb
= &rrec
->packet
->packet
.nmb
;
251 BOOL bcast
= sent_nmb
->header
.nm_flags
.bcast
;
252 BOOL success
= False
;
253 struct nmb_name
*question_name
= &sent_nmb
->question
.question_name
;
256 struct in_addr registered_ip
;
259 if(rrec
->num_msgs
== 0) {
260 /* Not receiving a message is success for broadcast registration. */
263 /* Pull the success values from the original request packet. */
264 nb_flags
= get_nb_flags(sent_nmb
->additional
->rdata
);
265 ttl
= sent_nmb
->additional
->ttl
;
266 putip(®istered_ip
,&sent_nmb
->additional
->rdata
[2]);
269 /* wins timeouts are special */
270 wins_registration_timeout(subrec
, rrec
);
274 DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
275 success
? "success" : "failure", nmb_namestr(question_name
), subrec
->subnet_name
));
277 /* Enter the registered name into the subnet name database before calling
278 the success function. */
279 standard_success_register(subrec
, rrec
->userdata
, question_name
, nb_flags
, ttl
, registered_ip
);
280 if( rrec
->success_fn
)
281 (*(register_name_success_function
)rrec
->success_fn
)(subrec
, rrec
->userdata
, question_name
, nb_flags
, ttl
, registered_ip
);
284 (*(register_name_fail_function
)rrec
->fail_fn
)(subrec
, rrec
, question_name
);
285 /* Remove the name. */
286 standard_fail_register( subrec
, rrec
, question_name
);
289 /* Ensure we don't retry. */
290 remove_response_record(subrec
, rrec
);
294 /****************************************************************************
295 initiate one multi-homed name registration packet
296 ****************************************************************************/
297 static void multihomed_register_one(struct nmb_name
*nmbname
,
299 register_name_success_function success_fn
,
300 register_name_fail_function fail_fn
,
304 struct userdata_struct
*userdata
;
305 struct in_addr wins_ip
= wins_srv_ip_tag(tag
, ip
);
308 userdata
= (struct userdata_struct
*)malloc(sizeof(*userdata
) + strlen(tag
) + 1);
310 DEBUG(0,("Failed to allocate userdata structure!\n"));
313 ZERO_STRUCTP(userdata
);
314 userdata
->userdata_len
= strlen(tag
) + 1;
315 strlcpy(userdata
->data
, tag
, userdata
->userdata_len
);
317 fstrcpy(ip_str
, inet_ntoa(ip
));
319 DEBUG(6,("Registering name %s IP %s with WINS server %s using tag '%s'\n",
320 nmb_namestr(nmbname
), ip_str
, inet_ntoa(wins_ip
), tag
));
322 if (queue_register_multihomed_name(unicast_subnet
,
323 register_name_response
,
324 register_name_timeout_response
,
332 DEBUG(0,("multihomed_register_one: Failed to send packet trying to register name %s IP %s\n",
333 nmb_namestr(nmbname
), inet_ntoa(ip
)));
340 /****************************************************************************
341 we have finished the registration of one IP and need to see if we have
342 any more IPs left to register with this group of wins server for this name
343 ****************************************************************************/
344 static void wins_next_registration(struct response_record
*rrec
)
346 struct nmb_packet
*sent_nmb
= &rrec
->packet
->packet
.nmb
;
347 struct nmb_name
*nmbname
= &sent_nmb
->question
.question_name
;
348 uint16 nb_flags
= get_nb_flags(sent_nmb
->additional
->rdata
);
349 struct userdata_struct
*userdata
= rrec
->userdata
;
351 struct in_addr last_ip
;
352 struct subnet_record
*subrec
;
354 putip(&last_ip
,&sent_nmb
->additional
->rdata
[2]);
357 /* it wasn't multi-homed */
361 tag
= (const char *)userdata
->data
;
363 for (subrec
= FIRST_SUBNET
; subrec
; subrec
= NEXT_SUBNET_EXCLUDING_UNICAST(subrec
)) {
364 if (ip_equal(last_ip
, subrec
->myip
)) {
365 subrec
= NEXT_SUBNET_EXCLUDING_UNICAST(subrec
);
375 switch (sent_nmb
->header
.opcode
) {
376 case NMB_NAME_MULTIHOMED_REG_OPCODE
:
377 multihomed_register_one(nmbname
, nb_flags
, NULL
, NULL
, subrec
->myip
, tag
);
379 case NMB_NAME_REFRESH_OPCODE_8
:
380 queue_wins_refresh(nmbname
,
381 register_name_response
,
382 register_name_timeout_response
,
383 nb_flags
, subrec
->myip
, tag
);
388 /****************************************************************************
389 Try and register one of our names on the unicast subnet - multihomed.
390 ****************************************************************************/
391 static void multihomed_register_name(struct nmb_name
*nmbname
, uint16 nb_flags
,
392 register_name_success_function success_fn
,
393 register_name_fail_function fail_fn
)
396 If we are adding a group name, we just send multiple
397 register name packets to the WINS server (this is an
400 If we are adding a unique name, We need first to add
401 our names to the unicast subnet namelist. This is
402 because when a WINS server receives a multihomed
403 registration request, the first thing it does is to
404 send a name query to the registering machine, to see
405 if it has put the name in it's local namelist.
406 We need the name there so the query response code in
407 nmbd_incomingrequests.c will find it.
409 We are adding this name prematurely (we don't really
410 have it yet), but as this is on the unicast subnet
411 only we will get away with this (only the WINS server
412 will ever query names from us on this subnet).
416 struct subnet_record
*subrec
;
418 struct in_addr
*ip_list
;
420 for(subrec
= FIRST_SUBNET
; subrec
; subrec
= NEXT_SUBNET_EXCLUDING_UNICAST(subrec
) )
423 if((ip_list
= (struct in_addr
*)malloc(num_ips
* sizeof(struct in_addr
)))==NULL
) {
424 DEBUG(0,("multihomed_register_name: malloc fail !\n"));
428 for (subrec
= FIRST_SUBNET
, i
= 0;
430 subrec
= NEXT_SUBNET_EXCLUDING_UNICAST(subrec
), i
++ ) {
431 ip_list
[i
] = subrec
->myip
;
434 add_name_to_subnet(unicast_subnet
, nmbname
->name
, nmbname
->name_type
,
435 nb_flags
, lp_max_ttl(), SELF_NAME
,
438 /* get the list of wins tags - we try to register for each of them */
439 wins_tags
= wins_srv_tags();
441 /* Now try and register the name for each wins tag. Note that
442 at this point we only register our first IP with each wins
443 group. We will register the rest from
444 wins_next_registration() when we get the reply for this
445 one. That follows the way W2K does things (tridge)
447 for (t
=0; wins_tags
&& wins_tags
[t
]; t
++) {
448 multihomed_register_one(nmbname
, nb_flags
,
454 wins_srv_tags_free(wins_tags
);
460 /****************************************************************************
461 Try and register one of our names.
462 ****************************************************************************/
463 void register_name(struct subnet_record
*subrec
,
464 const char *name
, int type
, uint16 nb_flags
,
465 register_name_success_function success_fn
,
466 register_name_fail_function fail_fn
,
467 struct userdata_struct
*userdata
)
469 struct nmb_name nmbname
;
471 make_nmb_name(&nmbname
, name
, type
);
473 /* Always set the NB_ACTIVE flag on the name we are
474 registering. Doesn't make sense without it.
477 nb_flags
|= NB_ACTIVE
;
479 if (subrec
== unicast_subnet
) {
480 /* we now always do multi-homed registration if we are
481 registering to a WINS server. This copes much
482 better with complex WINS setups */
483 multihomed_register_name(&nmbname
, nb_flags
,
484 success_fn
, fail_fn
);
488 if (queue_register_name(subrec
,
489 register_name_response
,
490 register_name_timeout_response
,
496 DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
497 nmb_namestr(&nmbname
)));
502 /****************************************************************************
503 Try and refresh one of our names. This is *only* called for WINS refresh
504 ****************************************************************************/
505 void wins_refresh_name(struct name_record
*namerec
)
510 /* get the list of wins tags - we try to refresh for each of them */
511 wins_tags
= wins_srv_tags();
513 for (t
=0; wins_tags
&& wins_tags
[t
]; t
++) {
514 queue_wins_refresh(&namerec
->name
,
515 register_name_response
,
516 register_name_timeout_response
,
517 namerec
->data
.nb_flags
,
518 namerec
->data
.ip
[0], wins_tags
[t
]);
521 wins_srv_tags_free(wins_tags
);