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-1998
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 2 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern fstring global_myworkgroup;
28 /****************************************************************************
29 Deal with a response packet when registering one of our names.
30 ****************************************************************************/
32 static void register_name_response(struct subnet_record *subrec,
33 struct response_record *rrec, struct packet_struct *p)
36 * If we are registering broadcast, then getting a response is an
37 * error - we do not have the name. If we are registering unicast,
38 * then we expect to get a response.
41 struct nmb_packet *nmb = &p->packet.nmb;
42 BOOL bcast = nmb->header.nm_flags.bcast;
44 struct nmb_name *question_name = &rrec->packet->packet.nmb.question.question_name;
45 struct nmb_name *answer_name = &nmb->answers->rr_name;
48 struct in_addr registered_ip;
50 /* Sanity check. Ensure that the answer name in the incoming packet is the
51 same as the requested name in the outgoing packet. */
53 if(!question_name || !answer_name)
55 DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
56 question_name ? "question_name" : "answer_name" ));
60 if(!nmb_name_equal(question_name, answer_name))
62 DEBUG(0,("register_name_response: Answer name %s differs from question \
63 name %s.\n", nmb_namestr(answer_name), nmb_namestr(question_name)));
70 * Special hack to cope with old Samba nmbd's.
71 * Earlier versions of Samba (up to 1.9.16p11) respond
72 * to a broadcast name registration of WORKGROUP<1b> when
73 * they should not. Hence, until these versions are gone,
74 * we should treat such errors as success for this particular
75 * case only. jallison@whistle.com.
78 #if 1 /* OLD_SAMBA_SERVER_HACK */
79 if((nmb->header.rcode == ACT_ERR) && strequal(global_myworkgroup, answer_name->name) &&
80 (answer_name->name_type == 0x1b))
82 /* Pretend we did not get this. */
85 DEBUG(5,("register_name_response: Ignoring broadcast response to \
86 registration of name %s due to old Samba server bug.\n", nmb_namestr(answer_name)));
89 #endif /* OLD_SAMBA_SERVER_HACK */
91 /* Someone else has the name. Log the problem. */
92 DEBUG(1,("register_name_response: Failed to register \
93 name %s on subnet %s via broadcast. Error code was %d. Reject came from IP %s\n",
94 nmb_namestr(answer_name),
95 subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
100 /* Unicast - check to see if the response allows us to have the name. */
101 if(nmb->header.rcode != 0)
103 /* Error code - we didn't get the name. */
106 DEBUG(0,("register_name_response: server at IP %s rejected our \
107 name registration of %s with error code %d.\n", inet_ntoa(p->ip),
108 nmb_namestr(answer_name), nmb->header.rcode));
111 else if(nmb->header.opcode == NMB_WACK_OPCODE)
113 /* WINS server is telling us to wait. Pretend we didn't get
114 the response but don't send out any more register requests. */
116 DEBUG(5,("register_name_response: WACK from WINS server %s in registering \
117 name %s on subnet %s.\n", inet_ntoa(p->ip), nmb_namestr(answer_name), subrec->subnet_name));
119 rrec->repeat_count = 0;
120 /* How long we should wait for. */
121 rrec->repeat_time = p->timestamp + nmb->answers->ttl;
128 /* Get the data we need to pass to the success function. */
129 nb_flags = get_nb_flags(nmb->answers->rdata);
130 putip((char*)®istered_ip,&nmb->answers->rdata[2]);
131 ttl = nmb->answers->ttl;
135 DEBUG(5,("register_name_response: %s in registering name %s on subnet %s.\n",
136 success ? "success" : "failure", nmb_namestr(answer_name), subrec->subnet_name));
140 /* Enter the registered name into the subnet name database before calling
141 the success function. */
142 standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
143 if( rrec->success_fn)
144 (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
149 (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
150 /* Remove the name. */
151 standard_fail_register( subrec, rrec, question_name);
154 /* Ensure we don't retry. */
155 remove_response_record(subrec, rrec);
158 /****************************************************************************
159 Deal with a timeout when registering one of our names.
160 ****************************************************************************/
162 static void register_name_timeout_response(struct subnet_record *subrec,
163 struct response_record *rrec)
166 * If we are registering unicast, then NOT getting a response is an
167 * error - we do not have the name. If we are registering broadcast,
168 * then we don't expect to get a response.
171 struct nmb_packet *sent_nmb = &rrec->packet->packet.nmb;
172 BOOL bcast = sent_nmb->header.nm_flags.bcast;
173 BOOL success = False;
174 struct nmb_name *question_name = &sent_nmb->question.question_name;
177 struct in_addr registered_ip;
181 if(rrec->num_msgs == 0)
183 /* Not receiving a message is success for broadcast registration. */
186 /* Pull the success values from the original request packet. */
187 nb_flags = get_nb_flags(sent_nmb->additional->rdata);
188 ttl = sent_nmb->additional->ttl;
189 putip(®istered_ip,&sent_nmb->additional->rdata[2]);
194 /* Unicast - if no responses then it's an error. */
195 if(rrec->num_msgs == 0)
197 DEBUG(2,("register_name_timeout_response: WINS server at address %s is not \
198 responding.\n", inet_ntoa(rrec->packet->ip)));
200 /* mark it temporarily dead */
201 wins_srv_died(rrec->packet->ip);
203 /* and try the next wins server in our failover list */
204 rrec->packet->ip = wins_srv_ip();
206 /* also update the UNICODE subnet IPs */
207 subrec->bcast_ip = subrec->mask_ip = subrec->myip = rrec->packet->ip;
209 /* Keep trying to contact the WINS server periodically. This allows
210 us to work correctly if the WINS server is down temporarily when
213 /* Reset the number of attempts to zero and double the interval between
214 retries. Max out at 5 minutes. */
215 rrec->repeat_count = 3;
216 rrec->repeat_interval *= 2;
217 if(rrec->repeat_interval > (5 * 60))
218 rrec->repeat_interval = (5 * 60);
219 rrec->repeat_time = time(NULL) + rrec->repeat_interval;
220 rrec->in_expiration_processing = False;
222 DEBUG(5,("register_name_timeout_response: increasing WINS timeout to %d seconds.\n",
223 (int)rrec->repeat_interval));
224 return; /* Don't remove the response record. */
228 DEBUG(5,("register_name_timeout_response: %s in registering name %s on subnet %s.\n",
229 success ? "success" : "failure", nmb_namestr(question_name), subrec->subnet_name));
232 /* Enter the registered name into the subnet name database before calling
233 the success function. */
234 standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
235 if( rrec->success_fn)
236 (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
241 (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
242 /* Remove the name. */
243 standard_fail_register( subrec, rrec, question_name);
246 /* Ensure we don't retry. */
247 remove_response_record(subrec, rrec);
250 /****************************************************************************
251 Try and register one of our names on the unicast subnet - multihomed.
252 ****************************************************************************/
254 static BOOL multihomed_register_name( struct nmb_name *nmbname, uint16 nb_flags,
255 register_name_success_function success_fn,
256 register_name_fail_function fail_fn)
259 If we are adding a group name, we just send multiple
260 register name packets to the WINS server (this is an
263 If we are adding a unique name, We need first to add
264 our names to the unicast subnet namelist. This is
265 because when a WINS server receives a multihomed
266 registration request, the first thing it does is to
267 send a name query to the registering machine, to see
268 if it has put the name in it's local namelist.
269 We need the name there so the query response code in
270 nmbd_incomingrequests.c will find it.
272 We are adding this name prematurely (we don't really
273 have it yet), but as this is on the unicast subnet
274 only we will get away with this (only the WINS server
275 will ever query names from us on this subnet).
280 struct in_addr *ip_list = NULL;
281 struct subnet_record *subrec;
283 for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
286 if((ip_list = (struct in_addr *)malloc(num_ips * sizeof(struct in_addr)))==NULL) {
287 DEBUG(0,("multihomed_register_name: malloc fail !\n"));
291 for( subrec = FIRST_SUBNET, i = 0;
293 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ ) {
294 ip_list[i] = subrec->myip;
297 (void)add_name_to_subnet( unicast_subnet, nmbname->name, nmbname->name_type,
298 nb_flags, lp_max_ttl(), SELF_NAME,
301 /* Now try and register the name, num_ips times. On the last time use
302 the given success and fail functions. */
304 for (i = 0; i < num_ips; i++) {
305 if (queue_register_multihomed_name( unicast_subnet,
306 register_name_response,
307 register_name_timeout_response,
308 (i == num_ips - 1) ? success_fn : NULL,
309 (i == num_ips - 1) ? fail_fn : NULL,
313 ip_list[i]) == NULL) {
314 DEBUG(0,("multihomed_register_name: Failed to send packet trying to \
315 register name %s IP %s\n", nmb_namestr(nmbname), inet_ntoa(ip_list[i]) ));
327 /****************************************************************************
328 Try and register one of our names.
329 ****************************************************************************/
331 BOOL register_name(struct subnet_record *subrec,
332 char *name, int type, uint16 nb_flags,
333 register_name_success_function success_fn,
334 register_name_fail_function fail_fn,
335 struct userdata_struct *userdata)
337 struct nmb_name nmbname;
339 make_nmb_name(&nmbname, name, type);
341 /* Always set the NB_ACTIVE flag on the name we are
342 registering. Doesn't make sense without it.
345 nb_flags |= NB_ACTIVE;
347 /* If this is the unicast subnet, and we are a multi-homed
348 host, then register a multi-homed name. */
350 if( (subrec == unicast_subnet) && we_are_multihomed()) {
351 return multihomed_register_name(&nmbname, nb_flags,
352 success_fn, fail_fn);
355 if(queue_register_name( subrec,
356 register_name_response,
357 register_name_timeout_response,
364 DEBUG(0,("register_name: Failed to send packet trying to register name %s\n",
365 nmb_namestr(&nmbname)));
371 /****************************************************************************
372 Try and refresh one of our names.
373 ****************************************************************************/
375 BOOL refresh_name(struct subnet_record *subrec, struct name_record *namerec,
376 refresh_name_success_function success_fn,
377 refresh_name_fail_function fail_fn,
378 struct userdata_struct *userdata)
383 * Go through and refresh the name for all known ip addresses.
384 * Only call the success/fail function on the last one (it should
385 * only be done once).
388 for( i = 0; i < namerec->data.num_ips; i++)
390 if(queue_refresh_name( subrec,
391 register_name_response,
392 register_name_timeout_response,
393 (i == (namerec->data.num_ips - 1)) ? success_fn : NULL,
394 (i == (namerec->data.num_ips - 1)) ? fail_fn : NULL,
395 (i == (namerec->data.num_ips - 1)) ? userdata : NULL,
397 namerec->data.ip[i]) == NULL)
399 DEBUG(0,("refresh_name: Failed to send packet trying to refresh name %s\n",
400 nmb_namestr(&namerec->name)));