r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[tprouty/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 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 */
26 static 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
33 static 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                 /* 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. */
111
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));
114
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;
123
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;
135
136                         /* send off a registration for the next IP, if any */
137                         wins_next_registration(rrec);
138                 }
139         } 
140
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)));
147
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);
159         }
160
161         /* Ensure we don't retry. */
162         remove_response_record(subrec, rrec);
163 }
164
165 /****************************************************************************
166  Deal with a timeout of a WINS registration request
167 ****************************************************************************/
168
169 static void wins_registration_timeout(struct subnet_record *subrec,
170                                       struct response_record *rrec)
171 {
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;
177
178         putip(&register_ip,&sent_nmb->additional->rdata[2]);
179
180         fstrcpy(src_addr, inet_ntoa(register_ip));
181
182         DEBUG(2,("wins_registration_timeout: WINS server %s timed out registering IP %s\n", 
183                  inet_ntoa(rrec->packet->ip), src_addr));
184
185         /* mark it temporarily dead for this source address */
186         wins_srv_died(rrec->packet->ip, register_ip);
187
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;
192
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);
196         }
197
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;
205
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);
214                 }
215
216                 /* send off a registration for the next IP, if any */
217                 wins_next_registration(rrec);
218
219                 /* don't need to send this packet any more */
220                 remove_response_record(subrec, rrec);
221                 return;
222         }
223         
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;
229
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)));
232
233         /* notice that we don't remove the response record. This keeps
234            us trying to register with each of our failover wins servers */
235 }
236
237 /****************************************************************************
238  Deal with a timeout when registering one of our names.
239 ****************************************************************************/
240
241 static void register_name_timeout_response(struct subnet_record *subrec,
242                                            struct response_record *rrec)
243 {
244         /*
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.
248          */
249
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;
257         
258         if (bcast) {
259                 if(rrec->num_msgs == 0) {
260                         /* Not receiving a message is success for broadcast registration. */
261                         success = True; 
262
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]);
267                 }
268         } else {
269                 /* wins timeouts are special */
270                 wins_registration_timeout(subrec, rrec);
271                 return;
272         }
273
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);
287         }
288
289         /* Ensure we don't retry. */
290         remove_response_record(subrec, rrec);
291 }
292
293 /****************************************************************************
294  Initiate one multi-homed name registration packet.
295 ****************************************************************************/
296
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)
303 {
304         struct userdata_struct *userdata;
305         struct in_addr wins_ip = wins_srv_ip_tag(tag, ip);
306         fstring ip_str;
307
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;
312         }
313         ZERO_STRUCTP(userdata);
314         userdata->userdata_len = strlen(tag) + 1;
315         strlcpy(userdata->data, tag, userdata->userdata_len);   
316
317         fstrcpy(ip_str, inet_ntoa(ip));
318
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));
321
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,
330                                            ip,
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)));         
334         }
335
336         free(userdata);
337 }
338
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 ****************************************************************************/
343
344 static void wins_next_registration(struct response_record *rrec)
345 {
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;
353
354         putip(&last_ip,&sent_nmb->additional->rdata[2]);
355
356         if (!userdata) {
357                 /* it wasn't multi-homed */
358                 return;
359         }
360
361         tag = (const char *)userdata->data;
362
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);
366                         break;
367                 }
368         }
369
370         if (!subrec) {
371                 /* no more to do! */
372                 return;
373         }
374
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;
385         }
386 }
387
388 /****************************************************************************
389  Try and register one of our names on the unicast subnet - multihomed.
390 ****************************************************************************/
391
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)
395 {
396         /*
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.
400
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.
409
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).
414         */
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;
421
422         for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
423                 num_ips++;
424         
425         if((ip_list = SMB_MALLOC_ARRAY(struct in_addr, num_ips))==NULL) {
426                 DEBUG(0,("multihomed_register_name: malloc fail !\n"));
427                 return;
428         }
429
430         for (subrec = FIRST_SUBNET, i = 0; 
431              subrec;
432              subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ ) {
433                 ip_list[i] = subrec->myip;
434         }
435
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);
440
441         /* get the list of wins tags - we try to register for each of them */
442         wins_tags = wins_srv_tags();
443
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)
449         */
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]);
455         }
456
457         wins_srv_tags_free(wins_tags);
458         
459         SAFE_FREE(ip_list);
460 }
461
462 /****************************************************************************
463  Try and register one of our names.
464 ****************************************************************************/
465
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)
471 {
472         struct nmb_name nmbname;
473         nstring nname;
474
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);
485         }
486
487         /* Always set the NB_ACTIVE flag on the name we are
488            registering. Doesn't make sense without it.
489         */
490         
491         nb_flags |= NB_ACTIVE;
492         
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;
500         }
501         
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)));
512         }
513 }
514
515 /****************************************************************************
516  Try and refresh one of our names. This is *only* called for WINS refresh
517 ****************************************************************************/
518
519 void wins_refresh_name(struct name_record *namerec)
520 {
521         int t;
522         char **wins_tags;
523
524         /* get the list of wins tags - we try to refresh for each of them */
525         wins_tags = wins_srv_tags();
526
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]);
533         }
534
535         wins_srv_tags_free(wins_tags);
536 }