mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
ee1db51941
and updated the other two.
lkcl
(This used to be commit 96d242826d
)
481 lines
21 KiB
Plaintext
481 lines
21 KiB
Plaintext
/*************************************************************************
|
|
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.
|
|
|