2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
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: nameserv.c
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
36 extern int DEBUGLEVEL;
39 extern pstring myname;
40 extern pstring ServerComment;
41 extern struct in_addr ipzero;
42 extern struct in_addr ipgrp;
44 extern struct subnet_record *subnetlist;
47 /****************************************************************************
48 remove an entry from the name list
50 note: the name will _always_ be removed: it's just a matter of when.
51 XXXX at present, the name is removed _even_ if a WINS server says keep it.
53 ****************************************************************************/
54 void remove_name_entry(struct subnet_record *d, char *name,int type)
56 /* XXXX BUG: if samba is offering WINS support, it should still broadcast
57 a de-registration packet to the local subnet before removing the
58 name from its local-subnet name database. */
61 struct name_record *n2=NULL;
63 make_nmb_name(&n.name,name,type,scope);
65 if ((n2 = find_name_search(&d, &n.name, FIND_SELF, ipzero)))
67 /* check name isn't already being de-registered */
68 if (NAME_DEREG(n2->nb_flags))
71 /* mark the name as in the process of deletion. */
72 n2->nb_flags &= NB_DEREG;
75 if (ip_equal(d->bcast_ip, ipgrp))
77 if (lp_wins_support())
79 /* we are a WINS server. */
80 /* XXXX assume that if we are a WINS server that we are therefore
81 not pointing to another WINS server as well. this may later NOT
84 remove_netbios_name(d,name,type,SELF,ipzero);
88 /* not a WINS server: cannot just remove our own names: we have to
89 release them on the network first. ask permission from the WINS
90 server, or if no reply is received, then we can remove the name */
92 queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
94 False, True, ipzero, ipzero);
99 /* local interface: cannot just remove our own names: we have to
100 release them on the network first. once no reply is received,
101 then we can remove the name. */
103 queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
105 True, True, d->bcast_ip, d->bcast_ip);
110 /****************************************************************************
111 add an entry to the name list
113 big note: our name will _always_ be added (if there are no objections).
114 it's just a matter of when this will be done (e.g after a time-out).
116 ****************************************************************************/
117 void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
124 /* not that it particularly matters, but if the SELF name already exists,
125 it must be re-registered, rather than just registered */
127 make_nmb_name(&n, name, type, scope);
128 if (find_name(d->namelist, &n, SELF))
131 /* XXXX BUG: if samba is offering WINS support, it should still add the
132 name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
133 regarding the point about M-nodes. */
135 if (ip_equal(d->bcast_ip, ipgrp))
137 if (lp_wins_support())
139 /* we are a WINS server. */
140 /* XXXX assume that if we are a WINS server that we are therefore
141 not pointing to another WINS server as well. this may later NOT
145 DEBUG(4,("samba as WINS server adding: "));
146 /* this will call add_netbios_entry() */
147 name_register_work(d, name, type, nb_flags,0, ipzero, False);
151 /* a time-to-live allows us to refresh this name with the WINS server. */
152 queue_netbios_pkt_wins(d,ClientNMB,
153 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
154 name, type, nb_flags, GET_TTL(0),
155 False, True, ipzero, ipzero);
160 /* broadcast the packet, but it comes from ipzero */
161 queue_netbios_packet(d,ClientNMB,
162 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
163 name, type, nb_flags, GET_TTL(0),
164 True, True, d->bcast_ip, ipzero);
169 /****************************************************************************
170 add the magic samba names, useful for finding samba servers
171 **************************************************************************/
172 void add_my_names(void)
174 BOOL wins = lp_wins_support();
175 struct subnet_record *d;
177 struct in_addr ip = ipzero;
179 /* each subnet entry, including WINS pseudo-subnet, has SELF names */
181 /* XXXX if there was a transport layer added to samba (ipx/spx etc) then
182 there would be yet _another_ for-loop, this time on the transport type
185 for (d = subnetlist; d; d = d->next)
187 BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
189 add_my_name_entry(d, myname,0x20,NB_ACTIVE);
190 add_my_name_entry(d, myname,0x03,NB_ACTIVE);
191 add_my_name_entry(d, myname,0x00,NB_ACTIVE);
192 add_my_name_entry(d, myname,0x1f,NB_ACTIVE);
194 /* these names are added permanently (ttl of zero) and will NOT be
195 refreshed with the WINS server */
196 add_netbios_entry(d,"*",0x0,NB_ACTIVE,0,SELF,ip,False,wins);
197 add_netbios_entry(d,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins);
198 add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
200 if (!wins_iface && lp_domain_logons() && lp_domain_master()) {
201 /* XXXX the 0x1c is apparently something to do with domain logons */
202 add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
205 if (lp_domain_master() && (d = find_subnet(ipgrp)))
207 struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
208 if (work && work->state == MST_NONE)
210 work->state = MST_DOMAIN_NONE;
211 become_master(d, work);
217 /****************************************************************************
218 remove all the samba names... from a WINS server if necessary.
219 **************************************************************************/
220 void remove_my_names()
222 struct subnet_record *d;
224 for (d = subnetlist; d; d = d->next)
226 struct name_record *n, *next;
228 for (n = d->namelist; n; n = next)
231 if (n->source == SELF)
233 /* get all SELF names removed from the WINS server's database */
234 /* XXXX note: problem occurs if this removes the wrong one! */
236 remove_name_entry(d,n->name.name, n->name.name_type);
243 /*******************************************************************
245 ******************************************************************/
246 void refresh_my_names(time_t t)
248 struct subnet_record *d;
250 for (d = subnetlist; d; d = d->next)
252 struct name_record *n;
254 for (n = d->namelist; n; n = n->next)
256 /* each SELF name has an individual time to be refreshed */
257 if (n->source == SELF && n->refresh_time < time(NULL) &&
260 add_my_name_entry(d,n->name.name,n->name.name_type,n->nb_flags);
267 /*******************************************************************
268 queries names occasionally. an over-cautious, non-trusting WINS server!
270 this function has been added because nmbd could be restarted. it
271 is generally a good idea to check all the names that have been
274 XXXX which names to poll and which not can be refined at a later date.
275 ******************************************************************/
276 void query_refresh_names(void)
278 struct name_record *n;
279 struct subnet_record *d = find_subnet(ipgrp);
281 static time_t lasttime = 0;
282 time_t t = time(NULL);
285 int name_refresh_time = NAME_POLL_REFRESH_TIME;
286 int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
287 if (max_count > 10) max_count = 10;
289 name_refresh_time = NAME_POLL_INTERVAL * max_count / 2;
291 /* if (!lp_poll_wins()) return; polling of registered names allowed */
295 if (!lasttime) lasttime = t;
296 if (t - lasttime < NAME_POLL_INTERVAL) return;
298 lasttime = time(NULL);
300 for (n = d->namelist; n; n = n->next)
302 /* only do unique, registered names */
304 if (n->source != REGISTER) continue;
305 if (!NAME_GROUP(n->nb_flags)) continue;
307 if (n->refresh_time < t)
309 DEBUG(3,("Polling name %s\n", namestr(&n->name)));
311 queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
312 n->name.name, n->name.name_type,
314 False,False,n->ip,n->ip);
318 if (count >= max_count)
320 /* don't do too many of these at once, but do enough to
321 cover everyone in the list */
325 /* this name will be checked on again, if it's not removed */
326 n->refresh_time += name_refresh_time;