Closed memory leak on error path.
[Samba/gbeck.git] / source3 / nmbd / nmbd_nameregister.c
blobedcf258519bec148919f3aaa708e2d76d32518a9
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
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.
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, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
25 /* forward declarations */
26 static void wins_next_registration(struct response_record *rrec);
29 /****************************************************************************
30 Deal with a response packet when registering one of our names.
31 ****************************************************************************/
33 static void register_name_response(struct subnet_record *subrec,
34 struct response_record *rrec, struct packet_struct *p)
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.
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;
53 putip(&register_ip,&sent_nmb->additional->rdata[2]);
54 fstrcpy(reg_name, inet_ntoa(register_ip));
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);
61 /* Sanity check. Ensure that the answer name in the incoming packet is the
62 same as the requested name in the outgoing packet. */
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;
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;
76 if(bcast) {
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.
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--;
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;
98 #endif /* OLD_SAMBA_SERVER_HACK */
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 /* Unicast - check to see if the response allows us to have the name. */
108 if (nmb->header.opcode == NMB_WACK_OPCODE) {
109 /* WINS server is telling us to wait. Pretend we didn't get
110 the response but don't send out any more register requests. */
112 DEBUG(5,("register_name_response: WACK from WINS server %s in registering name %s IP %s\n",
113 inet_ntoa(p->ip), nmb_namestr(answer_name), reg_name));
115 rrec->repeat_count = 0;
116 /* How long we should wait for. */
117 rrec->repeat_time = p->timestamp + nmb->answers->ttl;
118 rrec->num_msgs--;
119 return;
120 } else if (nmb->header.rcode != 0) {
121 /* Error code - we didn't get the name. */
122 success = False;
124 DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n",
125 subrec==unicast_subnet?"WINS ":"",
126 inet_ntoa(p->ip),
127 nmb_namestr(answer_name),
128 reg_name,
129 nmb->header.rcode));
130 } else {
131 success = True;
132 /* Get the data we need to pass to the success function. */
133 nb_flags = get_nb_flags(nmb->answers->rdata);
134 ttl = nmb->answers->ttl;
136 /* send off a registration for the next IP, if any */
137 wins_next_registration(rrec);
141 DEBUG(5,("register_name_response: %s in registering %sname %s IP %s with %s.\n",
142 success ? "success" : "failure",
143 subrec==unicast_subnet?"WINS ":"",
144 nmb_namestr(answer_name),
145 reg_name,
146 inet_ntoa(rrec->packet->ip)));
148 if(success) {
149 /* Enter the registered name into the subnet name database before calling
150 the success function. */
151 standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
152 if( rrec->success_fn)
153 (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
154 } else {
155 if( rrec->fail_fn)
156 (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
157 /* Remove the name. */
158 standard_fail_register( subrec, rrec, question_name);
161 /* Ensure we don't retry. */
162 remove_response_record(subrec, rrec);
165 /****************************************************************************
166 Deal with a timeout of a WINS registration request
167 ****************************************************************************/
169 static void wins_registration_timeout(struct subnet_record *subrec,
170 struct response_record *rrec)
172 struct userdata_struct *userdata = rrec->userdata;
173 struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
174 struct nmb_name *nmbname = &sent_nmb->question.question_name;
175 struct in_addr register_ip;
176 fstring src_addr;
178 putip(&register_ip,&sent_nmb->additional->rdata[2]);
180 fstrcpy(src_addr, inet_ntoa(register_ip));
182 DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n",
183 inet_ntoa(rrec->packet->ip), src_addr));
185 /* mark it temporarily dead for this source address */
186 wins_srv_died(rrec->packet->ip, register_ip);
188 /* if we have some userdata then use that to work out what
189 wins server to try next */
190 if (userdata) {
191 const char *tag = (const char *)userdata->data;
193 /* try the next wins server in our failover list for
194 this tag */
195 rrec->packet->ip = wins_srv_ip_tag(tag, register_ip);
198 /* if we have run out of wins servers for this tag then they
199 must all have timed out. We treat this as *success*, not
200 failure, and go into our standard name refresh mode. This
201 copes with all the wins servers being down */
202 if (wins_srv_is_dead(rrec->packet->ip, register_ip)) {
203 uint16 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
204 int ttl = sent_nmb->additional->ttl;
206 standard_success_register(subrec, userdata, nmbname, nb_flags, ttl, register_ip);
207 if(rrec->success_fn) {
208 (*(register_name_success_function)rrec->success_fn)(subrec,
209 rrec->userdata,
210 nmbname,
211 nb_flags,
212 ttl,
213 register_ip);
216 /* send off a registration for the next IP, if any */
217 wins_next_registration(rrec);
219 /* don't need to send this packet any more */
220 remove_response_record(subrec, rrec);
221 return;
224 /* we will be moving to the next WINS server for this group,
225 send it immediately */
226 rrec->repeat_count = 2;
227 rrec->repeat_time = time(NULL) + 1;
228 rrec->in_expiration_processing = False;
230 DEBUG(6,("Retrying register of name %s IP %s with WINS server %s\n",
231 nmb_namestr(nmbname), src_addr, inet_ntoa(rrec->packet->ip)));
233 /* notice that we don't remove the response record. This keeps
234 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;
254 uint16 nb_flags = 0;
255 int ttl = 0;
256 struct in_addr registered_ip;
258 if (bcast) {
259 if(rrec->num_msgs == 0) {
260 /* Not receiving a message is success for broadcast registration. */
261 success = True;
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(&registered_ip,&sent_nmb->additional->rdata[2]);
268 } else {
269 /* wins timeouts are special */
270 wins_registration_timeout(subrec, rrec);
271 return;
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));
276 if(success) {
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);
282 } else {
283 if( rrec->fail_fn)
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);
293 /****************************************************************************
294 Initiate one multi-homed name registration packet.
295 ****************************************************************************/
297 static void multihomed_register_one(struct nmb_name *nmbname,
298 uint16 nb_flags,
299 register_name_success_function success_fn,
300 register_name_fail_function fail_fn,
301 struct in_addr ip,
302 const char *tag)
304 struct userdata_struct *userdata;
305 struct in_addr wins_ip = wins_srv_ip_tag(tag, ip);
306 fstring ip_str;
308 userdata = (struct userdata_struct *)SMB_MALLOC(sizeof(*userdata) + strlen(tag) + 1);
309 if (!userdata) {
310 DEBUG(0,("Failed to allocate userdata structure!\n"));
311 return;
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,
325 success_fn,
326 fail_fn,
327 userdata,
328 nmbname,
329 nb_flags,
331 wins_ip) == NULL) {
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)));
336 free(userdata);
339 /****************************************************************************
340 We have finished the registration of one IP and need to see if we have
341 any more IPs left to register with this group of wins server for this name.
342 ****************************************************************************/
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;
350 const char *tag;
351 struct in_addr last_ip;
352 struct subnet_record *subrec;
354 putip(&last_ip,&sent_nmb->additional->rdata[2]);
356 if (!userdata) {
357 /* it wasn't multi-homed */
358 return;
361 tag = (const char *)userdata->data;
363 for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
364 if (ip_equal_v4(last_ip, subrec->myip)) {
365 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec);
366 break;
370 if (!subrec) {
371 /* no more to do! */
372 return;
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);
378 break;
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);
384 break;
388 /****************************************************************************
389 Try and register one of our names on the unicast subnet - multihomed.
390 ****************************************************************************/
392 static void multihomed_register_name(struct nmb_name *nmbname, uint16 nb_flags,
393 register_name_success_function success_fn,
394 register_name_fail_function fail_fn)
397 If we are adding a group name, we just send multiple
398 register name packets to the WINS server (this is an
399 internet group name.
401 If we are adding a unique name, We need first to add
402 our names to the unicast subnet namelist. This is
403 because when a WINS server receives a multihomed
404 registration request, the first thing it does is to
405 send a name query to the registering machine, to see
406 if it has put the name in it's local namelist.
407 We need the name there so the query response code in
408 nmbd_incomingrequests.c will find it.
410 We are adding this name prematurely (we don't really
411 have it yet), but as this is on the unicast subnet
412 only we will get away with this (only the WINS server
413 will ever query names from us on this subnet).
415 int num_ips=0;
416 int i, t;
417 struct subnet_record *subrec;
418 char **wins_tags;
419 struct in_addr *ip_list;
420 unstring name;
422 for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
423 num_ips++;
425 if((ip_list = SMB_MALLOC_ARRAY(struct in_addr, num_ips))==NULL) {
426 DEBUG(0,("multihomed_register_name: malloc fail !\n"));
427 return;
430 for (subrec = FIRST_SUBNET, i = 0;
431 subrec;
432 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ ) {
433 ip_list[i] = subrec->myip;
436 pull_ascii_nstring(name, sizeof(name), nmbname->name);
437 add_name_to_subnet(unicast_subnet, name, nmbname->name_type,
438 nb_flags, lp_max_ttl(), SELF_NAME,
439 num_ips, ip_list);
441 /* get the list of wins tags - we try to register for each of them */
442 wins_tags = wins_srv_tags();
444 /* Now try and register the name for each wins tag. Note that
445 at this point we only register our first IP with each wins
446 group. We will register the rest from
447 wins_next_registration() when we get the reply for this
448 one. That follows the way W2K does things (tridge)
450 for (t=0; wins_tags && wins_tags[t]; t++) {
451 multihomed_register_one(nmbname, nb_flags,
452 success_fn, fail_fn,
453 ip_list[0],
454 wins_tags[t]);
457 wins_srv_tags_free(wins_tags);
459 SAFE_FREE(ip_list);
462 /****************************************************************************
463 Try and register one of our names.
464 ****************************************************************************/
466 void register_name(struct subnet_record *subrec,
467 const char *name, int type, uint16 nb_flags,
468 register_name_success_function success_fn,
469 register_name_fail_function fail_fn,
470 struct userdata_struct *userdata)
472 struct nmb_name nmbname;
473 nstring nname;
475 errno = 0;
476 push_ascii_nstring(nname, name);
477 if (errno == E2BIG) {
478 unstring tname;
479 pull_ascii_nstring(tname, sizeof(tname), nname);
480 DEBUG(0,("register_name: NetBIOS name %s is too long. Truncating to %s\n",
481 name, tname));
482 make_nmb_name(&nmbname, tname, type);
483 } else {
484 make_nmb_name(&nmbname, name, type);
487 /* Always set the NB_ACTIVE flag on the name we are
488 registering. Doesn't make sense without it.
491 nb_flags |= NB_ACTIVE;
493 if (subrec == unicast_subnet) {
494 /* we now always do multi-homed registration if we are
495 registering to a WINS server. This copes much
496 better with complex WINS setups */
497 multihomed_register_name(&nmbname, nb_flags,
498 success_fn, fail_fn);
499 return;
502 if (queue_register_name(subrec,
503 register_name_response,
504 register_name_timeout_response,
505 success_fn,
506 fail_fn,
507 userdata,
508 &nmbname,
509 nb_flags) == NULL) {
510 DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
511 nmb_namestr(&nmbname)));
515 /****************************************************************************
516 Try and refresh one of our names. This is *only* called for WINS refresh
517 ****************************************************************************/
519 void wins_refresh_name(struct name_record *namerec)
521 int t;
522 char **wins_tags;
524 /* get the list of wins tags - we try to refresh for each of them */
525 wins_tags = wins_srv_tags();
527 for (t=0; wins_tags && wins_tags[t]; t++) {
528 queue_wins_refresh(&namerec->name,
529 register_name_response,
530 register_name_timeout_response,
531 namerec->data.nb_flags,
532 namerec->data.ip[0], wins_tags[t]);
535 wins_srv_tags_free(wins_tags);