Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/ruby_smb/smb1/packet/trans2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ module Trans2
require 'ruby_smb/smb1/packet/trans2/find_information_level'
require 'ruby_smb/smb1/packet/trans2/query_information_level'
require 'ruby_smb/smb1/packet/trans2/query_fs_information_level'
require 'ruby_smb/smb1/packet/trans2/set_information_level'
require 'ruby_smb/smb1/packet/trans2/set_fs_information_level'
require 'ruby_smb/smb1/packet/trans2/data_block'
require 'ruby_smb/smb1/packet/trans2/subcommands'
require 'ruby_smb/smb1/packet/trans2/request'
Expand All @@ -22,6 +24,12 @@ module Trans2
require 'ruby_smb/smb1/packet/trans2/set_file_information_response'
require 'ruby_smb/smb1/packet/trans2/query_path_information_request'
require 'ruby_smb/smb1/packet/trans2/query_path_information_response'
require 'ruby_smb/smb1/packet/trans2/set_path_information_request'
require 'ruby_smb/smb1/packet/trans2/set_path_information_response'
require 'ruby_smb/smb1/packet/trans2/query_fs_information_request'
require 'ruby_smb/smb1/packet/trans2/query_fs_information_response'
require 'ruby_smb/smb1/packet/trans2/set_fs_information_request'
require 'ruby_smb/smb1/packet/trans2/set_fs_information_response'
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions lib/ruby_smb/smb1/packet/trans2/query_fs_information_level.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@ module QueryFsInformationLevel
# [NT LANMAN] Query file system attributes.
SMB_QUERY_FS_ATTRIBUTE_INFO = 0x0105 # 261

# [CIFS UNIX Extensions] Query server UNIX extension capabilities.
SMB_QUERY_CIFS_UNIX_INFO = 0x0200 # 512

def self.name(value)
constants.select { |c| c.upcase == c }.find { |c| const_get(c) == value }
end

require 'ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_attribute_info'
require 'ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_cifs_unix_info'
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module RubySMB
module SMB1
module Packet
module Trans2
module QueryFsInformationLevel
# Response data for SMB_QUERY_CIFS_UNIX_INFO (0x0200) from the
# CIFS UNIX Extensions. 12 bytes: major/minor version pair plus
# a 64-bit capability bitfield that the client echoes back in
# SMB_SET_CIFS_UNIX_INFO to enable UNIX extensions for the session.
#
# Outside of MS-CIFS; wire format defined by the CIFS UNIX
# Extensions draft maintained by the Samba team. The parent
# subcommand is documented at
# [MS-CIFS 2.2.6.4 TRANS2_QUERY_FS_INFORMATION (0x0003)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/a96c1c03-cade-4a4a-81a9-b00674d23d93).
# The on-disk layout matches Samba's server-side `unix_info`
# struct at
# [source3/smbd/globals.h:419-424](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/globals.h#L419-L424),
# populated by `call_trans2qfsinfo` at
# [source3/smbd/smb1_trans2.c:1633-1703](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1633-L1703).
class QueryFsCifsUnixInfo < BinData::Record
endian :little

uint16 :major_version, label: 'Major Version'
uint16 :minor_version, label: 'Minor Version'
uint64 :capabilities, label: 'Capabilities'
end
end
end
end
end
end
16 changes: 12 additions & 4 deletions lib/ruby_smb/smb1/packet/trans2/query_fs_information_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ module RubySMB
module SMB1
module Packet
module Trans2
# The Trans2 Parameter Block for this particular Subcommand
# The Trans2 Parameter Block for a QUERY_FS_INFORMATION request as
# defined in
# [MS-CIFS 2.2.6.4.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cfa23a11-0e80-43bd-bbd4-e9cfb99b5dce).
class QueryFsInformationRequestTrans2Parameters < BinData::Record
endian :little

Expand All @@ -15,16 +17,22 @@ def length
end
end

# The {RubySMB::SMB1::DataBlock} specific to this packet type.
# The {RubySMB::SMB1::DataBlock} specific to this packet type. See
# [MS-CIFS 2.2.6.4.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cfa23a11-0e80-43bd-bbd4-e9cfb99b5dce).
# The request carries no Trans2 data payload, but the generic
# DataBlock padding helpers require a :trans2_data accessor, so
# we expose a zero-length string.
class QueryFsInformationRequestDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
uint8 :name, label: 'Name', initial_value: 0x00
string :pad1, length: -> { pad1_length }
query_fs_information_request_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
# trans2_data: No data is sent by this message.
string :trans2_data, length: 0, label: 'Trans2 Data'
end

