As has been stated previously, we are only considering the NBT and naked TCP transports. Both of these are IP-based and the behavior of SMB over these two is nearly identical, so it does not seem as though separating them would be very important... but this is CIFS we're talking about. The crux of the problem is whether or not the NBT SESSION REQUEST message is required. If the server is expecting correct NBT semantics, then we will need to find a valid NetBIOS name to place into the CALLED NAME field. This is a complicated process, involving a lot of trial-and-error. The recipe presented below is only one way to go about it. A good chef knows how to adjust the ingredients and choose seasonings to get the desired result. This is as much an art as it is a science. 10.3.1 Run NakedRunning naked is probably the easiest transport test to try first. The procedure is tasteful and dignified: simply assume that the server is expecting raw TCP transport. Open a TCP connection to port 445 on the server, but do not send an NBT SESSION REQUEST just start sending SMB messages and see if that works. There are four possible results from this test:
All of the above applies if the user did not specify a non-standard port number. If the input looks more like this: smb://server:2891/ then the option of falling back to NBT on port 139 is excluded. In addition, there is no way to guess which transport type should be used if a port number other than 139 or 445 is specified. (In theory, it is also possible to run NBT transport on port 445 and naked transport on port 139. If you catch anyone doing such a twisted thing you should probably notify the authorities.) Fortunately, Windows systems (Windows 95, 98, and 2000 were tested ) return an NBT NEGATIVE SESSION RESPONSE if they get naked semantics on an NBT service port. This makes sense, because it lets the client know that NBT semantics are required. Samba's smbd goes one better and simply ignores the lack of a SESSION REQUEST message. Samba's behavior effectively merges the two transport types and makes the distinction between them irrelevant, which simplifies things on the server side and makes life easier for the client. The transport discovery process is illustrated using the anachronistic flowchart presented in Figure 10.1. Figure 10.1. Transport discovery
10.3.2 Using the NetBIOS NameIf running naked didn't work, then you will probably need to try NBT transport. Also, back in Section 10.1 we talked about the different types of Server Identifiers that most implementations support. One of those is the NetBIOS name, and it seems logical to assume that if the Server Identifier is a NetBIOS name then the transport will be NBT. That's two good reasons to give NBT transport a whirl. As stated earlier, the critical difference between the raw TCP and NBT transports is that NBT requires the SESSION REQUEST/POSITIVE SESSION RESPONSE exchange before the SMB messages can start flowing . The SESSION REQUEST , in turn , must contain a valid CALLED NAME . If the CALLED NAME is not correct, then some server implementations will reject the connection. (Windows seems to be quite picky, but Samba ignores the CALLED NAME field.) Finding a valid CALLED NAME is easy if the Server Identifier is a NetBIOS name because, well... because there you are. The NetBIOS name is the correct CALLED NAME . Also, since the Server Identifier was resolved via an NBT Name Query, the server's IP address is known. That's everything you need. There is one small problem with this scenario that could cause a little trouble: some NBNS servers can be configured to pass NetBIOS name queries through to the DNS system, which means that the DNS not the NBNS may have resolved the name to an IP address. That would mean that we have a false positive and the Server Identifier is not, in fact, a NetBIOS name. If that happens, you could wind up trying to make an NBT connection to a system that isn't running NBT services. (The opposite of the "run naked" test described above.) Detecting an SMB service that wants naked transport is not as clean and easy as detecting one that wants NBT. In testing, a Windows 2000 system running naked TCP transport did not respond at all to an NBT SESSION REQUEST , and the client timed out waiting for the reply. This problem is neatly avoided if naked transport is attempted before NBT transport. Since Samba considers the SESSION REQUEST optional, this kind of transport confusion is not an issue when talking to a Samba server. 10.3.3 Reverse Mapping a NetBIOS NameReverse mapping is the last, desperate means for finding a workable NetBIOS CALLED NAME so that a valid SESSION REQUEST can be sent. Reverse mapping is also quite common. Your code will need to try this technique if naked transport didn't work and the Server Identifier was a DNS name or IP address a situation which is not unusual. As stated before, there is no right way to do reverse mapping. Fortunately, there are a few almost-right ways to go about it. Here they are: Try a Node Status query.
Try using the generic CALLED NAME .
Try using the DNS name.
If none of those options worked, then it is finally time to send an error message back to the user explaining that the Server Identifier is no good. Ignorance is Bliss Omission Alert
|