Chris will be pleased to know that mkproto.awk no longer runs on the
[Samba.git] / source / nameserv.c
bloba05db3983ec4fdb15c080e6364eb83a5b72865e0
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1997
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: nameserv.c
23 Revision History:
25 14 jan 96: lkcl@pires.co.uk
26 added multiple workgroup domain master support
28 04 jul 96: lkcl@pires.co.uk
29 module nameserv contains name server management functions
32 #include "includes.h"
34 extern int ClientNMB;
36 extern int DEBUGLEVEL;
38 extern pstring scope;
39 extern pstring myname;
40 extern fstring myworkgroup;
41 extern char **my_netbios_names;
42 extern struct in_addr ipzero;
43 extern struct in_addr wins_ip;
45 extern struct subnet_record *subnetlist;
47 extern uint16 nb_type; /* samba's NetBIOS type */
49 /****************************************************************************
50 remove an entry from the name list
52 note: the name will _always_ be removed
53 XXXX at present, the name is removed _even_ if a WINS server says keep it.
55 ****************************************************************************/
56 void remove_name_entry(struct subnet_record *d, char *name,int type)
58 /* XXXX BUG: if samba is offering WINS support, it should still broadcast
59 a de-registration packet to the local subnet before removing the
60 name from its local-subnet name database. */
62 struct name_record n;
63 struct name_record *n2=NULL;
65 make_nmb_name(&n.name,name,type,scope);
67 if ((n2 = find_name_on_subnet(d, &n.name, FIND_SELF_NAME)))
69 /* check name isn't already being de-registered */
70 if (NAME_DEREG(n2->ip_flgs[0].nb_flags))
71 return;
73 /* mark the name as in the process of deletion. */
74 n2->ip_flgs[0].nb_flags &= NB_DEREG;
77 if (!n2) return;
79 /* Only remove names with non-zero death times. */
80 if(n2->death_time == 0)
82 DEBUG(5,("remove_name_entry: Name %s(%d) has zero ttl - not removing.\n",
83 name, type));
84 return;
87 /* remove the name immediately. even if the spec says we should
88 first try to release them, this is too dangerous with our current
89 name structures as otherwise we will end up replying to names we
90 don't really own */
91 remove_netbios_name(d,name,type,SELF);
93 if (ip_equal(d->bcast_ip, wins_ip))
95 if (!lp_wins_support())
97 /* not a WINS server: we have to release them on the network */
98 queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE,
99 name, type, 0, 0,0,NULL,NULL,
100 ipzero, ipzero);
103 else
105 /* local interface: release them on the network */
106 queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
107 name, type, 0, 0,0,NULL,NULL,
108 True, False, d->bcast_ip, d->bcast_ip, 0);
113 /****************************************************************************
114 add an entry to the name list
116 big note: our name will _always_ be added (if there are no objections).
117 it's just a matter of when this will be done (e.g after a time-out).
119 ****************************************************************************/
120 void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
122 BOOL re_reg = False;
123 struct nmb_name n;
125 if (!d) return;
127 /* not that it particularly matters, but if the SELF name already exists,
128 it must be re-registered, rather than just registered */
130 make_nmb_name(&n, name, type, scope);
131 if (find_name_on_subnet(d, &n, FIND_SELF_NAME))
132 re_reg = True;
134 /* XXXX BUG: if samba is offering WINS support, it should still add the
135 name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
136 regarding the point about M-nodes. */
138 if (ip_equal(d->bcast_ip, wins_ip))
140 if (lp_wins_support())
142 /* we are a WINS server. */
143 if(lp_wins_support())
145 DEBUG(4,("add_my_name_entry: samba as WINS server adding: "));
148 /* this will call add_netbios_entry() */
149 name_register_work(d, name, type, nb_flags,0, ipzero, False);
151 else
153 DEBUG(4,("add_my_name_entry registering name %s with WINS server.\n",
154 name));
156 /* a time-to-live allows us to refresh this name with the WINS server. */
157 queue_netbios_pkt_wins(ClientNMB,
158 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
159 name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
160 ipzero, ipzero);
163 else
165 /* broadcast the packet */
166 queue_netbios_packet(d,ClientNMB,
167 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
168 name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
169 True, False, d->bcast_ip, ipzero, 0);
174 /****************************************************************************
175 add the internet group <1c> domain logon names by wins unicast and broadcast.
176 ****************************************************************************/
177 void add_domain_logon_names(void)
179 struct subnet_record *d;
181 if (!lp_domain_logons()) return;
183 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
185 struct work_record *work = find_workgroupstruct(d, myworkgroup, True);
187 if (work && work->log_state == LOGON_NONE)
189 struct nmb_name n;
190 make_nmb_name(&n,myworkgroup,0x1c,scope);
192 if (!find_name_on_subnet(d, &n, FIND_SELF_NAME))
194 /* logon servers are group names. don't expect failure */
196 DEBUG(0,("%s attempting to become logon server for %s %s\n",
197 timestring(), myworkgroup, inet_ntoa(d->bcast_ip)));
199 become_logon_server(d, work);
206 /****************************************************************************
207 add the <1b> domain master names by broadcast.
208 ****************************************************************************/
209 void add_domain_master_bcast(void)
211 struct subnet_record *d;
213 if (!lp_domain_master()) return;
215 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
217 struct work_record *work = find_workgroupstruct(d, myworkgroup, True);
219 if (work && work->dom_state == DOMAIN_NONE)
221 struct nmb_name n;
222 make_nmb_name(&n,myworkgroup,0x1b,scope);
224 if (!find_name_on_subnet(d, &n, FIND_SELF_NAME))
226 DEBUG(0,("%s add_domain_names: attempting to become domain \
227 master browser on workgroup %s %s\n", timestring(), myworkgroup, inet_ntoa(d->bcast_ip)));
229 /* send out a query to establish whether there's a
230 domain controller on the local subnet. if not,
231 we can become a domain controller. it's only
232 polite that we check, before claiming the
233 NetBIOS name 0x1b.
236 DEBUG(0,("add_domain_names:querying subnet %s \
237 for domain master on workgroup %s\n", inet_ntoa(d->bcast_ip), myworkgroup));
239 queue_netbios_packet(d,ClientNMB,NMB_QUERY,
240 NAME_QUERY_DOMAIN,
241 myworkgroup, 0x1b,
242 0, 0,0,NULL,NULL,
243 True, False,
244 d->bcast_ip, d->bcast_ip, 0);
251 /****************************************************************************
252 add the <1b> domain master name by wins unicast.
253 ****************************************************************************/
254 void add_domain_master_wins(void)
256 struct work_record *work;
258 if (!lp_domain_master() || wins_client_subnet == NULL) return;
260 work = find_workgroupstruct(wins_client_subnet, myworkgroup, True);
262 if (work && work->dom_state == DOMAIN_NONE)
264 struct nmb_name n;
265 make_nmb_name(&n,myworkgroup,0x1b,scope);
267 if (!find_name_on_subnet(wins_client_subnet, &n, FIND_SELF_NAME))
269 DEBUG(0,("%s add_domain_names: attempting to become domain \
270 master browser on workgroup %s %s\n",
271 timestring(), myworkgroup, inet_ntoa(wins_client_subnet->bcast_ip)));
273 if (lp_wins_support())
275 /* use the wins server's capabilities (indirectly). if
276 someone has already registered the domain<1b>
277 name with the WINS server, then the WINS
278 server's job is to _check_ that the owner still
279 wants it, before giving it away.
282 DEBUG(1,("%s initiate become domain master for %s\n",
283 timestring(), myworkgroup));
285 become_domain_master(wins_client_subnet, work);
287 else
289 /* send out a query to establish whether there's a
290 domain controller on the WINS subnet. if not,
291 we can become a domain controller. it's only
292 polite that we check, before claiming the
293 NetBIOS name 0x1b.
296 DEBUG(0,("add_domain_names:querying WINS \
297 for domain master on workgroup %s\n", myworkgroup));
299 queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
300 NAME_QUERY_DOMAIN,
301 myworkgroup, 0x1b,
302 0, 0,0,NULL,NULL,
303 ipzero, ipzero);
310 /****************************************************************************
311 add the domain logon server and domain master browser names
313 this code was written so that several samba servers can co-operate in
314 sharing the task of (one server) being a domain master, and of being
315 domain logon servers.
317 **************************************************************************/
318 void add_domain_names(time_t t)
320 static time_t lastrun = 0;
322 if (lastrun != 0 && t < lastrun + CHECK_TIME_ADD_DOM_NAMES * 60) return;
323 lastrun = t;
325 /* do the "internet group" - <1c> names */
326 add_domain_logon_names();
328 /* do the domain master names */
329 if (wins_client_subnet != NULL)
331 /* if the registration of the <1b> name is successful, then
332 add_domain_master_bcast() will be called. this will
333 result in domain logon services being gracefully provided,
334 as opposed to the aggressive nature of 1.9.16p2 to 1.9.16p11.
336 which, due to a bug in namelogon.c from 1.9.16p2 to 1.9.16p11
337 cannot _provide_ domain master / domain logon services!!!
340 add_domain_master_wins();
342 else
344 add_domain_master_bcast();
348 /****************************************************************************
349 add the magic samba names, useful for finding samba servers
350 **************************************************************************/
351 void add_my_names(void)
353 struct subnet_record *d;
354 /* each subnet entry, including WINS pseudo-subnet, has SELF names */
356 /* XXXX if there was a transport layer added to samba (ipx/spx etc) then
357 there would be yet _another_ for-loop, this time on the transport type
360 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
362 int n;
364 /* Add all our names including aliases. */
365 for (n=0; my_netbios_names[n]; n++)
367 add_my_name_entry(d, my_netbios_names[n],0x20,nb_type|NB_ACTIVE);
368 add_my_name_entry(d, my_netbios_names[n],0x03,nb_type|NB_ACTIVE);
369 add_my_name_entry(d, my_netbios_names[n],0x00,nb_type|NB_ACTIVE);
372 /* these names are added permanently (ttl of zero) and will NOT be
373 refreshed with the WINS server */
374 add_netbios_entry(d,"*",0x0,nb_type|NB_ACTIVE,0,SELF,d->myip,False);
375 add_netbios_entry(d,"*",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False);
376 add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False);
377 add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,d->myip,False);
382 /****************************************************************************
383 remove all the samba names... from a WINS server if necessary.
384 **************************************************************************/
385 void remove_my_names()
387 struct subnet_record *d;
389 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
391 struct name_record *n, *next;
393 for (n = d->namelist; n; n = next)
395 next = n->next;
396 if (n->source == SELF)
398 /* get all SELF names removed from the WINS server's database */
399 /* XXXX note: problem occurs if this removes the wrong one! */
401 remove_name_entry(d,n->name.name, n->name.name_type);
408 /*******************************************************************
409 refresh my own names
410 ******************************************************************/
411 void refresh_my_names(time_t t)
413 struct subnet_record *d;
415 for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
417 struct name_record *n;
419 for (n = d->namelist; n; n = n->next)
421 /* each SELF name has an individual time to be refreshed */
422 if (n->source == SELF && n->refresh_time < t &&
423 n->death_time != 0)
425 add_my_name_entry(d,n->name.name,n->name.name_type,
426 n->ip_flgs[0].nb_flags);
427 /* they get a new lease on life :-) */
428 n->death_time += GET_TTL(0);
429 n->refresh_time += GET_TTL(0);
436 /*******************************************************************
437 queries names occasionally. an over-cautious, non-trusting WINS server!
439 this function has been added because nmbd could be restarted. it
440 is generally a good idea to check all the names that have been
441 reloaded from file.
443 XXXX which names to poll and which not can be refined at a later date.
444 ******************************************************************/
445 void query_refresh_names(time_t t)
447 struct name_record *n;
448 struct subnet_record *d = wins_client_subnet;
450 static time_t lasttime = 0;
452 int count = 0;
453 int name_refresh_time = NAME_POLL_REFRESH_TIME;
454 int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
455 if (max_count > 10) max_count = 10;
457 name_refresh_time = NAME_POLL_INTERVAL * max_count / 2;
459 /* if (!lp_poll_wins()) return; polling of registered names allowed */
461 if (!d) return;
463 if (!lasttime) lasttime = t;
464 if (t - lasttime < NAME_POLL_INTERVAL) return;
466 lasttime = time(NULL);
468 for (n = d->namelist; n; n = n->next)
470 /* only do unique, registered names */
472 if (n->source != REGISTER) continue;
473 if (!NAME_GROUP(n->ip_flgs[0].nb_flags)) continue;
475 if (n->refresh_time < t)
477 DEBUG(3,("Polling name %s\n", namestr(&n->name)));
479 queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
480 n->name.name, n->name.name_type,
481 0,0,0,NULL,NULL,
482 False,False,n->ip_flgs[0].ip,n->ip_flgs[0].ip,
484 count++;
487 if (count >= max_count)
489 /* don't do too many of these at once, but do enough to
490 cover everyone in the list */
491 return;
494 /* this name will be checked on again, if it's not removed */
495 n->refresh_time += name_refresh_time;