# A Trans2 QUERY_FS_INFORMATION Request Packet as defined in
# [2.2.6.4.1](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cfa23a11-0e80-43bd-bbd4-e9cfb99b5dce)
# [MS-CIFS 2.2.6.4.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cfa23a11-0e80-43bd-bbd4-e9cfb99b5dce).
# See also the subcommand overview at
# [MS-CIFS 2.2.6.4 TRANS2_QUERY_FS_INFORMATION (0x0003)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/a96c1c03-cade-4a4a-81a9-b00674d23d93).
class QueryFsInformationRequest < RubySMB::GenericPacket
COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2

Expand Down
28 changes: 28 additions & 0 deletions lib/ruby_smb/smb1/packet/trans2/set_fs_information_level.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module RubySMB
module SMB1
module Packet
module Trans2
# SET_FS Information Levels used in TRANS2_SET_FS_INFORMATION.
#
# MS-CIFS marks the parent subcommand
# [TRANS2_SET_FS_INFORMATION (0x0004)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/ac4b00db-6015-416a-89a1-bf5da2503bc3)
# as "reserved but not implemented" — the info level codes below are
# defined by the CIFS UNIX Extensions draft maintained by the Samba
# team and implemented in
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
# They sit in the 0x0200–0x02FF range reserved by
# [MS-CIFS 2.2.2.3 Information Level Codes](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/03c10ab9-d723-4368-b9a6-c72de3244c77)
# for third-party extensions.
module SetFsInformationLevel
# Client advertises / negotiates CIFS UNIX Extensions support.
# Data block: major:u16, minor:u16, capabilities:u64.
SMB_SET_CIFS_UNIX_INFO = 0x0200

def self.name(value)
constants.select { |c| c.upcase == c }.find { |c| const_get(c) == value }
end
end
end
end
end
end
90 changes: 90 additions & 0 deletions lib/ruby_smb/smb1/packet/trans2/set_fs_information_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
module RubySMB
module SMB1
module Packet
module Trans2
# The Trans2 Parameter Block for TRANS2_SET_FS_INFORMATION.
# Observed on the wire (and required by Samba) as a 4-byte block
# containing a placeholder file handle plus the information level.
#
# The parent subcommand
# [MS-CIFS 2.2.6.5 TRANS2_SET_FS_INFORMATION (0x0004)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/ac4b00db-6015-416a-89a1-bf5da2503bc3)
# is marked "reserved but not implemented"; the on-the-wire format
# used here is defined by the CIFS UNIX Extensions draft and
# implemented in
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
class SetFsInformationRequestTrans2Parameters < BinData::Record
endian :little

uint16 :fid, label: 'File ID'
uint16 :information_level, label: 'Information Level'

# Returns the length of the Trans2Parameters struct
# in number of bytes
def length
do_num_bytes
end
end

# The Trans2 Data Block for TRANS2_SET_FS_INFORMATION.
#
# The data layout depends on the Information Level being set, so the
# block carries an opaque byte buffer that the caller fills in for
# the target info level. SMB_SET_CIFS_UNIX_INFO (0x0200) for example
# carries a QueryFsCifsUnixInfo-shaped record (major/minor/caps).
#
# Not documented in
# [MS-CIFS 2.2.6.5 TRANS2_SET_FS_INFORMATION (0x0004)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/ac4b00db-6015-416a-89a1-bf5da2503bc3);
# per-level layouts are defined by the CIFS UNIX Extensions draft
# and implemented in
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
class SetFsInformationRequestTrans2Data < BinData::Record
string :buffer, read_length: -> { parent.buffer_read_length }
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical: Problem: read_length: -> { parent.buffer_read_length } invokes buffer_read_length as a private method on an explicit receiver. Impact: parsing SetFsInformationRequest from bytes can fail with NoMethodError, breaking any code that attempts to decode captured traffic or secondary request flows. Fix: switch to read_length: :buffer_read_length (or an approach that uses send) to match the existing Trans2 buffer parsing behavior.

Suggested change
string :buffer, read_length: -> { parent.buffer_read_length }
string :buffer, read_length: :buffer_read_length

Copilot uses AI. Check for mistakes.

# Returns the length of the Trans2Data struct
# in number of bytes
def length
do_num_bytes
end
end

# The {RubySMB::SMB1::DataBlock} specific to this packet type. The
# parent subcommand
# [MS-CIFS 2.2.6.5 TRANS2_SET_FS_INFORMATION (0x0004)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/ac4b00db-6015-416a-89a1-bf5da2503bc3)
# is documented as "reserved but not implemented"; this data block
# is structured for the CIFS UNIX Extensions use in
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
class SetFsInformationRequestDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
uint8 :name, label: 'Name', initial_value: 0x00
string :pad1, length: -> { pad1_length }
set_fs_information_request_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
string :pad2, length: -> { pad2_length }
set_fs_information_request_trans2_data :trans2_data, label: 'Trans2 Data'
end

