Home > Protocol Analysis > Server Message Block (SMB) Dialects and Oplocks

Server Message Block (SMB) Dialects and Oplocks

July 2nd, 2011

This post describes typical message exchange sequence for a client connecting to a user level server, opening a file, reading its data, closing the file, and disconnecting from the server. Opportunistic Locking (Oplocks) are also explained.

You can also refer tothis capture: Download smbtorture from Wireshark Wiki to further understand the SMB dialogues. The capture was made using the Samba4 smbtorture suite, against a Windows Vista beta2 server.

Note: using the CIFS/SMB request batching mechanism (called the “AndX” mechanism), the second to sixth messages in this sequence can be combined into one, so that there are really only three round trips in the sequence. The last trip can be handled asynchronously by the client.

Client Command:
SMB_COM_NEGOTIATE

The format of this client request includes an array of NULL terminated strings, indicating the dialects of the CIFS protocol which the client supports. The server compares this list against the list of dialects the server supports and returns the index of the chosen dialect in the response message
Server Response:
This must be the first message sent by a client to the server and includes a list of SMB dialects supported by the client. The Server response will indicate which SMB dialect should be used.  See this post for an example of SMB Negotiate Requests and responses.

Client Command:
SMB_COM_SESSION_SETUP_ANDX
Server Response:
This transmits the user name and credentials to the server for authentication. A successful server response has UID field set in the SMB header, used for subsequent SMBs on behalf of this user.

Client Command:
SMB_COM_TREE_CONNECT_ANDX
Server Response:
The server transmits the name of the disk share (exported disk resource) that the client wants to access. A successful server response has the TID field set in the SMB header, used for subsequent SMBs referring to this resource.

Client Command:
SMB_COM_OPEN_ANDX
Server Response:
The server transmits the name of the file, relative to the TID that the client wishes to open. A successful server response includes a file id (FID) which the client should supply for subsequent operations on this file.

Client Command:
SMB_COM_READ
Server Response:
When the client supplies TID, FID, file offset, and number of bytes to read, a successful server response will include the requested file data.

Client Command:
SMB_COM_CLOSE
Server Response:
The client closes the file represented by Tid and Fid. The server will respond with a success code.

Client Command:
SMB_COM_TREE_DISCONNECT
Server Response:
The client disconnects from resource represented by TID.

Opportunistic Locks:
The CIFS/SMB protocol includes a mechanism called “opportunistic locks”, or oplocks, which allow the client to “lock” a file in such a manner that the server can revoke the lock. The purpose of these oplocks are to allow file data caching on the client to occur safely. This is achieved by defining the conditions under which an oplock is revoked.

When a client opens a file it may request an oplock on the file. If the oplock is given the client may safely perform caching. However, at some point in the future a second client may open the file. The following steps provide an overview of the actions taken in response to the open from the second client:

• The server holds off responding to the open from the second client.
• The server revokes the oplock of the first client.
• The first client flushes all cached data to the server.
• The first client acknowledges the revoke of the oplock.
• The server responds to the open from the second client.

As can be seen from the above steps, the first client has the opportunity to write back data and acquire record locks before the second client is allowed to examine the file. Because of this a client that holds an oplock can aggressively cache file data and state.

Oplock SMBs (also see “UNDERSTANDING OPLOCKS” further on this page)
Obtaining an Oplock:
The following SMB commands may be used to obtain an oplock:
• SMB_COM_OPEN
• SMB_COM_CREATE
• SMB_COM_CREATE_NEW
• SMB_COM_OPEN_ANDX
• SMB_COM_TRANSACTION2 (OPEN2)
• SMB_COM_NT_CREATE_ANDX
• SMB_COM_NT_TRANSACT (NT_CREATE)

The server may only grant a level II oplock to a client for a file when that file is opened using one of “SMB_COM_NT_CREATE_ANDX” or “SMB_COM_NT_TRANSACT (NT_CREATE)”.

Releasing an Oplock
A client releases an oplock with the SMB_COM_LOCKING_ANDX command. Alternatively the client may release the oplock by closing the file with the SMB_COM_CLOSE command. Any
operation that would invalidate the file handle results in the oplock being released. This includes disconnecting the tree, logging off the user that opened the file, and any action that would disconnect the session.

A client should release its exclusive or batch oplock on a file in response to the server revoking the oplock. Failure to do so is a violation of the protocol. A client does not need to release a level II oplock (i.e. respond to the server) on a file in response to the server revoking the oplock. However doing so is not an error.

Revoking an Oplock
The server revokes a client’s oplock by sending a SMB_COM_LOCKING_ANDX command to the client. The command is sent asynchronously sent from the server to the client. This message has the LOCKING_ANDX_OPLOCK_RELEASE flag set indicating to the client that the oplock is being broken.

OplockLevel indicates the type of oplock the client now owns. If OplockLevel is 0, the client possesses no oplocks on the file at all. If OplockLevel is 1, the client possesses a Level II oplock. The client is expected to flush any dirty buffers to the server, submit any file locks, and respond to the server with either an SMB_LOCKING_ANDX SMB having the LOCKING_ANDX_OPLOCK_RELEASE flag set, or with a file close if the file is no longer in use by the client.

