3.3.4.7 Object Store Indicates a Lease Break
The underlying object store indicates the breaking of a lease by specifying the ClientGuid, the ClientLeaseId, and the new lease state. The new lease state MUST be one of NONE, R, RW, and RH.
When the underlying object store indicates the lease break, the server MUST locate the Lease Table by performing a lookup in GlobalLeaseTableList using the provided ClientGuid as the lookup key, and then locate the Lease entry by performing a lookup in the LeaseTable.LeaseList using the provided ClientLeaseId as the lookup key.
If no entry is found, the server MUST complete the lease break call from the underlying object store with "NONE" as the new lease state, and take no further action.
If a Lease entry is found, the server MUST perform the following:
If Lease.LeaseOpens is empty, the server MUST complete the lease break call from the underlying object store with "NONE" as the new lease state, set Lease.LeaseState to "NONE", and take no further action.
If no connection is available among all Opens in Lease.LeaseOpens, the server MUST close every Open as specified in section 3.3.4.17 in one of the following cases:
Open.IsDurable, Open.IsResilient, and Open.IsPersistent are all FALSE.
The new lease state indicated by the object store does not contain SMB2_LEASE_HANDLE_CACHING and Open.IsDurable is TRUE.
Otherwise, the server MUST construct a Lease Break Notification (section 2.2.23.2) message to send to the client.
The server MUST set the Command field in the SMB2 header to SMB2 OPLOCK_BREAK, and the MessageId field to 0xFFFFFFFFFFFFFFFF. The server MUST set the SessionId and TreeId fields in the SMB2 header to 0.
If Lease.LeaseState is SMB2_LEASE_READ_CACHING, the server MUST set the Flags field of the message to zero and MUST set Open.OplockState to “None” for all opens in Lease.LeaseOpens. The server MUST set Lease.Breaking to FALSE, and the LeaseKey field MUST be set to Lease.LeaseKey.
Otherwise, the server MUST set the Flags field of the message to SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED, indicating to the client that lease acknowledgment is required. The LeaseKey field MUST be set to Lease.LeaseKey. The server MUST set Open.OplockState to “Breaking” for all Opens in Lease.LeaseOpens. The server MUST set the CurrentLeaseState field of the message to Lease.LeaseState, set Lease.Breaking to TRUE, set Lease.BreakToLeaseState and the NewLeaseState field to the new lease state indicated by the object store, and set Lease.LeaseBreakTimeout to the current time plus an implementation-specific<243> default value in milliseconds.
If the server implements the SMB 3.x dialect family and Lease.Version is 2, the server SHOULD<244> set NewEpoch to Lease.Epoch + 1. Otherwise, NewEpoch MUST be set to zero. The server MUST set Lease.Epoch to NewEpoch.
The message SHOULD NOT be signed. The server MUST set Lease.BreakNotification to the newly constructed Lease Break Notification.
The server MUST look up all the connections in ConnectionList where Connection.ClientGuid matches the provided ClientGuid. The server MUST send Lease.BreakNotification using the first available connection. If the server fails to send the notification to the client, the server MUST retry the send using an alternate connection available.
If the server succeeds in sending the Lease Break Notification, the server MUST set Lease.BreakNotification to empty and MUST start the lease break acknowledgment timer as specified in section 3.3.2.5.
Otherwise, the server MUST perform the following steps:
If Open.IsPersistent is TRUE and Lease.LeaseState is not SMB2_LEASE_READ_CACHING, the server MUST take no further action.
Otherwise, the server MUST set Open.Lease.Breaking to FALSE, Lease.Held to FALSE, Open.OplockState to None, Lease.BreakNotification to empty, and MUST complete the lease break call from the underlying object store with "NONE" as the new lease state.