The function add_name_to_subnet(), in file nmbd_namelistdb.c, returns a
[samba.git] / source3 / nmbd / nmbd_nameregister.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5    Copyright (C) Andrew Tridgell 1994-1998
6    Copyright (C) Luke Kenneth Casson Leighton 1994-1998
7    Copyright (C) Jeremy Allison 1994-1998
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22    
23 */
24
25 #include "includes.h"
26
27 extern int DEBUGLEVEL;
28
29 extern pstring scope;
30 extern fstring global_myworkgroup;
31
32 /****************************************************************************
33  Deal with a response packet when registering one of our names.
34 ****************************************************************************/
35
36 static void register_name_response(struct subnet_record *subrec,
37                        struct response_record *rrec, struct packet_struct *p)
38 {
39   /* 
40    * If we are registering broadcast, then getting a response is an
41    * error - we do not have the name. If we are registering unicast,
42    * then we expect to get a response.
43    */
44
45   struct nmb_packet *nmb = &p->packet.nmb;
46   BOOL bcast = nmb->header.nm_flags.bcast;
47   BOOL success = True;
48   struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
49   struct nmb_name *answer_name = &nmb->answers->rr_name;
50   int ttl = 0;
51   uint16 nb_flags = 0;
52   struct in_addr registered_ip;
53
54   /* Sanity check. Ensure that the answer name in the incoming packet is the
55      same as the requested name in the outgoing packet. */
56
57   if(!nmb_name_equal(question_name, answer_name))
58   {
59     DEBUG(0,("register_name_response: Answer name %s differs from question \
60 name %s.\n", namestr(answer_name), namestr(question_name)));
61     return;
62   }
63
64   if(bcast)
65   {
66     /*
67      * Special hack to cope with old Samba nmbd's.
68      * Earlier versions of Samba (up to 1.9.16p11) respond 
69      * to a broadcast name registration of WORKGROUP<1b> when 
70      * they should not. Hence, until these versions are gone, 
71      * we should treat such errors as success for this particular
72      * case only. jallison@whistle.com.
73      */
74
75 #if 1 /* OLD_SAMBA_SERVER_HACK */
76     if((nmb->header.rcode == ACT_ERR) && strequal(global_myworkgroup, answer_name->name) &&
77          (answer_name->name_type == 0x1b))
78     {
79       /* Pretend we did not get this. */
80       rrec->num_msgs--;
81
82       DEBUG(5,("register_name_response: Ignoring broadcast response to \
83 registration of name %s due to old Samba server bug.\n", namestr(answer_name)));
84       return;
85     }
86 #endif /* OLD_SAMBA_SERVER_HACK */
87
88     /* Someone else has the name. Log the problem. */
89     DEBUG(1,("register_name_response: Failed to register \
90 name %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n", 
91               namestr(answer_name), 
92               subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
93     success = False;
94   }
95   else
96   {
97     /* Unicast - check to see if the response allows us to have the name. */
98     if(nmb->header.rcode != 0)
99     {
100       /* Error code - we didn't get the name. */
101       success = False;
102
103       DEBUG(0,("register_name_response: server at IP %s rejected our \
104 name registration of %s with error code %d.\n", inet_ntoa(p->ip), 
105                   namestr(answer_name), nmb->header.rcode));
106
107     }
108     else if(nmb->header.opcode == NMB_WACK_OPCODE)
109     {
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 \
114 name %s on subnet %s.\n", inet_ntoa(p->ip), namestr(answer_name), subrec->subnet_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     }
122     else
123     {
124       success = True;
125       /* Get the data we need to pass to the success function. */
126       nb_flags = get_nb_flags(nmb->answers->rdata);
127       putip((char*)&registered_ip,&nmb->answers->rdata[2]);
128       ttl = nmb->answers->ttl;
129     }
130   } 
131
132   DEBUG(5,("register_name_response: %s in registering name %s on subnet %s.\n",
133         success ? "success" : "failure", namestr(answer_name), subrec->subnet_name));
134
135   if(success)
136   {
137     /* Enter the registered name into the subnet name database before calling
138        the success function. */
139     standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
140     if( rrec->success_fn)
141       (*rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
142   }
143   else
144   {
145     if( rrec->fail_fn)
146       (*rrec->fail_fn)(subrec, rrec, question_name);
147     /* Remove the name. */
148     standard_fail_register( subrec, rrec, question_name);
149   }
150
151   /* Ensure we don't retry. */
152   remove_response_record(subrec, rrec);
153 }
154
155 /****************************************************************************
156  Deal with a timeout when registering one of our names.
157 ****************************************************************************/
158
159 static void register_name_timeout_response(struct subnet_record *subrec,
160                        struct response_record *rrec)
161 {
162   /*
163    * If we are registering unicast, then NOT getting a response is an
164    * error - we do not have the name. If we are registering broadcast,
165    * then we don't expect to get a response.
166    */
167
168   struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
169   BOOL bcast = sent_nmb->header.nm_flags.bcast;
170   BOOL success = False;
171   struct nmb_name *question_name = &sent_nmb->question.question_name;
172   uint16 nb_flags = 0;
173   int ttl = 0;
174   struct in_addr registered_ip;
175
176   if(bcast)
177   {
178     if(rrec->num_msgs == 0)
179     {
180       /* Not receiving a message is success for broadcast registration. */
181       success = True; 
182
183       /* Pull the success values from the original request packet. */
184       nb_flags = get_nb_flags(sent_nmb->additional->rdata);
185       ttl = sent_nmb->additional->ttl;
186       putip(&registered_ip,&sent_nmb->additional->rdata[2]);
187     }
188   }
189   else
190   {
191     /* Unicast - if no responses then it's an error. */
192     if(rrec->num_msgs == 0)
193     {
194       DEBUG(2,("register_name_timeout_response: WINS server at address %s is not \
195 responding.\n", inet_ntoa(rrec->packet->ip)));
196
197       /* Keep trying to contact the WINS server periodically. This allows
198          us to work correctly if the WINS server is down temporarily when
199          we come up. */
200
201       /* Reset the number of attempts to zero and double the interval between
202          retries. Max out at 5 minutes. */
203       rrec->repeat_count = 3;
204       rrec->repeat_interval *= 2;
205       if(rrec->repeat_interval > (5 * 60))
206         rrec->repeat_interval = (5 * 60);
207       rrec->repeat_time = time(NULL) + rrec->repeat_interval;
208
209       DEBUG(5,("register_name_timeout_response: increasing WINS timeout to %d seconds.\n",
210               rrec->repeat_interval));
211       return; /* Don't remove the response record. */
212     }
213   }
214
215   DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
216         success ? "success" : "failure", namestr(question_name), subrec->subnet_name));
217   if(success)
218   {
219     /* Enter the registered name into the subnet name database before calling
220        the success function. */
221     standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
222     if( rrec->success_fn)
223       (*rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
224   }
225   else
226   {
227     if( rrec->fail_fn)
228       (*rrec->fail_fn)(subrec, rrec, question_name);
229     /* Remove the name. */
230     standard_fail_register( subrec, rrec, question_name);
231   }
232
233   /* Ensure we don't retry. */
234   remove_response_record(subrec, rrec);
235 }
236
237 /****************************************************************************
238  Try and register one of our names on the unicast subnet - multihomed.
239 ****************************************************************************/
240
241 static BOOL multihomed_register_name( struct nmb_name *nmbname, uint16 nb_flags,
242                                       register_name_success_function success_fn,
243                                       register_name_fail_function fail_fn,
244                                       struct userdata_struct *userdata)
245 {
246   /*
247      If we are adding a group name, we just send multiple
248      register name packets to the WINS server (this is an
249      internet group name.
250
251      If we are adding a unique name, We need first to add 
252      our names to the unicast subnet namelist. This is 
253      because when a WINS server receives a multihomed 
254      registration request, the first thing it does is to 
255      send a name query to the registering machine, to see 
256      if it has put the name in it's local namelist.
257      We need the name there so the query response code in
258      nmbd_incomingrequests.c will find it.
259
260      We are adding this name prematurely (we don't really
261      have it yet), but as this is on the unicast subnet
262      only we will get away with this (only the WINS server
263      will ever query names from us on this subnet).
264    */
265
266   int num_ips=0;
267   int i;
268   struct in_addr *ip_list = NULL;
269   struct subnet_record *subrec;
270
271   for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
272     num_ips++;
273
274   if((ip_list = (struct in_addr *)malloc(num_ips * sizeof(struct in_addr)))==NULL)
275   {
276     DEBUG(0,("multihomed_register_name: malloc fail !\n"));
277     return True;
278   }
279
280   for( subrec = FIRST_SUBNET, i = 0; 
281        subrec;
282        subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ )
283     ip_list[i] = subrec->myip;
284
285   (void)add_name_to_subnet( unicast_subnet, nmbname->name, nmbname->name_type,
286                             nb_flags, lp_max_ttl(), SELF_NAME,
287                             num_ips, ip_list);
288
289   /* Now try and register the name, num_ips times. On the last time use
290      the given success and fail functions. */
291
292   for( i = 0; i < num_ips; i++)
293   {
294     if(queue_register_multihomed_name( unicast_subnet,
295         register_name_response,
296         register_name_timeout_response,
297         (i == num_ips - 1) ? success_fn : NULL,
298         (i == num_ips - 1) ? fail_fn : NULL,
299         (i == num_ips - 1) ? userdata : NULL,
300         nmbname,
301         nb_flags,
302         ip_list[i]) == NULL)
303     {
304       DEBUG(0,("multihomed_register_name: Failed to send packet trying to \
305 register name %s IP %s\n", namestr(nmbname), inet_ntoa(ip_list[i]) ));
306
307       free((char *)ip_list);
308       return True;
309     }
310   }
311
312   free((char *)ip_list);
313
314   return False;
315 }
316
317 /****************************************************************************
318  Try and register one of our names.
319 ****************************************************************************/
320
321 BOOL register_name(struct subnet_record *subrec,
322                    char *name, int type, uint16 nb_flags,
323                    register_name_success_function success_fn,
324                    register_name_fail_function fail_fn,
325                    struct userdata_struct *userdata)
326 {
327   struct nmb_name nmbname;
328
329   make_nmb_name(&nmbname, name, type, scope);
330
331   /* Always set the NB_ACTIVE flag on the name we are
332      registering. Doesn't make sense without it.
333    */
334
335   nb_flags |= NB_ACTIVE;
336
337   /* If this is the unicast subnet, and we are a multi-homed
338      host, then register a multi-homed name. */
339
340   if( (subrec == unicast_subnet) && we_are_multihomed())
341     return multihomed_register_name(&nmbname, nb_flags,
342                                     success_fn, fail_fn,
343                                     userdata);
344
345   if(queue_register_name( subrec,
346         register_name_response,
347         register_name_timeout_response,
348         success_fn,
349         fail_fn,
350         userdata,
351         &nmbname,
352         nb_flags) == NULL)
353   {
354     DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
355           namestr(&nmbname)));
356     return True;
357   }
358   return False;
359 }
360
361 /****************************************************************************
362  Try and refresh one of our names.
363 ****************************************************************************/
364
365 BOOL refresh_name(struct subnet_record *subrec, struct name_record *namerec,
366                   refresh_name_success_function success_fn,
367                   refresh_name_fail_function fail_fn,
368                   struct userdata_struct *userdata)
369 {
370   int i;
371
372   /* 
373    * Go through and refresh the name for all known ip addresses.
374    * Only call the success/fail function on the last one (it should
375    * only be done once).
376    */
377
378   for( i = 0; i < namerec->data.num_ips; i++)
379   {
380     if(queue_refresh_name( subrec,
381         register_name_response,
382         register_name_timeout_response,
383         (i == (namerec->data.num_ips - 1)) ? success_fn : NULL,
384         (i == (namerec->data.num_ips - 1)) ? fail_fn : NULL,
385         (i == (namerec->data.num_ips - 1)) ? userdata : NULL,
386         namerec,
387         namerec->data.ip[i]) == NULL)
388     {
389       DEBUG(0,("refresh_name: Failed to send packet trying to refresh name %s\n",
390             namestr(&namerec->name)));
391       return True;
392     }
393   }
394   return False;
395 }