first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[ira/wip.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(!question_name || !answer_name)
58   {
59     DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
60            question_name ? "question_name" : "answer_name" ));
61     return;
62   }
63
64   if(!nmb_name_equal(question_name, answer_name))
65   {
66     DEBUG(0,("register_name_response: Answer name %s differs from question \
67 name %s.\n", nmb_namestr(answer_name), nmb_namestr(question_name)));
68     return;
69   }
70
71   if(bcast)
72   {
73     /*
74      * Special hack to cope with old Samba nmbd's.
75      * Earlier versions of Samba (up to 1.9.16p11) respond 
76      * to a broadcast name registration of WORKGROUP<1b> when 
77      * they should not. Hence, until these versions are gone, 
78      * we should treat such errors as success for this particular
79      * case only. jallison@whistle.com.
80      */
81
82 #if 1 /* OLD_SAMBA_SERVER_HACK */
83     if((nmb->header.rcode == ACT_ERR) && strequal(global_myworkgroup, answer_name->name) &&
84          (answer_name->name_type == 0x1b))
85     {
86       /* Pretend we did not get this. */
87       rrec->num_msgs--;
88
89       DEBUG(5,("register_name_response: Ignoring broadcast response to \
90 registration of name %s due to old Samba server bug.\n", nmb_namestr(answer_name)));
91       return;
92     }
93 #endif /* OLD_SAMBA_SERVER_HACK */
94
95     /* Someone else has the name. Log the problem. */
96     DEBUG(1,("register_name_response: Failed to register \
97 name %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n", 
98               nmb_namestr(answer_name), 
99               subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
100     success = False;
101   }
102   else
103   {
104     /* Unicast - check to see if the response allows us to have the name. */
105     if(nmb->header.rcode != 0)
106     {
107       /* Error code - we didn't get the name. */
108       success = False;
109
110       DEBUG(0,("register_name_response: server at IP %s rejected our \
111 name registration of %s with error code %d.\n", inet_ntoa(p->ip), 
112                   nmb_namestr(answer_name), nmb->header.rcode));
113
114     }
115     else if(nmb->header.opcode == NMB_WACK_OPCODE)
116     {
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 \
121 name %s on subnet %s.\n", inet_ntoa(p->ip), nmb_namestr(answer_name), subrec->subnet_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     }
129     else
130     {
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       putip((char*)&registered_ip,&nmb->answers->rdata[2]);
135       ttl = nmb->answers->ttl;
136     }
137   } 
138
139   DEBUG(5,("register_name_response: %s in registering name %s on subnet %s.\n",
140         success ? "success" : "failure", nmb_namestr(answer_name), subrec->subnet_name));
141
142   if(success)
143   {
144     /* Enter the registered name into the subnet name database before calling
145        the success function. */
146     standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
147     if( rrec->success_fn)
148       (*rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
149   }
150   else
151   {
152     if( rrec->fail_fn)
153       (*rrec->fail_fn)(subrec, rrec, question_name);
154     /* Remove the name. */
155     standard_fail_register( subrec, rrec, question_name);
156   }
157
158   /* Ensure we don't retry. */
159   remove_response_record(subrec, rrec);
160 }
161
162 /****************************************************************************
163  Deal with a timeout when registering one of our names.
164 ****************************************************************************/
165
166 static void register_name_timeout_response(struct subnet_record *subrec,
167                        struct response_record *rrec)
168 {
169   /*
170    * If we are registering unicast, then NOT getting a response is an
171    * error - we do not have the name. If we are registering broadcast,
172    * then we don't expect to get a response.
173    */
174
175   struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
176   BOOL bcast = sent_nmb->header.nm_flags.bcast;
177   BOOL success = False;
178   struct nmb_name *question_name = &sent_nmb->question.question_name;
179   uint16 nb_flags = 0;
180   int ttl = 0;
181   struct in_addr registered_ip;
182
183   if(bcast)
184   {
185     if(rrec->num_msgs == 0)
186     {
187       /* Not receiving a message is success for broadcast registration. */
188       success = True; 
189
190       /* Pull the success values from the original request packet. */
191       nb_flags = get_nb_flags(sent_nmb->additional->rdata);
192       ttl = sent_nmb->additional->ttl;
193       putip(&registered_ip,&sent_nmb->additional->rdata[2]);
194     }
195   }
196   else
197   {
198     /* Unicast - if no responses then it's an error. */
199     if(rrec->num_msgs == 0)
200     {
201       DEBUG(2,("register_name_timeout_response: WINS server at address %s is not \
202 responding.\n", inet_ntoa(rrec->packet->ip)));
203
204       /* Keep trying to contact the WINS server periodically. This allows
205          us to work correctly if the WINS server is down temporarily when
206          we come up. */
207
208       /* Reset the number of attempts to zero and double the interval between
209          retries. Max out at 5 minutes. */
210       rrec->repeat_count = 3;
211       rrec->repeat_interval *= 2;
212       if(rrec->repeat_interval > (5 * 60))
213         rrec->repeat_interval = (5 * 60);
214       rrec->repeat_time = time(NULL) + rrec->repeat_interval;
215
216       DEBUG(5,("register_name_timeout_response: increasing WINS timeout to %d seconds.\n",
217               (int)rrec->repeat_interval));
218       return; /* Don't remove the response record. */
219     }
220   }
221
222   DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
223         success ? "success" : "failure", nmb_namestr(question_name), subrec->subnet_name));
224   if(success)
225   {
226     /* Enter the registered name into the subnet name database before calling
227        the success function. */
228     standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
229     if( rrec->success_fn)
230       (*rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
231   }
232   else
233   {
234     if( rrec->fail_fn)
235       (*rrec->fail_fn)(subrec, rrec, question_name);
236     /* Remove the name. */
237     standard_fail_register( subrec, rrec, question_name);
238   }
239
240   /* Ensure we don't retry. */
241   remove_response_record(subrec, rrec);
242 }
243
244 /****************************************************************************
245  Try and register one of our names on the unicast subnet - multihomed.
246 ****************************************************************************/
247
248 static BOOL multihomed_register_name( struct nmb_name *nmbname, uint16 nb_flags,
249                                       register_name_success_function success_fn,
250                                       register_name_fail_function fail_fn,
251                                       struct userdata_struct *userdata)
252 {
253   /*
254      If we are adding a group name, we just send multiple
255      register name packets to the WINS server (this is an
256      internet group name.
257
258      If we are adding a unique name, We need first to add 
259      our names to the unicast subnet namelist. This is 
260      because when a WINS server receives a multihomed 
261      registration request, the first thing it does is to 
262      send a name query to the registering machine, to see 
263      if it has put the name in it's local namelist.
264      We need the name there so the query response code in
265      nmbd_incomingrequests.c will find it.
266
267      We are adding this name prematurely (we don't really
268      have it yet), but as this is on the unicast subnet
269      only we will get away with this (only the WINS server
270      will ever query names from us on this subnet).
271    */
272
273   int num_ips=0;
274   int i;
275   struct in_addr *ip_list = NULL;
276   struct subnet_record *subrec;
277
278   for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
279     num_ips++;
280
281   if((ip_list = (struct in_addr *)malloc(num_ips * sizeof(struct in_addr)))==NULL)
282   {
283     DEBUG(0,("multihomed_register_name: malloc fail !\n"));
284     return True;
285   }
286
287   for( subrec = FIRST_SUBNET, i = 0; 
288        subrec;
289        subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ )
290     ip_list[i] = subrec->myip;
291
292   (void)add_name_to_subnet( unicast_subnet, nmbname->name, nmbname->name_type,
293                             nb_flags, lp_max_ttl(), SELF_NAME,
294                             num_ips, ip_list);
295
296   /* Now try and register the name, num_ips times. On the last time use
297      the given success and fail functions. */
298
299   for( i = 0; i < num_ips; i++)
300   {
301     if(queue_register_multihomed_name( unicast_subnet,
302         register_name_response,
303         register_name_timeout_response,
304         (i == num_ips - 1) ? success_fn : NULL,
305         (i == num_ips - 1) ? fail_fn : NULL,
306         (i == num_ips - 1) ? userdata : NULL,
307         nmbname,
308         nb_flags,
309         ip_list[i]) == NULL)
310     {
311       DEBUG(0,("multihomed_register_name: Failed to send packet trying to \
312 register name %s IP %s\n", nmb_namestr(nmbname), inet_ntoa(ip_list[i]) ));
313
314       free((char *)ip_list);
315       return True;
316     }
317   }
318
319   free((char *)ip_list);
320
321   return False;
322 }
323
324 /****************************************************************************
325  Try and register one of our names.
326 ****************************************************************************/
327
328 BOOL register_name(struct subnet_record *subrec,
329                    char *name, int type, uint16 nb_flags,
330                    register_name_success_function success_fn,
331                    register_name_fail_function fail_fn,
332                    struct userdata_struct *userdata)
333 {
334   struct nmb_name nmbname;
335
336   make_nmb_name(&nmbname, name, type, scope);
337
338   /* Always set the NB_ACTIVE flag on the name we are
339      registering. Doesn't make sense without it.
340    */
341
342   nb_flags |= NB_ACTIVE;
343
344   /* If this is the unicast subnet, and we are a multi-homed
345      host, then register a multi-homed name. */
346
347   if( (subrec == unicast_subnet) && we_are_multihomed())
348     return multihomed_register_name(&nmbname, nb_flags,
349                                     success_fn, fail_fn,
350                                     userdata);
351
352   if(queue_register_name( subrec,
353         register_name_response,
354         register_name_timeout_response,
355         success_fn,
356         fail_fn,
357         userdata,
358         &nmbname,
359         nb_flags) == NULL)
360   {
361     DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
362           nmb_namestr(&nmbname)));
363     return True;
364   }
365   return False;
366 }
367
368 /****************************************************************************
369  Try and refresh one of our names.
370 ****************************************************************************/
371
372 BOOL refresh_name(struct subnet_record *subrec, struct name_record *namerec,
373                   refresh_name_success_function success_fn,
374                   refresh_name_fail_function fail_fn,
375                   struct userdata_struct *userdata)
376 {
377   int i;
378
379   /* 
380    * Go through and refresh the name for all known ip addresses.
381    * Only call the success/fail function on the last one (it should
382    * only be done once).
383    */
384
385   for( i = 0; i < namerec->data.num_ips; i++)
386   {
387     if(queue_refresh_name( subrec,
388         register_name_response,
389         register_name_timeout_response,
390         (i == (namerec->data.num_ips - 1)) ? success_fn : NULL,
391         (i == (namerec->data.num_ips - 1)) ? fail_fn : NULL,
392         (i == (namerec->data.num_ips - 1)) ? userdata : NULL,
393         namerec,
394         namerec->data.ip[i]) == NULL)
395     {
396       DEBUG(0,("refresh_name: Failed to send packet trying to refresh name %s\n",
397             nmb_namestr(&namerec->name)));
398       return True;
399     }
400   }
401   return False;
402 }