Skip to content

Commit 8bdfead

Browse files
authored
Server 2016 Create request bug fix + Related issue fixes (#154)
Resolves #153 - Fix MxAc parsing + check failure on access mask with status - Remove all reserved assertions @coderabbitai ignore
1 parent 4289089 commit 8bdfead

File tree

21 files changed

+66
-60
lines changed

21 files changed

+66
-60
lines changed

crates/smb-dtyp/src/security/ace.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ pub struct ClaimSecurityAttributeRelativeV1 {
310310
_name: PosMarker<u32>, // TODO: Figure out what this is.
311311
pub value_type: ClaimSecurityAttributeType,
312312
#[bw(calc = 0)]
313-
#[br(assert(reserved == 0))]
314313
reserved: u16,
315314
pub flags: FciClaimSecurityAttributes,
316315
value_count: u32,

crates/smb-fscc/src/common_info.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ pub struct FileBasicInformation {
3232
/// The file attributes.
3333
pub file_attributes: FileAttributes,
3434
#[bw(calc = 0)]
35-
#[br(assert(_reserved == 0))]
3635
_reserved: u32,
3736
}
3837

crates/smb-fscc/src/filesystem_info.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,6 @@ pub struct FileFsVolumeInformation {
365365
/// Set to TRUE if the file system supports object-oriented file system objects; set to FALSE otherwise.
366366
pub supports_objects: Boolean,
367367
#[bw(calc = 0)]
368-
#[br(assert(reserved == 0))]
369368
reserved: u8,
370369
/// The content of this field can be a null-terminated string or can be a string padded with the space character to be VolumeLabelLength bytes long.
371370
#[br(args { size: SizedStringSize::bytes(volume_label_length) })]

crates/smb-fscc/src/query_file_info.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,6 @@ pub struct FileStandardInformation {
372372
/// Set to TRUE if the file is a directory.
373373
pub directory: Boolean,
374374
#[bw(calc = 0)]
375-
#[br(assert(reserved == 0))]
376375
reserved: u16,
377376
}
378377

crates/smb-msg/src/cancel.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ pub struct CancelRequest {
88
#[br(assert(_structure_size == 4))]
99
#[bw(calc = 4)]
1010
_structure_size: u16,
11-
#[br(assert(_reserved == 0))]
1211
#[bw(calc = 0)]
1312
_reserved: u16,
1413
}

crates/smb-msg/src/create.rs

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ pub struct CreateRequest {
7575
#[br(assert(_smb_create_flags == 0))]
7676
_smb_create_flags: u64,
7777
#[bw(calc = 0)]
78-
#[br(assert(_reserved == 0))]
7978
_reserved: u64,
8079
pub desired_access: FileAccessMask,
8180
pub file_attributes: FileAttributes,
@@ -196,7 +195,6 @@ pub struct CreateResponse {
196195
pub endof_file: u64,
197196
pub file_attributes: FileAttributes,
198197
#[bw(calc = 0)]
199-
#[br(assert(_reserved2 == 0))]
200198
_reserved2: u32,
201199
pub file_id: FileId,
202200
// assert it's 8-aligned
@@ -250,7 +248,6 @@ where
250248
#[bw(calc = u16::try_from(name.len()).unwrap())]
251249
name_length: u16,
252250
#[bw(calc = 0)]
253-
#[br(assert(_reserved == 0))]
254251
_reserved: u16,
255252
#[bw(calc = PosMarker::default())]
256253
_data_offset: PosMarker<u16>,
@@ -527,7 +524,6 @@ pub struct RequestLeaseV2 {
527524
pub parent_lease_key: u128,
528525
pub epoch: u16,
529526
#[bw(calc = 0)]
530-
#[br(assert(reserved == 0))]
531527
reserved: u16,
532528
}
533529

@@ -551,7 +547,6 @@ pub struct DurableHandleRequestV2 {
551547
pub timeout: u32,
552548
pub flags: DurableHandleV2Flags,
553549
#[bw(calc = 0)]
554-
#[br(assert(_reserved == 0))]
555550
_reserved: u64,
556551
pub create_guid: Guid,
557552
}
@@ -583,7 +578,6 @@ pub struct AppInstanceId {
583578
#[br(assert(structure_size == 20))]
584579
structure_size: u16,
585580
#[bw(calc = 0)]
586-
#[br(assert(_reserved == 0))]
587581
_reserved: u16,
588582
pub app_instance_id: Guid,
589583
}
@@ -595,10 +589,8 @@ pub struct AppInstanceVersion {
595589
#[br(assert(structure_size == 24))]
596590
structure_size: u16,
597591
#[bw(calc = 0)]
598-
#[br(assert(_reserved == 0))]
599592
_reserved: u16,
600593
#[bw(calc = 0)]
601-
#[br(assert(_reserved2 == 0))]
602594
_reserved2: u32,
603595
pub app_instance_version_high: u64,
604596
pub app_instance_version_low: u64,
@@ -618,10 +610,8 @@ pub struct SvhdxOpenDeviceContextV1 {
618610
pub version: u32,
619611
pub has_initiator_id: Boolean,
620612
#[bw(calc = 0)]
621-
#[br(assert(reserved1 == 0))]
622613
reserved1: u8,
623614
#[bw(calc = 0)]
624-
#[br(assert(reserved2 == 0))]
625615
reserved2: u16,
626616
pub initiator_id: Guid,
627617
pub flags: u32,
@@ -637,10 +627,8 @@ pub struct SvhdxOpenDeviceContextV2 {
637627
pub version: u32,
638628
pub has_initiator_id: Boolean,
639629
#[bw(calc = 0)]
640-
#[br(assert(reserved1 == 0))]
641630
reserved1: u8,
642631
#[bw(calc = 0)]
643-
#[br(assert(reserved2 == 0))]
644632
reserved2: u16,
645633
pub initiator_id: Guid,
646634
pub flags: u32,
@@ -658,17 +646,39 @@ pub struct SvhdxOpenDeviceContextV2 {
658646
#[binrw::binrw]
659647
#[derive(Debug, PartialEq, Eq)]
660648
pub struct QueryMaximalAccessResponse {
649+
// MS-SMB2, 2.2.14.2.5: "MaximalAccess field is valid only if QueryStatus is STATUS_SUCCESS.
650+
// he status code MUST be one of those defined in [MS-ERREF] section 2.3"
651+
/// Use [`is_success()`][QueryMaximalAccessResponse::is_success] to check if the query was successful.
661652
pub query_status: Status,
653+
654+
/// The maximal access mask for the opened file.
655+
///
656+
/// Use [`access_mask()`][QueryMaximalAccessResponse::access_mask] to get the access mask if the query was successful.
662657
pub maximal_access: FileAccessMask,
663658
}
664659

660+
impl QueryMaximalAccessResponse {
661+
/// Returns true if the query was successful.
662+
pub fn is_success(&self) -> bool {
663+
self.query_status == Status::Success
664+
}
665+
666+
/// Returns the maximal access mask if the query was successful.
667+
pub fn maximal_access(&self) -> Option<FileAccessMask> {
668+
if self.is_success() {
669+
Some(self.maximal_access)
670+
} else {
671+
None
672+
}
673+
}
674+
}
675+
665676
#[binrw::binrw]
666677
#[derive(Debug, PartialEq, Eq)]
667678
pub struct QueryOnDiskIdResp {
668679
pub file_id: u64,
669680
pub volume_id: u64,
670681
#[bw(calc = 0)]
671-
#[br(assert(_reserved == 0))]
672682
_reserved: u128,
673683
}
674684

@@ -689,7 +699,6 @@ pub struct CloseRequest {
689699
#[br(assert(_flags == CloseFlags::new().with_postquery_attrib(true)))]
690700
_flags: CloseFlags,
691701
#[bw(calc = 0)]
692-
#[br(assert(_reserved == 0))]
693702
_reserved: u32,
694703
pub file_id: FileId,
695704
}
@@ -702,7 +711,6 @@ pub struct CloseResponse {
702711
_structure_size: u16,
703712
pub flags: CloseFlags,
704713
#[bw(calc = 0)]
705-
#[br(assert(_reserved == 0))]
706714
_reserved: u32,
707715
pub creation_time: FileTime,
708716
pub last_access_time: FileTime,
@@ -793,6 +801,39 @@ mod tests {
793801
0000000000000000000000000000000000000000"
794802
}
795803

804+
use smb_dtyp::make_guid;
805+
806+
test_response_read! {
807+
server2016: Create {
808+
oplock_level: OplockLevel::None,
809+
flags: CreateResponseFlags::new(),
810+
create_action: CreateAction::Opened,
811+
creation_time: FileTime::ZERO,
812+
last_access_time: FileTime::ZERO,
813+
last_write_time: FileTime::ZERO,
814+
change_time: FileTime::ZERO,
815+
allocation_size: 4096,
816+
endof_file: 0,
817+
file_attributes: FileAttributes::new().with_normal(true),
818+
file_id: make_guid!("00000001-0001-0000-0100-000001000000").into(),
819+
create_contexts: vec![
820+
QueryMaximalAccessResponse {
821+
query_status: Status::NotMapped, // Server 2016 IPC$ bug
822+
maximal_access: FileAccessMask::default(),
823+
}
824+
.into(),
825+
QueryOnDiskIdResp {
826+
file_id: 0xffff870415d75290,
827+
volume_id: 0xffffe682cb589c90,
828+
}
829+
.into(),
830+
].into(),
831+
} => "59000000010000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000
832+
000000008000000076007300010000000100000001000000010000009800000058000000200000001000040000001800080000004d7841
833+
6300000000730000c0000000000000000010000400000018002000000051466964000000009052d7150487ffff909c58cb82e6ffff0000
834+
0000000000000000000000000000"
835+
}
836+
796837
/*
797838
Tests to add for contexts:
798839
dhnc: b"DHNc", DurableHandleReconnect, DurableHandleReconnect,

crates/smb-msg/src/echo.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ pub struct EchoMesasge {
77
#[br(assert(_structure_size == 4))]
88
#[bw(calc = 4)]
99
_structure_size: u16,
10-
#[br(assert(_reserved == 0))]
1110
#[bw(calc = 0)]
1211
_reserved: u16,
1312
}

crates/smb-msg/src/encrypted.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ pub struct EncryptedHeader {
1818
pub nonce: EncryptionNonce,
1919
pub original_message_size: u32,
2020
#[bw(calc = 0)]
21-
#[br(assert(_reserved == 0))]
2221
_reserved: u16,
2322
#[bw(calc = 1)] // MUST be set to 1.
2423
#[br(assert(_flags == 1))]

crates/smb-msg/src/error.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ pub struct ErrorResponse {
1414
#[bw(try_calc = error_data.len().try_into())]
1515
_error_context_count: u8,
1616

17-
#[br(assert(_reserved == 0))]
1817
#[bw(calc = 0)]
1918
_reserved: u8,
2019

crates/smb-msg/src/file.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ pub struct FlushRequest {
1616
#[br(assert(_structure_size == 24))]
1717
_structure_size: u16,
1818
#[bw(calc = 0)]
19-
#[br(assert(_reserved1 == 0))]
2019
_reserved1: u16,
2120
#[bw(calc = 0)]
22-
#[br(assert(_reserved2 == 0))]
2321
_reserved2: u32,
2422
pub file_id: FileId,
2523
}
@@ -31,7 +29,6 @@ pub struct FlushResponse {
3129
#[br(assert(_structure_size == 4))]
3230
_structure_size: u16,
3331
#[bw(calc = 0)]
34-
#[br(assert(_reserved == 0))]
3532
_reserved: u16,
3633
}
3734

@@ -82,7 +79,6 @@ pub struct ReadResponse {
8279
#[bw(calc = PosMarker::default())]
8380
_data_offset: PosMarker<u8>,
8481
#[bw(calc = 0)]
85-
#[br(assert(_reserved == 0))]
8682
_reserved: u8,
8783
#[bw(try_calc = buffer.len().try_into())]
8884
#[br(assert(_data_length > 0))] // sanity
@@ -93,7 +89,6 @@ pub struct ReadResponse {
9389

9490
// No RDMA support -- always zero, for both reserved and flags case:
9591
#[bw(calc = 0)]
96-
#[br(assert(_reserved2 == 0))]
9792
_reserved2: u32,
9893

9994
#[br(seek_before = SeekFrom::Start(_data_offset.value as u64))]
@@ -187,7 +182,6 @@ pub struct WriteResponse {
187182
#[br(assert(_structure_size == 17))]
188183
_structure_size: u16,
189184
#[bw(calc = 0)]
190-
#[br(assert(_reserved == 0))]
191185
_reserved: u16,
192186
pub count: u32,
193187
#[bw(calc = 0)] // reserved

0 commit comments

Comments
 (0)