added code that checks whether the DOMAIN<1b> name is claimed on the
[Samba.git] / source / nameresp.c
blob77addc298529970ac253cc8dbca8603b65f75aad
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 NBT netbios library routines
5 Copyright (C) Andrew Tridgell 1994-1996
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 Module name: nameresp.c
25 #include "includes.h"
27 extern int ClientNMB;
28 extern int ClientDGRAM;
30 extern struct subnet_record *subnetlist;
32 extern int DEBUGLEVEL;
34 extern pstring scope;
35 extern struct in_addr ipzero;
36 extern struct in_addr ipgrp;
39 /***************************************************************************
40 deals with an entry before it dies
41 **************************************************************************/
42 static void dead_netbios_entry(struct subnet_record *d,
43 struct response_record *n)
45 DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
46 inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
48 debug_state_type(n->state);
50 switch (n->state)
52 case NAME_QUERY_CONFIRM:
54 if (!lp_wins_support()) return; /* only if we're a WINS server */
56 if (n->num_msgs == 0)
58 /* oops. name query had no response. check that the name is
59 unique and then remove it from our WINS database */
61 /* IMPORTANT: see query_refresh_names() */
63 if ((!NAME_GROUP(n->nb_flags)))
65 struct subnet_record *d1 = find_subnet(ipgrp);
66 if (d1)
68 /* remove the name that had been registered with us,
69 and we're now getting no response when challenging.
70 see rfc1001.txt 15.5.2
72 remove_netbios_name(d1, n->name.name, n->name.name_type,
73 REGISTER, n->send_ip);
77 break;
80 case NAME_QUERY_MST_CHK:
82 /* if no response received, the master browser must have gone
83 down on that subnet, without telling anyone. */
85 /* IMPORTANT: see response_netbios_packet() */
87 if (n->num_msgs == 0)
88 browser_gone(n->name.name, n->send_ip);
89 break;
92 case NAME_RELEASE:
94 /* if no response received, it must be OK for us to release the
95 name. nobody objected (including a potentially dead or deaf
96 WINS server) */
98 /* IMPORTANT: see response_name_release() */
100 if (ismyip(n->send_ip))
102 name_unregister_work(d,n->name.name,n->name.name_type);
104 if (!n->bcast && n->num_msgs == 0)
106 DEBUG(0,("WINS server did not respond to name release!\n"));
107 /* XXXX whoops. we have problems. must deal with this */
109 break;
112 case NAME_REGISTER_CHALLENGE:
114 /* name challenge: no reply. we can reply to the person that
115 wanted the unique name and tell them that they can have it
118 add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
119 n->nb_flags, GET_TTL(0),
120 n->reply_to_ip, False, n->reply_to_ip);
122 if (!n->bcast && n->num_msgs == 0)
124 DEBUG(1,("WINS server did not respond to name registration!\n"));
125 /* XXXX whoops. we have problems. must deal with this */
127 break;
130 case NAME_REGISTER:
132 /* if no response received, and we are using a broadcast registration
133 method, it must be OK for us to register the name: nobody objected
134 on that subnet. if we are using a WINS server, then the WINS
135 server must be dead or deaf.
137 if (n->num_msgs == 0)
139 if (n->bcast)
141 /* broadcast method: implicit acceptance of the name registration
142 by not receiving any objections. */
144 /* IMPORTANT: see response_name_reg() */
146 name_register_work(d,n->name.name,n->name.name_type,
147 n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
149 else
151 /* received no response. rfc1001.txt states that after retrying,
152 we should assume the WINS server is dead, and fall back to
153 broadcasting (see bits about M nodes: can't find any right
154 now) */
156 DEBUG(1,("WINS server did not respond to name registration!\n"));
157 /* XXXX whoops. we have problems. must deal with this */
160 break;
163 case NAME_QUERY_DOMAIN:
165 /* if no response received, there is no domain controller on
166 this local subnet. it's ok for us to register
169 if (!n->bcast)
171 DEBUG(0,("NAME_QUERY_DOMAIN incorrectly used - contact samba-bugs!\n"));
172 /* XXXX whoops. someone's using this to unicast a packet. this state
173 should only be used for broadcast checks
175 break;
177 if (n->num_msgs == 0)
179 if (ismyip(n->send_ip))
181 struct work_record *work = find_workgroupstruct(d,n->name.name,False);
182 if (work && d)
184 become_domain_master(d,work);
188 break;
191 default:
193 /* nothing to do but delete the dead expected-response structure */
194 /* this is normal. */
195 break;
201 /*******************************************************************
202 remove old name response entries
204 XXXX retry code needs to be added, including a retry wait period and a count
205 see name_query() and name_status() for suggested implementation.
207 ******************************************************************/
208 void expire_netbios_response_entries(time_t t)
210 struct subnet_record *d;
212 for (d = subnetlist; d; d = d->next)
214 struct response_record *n, *nextn;
216 for (n = d->responselist; n; n = nextn)
218 nextn = n->next;
220 if (n->repeat_time <= t)
222 if (n->repeat_count > 0)
224 /* resend the entry */
225 initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
226 n->name.name, n->name.name_type,
227 n->nb_flags, n->bcast, n->recurse, n->send_ip);
229 n->repeat_time += n->repeat_interval; /* XXXX ms needed */
230 n->repeat_count--;
233 else
235 DEBUG(4,("timeout response %d for %s %s\n",
236 n->response_id, namestr(&n->name),
237 inet_ntoa(n->send_ip)));
239 dead_netbios_entry (d,n); /* process the non-response */
240 remove_response_record(d,n); /* remove the non-response */
242 continue;
250 /****************************************************************************
251 wrapper function to override a broadcast message and send it to the WINS
252 name server instead, if it exists. if wins is false, and there has been no
253 WINS server specified, the packet will NOT be sent.
254 ****************************************************************************/
255 struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
256 int fd,int quest_type,enum state_type state,
257 char *name,int name_type,int nb_flags, time_t ttl,
258 int server_type, char *my_name, char *my_comment,
259 BOOL bcast,BOOL recurse,
260 struct in_addr send_ip, struct in_addr reply_to_ip)
262 /* XXXX note: please see rfc1001.txt section 10 for details on this
263 function: it is currently inappropriate to use this - it will do
264 for now - once there is a clarification of B, M and P nodes and
265 which one samba is supposed to be
268 if ((!lp_wins_support()) && (*lp_wins_server()))
270 /* samba is not a WINS server, and we are using a WINS server */
271 struct in_addr wins_ip;
272 wins_ip = *interpret_addr2(lp_wins_server());
274 if (!zero_ip(wins_ip))
276 bcast = False;
277 send_ip = wins_ip;
279 else
281 /* oops. smb.conf's wins server parameter MUST be a host_name
282 or an ip_address. */
283 DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
287 if (zero_ip(send_ip)) return NULL;
289 return queue_netbios_packet(d,fd, quest_type, state,
290 name, name_type, nb_flags, ttl,
291 server_type,my_name,my_comment,
292 bcast, recurse, send_ip, reply_to_ip);
296 /****************************************************************************
297 initiate a netbios name query to find someone's or someones' IP
298 this is intended to be used (not exclusively) for broadcasting to
299 master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
300 complete lists across a wide area network
301 ****************************************************************************/
302 struct response_record *queue_netbios_packet(struct subnet_record *d,
303 int fd,int quest_type,enum state_type state,char *name,
304 int name_type,int nb_flags, time_t ttl,
305 int server_type, char *my_name, char *my_comment,
306 BOOL bcast,BOOL recurse,
307 struct in_addr send_ip, struct in_addr reply_to_ip)
309 struct in_addr wins_ip = ipgrp;
310 struct response_record *n;
311 uint16 id = 0xffff;
313 /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
314 if (ip_equal(wins_ip, send_ip)) return NULL;
316 initiate_netbios_packet(&id, fd, quest_type, name, name_type,
317 nb_flags, bcast, recurse, send_ip);
319 if (id == 0xffff) {
320 DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
321 return NULL;
324 if ((n = make_response_queue_record(state,id,fd,
325 quest_type,name,name_type,nb_flags,ttl,
326 server_type,my_name, my_comment,
327 bcast,recurse,send_ip,reply_to_ip)))
329 add_response_record(d,n);
330 return n;
332 return NULL;