1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
|
/*************************************************************************
process_nmb()
*************************************************************************/
this function receives a packet identified as a netbios packet.
it further identifies whether it is a response or a query packet.
by identifying the type of packet (name registration, query etc)
process_nmb() will call the appropriate function to deal with the
type of packet received.
/*************************************************************************
response_netbios_packet()
*************************************************************************/
this function received netbios response packets. the samba server
(or a rogue tcp/ip system, or nmblookup) will have sent out a packet
requesting a response. a client (or a rogue tcp/ip system) responds
to that request.
this function checks the validity of the packet it receives.
the expected response records are searched for the transaction id,
to see if it's a response expected by the samba server. if it isn't
it's reported as such, and ignored.
if the response is found, then the subnet it was expected from will
also have been found. the subnet it actually came in on can be
checked against the subnet it was expected from and reported,
otherwise this function just carries on.
the number of responses received is increased, and the number of
retries left to be sent is set to zero.
after debug information is reported, and validation of the netbios
packet (e.g only one response from one machine is expected for some
functions) has occurred, the packet is processed. when the initial
request was sent out, the expected response record was flagged with,
for lack of a better word, a samba 'state' type. whenever a
response is received, the appropriate function is called to carry on
where the program control flow was interrupted while awaiting exactly
such a response.
please note that _not_ receiving a response is dealt with in another
area of code - expire_netbios_response_entries().
/*************************************************************************
response_name_query_sync()
*************************************************************************/
this function receives responses to samba 'states' NAME_QUERY_SYNC and
NAME_QUERY_CONFIRM.
NAME_QUERY_SYNC: name query a server before synchronising browse lists.
NAME_QUERY_CONFIRM: name query a server to check that it's alive.
a NAME_QUERY_SYNC will be carried out in order to check that a server
is alive before syncing browse lists. we don't want to delay the SMB
NetServerEnum api just because the server has gone down: we have too
much else to do.
a NAME_QUERY_CONFIRM is just a name query to see whether the server is
alive. these queries are sent out by samba's WINS server side, to verify
its netbios name database of all machines that have registered with it.
we don't normally expect a negative response from such a query, although
we may do so if the query was sent to another WINS server. the registered
entry should be removed if we receive a negative response.
/*************************************************************************
response_name_status_check()
*************************************************************************/
this function receives responses to samba 'states' NAME_STATUS_CHECK
and NAME_STATUS_MASTER_CHECK
NAME_STATUS_MASTER_CHECK: name status a primary domain controller,
confirm its domain and then initiate syncing
its browse list.
NAME_STATUS_CHECK: same as NAME_STATUS_MASTER_CHECK except the name status
is issued to a master browser.
if we don't know what workgroup a server is responsible for, but we
know that there is a master browser at a certain ip, we can issue a
name status check. from the response received, there will be
a master browser netbios entry. this will allow us to synchronise
browse lists with that machine and then add the information to the
correct part of samba's workgroup - server database.
/*************************************************************************
response_server_check()
*************************************************************************/
this function receives responses to samba 'states' NAME_QUERY_MST_SRV_CHK,
NAME_QUERY_SRV_CHK and NAME_QUERY_FIND_MST.
NAME_QUERY_FIND_MST: issued as a broadcast when we wish to find out all
master browsers (i.e all servers that have registered
the NetBIOS name ^1^2__MSBROWSE__^2(0x1), and then
issue a NAME_STATUS_MASTER_CHECK on any servers that
respond, which will initiate a sync browse lists.
NAME_QUERY_MST_SRV_CHK: same as a NAME_QUERY_FIND_MST except this is sent
to a primary domain controller.
NAME_QUERY_SRV_CHK: same as a NAME_QUERY_MST_SRV_CHK except this is sent to
a master browser.
the purpose of each of these states is to do a broadcast name query, or
a name query directed at a WINS server, then to all hosts that respond,
we issue a name status check, which will confirm for us the workgroup
or domain name, and then initiate issuing a sync browse list call with
that server.
a NAME_QUERY_SRV_CHK is sent when samba receives a list of backup
browsers. it checks to see if that server is alive (by doing a
name query on a server) and then syncs browse lists with it.
/*************************************************************************
reply_name_query()
*************************************************************************/
this function is responsible for replying to a NetBIOS name query.
there are two kinds of name queries: directed, and broadcast. directed
queries are usually sent to samba in its WINS capacity. such hosts are
termed 'point-to-point' hosts. broadcast queries are usually sent from
'broadcast' or 'mixed' hosts.
broadcasting is used by either older NetBIOS hosts, new NetBIOS hosts that
have not had WINS capabilities added and new NetBIOS hosts that think the
WINS server has died.
the samba NetBIOS name database is divided into sections, on a
per-subnet basis. there is also a WINS NetBIOS name database, and for
convenience this is added as a pseudo-subnet with the ip address of
255.255.255.255.
the local subnet NetBIOS name databases only contain samba's names.
the reason for this is that if a broadcast query is received, a NetBIOS
hosts is only expected to respond if that query is for one of its own
names (the exception to this is if a host is configured as a 'proxy'
server, in which case, samba should redirect the query to another WINS
server).
the WINS pseudo-subnet NetBIOS database contains all NetBIOS names
that are not 'special browser' type names (regarding this i am a
_bit_ confused :-). names of type 0x01, 0x1d and 0x1e i consider to
be 'special browser' names. at the moment. maybe.
the type of search to be initiated is determined. if the NetBIOS name
type is a non-special-browser name, then the WINS database is included
in the search.
if the name is not a special browser name, then we need to find the
right subnet that the query came from. this is done using
find_req_subnet(). this also has the benefit of stopping any queries
from subnets that samba does not know about.
if the query is a broadcast query, then the database of the local subnet
is included in the search.
the name is then searched for in the appropriate NetBIOS data structures.
if it is found, then we need to check whether it is appropriate for us
to reply to such a query.
we will only reply if the query is a directed query, the name belongs to
samba on that subnet, or the name is a primary domain controller type,
or we're doing replies on behalf of hosts on subnets not known to the
host issuing the query. in the latter instance, it would be appropriate
if samba is using a WINS server for it to forward the name query on to
this WINS server.
reply_name_query() then takes note of all the information that is
needed to construct a reply to the caller. a negative reply (if the
name is unknown to samba) or a positive reply (the name is known to
samba) is then issued.
/*************************************************************************
search_for_name()
*************************************************************************/
this function is responsible for finding a name in the appropriate part
of samba's NetBIOS name database. if the name cannot be found, then it
should look the name up using DNS. later modifications will be to
forward the request on to another WINS server, should samba not be able
to find out about the requested name (this will be implemented through
issuing a new type of samba 'state').
the name is first searched for in the NetBIOS cache. if it cannot be
found, then it if the name looks like it's a server-type name (0x20
0x0 or 0x1b) then DNS is used to look for the name.
if DNS fails, then a record of this failure is kept. if it succeeds, then
a new NetBIOS entry is added.
the successfully found name is returned. on failure, NULL is returned.
/*************************************************************************
reply_name_status()
*************************************************************************/
this function is responsible for constructing a reply to a NetBIOS
name status query. this response contains all samba's NetBIOS names
on the subnet that the query came in from.
a reply will only be made if the NetBIOS name being queried exists.
see rfc1001.txt and rfc1002.txt for details of the name status reply.
/*************************************************************************
reply_name_reg()
*************************************************************************/
this function is responsible for updating the NetBIOS name database
from registration packets sent out by hosts wishing to register a
name, and for informing them, if necessary, if this is acceptable
or not.
name registration can be done by broadcast or by point-to-point,
i.e the registration is sent directly to samba in its capacity as
a WINS server.
if the name registration is done by broadcast (see rfc1001.txt 15.2.1),
then samba's involvement in replying is limited to whether that name
is owned by samba or not, on the relevant subnet.
if the name registration is done point-to-point (see rfc1001.txt 15.2.2)
then samba will first need to check its WINS name database records and
proceed accordingly.
samba looks for the appropriate subnet record that the registration
should be added to / checked against, using find_req_subnet().
next, the name is searched for in the local database or the WINS
database as appropriate.
if the name is not found, then it is added to the NetBIOS name database,
using add_netbios_entry(), which may choose not to add the name (not
that this affects the registration of the name on the network in any way).
it will only add names to the WINS database, and even then it will only
add non-special-browser type names.
if the name is found, then samba must decide whether to accept the name
or not. a group name is always added. for unique names, further checks
need to be carried out.
firstly, if the name in the database is one of samba's names, or if the
name in the database is a group name, then it cannot be added as a unique
name belonging to someone else. it is therefore rejected.
secondly, if the ip address of the name being registered does not match
against the ip in the database, then the unique name may belong to
someone else. a check needs to be carried out with the owner in case
they still wish to keep this name. a detailed discussion of what action
to take is in rfc1001.txt 15.2.2.2 and 15.2.2.3.
samba currently implements non-secured WINS, whereupon the responsibility
for checking the name is passed on to the host doing the registration.
rfc1001.txt refers to this as an END-NODE CHALLENGE REGISTRATION RESPONSE.
(samba itself cannot yet cope with receiving such responses if it
registers its names with another WINS server).
having decided what kind of response to send (if any - acceptance of
name registrations by broadcast is implicit), samba will send either a
positive or negative NAME REGISTRATION RESPONSE, or an END-NODE CHALLENGE
REGISTRATION RESPONSE to the host that initially sent the registration.
whew.
/*************************************************************************
response_name_reg()
*************************************************************************/
this function is responsible for dealing with samba's registration
attempts, by broadcast to a local subnet, or point-to-point with
another WINS server.
please note that it cannot cope with END-NODE CHALLENGE REGISTRATION
RESPONSEs at present.
when a response is received, samba determines if the response is a
positive or a negative one. if it is a positive response, the name
is added to samba's database.
when a negative response is received, samba will remove the name
from its database. if, however, the name is a browser type (0x1b is
a primary domain controller type name; or 0x1d, which is a master
browser type name) then it must also stop being a primary domain
controller or master browser respectively, depending on what kind
of name was rejected.
(when no response is received, then expire_netbios_response_entries()
is expected to deal with this. the only case that is dealt with here
at present is when the registration was done by broadcast. if there
is no challenge to the broadcast registration, it is implicitly
assumed that claiming the name is acceptable).
/*************************************************************************
response_name_release()
*************************************************************************/
this function is responsible for removing samba's NetBIOS name when
samba contacts another WINS server with which it had registered the
name.
only positive name releases are expected and dealt with. exactly what
to do if a negative name release (i.e someone says 'oi! you have to
keep that name!') is received is uncertain.
(when no response is received, then expire_netbios_response_entries()
is expected to deal with this. if there is no challenge to the release
of the name, the name is then removed from that subnet's NetBIOS
name database).
/*************************************************************************
expire_names()
*************************************************************************/
this function is responsible for removing old NetBIOS names from its
database. no further action is required.
for over-zealous WINS systems, the use of query_refresh_names() is
recommended. this function initiates polling of hosts that have
registered with samba in its capacity as a WINS server. an alternative
means to achieve the same end as query_refresh_names() is to
reduce the time to live when the name is registered with samba,
except that in this instance the responsibility for refreshing the
name is with the owner of the name, not the server with which the name
is registered.
/*************************************************************************
query_refresh_names()
*************************************************************************/
this function is responsible for polling all names registered in the
WINS database. it is planned to enable this function should samba
detect an inconsistency on the network, which could occur if the
samba NetBIOS daemon dies and is restarted.
polling is done very infrequently, but all names will be covered
within a period NAME_POLL_REFRESH_TIME. a group of at most ten names
will be queried at once, at intervals of NAME_POLL_INTERVAL seconds.
if the total number of names queried in this way will take too long,
then the time that an individual name will next be polled is
increased accordingly.
name query polling is functionality over-and-above the normal
requirement (see rfc1001.txt 15.1.7 point 7). it is normally the
responsibility of the owner of a name to re-register the name at
regular intervals.
/*************************************************************************
refresh_my_names()
*************************************************************************/
this function is responsible for refreshing samba's names that have
been registered with other servers on a local subnet, or with another
WINS server if samba is using one.
samba's names' refresh_time will be updated through the use of the function
add_my_name_entry().
/*************************************************************************
remove_my_names()
*************************************************************************/
this function is responsible for removing all samba's SELF names. it
is used when samba receives a SIG_TERM. samba at present does not wait
for the WINS server to reply to the name releases sent out.
/*************************************************************************
add_my_names()
*************************************************************************/
this function is responsible for adding and registering if necessary all
samba's SELF names, on each of its local subnets and with another WINS
server if samba is using one.
/*************************************************************************
add_my_name_entry()
*************************************************************************/
this function is responsible for registering or re-registering one of
samba's names, either on the local subnet or with another WINS server
if samba is using one.
if the name is already in samba's database, then it is re-registered,
otherwise it is simply registered.
if samba registers its name with another WINS server, then the function
response_name_reg() is responsible for updating samba's name database
to reflect the claim or otherwise of the name.
expire_netbios_response_entries() is responsible for taking further action
if no response to the registration is received.
/*************************************************************************
remove_name_entry()
*************************************************************************/
this function is responsible for removing a NetBIOS name. if the name
being removed is registered on a local subnet, a name release should be
broadcast on the local subnet.
if samba has registered the name with a WINS server, it must send a
name release to the WINS server it is using. once it receives a reply,
it can proceed (see response_name_rel())
expire_netbios_response_entries() is responsible for taking further action
if no response to the name release is received.
/*************************************************************************
load_netbios_names()
*************************************************************************/
this function is responsible for loading any NetBIOS names that samba,
in its WINS capacity, has written out to disk. all the relevant details
are recorded in this file, including the time-to-live. should the
time left to live be small, the name is not added back in to samba's
WINS database.
/*************************************************************************
dump_names()
*************************************************************************/
this function is responsible for outputting NetBIOS names in two formats.
firstly, as debugging information, and secondly, all names that have been
registered with samba in its capacity as a WINS server are written to
disk.
writing all WINS names allows two things. firstly, if samba's NetBIOS
daemon dies or is terminated, on restarting the daemon most if not all
of the registered WINS names will be preserved (which is a good reason
why query_netbios_names() should be used).
/*************************************************************************
find_name_search()
*************************************************************************/
this function is a wrapper around find_name(). find_name_search() can
be told whether to search for the name in a local subnet structure or
in the WINS database. on top of this, it can be told to search only
for samba's SELF names.
if it finds the name in the WINS database, it will set the subnet_record
and also return the name it finds.
/*************************************************************************
find_req_subnet()
*************************************************************************/
this function is responsible for finding the appropriate subnet record
to use. it is assumed that any directed packets are going to need to
use the WINS pseudo-subnet records, and that any broadcast transactions
received are going to need to use a local subnet record, which is found
from the ip address that the transaction was received on.
a side-effect of this function is that any broadcast packet received
on a subnet not known to samba is ignored.
|