smb_msg/
oplock.rs

1//! OpLock messages (requests, responses, notifications)
2
3use crate::FileId;
4use binrw::prelude::*;
5use modular_bitfield::prelude::*;
6use smb_dtyp::Guid;
7use smb_msg_derive::*;
8
9/// Oplock Break Notification/Acknowledgment/Response message.
10///
11/// Used for oplock break notification (server to client), acknowledgment (client to server),
12/// and response (server to client) operations. The structure is identical for all three operations.
13///
14/// Reference: MS-SMB2 2.2.23.1, 2.2.24.1, 2.2.25.1
15#[smb_request_response(size = 12)]
16pub struct OplockBreakMsg {
17    /// The oplock level. For notifications, this is the maximum level the server will accept.
18    /// For acknowledgments, this is the lowered level the client accepts.
19    /// For responses, this is the granted level.
20    oplock_level: u8,
21    reserved: u8,
22    reserved: u32,
23    /// The file identifier on which the oplock break occurred.
24    file_id: FileId,
25}
26
27/// Lease Break Notification message.
28///
29/// Sent by the server when the underlying object store indicates that a lease is being broken,
30/// representing a change in the lease state. Not valid for SMB 2.0.2 dialect.
31///
32/// Reference: MS-SMB2 2.2.23.2
33#[smb_response(size = 44)]
34pub struct LeaseBreakNotify {
35    /// A 16-bit unsigned integer indicating a lease state change by the server.
36    /// Only valid for SMB 3.x dialect family. For SMB 2.1, this field is reserved.
37    new_epoch: u16,
38    /// Flag indicating whether a Lease Break Acknowledgment is required.
39    ack_required: u32,
40    /// The client-generated key that identifies the owner of the lease.
41    lease_key: Guid,
42    /// The current lease state of the open.
43    current_lease_state: LeaseState,
44    /// The new lease state for the open.
45    new_lease_state: LeaseState,
46    #[bw(calc = 0)]
47    #[br(assert(break_reason == 0))]
48    #[br(temp)]
49    break_reason: u32,
50    #[bw(calc = 0)]
51    #[br(assert(access_mask_hint == 0))]
52    #[br(temp)]
53    access_mask_hint: u32,
54    #[bw(calc = 0)]
55    #[br(assert(share_mask_hint == 0))]
56    #[br(temp)]
57    share_mask_hint: u32,
58}
59
60/// Oplock level values used in oplock break operations.
61///
62/// Reference: MS-SMB2 2.2.23.1
63#[smb_message_binrw]
64#[brw(repr(u8))]
65pub enum OplockLevel {
66    /// No oplock is available.
67    None = 0,
68    /// A level II oplock is available.
69    II = 1,
70    /// Exclusive oplock is available.
71    Exclusive = 2,
72}
73
74/// Lease state bitfield representing different types of caching permissions.
75///
76/// Reference: MS-SMB2 2.2.23.2
77#[smb_dtyp::mbitfield]
78pub struct LeaseState {
79    /// A read caching lease is granted/requested.
80    pub read_caching: bool,
81    /// A handle caching lease is granted/requested.
82    pub handle_caching: bool,
83    /// A write caching lease is granted/requested.
84    pub write_caching: bool,
85    #[skip]
86    __: B29,
87}
88
89// Type aliases for oplock break operations that use the same structure.
90// Reference: MS-SMB2 2.2.23.1, 2.2.24.1, 2.2.25.1
91
92/// Oplock Break Notification - sent by server when an oplock is being broken.
93pub type OplockBreakNotify = OplockBreakMsg;
94
95/// Oplock Break Acknowledgment - sent by client in response to oplock break notification.
96pub type OplockBreakAck = OplockBreakMsg;
97
98/// Oplock Break Response - sent by server in response to oplock break acknowledgment.
99pub type OplockBreakResponse = OplockBreakMsg;
100
101/// Lease Break Acknowledgment/Response message.
102///
103/// Used for lease break acknowledgment (client to server) and response (server to client).
104/// The structure is identical for both operations. Not valid for SMB 2.0.2 dialect.
105///
106/// Reference: MS-SMB2 2.2.24.2, 2.2.25.2
107#[smb_request_response(size = 36)]
108pub struct LeaseBreakAckResponse {
109    reserved: u16,
110    /// Flags (reserved)
111    reserved: u32,
112
113    /// The client-generated key that identifies the owner of the lease.
114    lease_key: Guid,
115    /// The lease state. For acknowledgments, this must be a subset of the lease state
116    /// granted by the server. For responses, this is the requested lease state.
117    lease_state: LeaseState,
118
119    /// Lease duration (reserved)
120    reserved: u64,
121}
122
123// Type aliases for lease break operations that use the same structure.
124// Reference: MS-SMB2 2.2.24.2, 2.2.25.2
125
126/// Lease Break Acknowledgment - sent by client in response to lease break notification.
127pub type LeaseBreakAck = LeaseBreakAckResponse;
128
129/// Lease Break Response - sent by server in response to lease break acknowledgment.
130pub type LeaseBreakResponse = LeaseBreakAckResponse;
131
132#[cfg(test)]
133mod tests {
134    use crate::*;
135
136    use super::*;
137
138    test_binrw_response! {
139        struct LeaseBreakNotify {
140            new_epoch: 2,
141            ack_required: 1,
142            lease_key: "70c8619e-165d-315e-d492-a01b0cbb3af2".parse().unwrap(),
143            current_lease_state: LeaseState::new()
144                .with_read_caching(true)
145                .with_handle_caching(true),
146            new_lease_state: LeaseState::new(),
147        } => "2c000200010000009e61c8705d165e31d492a01b0cbb3af20300000000000000000000000000000000000000"
148    }
149
150    test_binrw_response! {
151        struct LeaseBreakAck {
152            lease_key: "70c8619e-165d-315e-d492-a01b0cbb3af2".parse().unwrap(),
153            lease_state: LeaseState::new(),
154        } => "24000000000000009e61c8705d165e31d492a01b0cbb3af2000000000000000000000000"
155    }
156
157    test_binrw_response! {
158        struct LeaseBreakAckResponse {
159            lease_key: "70c8619e-165d-315e-d492-a01b0cbb3af2".parse().unwrap(),
160            lease_state: LeaseState::new(),
161        } => "24000000000000009e61c8705d165e31d492a01b0cbb3af2000000000000000000000000"
162    }
163}