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 if (!d
->my_interface
&& !wins_iface
) continue;
191 add_my_name_entry(d
, myname
,0x20,NB_ACTIVE
);
192 add_my_name_entry(d
, myname
,0x03,NB_ACTIVE
);
193 add_my_name_entry(d
, myname
,0x00,NB_ACTIVE
);
194 add_my_name_entry(d
, myname
,0x1f,NB_ACTIVE
);
196 /* these names are added permanently (ttl of zero) and will NOT be
197 refreshed with the WINS server */
198 add_netbios_entry(d
,"*",0x0,NB_ACTIVE
,0,SELF
,ip
,False
,wins
);
199 add_netbios_entry(d
,"__SAMBA__",0x20,NB_ACTIVE
,0,SELF
,ip
,False
,wins
);
200 add_netbios_entry(d
,"__SAMBA__",0x00,NB_ACTIVE
,0,SELF
,ip
,False
,wins
);
202 if (!wins_iface
&& lp_domain_logons() && lp_domain_master()) {
203 /* XXXX the 0x1c is apparently something to do with domain logons */
204 add_my_name_entry(d
, my_workgroup(),0x1c,NB_ACTIVE
|NB_GROUP
);
207 if (lp_domain_master() && (d
= find_subnet(ipgrp
)))
209 struct work_record
*work
= find_workgroupstruct(d
, lp_workgroup(), True
);
210 if (work
&& work
->state
== MST_NONE
)
212 work
->state
= MST_DOMAIN_NONE
;
213 become_master(d
, work
);
219 /****************************************************************************
220 remove all the samba names... from a WINS server if necessary.
221 **************************************************************************/
222 void remove_my_names()
224 struct subnet_record
*d
;
226 for (d
= subnetlist
; d
; d
= d
->next
)
228 struct name_record
*n
, *next
;
230 for (n
= d
->namelist
; n
; n
= next
)
233 if (n
->source
== SELF
)
235 /* get all SELF names removed from the WINS server's database */
236 /* XXXX note: problem occurs if this removes the wrong one! */
238 remove_name_entry(d
,n
->name
.name
, n
->name
.name_type
);
245 /*******************************************************************
247 ******************************************************************/
248 void refresh_my_names(time_t t
)
250 struct subnet_record
*d
;
252 for (d
= subnetlist
; d
; d
= d
->next
)
254 struct name_record
*n
;
256 for (n
= d
->namelist
; n
; n
= n
->next
)
258 /* each SELF name has an individual time to be refreshed */
259 if (n
->source
== SELF
&& n
->refresh_time
< time(NULL
) &&
262 add_my_name_entry(d
,n
->name
.name
,n
->name
.name_type
,n
->nb_flags
);
269 /*******************************************************************
270 queries names occasionally. an over-cautious, non-trusting WINS server!
272 this function has been added because nmbd could be restarted. it
273 is generally a good idea to check all the names that have been
276 XXXX which names to poll and which not can be refined at a later date.
277 ******************************************************************/
278 void query_refresh_names(void)
280 struct name_record
*n
;
281 struct subnet_record
*d
= find_subnet(ipgrp
);
283 static time_t lasttime
= 0;
284 time_t t
= time(NULL
);
287 int name_refresh_time
= NAME_POLL_REFRESH_TIME
;
288 int max_count
= name_refresh_time
* 2 / NAME_POLL_INTERVAL
;
289 if (max_count
> 10) max_count
= 10;
291 name_refresh_time
= NAME_POLL_INTERVAL
* max_count
/ 2;
293 /* if (!lp_poll_wins()) return; polling of registered names allowed */
297 if (!lasttime
) lasttime
= t
;
298 if (t
- lasttime
< NAME_POLL_INTERVAL
) return;
300 lasttime
= time(NULL
);
302 for (n
= d
->namelist
; n
; n
= n
->next
)
304 /* only do unique, registered names */
306 if (n
->source
!= REGISTER
) continue;
307 if (!NAME_GROUP(n
->nb_flags
)) continue;
309 if (n
->refresh_time
< t
)
311 DEBUG(3,("Polling name %s\n", namestr(&n
->name
)));
313 queue_netbios_packet(d
,ClientNMB
,NMB_QUERY
,NAME_QUERY_CONFIRM
,
314 n
->name
.name
, n
->name
.name_type
,
316 False
,False
,n
->ip
,n
->ip
);
320 if (count
>= max_count
)
322 /* don't do too many of these at once, but do enough to
323 cover everyone in the list */
327 /* this name will be checked on again, if it's not removed */
328 n
->refresh_time
+= name_refresh_time
;