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