Skip to content

Commit

Permalink
Fix process_irp_set_information (gravitational#15364)
Browse files Browse the repository at this point in the history
  • Loading branch information
Isaiah Becker-Mayer authored Aug 23, 2022
1 parent 4b6e277 commit 72e3f90
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
33 changes: 24 additions & 9 deletions lib/srv/desktop/rdp/rdpclient/src/rdpdr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,21 @@ impl Client {
"FileInformationClass does not match FileInformationClassLevel",
)),
},
FileInformationClassLevel::FileDispositionInformation => match rdp_req.set_buffer {
FileInformationClass::FileDispositionInformation(ref info) => {
if let Some(file) = self.file_cache.get_mut(rdp_req.device_io_request.file_id) {
file.delete_pending = info.delete_pending == 1;
return self.prep_set_info_response(&rdp_req, NTSTATUS::STATUS_SUCCESS);
}

// File not found in cache
self.prep_set_info_response(&rdp_req, NTSTATUS::STATUS_UNSUCCESSFUL)
}
_ => Err(invalid_data_error(
"FileInformationClass does not match FileInformationClassLevel",
)),

},
FileInformationClassLevel::FileBasicInformation
| FileInformationClassLevel::FileEndOfFileInformation
| FileInformationClassLevel::FileAllocationInformation => {
Expand All @@ -795,9 +810,7 @@ impl Client {
self.prep_set_info_response(&rdp_req, NTSTATUS::STATUS_SUCCESS)
}

// TODO(isaiah) or TODO(lkozlowski): implement FileDispositionInformation as is the case in FreeRDP.
// Remove the #[allow(clippy::wildcard_in_or_patterns)] macro above this function once completed.
FileInformationClassLevel::FileDispositionInformation | _ => {
_ => {
Err(not_implemented_error(&format!(
"support for ServerDriveSetInformationRequest with fs_info_class_lvl = {:?} is not implemented",
rdp_req.file_information_class_level
Expand Down Expand Up @@ -2422,6 +2435,7 @@ impl FileInformationClass {

fn decode(
file_information_class_level: &FileInformationClassLevel,
length: u32,
payload: &mut Payload,
) -> RdpResult<Self> {
match file_information_class_level {
Expand All @@ -2435,7 +2449,7 @@ impl FileInformationClass {
}
FileInformationClassLevel::FileDispositionInformation => {
Ok(FileInformationClass::FileDispositionInformation(
FileDispositionInformation::decode(payload)?,
FileDispositionInformation::decode(payload, length)?,
))
}
FileInformationClassLevel::FileRenameInformation => {
Expand Down Expand Up @@ -2844,8 +2858,9 @@ impl FileDispositionInformation {
Ok(w)
}

fn decode(payload: &mut Payload) -> RdpResult<Self> {
let delete_pending = payload.read_u8()?;
fn decode(payload: &mut Payload, length: u32) -> RdpResult<Self> {
// https://github.com/FreeRDP/FreeRDP/blob/dfa231c0a55b005af775b833f92f6bcd30363d77/channels/drive/client/drive_file.c#L684-L692
let delete_pending = if length != 0 { payload.read_u8()? } else { 1 };
Ok(Self { delete_pending })
}

Expand Down Expand Up @@ -3555,14 +3570,14 @@ impl ServerDriveSetInformationRequest {
}
};

// length, u32
payload.seek(SeekFrom::Current(4))?;
let length = payload.read_u32::<LittleEndian>()?;

// There is a padding of 24 bytes between offset and write data so we
// must ignore it
payload.seek(SeekFrom::Current(24))?;

let set_buffer = FileInformationClass::decode(&file_information_class_level, payload)?;
let set_buffer =
FileInformationClass::decode(&file_information_class_level, length, payload)?;

Ok(Self {
device_io_request,
Expand Down
5 changes: 3 additions & 2 deletions lib/srv/desktop/tdp/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,7 @@ func (s SharedDirectoryCreateResponse) Encode() ([]byte, error) {
return nil, trace.Wrap(err)
}
buf.Write(fsoEnc)

return buf.Bytes(), nil
}

Expand Down Expand Up @@ -1024,8 +1025,8 @@ func decodeSharedDirectoryDeleteResponse(in peekReader) (SharedDirectoryDeleteRe
if err != nil {
return SharedDirectoryDeleteResponse{}, trace.Wrap(err)
}
if t != byte(TypeSharedDirectoryDeleteRequest) {
return SharedDirectoryDeleteResponse{}, trace.BadParameter("got message type %v, expected SharedDirectoryDeleteResponse(%v)", t, TypeSharedDirectoryDeleteRequest)
if t != byte(TypeSharedDirectoryDeleteResponse) {
return SharedDirectoryDeleteResponse{}, trace.BadParameter("got message type %v, expected SharedDirectoryDeleteResponse(%v)", t, TypeSharedDirectoryDeleteResponse)
}

var res SharedDirectoryDeleteResponse
Expand Down

0 comments on commit 72e3f90

Please sign in to comment.