Module: RubySMB::Server::Share::Provider::Disk::Processor::Query
- Included in:
- RubySMB::Server::Share::Provider::Disk::Processor
- Defined in:
- lib/ruby_smb/server/share/provider/disk/processor/query.rb
Instance Method Summary collapse
- #do_query_directory_smb2(request) ⇒ Object
- #do_query_info_smb2(request) ⇒ Object
- #do_transactions2_smb1(request) ⇒ Object
Instance Method Details
#do_query_directory_smb2(request) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/ruby_smb/server/share/provider/disk/processor/query.rb', line 45 def do_query_directory_smb2(request) local_path = get_local_path(request.file_id) if local_path.nil? response = RubySMB::SMB2::Packet::ErrorPacket.new response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_FILE_CLOSED return response end # see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/29dfcc9b-3aec-406b-abb5-0b4fe96712e2 info_class = request.file_information_class.snapshot begin # probe #build_fscc_file_information to see if it supports the requested info class build_fscc_file_information(Pathname.new(__FILE__), info_class) rescue NotImplementedError logger.warn("Can not handle QUERY_DIRECTORY request for class: #{info_class}") raise end unless local_path.directory? response = SMB2::Packet::ErrorPacket.new response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_INVALID_PARAMETER return response end search_pattern = request.name.snapshot.dup.encode begin search_regex = wildcard_to_regex(search_pattern) rescue NotImplementedError logger.warn("Can not handle QUERY_DIRECTORY wildcard pattern: #{search_pattern}") raise end return_single = request.flags.return_single == 1 align = 8 infos = [] total_size = 0 if @query_directory_context[request.file_id.to_binary_s].nil? || request.flags.reopen == 1 || request.flags.restart_scans == 1 dirents = local_path.children.sort.to_a dirents.unshift(local_path.parent) unless local_path.parent == local_path dirents.unshift(local_path) @query_directory_context[request.file_id.to_binary_s] = dirents else dirents = @query_directory_context[request.file_id.to_binary_s] end consume_dirents(local_path, dirents, filter_regex: search_regex) do |dirent, dirent_name| info = build_fscc_file_information(dirent, info_class, rename: dirent_name) info_size = info.num_bytes + ((align - info.num_bytes % align) % align) if total_size + info_size > request.output_length dirents.unshift(dirent) # no space left for this one so put it back break end infos << info total_size += info_size break if return_single end if infos.length == 0 response = SMB2::Packet::QueryDirectoryResponse.new response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_NO_MORE_FILES return response end response = SMB2::Packet::QueryDirectoryResponse.new infos.last.next_offset = 0 if infos.last buffer = "" infos.each do |info| info = info.to_binary_s buffer << info + "\x00".b * ((align - info.length % align) % align) end response.buffer = buffer response end |
#do_query_info_smb2(request) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/ruby_smb/server/share/provider/disk/processor/query.rb', line 122 def do_query_info_smb2(request) local_path = get_local_path(request.file_id) if local_path.nil? response = RubySMB::SMB2::Packet::ErrorPacket.new response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_FILE_CLOSED return response end case request.info_type when SMB2::SMB2_INFO_FILE info = query_info_smb2_file(request, local_path) when SMB2::SMB2_INFO_FILESYSTEM info = query_info_smb2_filesystem(request, local_path) else logger.warn("Can not handle QUERY_INFO request for type: #{request.info_type}, class: #{request.file_information_class}") raise NotImplementedError end response = SMB2::Packet::QueryInfoResponse.new response.buffer = info.to_binary_s response end |
#do_transactions2_smb1(request) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/ruby_smb/server/share/provider/disk/processor/query.rb', line 10 def do_transactions2_smb1(request) # can't find an example where more than one setup is set, this code makes alot of assumptions that there # are exactly 0 or 1 entries if request.parameter_block.setup.length > 1 raise NotImplementedError, 'There are more than 1 TRANSACTION2 setup values' end case request.data_block.trans2_parameters when SMB1::Packet::Trans2::FindFirst2RequestTrans2Parameters response = transaction2_smb1_find_first2(request) when SMB1::Packet::Trans2::QueryFileInformationRequestTrans2Parameters response = transaction2_smb1_query_file_information(request) when SMB1::Packet::Trans2::QueryPathInformationRequestTrans2Parameters response = transaction2_smb1_query_path_information(request) when SMB1::Packet::Trans2::QueryFsInformationRequestTrans2Parameters response = transaction2_smb1_query_fs_information(request) else subcommand = request.parameter_block.setup.first if subcommand logger.warn("Can not handle TRANSACTION2 request for subcommand #{subcommand} (#{SMB1::Packet::Trans2::Subcommands.name(subcommand)})") else logger.warn('Can not handle TRANSACTION2 request with missing subcommand') end raise NotImplementedError end if response and response.parameter_block.is_a?(RubySMB::SMB1::Packet::Trans2::Response::ParameterBlock) response.parameter_block.setup = [] response.parameter_block.total_parameter_count = response.parameter_block.parameter_count = response.data_block.trans2_parameters.num_bytes response.parameter_block.total_data_count = response.parameter_block.data_count = response.data_block.trans2_data.num_bytes end response end |