/************************************************************************* 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.