UNDERSTANDING OPLOCKS
There are three types of oplocks:
• Exclusive
• Batch
• Level II (Level II oplocks were introduced in NTLM 0.12)

Exclusive and Batch Oplocks

Exclusive:
When a client has an exclusive oplock on a file, it is the only client to have the file open. The exclusive oplock allows the client to safely perform file data read and write caching, metadata caching, and record lock caching. All other operations on the file cannot be safely cached. The server may revoke the exclusive oplock at any time. The client is guaranteed that the server will revoke the exclusive oplock prior to another client successfully opening the file. This gives the client that holds the oplock the opportunity to write back cached information to the file.

Batch:
The batch oplock was introduced to allow a client to defer closing a file that was opened and reopened repetitively by an application. It has the same semantics as the exclusive oplock with the following additional guarantee: The client holding a batch oplock has the additional guarantee that the server will revoke the batch oplock prior to another client successfully making any change to the file.

Client Requesting Oplocks:
• When a client opens a file it can specify that it wants an exclusive oplock, a batch oplock, or no oplock. Exclusive and batch oplocks can only be obtained as a side effect of a file being opened. The protocol does not support other means to obtain exclusive and batch oplocks.
• Oplocks can only be obtained on files. Oplocks are not supported on directories and named pipes. However it is not an error to request an oplock on directories and named pipes. In this case the server must return that no oplock was granted.

The server response to a successful open request includes information about what type of oplock was obtained. (A server that does not support oplocks should always return that no oplock was granted!).

A client that requests an exclusive oplock will get one of the following:
• An exclusive oplock
• A level II oplock
• No oplock

A client that requests a batch oplock will get one of the following:
• A batch oplock
• A level II oplock
• No oplock
A client that requests no oplock will always get no oplock.

Server Revoking Oplocks:
The revoking of an exclusive or batch oplock involves the server sending an oplock break message to the client, followed by the client flushing file information to the server, followed by the client releasing the oplock. If the client does not respond by releasing the oplock within a period of time acceptable to the server, then the server may consider the oplock released and allow pending operations to proceed. The protocol does not define the duration of the time out period.

When a client opens a file that already has an exclusive oplock, the server first checks the share mode on the file. If the sharing allows the client open to succeed then the exclusive oplock is broken, after which the open is allowed to proceed.

When a client opens a file that already has a batch oplock, the server first revokes the batch oplock. Then the open is allowed to proceed. The reason for this server behavior is that it gives the holder of the oplock the opportunity to close the file. This in turn allows the open to obtain an exclusive or batch oplock.

When a client opens a file that has a security descriptor, the server first checks if the open for the desired access is allowed by the security descriptor. If access is not allowed, the open fails. Any exclusive or batch oplock on the file is not disturbed. Because of this behavior a client holding an exclusive or batch oplock cannot safely cache security descriptor information.

Level II Oplocks
When a client has a level II oplock on a file, it is an indication to the client that other clients may also have the file open. The level II oplock allows the client to safely perform file data read caching. All other operations on the file cannot be safely cached.

The server may revoke the level II oplock at any time. The client is guaranteed that the server will revoke the level II oplock prior to another client successfully writing the file. This gives the client that holds the level II oplock the opportunity to discard its cached data.

Note however that the level II oplock is revoked differently than an exclusive or batch oplock. A level II oplock break is sent to the client, but a response from the client is not expected. The server allows the write to proceed immediately after the level II oplock break is sent to the client.

A client cannot explicitly request that a level II oplock be granted. A level II oplock is granted either when a file is opened or when a server revokes an exclusive or batch oplock.

When a file is opened the client may request an exclusive or batch oplock. The server has the option of granting a level II oplock instead of the requested type of oplock. This is the only way to obtain a level II oplock when a file is opened.

When a server revokes an exclusive or batch oplock, it may indicate to the client that in conjunction with the revocation that the client is being granted a level II oplock.

BROKEN OPLOCKS:
Due to timing, the client could get an “oplock broken” notification in a user’s data buffer as a result of this notification crossing on the wire with an SMB_COM_READ_RAW request. The client must detect this (use length of message, “FFSMB,” MID of -1 and Command of SMB_COM_LOCKING_ANDX) and honor the “oplock broken” notification as usual. The server must also note on receipt of an SMB_COM_READ_RAW request that there is an outstanding (unanswered) “oplock broken” notification to the client; it must then return a zero length response denoting failure of the read raw request. The client should (after responding to the “oplock broken” notification) use a non-raw read request to redo the read. This allows a file to actually contain data matching an “oplock broken” notification and still be read correctly.

When an exclusive or batch oplock is being revoked, more than one client open request may be paused until the oplock is released. Once the oplock is released, the order that the paused open requests are processed is not defined.

Categories: Protocol Analysis Tags: ,
Comments are closed.