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