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