ruby_smb 3.3.20 → 3.3.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_cifs_unix_info.rb +31 -0
- data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_level.rb +4 -0
- data/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request.rb +12 -4
- data/lib/ruby_smb/smb1/packet/trans2/set_fs_information_level.rb +28 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_fs_information_request.rb +90 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_fs_information_response.rb +56 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_information_level.rb +35 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_path_information_request.rb +75 -0
- data/lib/ruby_smb/smb1/packet/trans2/set_path_information_response.rb +51 -0
- data/lib/ruby_smb/smb1/packet/trans2.rb +8 -0
- data/lib/ruby_smb/smb1/tree.rb +124 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/query_fs_information_request_spec.rb +6 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_request_spec.rb +52 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_response_spec.rb +29 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_request_spec.rb +114 -0
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_response_spec.rb +54 -0
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +124 -0
- metadata +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a002233be5acb354928b1a3144a55f1e7224ca543ddd02ca8aed49f10d147bf
|
|
4
|
+
data.tar.gz: d410e410c764cec434426a75dab79b46f72700862750b470c068e3eee822d43c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a7e1295bb0a883cb00546a32ead1d647254bce82d8cd1bbad3217c3d8d68a8fb404a488f2b97b0a494e899fe33d39cd7f552b5e0515f202d97bb53525d869ca7
|
|
7
|
+
data.tar.gz: 698f56e64e2c419c4faddaaf18d0efa201e162a6cfabfe580a2472f98bb16d6f4729d2166aa546336357326847db6cdd520f37c26e5305a2019b5ec5397513eb
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module SMB1
|
|
3
|
+
module Packet
|
|
4
|
+
module Trans2
|
|
5
|
+
module QueryFsInformationLevel
|
|
6
|
+
# Response data for SMB_QUERY_CIFS_UNIX_INFO (0x0200) from the
|
|
7
|
+
# CIFS UNIX Extensions. 12 bytes: major/minor version pair plus
|
|
8
|
+
# a 64-bit capability bitfield that the client echoes back in
|
|
9
|
+
# SMB_SET_CIFS_UNIX_INFO to enable UNIX extensions for the session.
|
|
10
|
+
#
|
|
11
|
+
# Outside of MS-CIFS; wire format defined by the CIFS UNIX
|
|
12
|
+
# Extensions draft maintained by the Samba team. The parent
|
|
13
|
+
# subcommand is documented at
|
|
14
|
+
# [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).
|
|
15
|
+
# The on-disk layout matches Samba's server-side `unix_info`
|
|
16
|
+
# struct at
|
|
17
|
+
# [source3/smbd/globals.h:419-424](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/globals.h#L419-L424),
|
|
18
|
+
# populated by `call_trans2qfsinfo` at
|
|
19
|
+
# [source3/smbd/smb1_trans2.c:1633-1703](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1633-L1703).
|
|
20
|
+
class QueryFsCifsUnixInfo < BinData::Record
|
|
21
|
+
endian :little
|
|
22
|
+
|
|
23
|
+
uint16 :major_version, label: 'Major Version'
|
|
24
|
+
uint16 :minor_version, label: 'Minor Version'
|
|
25
|
+
uint64 :capabilities, label: 'Capabilities'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -28,11 +28,15 @@ module RubySMB
|
|
|
28
28
|
# [NT LANMAN] Query file system attributes.
|
|
29
29
|
SMB_QUERY_FS_ATTRIBUTE_INFO = 0x0105 # 261
|
|
30
30
|
|
|
31
|
+
# [CIFS UNIX Extensions] Query server UNIX extension capabilities.
|
|
32
|
+
SMB_QUERY_CIFS_UNIX_INFO = 0x0200 # 512
|
|
33
|
+
|
|
31
34
|
def self.name(value)
|
|
32
35
|
constants.select { |c| c.upcase == c }.find { |c| const_get(c) == value }
|
|
33
36
|
end
|
|
34
37
|
|
|
35
38
|
require 'ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_attribute_info'
|
|
39
|
+
require 'ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_cifs_unix_info'
|
|
36
40
|
end
|
|
37
41
|
end
|
|
38
42
|
end
|
|
@@ -2,7 +2,9 @@ module RubySMB
|
|
|
2
2
|
module SMB1
|
|
3
3
|
module Packet
|
|
4
4
|
module Trans2
|
|
5
|
-
# The Trans2 Parameter Block for
|
|
5
|
+
# The Trans2 Parameter Block for a QUERY_FS_INFORMATION request as
|
|
6
|
+
# defined in
|
|
7
|
+
# [MS-CIFS 2.2.6.4.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cfa23a11-0e80-43bd-bbd4-e9cfb99b5dce).
|
|
6
8
|
class QueryFsInformationRequestTrans2Parameters < BinData::Record
|
|
7
9
|
endian :little
|
|
8
10
|
|
|
@@ -15,16 +17,22 @@ module RubySMB
|
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
|
|
18
|
-
# The {RubySMB::SMB1::DataBlock} specific to this packet type.
|
|
20
|
+
# The {RubySMB::SMB1::DataBlock} specific to this packet type. See
|
|
21
|
+
# [MS-CIFS 2.2.6.4.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cfa23a11-0e80-43bd-bbd4-e9cfb99b5dce).
|
|
22
|
+
# The request carries no Trans2 data payload, but the generic
|
|
23
|
+
# DataBlock padding helpers require a :trans2_data accessor, so
|
|
24
|
+
# we expose a zero-length string.
|
|
19
25
|
class QueryFsInformationRequestDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
|
20
26
|
uint8 :name, label: 'Name', initial_value: 0x00
|
|
21
27
|
string :pad1, length: -> { pad1_length }
|
|
22
28
|
query_fs_information_request_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
|
23
|
-
|
|
29
|
+
string :trans2_data, length: 0, label: 'Trans2 Data'
|
|
24
30
|
end
|
|
25
31
|
|
|
26
32
|
# A Trans2 QUERY_FS_INFORMATION Request Packet as defined in
|
|
27
|
-
# [2.2.6.4.1](https://
|
|
33
|
+
# [MS-CIFS 2.2.6.4.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cfa23a11-0e80-43bd-bbd4-e9cfb99b5dce).
|
|
34
|
+
# See also the subcommand overview at
|
|
35
|
+
# [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).
|
|
28
36
|
class QueryFsInformationRequest < RubySMB::GenericPacket
|
|
29
37
|
COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
|
|
30
38
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module SMB1
|
|
3
|
+
module Packet
|
|
4
|
+
module Trans2
|
|
5
|
+
# SET_FS Information Levels used in TRANS2_SET_FS_INFORMATION.
|
|
6
|
+
#
|
|
7
|
+
# MS-CIFS marks the parent subcommand
|
|
8
|
+
# [TRANS2_SET_FS_INFORMATION (0x0004)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/ac4b00db-6015-416a-89a1-bf5da2503bc3)
|
|
9
|
+
# as "reserved but not implemented" — the info level codes below are
|
|
10
|
+
# defined by the CIFS UNIX Extensions draft maintained by the Samba
|
|
11
|
+
# team and implemented in
|
|
12
|
+
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
|
|
13
|
+
# They sit in the 0x0200–0x02FF range reserved by
|
|
14
|
+
# [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)
|
|
15
|
+
# for third-party extensions.
|
|
16
|
+
module SetFsInformationLevel
|
|
17
|
+
# Client advertises / negotiates CIFS UNIX Extensions support.
|
|
18
|
+
# Data block: major:u16, minor:u16, capabilities:u64.
|
|
19
|
+
SMB_SET_CIFS_UNIX_INFO = 0x0200
|
|
20
|
+
|
|
21
|
+
def self.name(value)
|
|
22
|
+
constants.select { |c| c.upcase == c }.find { |c| const_get(c) == value }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module SMB1
|
|
3
|
+
module Packet
|
|
4
|
+
module Trans2
|
|
5
|
+
# The Trans2 Parameter Block for TRANS2_SET_FS_INFORMATION.
|
|
6
|
+
# Observed on the wire (and required by Samba) as a 4-byte block
|
|
7
|
+
# containing a placeholder file handle plus the information level.
|
|
8
|
+
#
|
|
9
|
+
# The parent subcommand
|
|
10
|
+
# [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)
|
|
11
|
+
# is marked "reserved but not implemented"; the on-the-wire format
|
|
12
|
+
# used here is defined by the CIFS UNIX Extensions draft and
|
|
13
|
+
# implemented in
|
|
14
|
+
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
|
|
15
|
+
class SetFsInformationRequestTrans2Parameters < BinData::Record
|
|
16
|
+
endian :little
|
|
17
|
+
|
|
18
|
+
uint16 :fid, label: 'File ID'
|
|
19
|
+
uint16 :information_level, label: 'Information Level'
|
|
20
|
+
|
|
21
|
+
# Returns the length of the Trans2Parameters struct
|
|
22
|
+
# in number of bytes
|
|
23
|
+
def length
|
|
24
|
+
do_num_bytes
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# The Trans2 Data Block for TRANS2_SET_FS_INFORMATION.
|
|
29
|
+
#
|
|
30
|
+
# The data layout depends on the Information Level being set, so the
|
|
31
|
+
# block carries an opaque byte buffer that the caller fills in for
|
|
32
|
+
# the target info level. SMB_SET_CIFS_UNIX_INFO (0x0200) for example
|
|
33
|
+
# carries a QueryFsCifsUnixInfo-shaped record (major/minor/caps).
|
|
34
|
+
#
|
|
35
|
+
# Not documented in
|
|
36
|
+
# [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);
|
|
37
|
+
# per-level layouts are defined by the CIFS UNIX Extensions draft
|
|
38
|
+
# and implemented in
|
|
39
|
+
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
|
|
40
|
+
class SetFsInformationRequestTrans2Data < BinData::Record
|
|
41
|
+
string :buffer, read_length: -> { parent.buffer_read_length }
|
|
42
|
+
|
|
43
|
+
# Returns the length of the Trans2Data struct
|
|
44
|
+
# in number of bytes
|
|
45
|
+
def length
|
|
46
|
+
do_num_bytes
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# The {RubySMB::SMB1::DataBlock} specific to this packet type. The
|
|
51
|
+
# parent subcommand
|
|
52
|
+
# [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)
|
|
53
|
+
# is documented as "reserved but not implemented"; this data block
|
|
54
|
+
# is structured for the CIFS UNIX Extensions use in
|
|
55
|
+
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
|
|
56
|
+
class SetFsInformationRequestDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
|
57
|
+
uint8 :name, label: 'Name', initial_value: 0x00
|
|
58
|
+
string :pad1, length: -> { pad1_length }
|
|
59
|
+
set_fs_information_request_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
|
60
|
+
string :pad2, length: -> { pad2_length }
|
|
61
|
+
set_fs_information_request_trans2_data :trans2_data, label: 'Trans2 Data'
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# A Trans2 SET_FS_INFORMATION Request Packet. The on-disk layout
|
|
65
|
+
# described by
|
|
66
|
+
# [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)
|
|
67
|
+
# is marked "reserved but not implemented" and does not document the
|
|
68
|
+
# CIFS UNIX Extensions info levels; their wire format is defined by
|
|
69
|
+
# the CIFS UNIX Extensions draft and matched by Samba's
|
|
70
|
+
# `call_trans2setfsinfo` in
|
|
71
|
+
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
|
|
72
|
+
class SetFsInformationRequest < RubySMB::GenericPacket
|
|
73
|
+
COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
|
|
74
|
+
|
|
75
|
+
class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
smb_header :smb_header
|
|
79
|
+
parameter_block :parameter_block
|
|
80
|
+
set_fs_information_request_data_block :data_block
|
|
81
|
+
|
|
82
|
+
def initialize_instance
|
|
83
|
+
super
|
|
84
|
+
parameter_block.setup << RubySMB::SMB1::Packet::Trans2::Subcommands::SET_FS_INFORMATION
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module SMB1
|
|
3
|
+
module Packet
|
|
4
|
+
module Trans2
|
|
5
|
+
# The Trans2 Parameter Block for a TRANS2_SET_FS_INFORMATION response.
|
|
6
|
+
# The field is intentionally empty — servers return only an NT status
|
|
7
|
+
# in the SMB header to acknowledge the SET.
|
|
8
|
+
#
|
|
9
|
+
# Parent subcommand:
|
|
10
|
+
# [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)
|
|
11
|
+
# ("reserved but not implemented"). Response shape observed in the
|
|
12
|
+
# CIFS UNIX Extensions implementation in
|
|
13
|
+
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
|
|
14
|
+
class SetFsInformationResponseTrans2Parameters < BinData::Record
|
|
15
|
+
def length
|
|
16
|
+
do_num_bytes
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# The {RubySMB::SMB1::DataBlock} specific to this packet type.
|
|
21
|
+
# Parent subcommand:
|
|
22
|
+
# [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)
|
|
23
|
+
# ("reserved but not implemented"); actual shape used by the CIFS
|
|
24
|
+
# UNIX Extensions implementation in
|
|
25
|
+
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
|
|
26
|
+
class SetFsInformationResponseDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
|
27
|
+
uint8 :name, label: 'Name', initial_value: 0x00
|
|
28
|
+
string :pad1, length: -> { pad1_length }
|
|
29
|
+
set_fs_information_response_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# A Trans2 SET_FS_INFORMATION Response Packet. Parent subcommand:
|
|
33
|
+
# [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)
|
|
34
|
+
# ("reserved but not implemented"). Response shape is defined by the
|
|
35
|
+
# CIFS UNIX Extensions implementation in
|
|
36
|
+
# [source3/smbd/smb1_trans2.c:1706-1915 (`call_trans2setfsinfo`)](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L1706-L1915).
|
|
37
|
+
class SetFsInformationResponse < RubySMB::GenericPacket
|
|
38
|
+
COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
|
|
39
|
+
|
|
40
|
+
class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Response::ParameterBlock
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
smb_header :smb_header
|
|
44
|
+
parameter_block :parameter_block
|
|
45
|
+
set_fs_information_response_data_block :data_block
|
|
46
|
+
|
|
47
|
+
def initialize_instance
|
|
48
|
+
super
|
|
49
|
+
parameter_block.setup << RubySMB::SMB1::Packet::Trans2::Subcommands::SET_FS_INFORMATION
|
|
50
|
+
smb_header.flags.reply = 1
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module SMB1
|
|
3
|
+
module Packet
|
|
4
|
+
module Trans2
|
|
5
|
+
# Information Level codes valid for Trans2 SET_PATH_INFORMATION and
|
|
6
|
+
# SET_FILE_INFORMATION requests. See
|
|
7
|
+
# [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).
|
|
8
|
+
#
|
|
9
|
+
# FSCC pass-through levels are defined in
|
|
10
|
+
# {RubySMB::Fscc::FileInformation} and require
|
|
11
|
+
# `SMB_INFO_PASSTHROUGH` to be added. The constants defined here are
|
|
12
|
+
# the CIFS UNIX Extensions info levels used by Samba servers that
|
|
13
|
+
# advertise UNIX extensions support in their negotiate response. These
|
|
14
|
+
# levels fall outside MS-CIFS; their wire format is defined by the
|
|
15
|
+
# CIFS UNIX Extensions draft and implemented by Samba's
|
|
16
|
+
# `smb_set_file_unix_link` handler at
|
|
17
|
+
# [source3/smbd/smb1_trans2.c:3643-3712](https://github.com/samba-team/samba/blob/33f516c06756e12a9d11f50e2bf309171cdf5c88/source3/smbd/smb1_trans2.c#L3643-L3712).
|
|
18
|
+
module SetInformationLevel
|
|
19
|
+
# Set the symbolic link target for a file. The Trans2 parameters
|
|
20
|
+
# block carries the path being created (the symlink itself); the
|
|
21
|
+
# Trans2 data block carries the target path as a null-terminated
|
|
22
|
+
# string.
|
|
23
|
+
SMB_SET_FILE_UNIX_LINK = 0x0201
|
|
24
|
+
|
|
25
|
+
# Create a hard link. Data block carries the existing file path.
|
|
26
|
+
SMB_SET_FILE_UNIX_HLINK = 0x0203
|
|
27
|
+
|
|
28
|
+
def self.name(value)
|
|
29
|
+
constants.select { |c| c.upcase == c }.find { |c| const_get(c) == value }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module SMB1
|
|
3
|
+
module Packet
|
|
4
|
+
module Trans2
|
|
5
|
+
# The Trans2 Parameter Block for a SET_PATH_INFORMATION request as
|
|
6
|
+
# defined in
|
|
7
|
+
# [MS-CIFS 2.2.6.7.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/2ca0642a-1cd4-4e72-a16f-9e804a218262).
|
|
8
|
+
class SetPathInformationRequestTrans2Parameters < BinData::Record
|
|
9
|
+
endian :little
|
|
10
|
+
|
|
11
|
+
uint16 :information_level, label: 'Information Level'
|
|
12
|
+
uint32 :reserved, label: 'Reserved'
|
|
13
|
+
choice :filename, copy_on_change: true, selection: -> { parent.parent.smb_header.flags2.unicode } do
|
|
14
|
+
stringz16 1, label: 'FileName'
|
|
15
|
+
stringz 0, label: 'FileName'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns the length of the Trans2Parameters struct
|
|
19
|
+
# in number of bytes
|
|
20
|
+
def length
|
|
21
|
+
do_num_bytes
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# The Trans2 Data Block for a SET_PATH_INFORMATION request as defined
|
|
26
|
+
# in
|
|
27
|
+
# [MS-CIFS 2.2.6.7.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/2ca0642a-1cd4-4e72-a16f-9e804a218262).
|
|
28
|
+
#
|
|
29
|
+
# The data layout depends on the Information Level being set, so the
|
|
30
|
+
# block carries an opaque byte buffer that the caller fills in for the
|
|
31
|
+
# target info level. SMB_SET_FILE_UNIX_LINK (0x0201) for example
|
|
32
|
+
# carries the symlink target as a null-terminated string.
|
|
33
|
+
class SetPathInformationRequestTrans2Data < BinData::Record
|
|
34
|
+
string :buffer, read_length: -> { parent.buffer_read_length }
|
|
35
|
+
|
|
36
|
+
# Returns the length of the Trans2Data struct
|
|
37
|
+
# in number of bytes
|
|
38
|
+
def length
|
|
39
|
+
do_num_bytes
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# The {RubySMB::SMB1::DataBlock} specific to this packet type. See
|
|
44
|
+
# [MS-CIFS 2.2.6.7.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/2ca0642a-1cd4-4e72-a16f-9e804a218262).
|
|
45
|
+
class SetPathInformationRequestDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
|
46
|
+
uint8 :name, label: 'Name', initial_value: 0x00
|
|
47
|
+
string :pad1, length: -> { pad1_length }
|
|
48
|
+
set_path_information_request_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
|
49
|
+
string :pad2, length: -> { pad2_length }
|
|
50
|
+
set_path_information_request_trans2_data :trans2_data, label: 'Trans2 Data'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# A Trans2 SET_PATH_INFORMATION Request Packet as defined in
|
|
54
|
+
# [MS-CIFS 2.2.6.7.1 Request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/2ca0642a-1cd4-4e72-a16f-9e804a218262).
|
|
55
|
+
# See also the subcommand overview at
|
|
56
|
+
# [MS-CIFS 2.2.6.7 TRANS2_SET_PATH_INFORMATION (0x0006)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/a23483d9-6543-4aaa-a996-e7c9506f8b94).
|
|
57
|
+
class SetPathInformationRequest < RubySMB::GenericPacket
|
|
58
|
+
COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
|
|
59
|
+
|
|
60
|
+
class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
smb_header :smb_header
|
|
64
|
+
parameter_block :parameter_block
|
|
65
|
+
set_path_information_request_data_block :data_block
|
|
66
|
+
|
|
67
|
+
def initialize_instance
|
|
68
|
+
super
|
|
69
|
+
parameter_block.setup << RubySMB::SMB1::Packet::Trans2::Subcommands::SET_PATH_INFORMATION
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module RubySMB
|
|
2
|
+
module SMB1
|
|
3
|
+
module Packet
|
|
4
|
+
module Trans2
|
|
5
|
+
# The Trans2 Parameter Block for a SET_PATH_INFORMATION response as
|
|
6
|
+
# defined in
|
|
7
|
+
# [MS-CIFS 2.2.6.7.2 Response](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cf1cd579-9687-465d-9274-08ebb5944cd3).
|
|
8
|
+
class SetPathInformationResponseTrans2Parameters < BinData::Record
|
|
9
|
+
endian :little
|
|
10
|
+
|
|
11
|
+
uint16 :ea_error_offset, label: 'Extended Attribute Error Offset'
|
|
12
|
+
|
|
13
|
+
# Returns the length of the Trans2Parameters struct
|
|
14
|
+
# in number of bytes
|
|
15
|
+
def length
|
|
16
|
+
do_num_bytes
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# The {RubySMB::SMB1::DataBlock} specific to this packet type. See
|
|
21
|
+
# [MS-CIFS 2.2.6.7.2 Response](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cf1cd579-9687-465d-9274-08ebb5944cd3).
|
|
22
|
+
class SetPathInformationResponseDataBlock < RubySMB::SMB1::Packet::Trans2::DataBlock
|
|
23
|
+
string :pad1, length: -> { pad1_length }
|
|
24
|
+
set_path_information_response_trans2_parameters :trans2_parameters, label: 'Trans2 Parameters'
|
|
25
|
+
# trans2_data: No data is sent by this message.
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# A Trans2 SET_PATH_INFORMATION Response Packet as defined in
|
|
29
|
+
# [MS-CIFS 2.2.6.7.2 Response](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/cf1cd579-9687-465d-9274-08ebb5944cd3).
|
|
30
|
+
# See also the subcommand overview at
|
|
31
|
+
# [MS-CIFS 2.2.6.7 TRANS2_SET_PATH_INFORMATION (0x0006)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/a23483d9-6543-4aaa-a996-e7c9506f8b94).
|
|
32
|
+
class SetPathInformationResponse < RubySMB::GenericPacket
|
|
33
|
+
COMMAND = RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
|
|
34
|
+
|
|
35
|
+
class ParameterBlock < RubySMB::SMB1::Packet::Trans2::Response::ParameterBlock
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
smb_header :smb_header
|
|
39
|
+
parameter_block :parameter_block
|
|
40
|
+
set_path_information_response_data_block :data_block
|
|
41
|
+
|
|
42
|
+
def initialize_instance
|
|
43
|
+
super
|
|
44
|
+
parameter_block.setup << RubySMB::SMB1::Packet::Trans2::Subcommands::SET_PATH_INFORMATION
|
|
45
|
+
smb_header.flags.reply = 1
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -7,6 +7,8 @@ module RubySMB
|
|
|
7
7
|
require 'ruby_smb/smb1/packet/trans2/find_information_level'
|
|
8
8
|
require 'ruby_smb/smb1/packet/trans2/query_information_level'
|
|
9
9
|
require 'ruby_smb/smb1/packet/trans2/query_fs_information_level'
|
|
10
|
+
require 'ruby_smb/smb1/packet/trans2/set_information_level'
|
|
11
|
+
require 'ruby_smb/smb1/packet/trans2/set_fs_information_level'
|
|
10
12
|
require 'ruby_smb/smb1/packet/trans2/data_block'
|
|
11
13
|
require 'ruby_smb/smb1/packet/trans2/win9x_framing'
|
|
12
14
|
require 'ruby_smb/smb1/packet/trans2/subcommands'
|
|
@@ -23,6 +25,12 @@ module RubySMB
|
|
|
23
25
|
require 'ruby_smb/smb1/packet/trans2/set_file_information_response'
|
|
24
26
|
require 'ruby_smb/smb1/packet/trans2/query_path_information_request'
|
|
25
27
|
require 'ruby_smb/smb1/packet/trans2/query_path_information_response'
|
|
28
|
+
require 'ruby_smb/smb1/packet/trans2/set_path_information_request'
|
|
29
|
+
require 'ruby_smb/smb1/packet/trans2/set_path_information_response'
|
|
30
|
+
require 'ruby_smb/smb1/packet/trans2/query_fs_information_request'
|
|
31
|
+
require 'ruby_smb/smb1/packet/trans2/query_fs_information_response'
|
|
32
|
+
require 'ruby_smb/smb1/packet/trans2/set_fs_information_request'
|
|
33
|
+
require 'ruby_smb/smb1/packet/trans2/set_fs_information_response'
|
|
26
34
|
end
|
|
27
35
|
end
|
|
28
36
|
end
|
data/lib/ruby_smb/smb1/tree.rb
CHANGED
|
@@ -195,6 +195,66 @@ module RubySMB
|
|
|
195
195
|
results
|
|
196
196
|
end
|
|
197
197
|
|
|
198
|
+
# Create a UNIX symbolic link on the remote share using the CIFS UNIX
|
|
199
|
+
# Extensions SMB_SET_FILE_UNIX_LINK information level (0x0201) via a
|
|
200
|
+
# Trans2 SET_PATH_INFORMATION request.
|
|
201
|
+
#
|
|
202
|
+
# @example
|
|
203
|
+
# tree = client.tree_connect("\\\\samba\\writable")
|
|
204
|
+
# tree.set_unix_link(symlink: 'escape', target: '../../../../etc')
|
|
205
|
+
#
|
|
206
|
+
# @param symlink [String] the path, relative to the share, where the
|
|
207
|
+
# symbolic link file will be created
|
|
208
|
+
# @param target [String] the destination the symbolic link points to
|
|
209
|
+
# @return [WindowsError::ErrorCode] the NTStatus returned by the server
|
|
210
|
+
# @raise [RubySMB::Error::InvalidPacket] if the response is not a Trans2
|
|
211
|
+
# SET_PATH_INFORMATION response
|
|
212
|
+
# @raise [RubySMB::Error::UnexpectedStatusCode] if the response NTStatus
|
|
213
|
+
# is not STATUS_SUCCESS
|
|
214
|
+
def set_unix_link(symlink:, target:)
|
|
215
|
+
# Samba gates SMB_SET_FILE_UNIX_LINK behind a per-session CIFS UNIX
|
|
216
|
+
# Extensions handshake: query server capabilities, then echo them
|
|
217
|
+
# back via SMB_SET_CIFS_UNIX_INFO. Without this, Samba responds to
|
|
218
|
+
# the symlink request with STATUS_INVALID_LEVEL even when
|
|
219
|
+
# `unix extensions = yes` is set server-side.
|
|
220
|
+
enable_cifs_unix_extensions
|
|
221
|
+
|
|
222
|
+
request = RubySMB::SMB1::Packet::Trans2::SetPathInformationRequest.new
|
|
223
|
+
request = set_header_fields(request)
|
|
224
|
+
# CIFS UNIX Extensions paths are raw byte strings, not UTF-16. Clear
|
|
225
|
+
# flags2.unicode so the filename parameter and target data block are
|
|
226
|
+
# emitted as bytes — Samba rejects the UTF-16 variant with
|
|
227
|
+
# STATUS_INVALID_LEVEL.
|
|
228
|
+
request.smb_header.flags2.unicode = 0
|
|
229
|
+
|
|
230
|
+
t2_params = request.data_block.trans2_parameters
|
|
231
|
+
t2_params.information_level = RubySMB::SMB1::Packet::Trans2::SetInformationLevel::SMB_SET_FILE_UNIX_LINK
|
|
232
|
+
t2_params.filename = symlink
|
|
233
|
+
|
|
234
|
+
encoded_target = target.dup.force_encoding(Encoding::ASCII_8BIT)
|
|
235
|
+
encoded_target << "\x00".b unless encoded_target.end_with?("\x00".b)
|
|
236
|
+
request.data_block.trans2_data.buffer = encoded_target
|
|
237
|
+
|
|
238
|
+
request.parameter_block.total_parameter_count = request.parameter_block.parameter_count
|
|
239
|
+
request.parameter_block.total_data_count = request.parameter_block.data_count
|
|
240
|
+
request.parameter_block.max_parameter_count = request.parameter_block.parameter_count
|
|
241
|
+
request.parameter_block.max_data_count = 0
|
|
242
|
+
|
|
243
|
+
raw_response = client.send_recv(request)
|
|
244
|
+
response = RubySMB::SMB1::Packet::Trans2::SetPathInformationResponse.read(raw_response)
|
|
245
|
+
unless response.valid?
|
|
246
|
+
raise RubySMB::Error::InvalidPacket.new(
|
|
247
|
+
expected_proto: RubySMB::SMB1::SMB_PROTOCOL_ID,
|
|
248
|
+
expected_cmd: RubySMB::SMB1::Packet::Trans2::SetPathInformationResponse::COMMAND,
|
|
249
|
+
packet: response
|
|
250
|
+
)
|
|
251
|
+
end
|
|
252
|
+
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
253
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
|
254
|
+
end
|
|
255
|
+
response.status_code
|
|
256
|
+
end
|
|
257
|
+
|
|
198
258
|
# Sets a few preset header fields that will always be set the same
|
|
199
259
|
# way for Tree operations. This is, the TreeID and Extended Attributes.
|
|
200
260
|
#
|
|
@@ -206,8 +266,72 @@ module RubySMB
|
|
|
206
266
|
request
|
|
207
267
|
end
|
|
208
268
|
|
|
269
|
+
# Perform the CIFS UNIX Extensions handshake on this tree: query the
|
|
270
|
+
# server's supported extensions (SMB_QUERY_CIFS_UNIX_INFO) and then
|
|
271
|
+
# echo the version and capability bits back via SMB_SET_CIFS_UNIX_INFO.
|
|
272
|
+
# Samba requires this round-trip to have completed on the current
|
|
273
|
+
# session before it will honor UNIX-extension info levels such as
|
|
274
|
+
# SMB_SET_FILE_UNIX_LINK.
|
|
275
|
+
#
|
|
276
|
+
# @return [WindowsError::ErrorCode] NTStatus of the SET reply
|
|
277
|
+
# @raise [RubySMB::Error::UnexpectedStatusCode] if either leg fails
|
|
278
|
+
def enable_cifs_unix_extensions
|
|
279
|
+
major, minor, capabilities = query_cifs_unix_info
|
|
280
|
+
set_cifs_unix_info(major: major, minor: minor, capabilities: capabilities)
|
|
281
|
+
end
|
|
282
|
+
|
|
209
283
|
private
|
|
210
284
|
|
|
285
|
+
def query_cifs_unix_info
|
|
286
|
+
request = RubySMB::SMB1::Packet::Trans2::QueryFsInformationRequest.new
|
|
287
|
+
request = set_header_fields(request)
|
|
288
|
+
request.smb_header.flags2.unicode = 0
|
|
289
|
+
request.data_block.trans2_parameters.information_level =
|
|
290
|
+
RubySMB::SMB1::Packet::Trans2::QueryFsInformationLevel::SMB_QUERY_CIFS_UNIX_INFO
|
|
291
|
+
request.parameter_block.total_parameter_count = request.parameter_block.parameter_count
|
|
292
|
+
request.parameter_block.total_data_count = 0
|
|
293
|
+
request.parameter_block.max_parameter_count = 0
|
|
294
|
+
request.parameter_block.max_data_count = 560
|
|
295
|
+
|
|
296
|
+
raw_response = client.send_recv(request)
|
|
297
|
+
response = RubySMB::SMB1::Packet::Trans2::QueryFsInformationResponse.read(raw_response)
|
|
298
|
+
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
299
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
|
300
|
+
end
|
|
301
|
+
info = RubySMB::SMB1::Packet::Trans2::QueryFsInformationLevel::QueryFsCifsUnixInfo.read(
|
|
302
|
+
response.data_block.trans2_data.buffer
|
|
303
|
+
)
|
|
304
|
+
[info.major_version.to_i, info.minor_version.to_i, info.capabilities.to_i]
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def set_cifs_unix_info(major:, minor:, capabilities:)
|
|
308
|
+
request = RubySMB::SMB1::Packet::Trans2::SetFsInformationRequest.new
|
|
309
|
+
request = set_header_fields(request)
|
|
310
|
+
request.smb_header.flags2.unicode = 0
|
|
311
|
+
request.data_block.trans2_parameters.fid = 0
|
|
312
|
+
request.data_block.trans2_parameters.information_level =
|
|
313
|
+
RubySMB::SMB1::Packet::Trans2::SetFsInformationLevel::SMB_SET_CIFS_UNIX_INFO
|
|
314
|
+
|
|
315
|
+
info = RubySMB::SMB1::Packet::Trans2::QueryFsInformationLevel::QueryFsCifsUnixInfo.new
|
|
316
|
+
info.major_version = major
|
|
317
|
+
info.minor_version = minor
|
|
318
|
+
info.capabilities = capabilities
|
|
319
|
+
request.data_block.trans2_data.buffer = info.to_binary_s
|
|
320
|
+
|
|
321
|
+
request.parameter_block.total_parameter_count = request.parameter_block.parameter_count
|
|
322
|
+
request.parameter_block.total_data_count = request.parameter_block.data_count
|
|
323
|
+
request.parameter_block.max_parameter_count = request.parameter_block.parameter_count
|
|
324
|
+
request.parameter_block.max_data_count = 0
|
|
325
|
+
|
|
326
|
+
raw_response = client.send_recv(request)
|
|
327
|
+
response = RubySMB::SMB1::Packet::Trans2::SetFsInformationResponse.read(raw_response)
|
|
328
|
+
unless response.status_code == WindowsError::NTStatus::STATUS_SUCCESS
|
|
329
|
+
raise RubySMB::Error::UnexpectedStatusCode, response.status_code
|
|
330
|
+
end
|
|
331
|
+
response.status_code
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
|
|
211
335
|
def _open(filename:, flags: nil, options: nil, disposition: RubySMB::Dispositions::FILE_OPEN,
|
|
212
336
|
impersonation: RubySMB::ImpersonationLevels::SEC_IMPERSONATE, read: true, write: false, delete: false)
|
|
213
337
|
unless client.server_supports_nt_smbs
|
data/lib/ruby_smb/version.rb
CHANGED
|
@@ -40,7 +40,12 @@ RSpec.describe RubySMB::SMB1::Packet::Trans2::QueryFsInformationRequest do
|
|
|
40
40
|
|
|
41
41
|
it { is_expected.to respond_to :name }
|
|
42
42
|
it { is_expected.to respond_to :trans2_parameters }
|
|
43
|
-
it { is_expected.
|
|
43
|
+
it { is_expected.to respond_to :trans2_data }
|
|
44
|
+
|
|
45
|
+
it '#trans2_data is a zero-length placeholder (this request carries no data payload)' do
|
|
46
|
+
expect(data_block.trans2_data).to be_a BinData::String
|
|
47
|
+
expect(data_block.trans2_data.num_bytes).to eq 0
|
|
48
|
+
end
|
|
44
49
|
|
|
45
50
|
it 'should keep #trans2_parameters 4-byte aligned' do
|
|
46
51
|
expect(data_block.trans2_parameters.abs_offset % 4).to eq 0
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe RubySMB::SMB1::Packet::Trans2::SetFsInformationRequest do
|
|
4
|
+
subject(:packet) { described_class.new }
|
|
5
|
+
|
|
6
|
+
describe '#smb_header' do
|
|
7
|
+
subject(:header) { packet.smb_header }
|
|
8
|
+
|
|
9
|
+
it { is_expected.to be_a RubySMB::SMB1::SMBHeader }
|
|
10
|
+
|
|
11
|
+
it 'has the command set to SMB_COM_TRANSACTION2' do
|
|
12
|
+
expect(header.command).to eq RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#parameter_block' do
|
|
17
|
+
subject(:parameter_block) { packet.parameter_block }
|
|
18
|
+
|
|
19
|
+
it { is_expected.to be_a RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock }
|
|
20
|
+
|
|
21
|
+
it 'uses the SET_FS_INFORMATION subcommand' do
|
|
22
|
+
expect(parameter_block.setup[0]).to eq RubySMB::SMB1::Packet::Trans2::Subcommands::SET_FS_INFORMATION
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '#data_block' do
|
|
27
|
+
subject(:data_block) { packet.data_block }
|
|
28
|
+
|
|
29
|
+
it { is_expected.to respond_to :trans2_parameters }
|
|
30
|
+
it { is_expected.to respond_to :trans2_data }
|
|
31
|
+
|
|
32
|
+
describe '#trans2_parameters' do
|
|
33
|
+
subject(:parameters) { data_block.trans2_parameters }
|
|
34
|
+
|
|
35
|
+
it { is_expected.to respond_to :fid }
|
|
36
|
+
it { is_expected.to respond_to :information_level }
|
|
37
|
+
|
|
38
|
+
it 'is 4 bytes on the wire (fid + information_level)' do
|
|
39
|
+
parameters.fid = 0
|
|
40
|
+
parameters.information_level = RubySMB::SMB1::Packet::Trans2::SetFsInformationLevel::SMB_SET_CIFS_UNIX_INFO
|
|
41
|
+
expect(parameters.to_binary_s.bytesize).to eq 4
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe '#trans2_data' do
|
|
46
|
+
it 'carries an opaque byte buffer whose contents depend on the information level' do
|
|
47
|
+
data_block.trans2_data.buffer = "\x01\x00\x00\x00".b + "\x00".b * 8
|
|
48
|
+
expect(data_block.trans2_data.buffer.bytesize).to eq 12
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe RubySMB::SMB1::Packet::Trans2::SetFsInformationResponse do
|
|
4
|
+
subject(:packet) { described_class.new }
|
|
5
|
+
|
|
6
|
+
describe '#smb_header' do
|
|
7
|
+
subject(:header) { packet.smb_header }
|
|
8
|
+
|
|
9
|
+
it { is_expected.to be_a RubySMB::SMB1::SMBHeader }
|
|
10
|
+
|
|
11
|
+
it 'has the command set to SMB_COM_TRANSACTION2' do
|
|
12
|
+
expect(header.command).to eq RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'sets the reply flag' do
|
|
16
|
+
expect(header.flags.reply).to eq 1
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#parameter_block' do
|
|
21
|
+
subject(:parameter_block) { packet.parameter_block }
|
|
22
|
+
|
|
23
|
+
it { is_expected.to be_a RubySMB::SMB1::Packet::Trans2::Response::ParameterBlock }
|
|
24
|
+
|
|
25
|
+
it 'uses the SET_FS_INFORMATION subcommand' do
|
|
26
|
+
expect(parameter_block.setup[0]).to eq RubySMB::SMB1::Packet::Trans2::Subcommands::SET_FS_INFORMATION
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
RSpec.describe RubySMB::SMB1::Packet::Trans2::SetPathInformationRequest do
|
|
2
|
+
subject(:packet) { described_class.new }
|
|
3
|
+
|
|
4
|
+
describe '#smb_header' do
|
|
5
|
+
subject(:header) { packet.smb_header }
|
|
6
|
+
|
|
7
|
+
it 'is a standard SMB Header' do
|
|
8
|
+
expect(header).to be_a RubySMB::SMB1::SMBHeader
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'should have the command set to SMB_COM_TRANSACTION2' do
|
|
12
|
+
expect(header.command).to eq RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'should not have the response flag set' do
|
|
16
|
+
expect(header.flags.reply).to eq 0
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#parameter_block' do
|
|
21
|
+
subject(:parameter_block) { packet.parameter_block }
|
|
22
|
+
|
|
23
|
+
it 'is a standard ParameterBlock' do
|
|
24
|
+
expect(parameter_block).to be_a RubySMB::SMB1::Packet::Trans2::Request::ParameterBlock
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should have the setup set to the SET_PATH_INFORMATION subcommand' do
|
|
28
|
+
expect(parameter_block.setup).to include RubySMB::SMB1::Packet::Trans2::Subcommands::SET_PATH_INFORMATION
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe '#data_block' do
|
|
33
|
+
subject(:data_block) { packet.data_block }
|
|
34
|
+
|
|
35
|
+
it 'is a standard DataBlock' do
|
|
36
|
+
expect(data_block).to be_a RubySMB::SMB1::DataBlock
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it { is_expected.to respond_to :name }
|
|
40
|
+
it { is_expected.to respond_to :trans2_parameters }
|
|
41
|
+
it { is_expected.to respond_to :trans2_data }
|
|
42
|
+
|
|
43
|
+
it 'should keep #trans2_parameters 4-byte aligned' do
|
|
44
|
+
expect(data_block.trans2_parameters.abs_offset % 4).to eq 0
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe '#trans2_parameters' do
|
|
48
|
+
subject(:parameters) { data_block.trans2_parameters }
|
|
49
|
+
|
|
50
|
+
it { is_expected.to respond_to :information_level }
|
|
51
|
+
it { is_expected.to respond_to :reserved }
|
|
52
|
+
it { is_expected.to respond_to :filename }
|
|
53
|
+
|
|
54
|
+
describe '#information_level' do
|
|
55
|
+
it 'is a 16-bit field' do
|
|
56
|
+
expect(parameters.information_level).to be_a BinData::Uint16le
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe '#reserved' do
|
|
61
|
+
it 'is a 32-bit field' do
|
|
62
|
+
expect(parameters.reserved).to be_a BinData::Uint32le
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
describe '#filename' do
|
|
67
|
+
it 'is a BinData::Choice' do
|
|
68
|
+
expect(parameters.filename).to be_a BinData::Choice
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'encodes the filename as OEM when the unicode flag is cleared' do
|
|
72
|
+
packet.smb_header.flags2.unicode = 0
|
|
73
|
+
parameters.filename = 'link'
|
|
74
|
+
expect(parameters.filename.to_binary_s).to eq "link\x00".b
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'encodes the filename as UTF-16LE when the unicode flag is set' do
|
|
78
|
+
packet.smb_header.flags2.unicode = 1
|
|
79
|
+
parameters.filename = 'link'
|
|
80
|
+
expect(parameters.filename.to_binary_s).to eq "link\x00".encode('UTF-16LE').b
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe '#trans2_data' do
|
|
86
|
+
subject(:data) { data_block.trans2_data }
|
|
87
|
+
|
|
88
|
+
it { is_expected.to respond_to :buffer }
|
|
89
|
+
|
|
90
|
+
it 'carries an opaque byte buffer for the info-level-specific payload' do
|
|
91
|
+
data.buffer = "target\x00"
|
|
92
|
+
expect(data.buffer.to_binary_s).to eq "target\x00".b
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe 'encoded bytes for an SMB_SET_FILE_UNIX_LINK request' do
|
|
98
|
+
it 'encodes the information level, filename and target in the expected positions' do
|
|
99
|
+
packet.smb_header.flags2.unicode = 1
|
|
100
|
+
packet.data_block.trans2_parameters.information_level =
|
|
101
|
+
RubySMB::SMB1::Packet::Trans2::SetInformationLevel::SMB_SET_FILE_UNIX_LINK
|
|
102
|
+
packet.data_block.trans2_parameters.filename = 'foo'
|
|
103
|
+
packet.data_block.trans2_data.buffer = "bar\x00".encode('UTF-16LE')
|
|
104
|
+
|
|
105
|
+
raw = packet.to_binary_s
|
|
106
|
+
# Information level (little-endian 0x0201)
|
|
107
|
+
expect(raw).to include("\x01\x02".b)
|
|
108
|
+
# Filename in UTF-16LE with null terminator
|
|
109
|
+
expect(raw).to include("foo\x00".encode('UTF-16LE').b)
|
|
110
|
+
# Target in UTF-16LE with null terminator
|
|
111
|
+
expect(raw).to include("bar\x00".encode('UTF-16LE').b)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
RSpec.describe RubySMB::SMB1::Packet::Trans2::SetPathInformationResponse do
|
|
2
|
+
subject(:packet) { described_class.new }
|
|
3
|
+
|
|
4
|
+
describe '#smb_header' do
|
|
5
|
+
subject(:header) { packet.smb_header }
|
|
6
|
+
|
|
7
|
+
it 'is a standard SMB Header' do
|
|
8
|
+
expect(header).to be_a RubySMB::SMB1::SMBHeader
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'should have the command set to SMB_COM_TRANSACTION2' do
|
|
12
|
+
expect(header.command).to eq RubySMB::SMB1::Commands::SMB_COM_TRANSACTION2
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'should have the response flag set' do
|
|
16
|
+
expect(header.flags.reply).to eq 1
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe '#parameter_block' do
|
|
21
|
+
subject(:parameter_block) { packet.parameter_block }
|
|
22
|
+
|
|
23
|
+
it 'should have the setup set to the SET_PATH_INFORMATION subcommand' do
|
|
24
|
+
expect(parameter_block.setup).to include RubySMB::SMB1::Packet::Trans2::Subcommands::SET_PATH_INFORMATION
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '#data_block' do
|
|
29
|
+
subject(:data_block) { packet.data_block }
|
|
30
|
+
|
|
31
|
+
it 'is a standard DataBlock' do
|
|
32
|
+
expect(data_block).to be_a RubySMB::SMB1::DataBlock
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it { is_expected.to respond_to :trans2_parameters }
|
|
36
|
+
it { is_expected.to_not respond_to :trans2_data }
|
|
37
|
+
|
|
38
|
+
it 'should keep #trans2_parameters 4-byte aligned' do
|
|
39
|
+
expect(data_block.trans2_parameters.abs_offset % 4).to eq 0
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe '#trans2_parameters' do
|
|
43
|
+
subject(:parameters) { data_block.trans2_parameters }
|
|
44
|
+
|
|
45
|
+
it { is_expected.to respond_to :ea_error_offset }
|
|
46
|
+
|
|
47
|
+
describe '#ea_error_offset' do
|
|
48
|
+
it 'is a 16-bit field' do
|
|
49
|
+
expect(parameters.ea_error_offset).to be_a BinData::Uint16le
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -582,6 +582,130 @@ RSpec.describe RubySMB::SMB1::Tree do
|
|
|
582
582
|
end
|
|
583
583
|
end
|
|
584
584
|
|
|
585
|
+
describe '#set_unix_link' do
|
|
586
|
+
let(:set_path_response) { RubySMB::SMB1::Packet::Trans2::SetPathInformationResponse.new }
|
|
587
|
+
|
|
588
|
+
before :each do
|
|
589
|
+
# Stub out the CIFS UNIX Extensions handshake — covered separately below.
|
|
590
|
+
allow(tree).to receive(:enable_cifs_unix_extensions)
|
|
591
|
+
allow(client).to receive(:send_recv)
|
|
592
|
+
allow(RubySMB::SMB1::Packet::Trans2::SetPathInformationResponse).to receive(:read).and_return(set_path_response)
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
it 'performs the CIFS UNIX Extensions handshake before issuing the symlink request' do
|
|
596
|
+
call_order = []
|
|
597
|
+
allow(tree).to receive(:enable_cifs_unix_extensions) { call_order << :handshake }
|
|
598
|
+
allow(client).to receive(:send_recv) { call_order << :set_path; '' }
|
|
599
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
600
|
+
expect(call_order).to eq([:handshake, :set_path])
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
it 'sends a Trans2 SetPathInformationRequest with the UNIX_LINK info level' do
|
|
604
|
+
allow(client).to receive(:send_recv) do |request|
|
|
605
|
+
expect(request).to be_a(RubySMB::SMB1::Packet::Trans2::SetPathInformationRequest)
|
|
606
|
+
expect(request.data_block.trans2_parameters.information_level).to(
|
|
607
|
+
eq(RubySMB::SMB1::Packet::Trans2::SetInformationLevel::SMB_SET_FILE_UNIX_LINK)
|
|
608
|
+
)
|
|
609
|
+
end
|
|
610
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
it 'sets the Tree ID on the request' do
|
|
614
|
+
allow(client).to receive(:send_recv) do |request|
|
|
615
|
+
expect(request.smb_header.tid).to eq(tree.id)
|
|
616
|
+
end
|
|
617
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
it 'encodes the symlink path and target as raw byte strings (non-unicode)' do
|
|
621
|
+
allow(client).to receive(:send_recv) do |request|
|
|
622
|
+
raw = request.to_binary_s
|
|
623
|
+
expect(request.smb_header.flags2.unicode).to eq(0)
|
|
624
|
+
expect(raw).to include('escape'.b)
|
|
625
|
+
expect(raw).to include('../../etc'.b)
|
|
626
|
+
expect(raw).not_to include('escape'.encode('UTF-16LE').b)
|
|
627
|
+
end
|
|
628
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
it 'returns STATUS_SUCCESS on a successful response' do
|
|
632
|
+
expect(tree.set_unix_link(symlink: 'escape', target: '../../etc'))
|
|
633
|
+
.to eq(WindowsError::NTStatus::STATUS_SUCCESS)
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
context 'when the server returns a non-Trans2 response packet' do
|
|
637
|
+
it 'raises InvalidPacket' do
|
|
638
|
+
allow(set_path_response).to receive(:valid?).and_return(false)
|
|
639
|
+
expect {
|
|
640
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
641
|
+
}.to raise_error(RubySMB::Error::InvalidPacket)
|
|
642
|
+
end
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
context 'when the response has a non-success status code' do
|
|
646
|
+
it 'raises UnexpectedStatusCode' do
|
|
647
|
+
set_path_response.smb_header.nt_status =
|
|
648
|
+
WindowsError::NTStatus::STATUS_ACCESS_DENIED.value
|
|
649
|
+
expect {
|
|
650
|
+
tree.set_unix_link(symlink: 'escape', target: '../../etc')
|
|
651
|
+
}.to raise_error(RubySMB::Error::UnexpectedStatusCode)
|
|
652
|
+
end
|
|
653
|
+
end
|
|
654
|
+
end
|
|
655
|
+
|
|
656
|
+
describe '#enable_cifs_unix_extensions' do
|
|
657
|
+
let(:query_response) { RubySMB::SMB1::Packet::Trans2::QueryFsInformationResponse.new }
|
|
658
|
+
let(:set_response) { RubySMB::SMB1::Packet::Trans2::SetFsInformationResponse.new }
|
|
659
|
+
|
|
660
|
+
before :each do
|
|
661
|
+
# Server advertises major=1, minor=0, caps=0x0000_0000_0000_017B
|
|
662
|
+
info = RubySMB::SMB1::Packet::Trans2::QueryFsInformationLevel::QueryFsCifsUnixInfo.new
|
|
663
|
+
info.major_version = 1
|
|
664
|
+
info.minor_version = 0
|
|
665
|
+
info.capabilities = 0x17B
|
|
666
|
+
query_response.data_block.trans2_data.buffer = info.to_binary_s
|
|
667
|
+
allow(RubySMB::SMB1::Packet::Trans2::QueryFsInformationResponse).to receive(:read).and_return(query_response)
|
|
668
|
+
allow(RubySMB::SMB1::Packet::Trans2::SetFsInformationResponse).to receive(:read).and_return(set_response)
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
it 'queries the server for CIFS UNIX info and then echoes the capability bits back via SET_CIFS_UNIX_INFO' do
|
|
672
|
+
sent = []
|
|
673
|
+
allow(client).to receive(:send_recv) do |req|
|
|
674
|
+
sent << req
|
|
675
|
+
''
|
|
676
|
+
end
|
|
677
|
+
tree.enable_cifs_unix_extensions
|
|
678
|
+
|
|
679
|
+
expect(sent[0]).to be_a(RubySMB::SMB1::Packet::Trans2::QueryFsInformationRequest)
|
|
680
|
+
expect(sent[0].data_block.trans2_parameters.information_level).to(
|
|
681
|
+
eq(RubySMB::SMB1::Packet::Trans2::QueryFsInformationLevel::SMB_QUERY_CIFS_UNIX_INFO)
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
expect(sent[1]).to be_a(RubySMB::SMB1::Packet::Trans2::SetFsInformationRequest)
|
|
685
|
+
expect(sent[1].data_block.trans2_parameters.information_level).to(
|
|
686
|
+
eq(RubySMB::SMB1::Packet::Trans2::SetFsInformationLevel::SMB_SET_CIFS_UNIX_INFO)
|
|
687
|
+
)
|
|
688
|
+
echoed = RubySMB::SMB1::Packet::Trans2::QueryFsInformationLevel::QueryFsCifsUnixInfo.read(
|
|
689
|
+
sent[1].data_block.trans2_data.buffer
|
|
690
|
+
)
|
|
691
|
+
expect(echoed.major_version).to eq(1)
|
|
692
|
+
expect(echoed.minor_version).to eq(0)
|
|
693
|
+
expect(echoed.capabilities).to eq(0x17B)
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
it 'raises UnexpectedStatusCode when the QUERY leg fails' do
|
|
697
|
+
query_response.smb_header.nt_status = WindowsError::NTStatus::STATUS_ACCESS_DENIED.value
|
|
698
|
+
allow(client).to receive(:send_recv).and_return('')
|
|
699
|
+
expect { tree.enable_cifs_unix_extensions }.to raise_error(RubySMB::Error::UnexpectedStatusCode)
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
it 'raises UnexpectedStatusCode when the SET leg fails' do
|
|
703
|
+
set_response.smb_header.nt_status = WindowsError::NTStatus::STATUS_INVALID_PARAMETER.value
|
|
704
|
+
allow(client).to receive(:send_recv).and_return('')
|
|
705
|
+
expect { tree.enable_cifs_unix_extensions }.to raise_error(RubySMB::Error::UnexpectedStatusCode)
|
|
706
|
+
end
|
|
707
|
+
end
|
|
708
|
+
|
|
585
709
|
describe '#set_header_fields' do
|
|
586
710
|
let(:modified_request) { tree.set_header_fields(disco_req) }
|
|
587
711
|
it 'adds the TreeID to the header' do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_smb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.3.
|
|
4
|
+
version: 3.3.21
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Metasploit Hackers
|
|
@@ -13,7 +13,7 @@ authors:
|
|
|
13
13
|
autorequire:
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
|
-
date: 2026-
|
|
16
|
+
date: 2026-06-08 00:00:00.000000000 Z
|
|
17
17
|
dependencies:
|
|
18
18
|
- !ruby/object:Gem::Dependency
|
|
19
19
|
name: redcarpet
|
|
@@ -571,6 +571,7 @@ files:
|
|
|
571
571
|
- lib/ruby_smb/smb1/packet/trans2/query_file_information_response.rb
|
|
572
572
|
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_level.rb
|
|
573
573
|
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_attribute_info.rb
|
|
574
|
+
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_level/query_fs_cifs_unix_info.rb
|
|
574
575
|
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_request.rb
|
|
575
576
|
- lib/ruby_smb/smb1/packet/trans2/query_fs_information_response.rb
|
|
576
577
|
- lib/ruby_smb/smb1/packet/trans2/query_information_level.rb
|
|
@@ -583,6 +584,12 @@ files:
|
|
|
583
584
|
- lib/ruby_smb/smb1/packet/trans2/response.rb
|
|
584
585
|
- lib/ruby_smb/smb1/packet/trans2/set_file_information_request.rb
|
|
585
586
|
- lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb
|
|
587
|
+
- lib/ruby_smb/smb1/packet/trans2/set_fs_information_level.rb
|
|
588
|
+
- lib/ruby_smb/smb1/packet/trans2/set_fs_information_request.rb
|
|
589
|
+
- lib/ruby_smb/smb1/packet/trans2/set_fs_information_response.rb
|
|
590
|
+
- lib/ruby_smb/smb1/packet/trans2/set_information_level.rb
|
|
591
|
+
- lib/ruby_smb/smb1/packet/trans2/set_path_information_request.rb
|
|
592
|
+
- lib/ruby_smb/smb1/packet/trans2/set_path_information_response.rb
|
|
586
593
|
- lib/ruby_smb/smb1/packet/trans2/subcommands.rb
|
|
587
594
|
- lib/ruby_smb/smb1/packet/trans2/win9x_framing.rb
|
|
588
595
|
- lib/ruby_smb/smb1/packet/tree_connect_request.rb
|
|
@@ -922,6 +929,10 @@ files:
|
|
|
922
929
|
- spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb
|
|
923
930
|
- spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb
|
|
924
931
|
- spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb
|
|
932
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_request_spec.rb
|
|
933
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_response_spec.rb
|
|
934
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_request_spec.rb
|
|
935
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_response_spec.rb
|
|
925
936
|
- spec/lib/ruby_smb/smb1/packet/trans2/win9x_framing_spec.rb
|
|
926
937
|
- spec/lib/ruby_smb/smb1/packet/tree_connect_request_spec.rb
|
|
927
938
|
- spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb
|
|
@@ -1275,6 +1286,10 @@ test_files:
|
|
|
1275
1286
|
- spec/lib/ruby_smb/smb1/packet/trans2/response_spec.rb
|
|
1276
1287
|
- spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_request_spec.rb
|
|
1277
1288
|
- spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb
|
|
1289
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_request_spec.rb
|
|
1290
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_fs_information_response_spec.rb
|
|
1291
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_request_spec.rb
|
|
1292
|
+
- spec/lib/ruby_smb/smb1/packet/trans2/set_path_information_response_spec.rb
|
|
1278
1293
|
- spec/lib/ruby_smb/smb1/packet/trans2/win9x_framing_spec.rb
|
|
1279
1294
|
- spec/lib/ruby_smb/smb1/packet/tree_connect_request_spec.rb
|
|
1280
1295
|
- spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb
|