# A Trans2 SET_FS_INFORMATION Request Packet. The on-disk layout
# described by
# [MS-CIFS 2.2.6.5 TRANS2_SET_FS_INFORMATION (0x0004)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/ac4b00db-6015-416a-89a1-bf5da2503bc3)
# is marked "reserved but not implemented" and does not document the
# CIFS UNIX Extensions info levels; their wire format is defined by
# the CIFS UNIX Extensions draft and matched by Samba's
# `call_trans2setfsinfo` in
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
class SetFsInformationRequest < RubySMB::GenericPacket
COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2

class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
end

smb_header :smb_header
parameter_block :parameter_block
set_fs_information_request_data_block :data_block

def initialize_instance
super
parameter_block.setup << RubySMB::SMB1::Packet::Trans2::Subcommands::SET_FS_INFORMATION
end
end
end
end
end
end
56 changes: 56 additions & 0 deletions lib/ruby_smb/smb1/packet/trans2/set_fs_information_response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
module RubySMB
module SMB1
module Packet
module Trans2
# The Trans2 Parameter Block for a TRANS2_SET_FS_INFORMATION response.
# The field is intentionally empty — servers return only an NT status
# in the SMB header to acknowledge the SET.
#
# Parent subcommand:
# [MS-CIFS 2.2.6.5 TRANS2_SET_FS_INFORMATION (0x0004)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/ac4b00db-6015-416a-89a1-bf5da2503bc3)
# ("reserved but not implemented"). Response shape observed in the
# CIFS UNIX Extensions implementation in
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
class SetFsInformationResponseTrans2Parameters < BinData::Record
def length
do_num_bytes
end
end

# The {RubySMB::SMB1::DataBlock} specific to this packet type.
# Parent subcommand:
# [MS-CIFS 2.2.6.5 TRANS2_SET_FS_INFORMATION (0x0004)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/ac4b00db-6015-416a-89a1-bf5da2503bc3)
# ("reserved but not implemented"); actual shape used by the CIFS
# UNIX Extensions implementation in
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
class SetFsInformationResponseDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
uint8 :name, label: 'Name', initial_value: 0x00
string :pad1, length: -> { pad1_length }
set_fs_information_response_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
end

# A Trans2 SET_FS_INFORMATION Response Packet. Parent subcommand:
# [MS-CIFS 2.2.6.5 TRANS2_SET_FS_INFORMATION (0x0004)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/ac4b00db-6015-416a-89a1-bf5da2503bc3)
# ("reserved but not implemented"). Response shape is defined by the
# CIFS UNIX Extensions implementation in
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
class SetFsInformationResponse < RubySMB::GenericPacket
COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2

class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Response::ParameterBlock
end

smb_header :smb_header
parameter_block :parameter_block
set_fs_information_response_data_block :data_block

def initialize_instance
super
parameter_block.setup << RubySMB::SMB1::Packet::Trans2::Subcommands::SET_FS_INFORMATION
smb_header.flags.reply = 1
end
end
end
end
end
end
35 changes: 35 additions & 0 deletions lib/ruby_smb/smb1/packet/trans2/set_information_level.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module RubySMB
module SMB1
module Packet
module Trans2
# Information Level codes valid for Trans2 SET_PATH_INFORMATION and
# SET_FILE_INFORMATION requests. See
# [MS-CIFS 2.2.2.3.4 SET Information Level Codes](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/0321265e-312a-4721-90fa-cd40a443ed86).
#
# FSCC pass-through levels are defined in
# {RubySMB::Fscc::FileInformation} and require
# `SMB_INFO_PASSTHROUGH` to be added. The constants defined here are
# the CIFS UNIX Extensions info levels used by Samba servers that
# advertise UNIX extensions support in their negotiate response. These
# levels fall outside MS-CIFS; their wire format is defined by the
# CIFS UNIX Extensions draft and implemented by Samba's
# `smb_set_file_unix_link` handler at
# [source3/smbd/smb1_trans2.c:3643-3712](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L3643-L3712).
module SetInformationLevel
# Set the symbolic link target for a file. The Trans2 parameters
# block carries the path being created (the symlink itself); the
# Trans2 data block carries the target path as a null-terminated
# string.
SMB_SET_FILE_UNIX_LINK = 0x0201

# Create a hard link. Data block carries the existing file path.
SMB_SET_FILE_UNIX_HLINK = 0x0203

def self.name(value)
constants.select { |c| c.upcase == c }.find { |c| const_get(c) == value }
end
end
end
end
end
end
Loading
Loading