backout all the changes to nmbd.
[samba.git] / source3 / nameresp.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios library routines
5    Copyright (C) Andrew Tridgell 1994-1996
6    
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.
11    
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.
16    
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.
20    
21    Module name: nameresp.c
22
23 */
24
25 #include "includes.h"
26
27 extern int ClientNMB;
28 extern int ClientDGRAM;
29
30 extern struct subnet_record *subnetlist;
31
32 extern int DEBUGLEVEL;
33
34 extern pstring scope;
35 extern struct in_addr ipzero;
36 extern struct in_addr ipgrp;
37
38
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)
44 {
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));
47
48   debug_state_type(n->state);
49
50   switch (n->state)
51   {
52     case NAME_QUERY_CONFIRM:
53     {
54                 if (!lp_wins_support()) return; /* only if we're a WINS server */
55
56                 if (n->num_msgs == 0)
57         {
58                         /* oops. name query had no response. check that the name is
59                            unique and then remove it from our WINS database */
60
61                         /* IMPORTANT: see query_refresh_names() */
62
63                         if ((!NAME_GROUP(n->nb_flags)))
64                         {
65                                 struct subnet_record *d1 = find_subnet(ipgrp);
66                                 if (d1)
67                                 {
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
71                                          */
72                                         remove_netbios_name(d1, n->name.name, n->name.name_type,
73                                                                         REGISTER, n->send_ip);
74                                 }
75                         }
76                 }
77                 break;
78     }
79
80         case NAME_QUERY_MST_CHK:
81         {
82           /* if no response received, the master browser must have gone
83                  down on that subnet, without telling anyone. */
84
85           /* IMPORTANT: see response_netbios_packet() */
86
87           if (n->num_msgs == 0)
88                   browser_gone(n->name.name, n->send_ip);
89           break;
90         }
91
92         case NAME_RELEASE:
93         {
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) */
97
98           /* IMPORTANT: see response_name_release() */
99
100           if (ismyip(n->send_ip))
101           {
102                 name_unregister_work(d,n->name.name,n->name.name_type);
103           }
104           if (!n->bcast)
105           {
106                  DEBUG(0,("WINS server did not respond to name release!\n"));
107          /* XXXX whoops. we have problems. must deal with this */
108           }
109           break;
110         }
111
112         case NAME_REGISTER_CHALLENGE:
113         {
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
116                  */
117
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);
121
122           if (!n->bcast)
123           {
124                  DEBUG(1,("WINS server did not respond to name registration!\n"));
125          /* XXXX whoops. we have problems. must deal with this */
126           }
127       break;
128         }
129
130         case NAME_REGISTER:
131         {
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.
136            */
137           if (n->bcast)
138           {
139                 /* broadcast method: implicit acceptance of the name registration
140                    by not receiving any objections. */
141
142                 /* IMPORTANT: see response_name_reg() */
143
144                 name_register_work(d,n->name.name,n->name.name_type,
145                                 n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
146           }
147           else
148           {
149                 /* received no response. rfc1001.txt states that after retrying,
150                    we should assume the WINS server is dead, and fall back to
151                    broadcasting (see bits about M nodes: can't find any right
152            now) */
153                 
154                 DEBUG(1,("WINS server did not respond to name registration!\n"));
155         /* XXXX whoops. we have problems. must deal with this */
156           }
157           break;
158         }
159
160         default:
161         {
162           /* nothing to do but delete the dead expected-response structure */
163           /* this is normal. */
164           break;
165         }
166   }
167 }
168
169
170 /*******************************************************************
171   remove old name response entries
172
173   XXXX retry code needs to be added, including a retry wait period and a count
174        see name_query() and name_status() for suggested implementation.
175
176   ******************************************************************/
177 void expire_netbios_response_entries()
178 {
179   struct subnet_record *d;
180
181   for (d = subnetlist; d; d = d->next)
182   {
183     struct response_record *n, *nextn;
184
185     for (n = d->responselist; n; n = nextn)
186     {
187           nextn = n->next;
188
189       if (n->repeat_time <= time(NULL))
190           {
191                   if (n->repeat_count > 0)
192                   {
193                         /* resend the entry */
194                         initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
195                                                 n->name.name, n->name.name_type,
196                                       n->nb_flags, n->bcast, n->recurse, n->send_ip);
197
198             n->repeat_time += n->repeat_interval; /* XXXX ms needed */
199             n->repeat_count--;
200
201                   }
202                   else
203                   {
204               DEBUG(4,("timeout response %d for %s %s\n",
205                                                 n->response_id, namestr(&n->name),
206                         inet_ntoa(n->send_ip)));
207
208                           dead_netbios_entry    (d,n); /* process the non-response */
209               remove_response_record(d,n); /* remove the non-response */
210
211                           continue;
212                    }
213           }
214     }
215   }
216 }
217
218
219 /****************************************************************************
220   wrapper function to override a broadcast message and send it to the WINS
221   name server instead, if it exists. if wins is false, and there has been no
222   WINS server specified, the packet will NOT be sent.
223   ****************************************************************************/
224 struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
225                                 int fd,int quest_type,enum state_type state,
226                             char *name,int name_type,int nb_flags, time_t ttl,
227                                 int server_type, char *my_name, char *my_comment,
228                             BOOL bcast,BOOL recurse,
229                                 struct in_addr send_ip, struct in_addr reply_to_ip)
230 {
231   /* XXXX note: please see rfc1001.txt section 10 for details on this
232      function: it is currently inappropriate to use this - it will do
233      for now - once there is a clarification of B, M and P nodes and
234      which one samba is supposed to be
235    */
236
237   if ((!lp_wins_support()) && (*lp_wins_server()))
238     {
239       /* samba is not a WINS server, and we are using a WINS server */
240       struct in_addr wins_ip;
241       wins_ip = *interpret_addr2(lp_wins_server());
242
243       if (!zero_ip(wins_ip))
244         {
245           bcast = False;
246           send_ip = wins_ip;
247         }
248       else
249         {
250           /* oops. smb.conf's wins server parameter MUST be a host_name 
251              or an ip_address. */
252           DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
253         }
254     }
255
256   if (zero_ip(send_ip)) return NULL;
257
258   return queue_netbios_packet(d,fd, quest_type, state, 
259                        name, name_type, nb_flags, ttl,
260                server_type,my_name,my_comment,
261                        bcast, recurse, send_ip, reply_to_ip);
262 }
263
264
265 /****************************************************************************
266   initiate a netbios name query to find someone's or someones' IP
267   this is intended to be used (not exclusively) for broadcasting to
268   master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
269   complete lists across a wide area network
270   ****************************************************************************/
271 struct response_record *queue_netbios_packet(struct subnet_record *d,
272                         int fd,int quest_type,enum state_type state,char *name,
273                         int name_type,int nb_flags, time_t ttl,
274                         int server_type, char *my_name, char *my_comment,
275                     BOOL bcast,BOOL recurse,
276                         struct in_addr send_ip, struct in_addr reply_to_ip)
277 {
278   struct in_addr wins_ip = ipgrp;
279   struct response_record *n;
280   uint16 id = 0xffff;
281
282   /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
283   if (ip_equal(wins_ip, send_ip)) return NULL;
284
285   initiate_netbios_packet(&id, fd, quest_type, name, name_type,
286                                       nb_flags, bcast, recurse, send_ip);
287
288   if (id == 0xffff) {
289     DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
290     return NULL;
291   }
292   
293   if ((n = make_response_queue_record(state,id,fd,
294                                                 quest_type,name,name_type,nb_flags,ttl,
295                                                 server_type,my_name, my_comment,
296                                                 bcast,recurse,send_ip,reply_to_ip)))
297     {
298       add_response_record(d,n);
299       return n;
300     }
301    return NULL;
302 }