rawsearch.c
来自「samba最新软件」· C语言 代码 · 共 842 行 · 第 1/2 页
C
842 行
/* Unix SMB/CIFS implementation. client directory search routines Copyright (C) James Myers 2003 <myersjj@samba.org> Copyright (C) James Peach 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "libcli/raw/libcliraw.h"#include "libcli/raw/raw_proto.h"/**************************************************************************** Old style search backend - process output.****************************************************************************/static void smb_raw_search_backend(struct smbcli_request *req, TALLOC_CTX *mem_ctx, uint16_t count, void *private, smbcli_search_callback callback){ union smb_search_data search_data; int i; uint8_t *p; if (req->in.data_size < 3 + count*43) { req->status = NT_STATUS_INVALID_PARAMETER; return; } p = req->in.data + 3; for (i=0; i < count; i++) { char *name; search_data.search.id.reserved = CVAL(p, 0); memcpy(search_data.search.id.name, p+1, 11); search_data.search.id.handle = CVAL(p, 12); search_data.search.id.server_cookie = IVAL(p, 13); search_data.search.id.client_cookie = IVAL(p, 17); search_data.search.attrib = CVAL(p, 21); search_data.search.write_time = raw_pull_dos_date(req->transport, p + 22); search_data.search.size = IVAL(p, 26); smbcli_req_pull_ascii(&req->in.bufinfo, mem_ctx, &name, p+30, 13, STR_ASCII); search_data.search.name = name; if (!callback(private, &search_data)) { break; } p += 43; }}/**************************************************************************** Old style search first.****************************************************************************/static NTSTATUS smb_raw_search_first_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_first *io, void *private, smbcli_search_callback callback){ struct smbcli_request *req; uint8_t op = SMBsearch; if (io->generic.level == RAW_SEARCH_FFIRST) { op = SMBffirst; } else if (io->generic.level == RAW_SEARCH_FUNIQUE) { op = SMBfunique; } req = smbcli_request_setup(tree, op, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->search_first.in.max_count); SSVAL(req->out.vwv, VWV(1), io->search_first.in.search_attrib); smbcli_req_append_ascii4(req, io->search_first.in.pattern, STR_TERMINATE); smbcli_req_append_var_block(req, NULL, 0); if (!smbcli_request_send(req) || !smbcli_request_receive(req)) { return smbcli_request_destroy(req); } if (NT_STATUS_IS_OK(req->status)) { io->search_first.out.count = SVAL(req->in.vwv, VWV(0)); smb_raw_search_backend(req, mem_ctx, io->search_first.out.count, private, callback); } return smbcli_request_destroy(req);}/**************************************************************************** Old style search next.****************************************************************************/static NTSTATUS smb_raw_search_next_old(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, void *private, smbcli_search_callback callback){ struct smbcli_request *req; uint8_t var_block[21]; uint8_t op = SMBsearch; if (io->generic.level == RAW_SEARCH_FFIRST) { op = SMBffirst; } req = smbcli_request_setup(tree, op, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->search_next.in.max_count); SSVAL(req->out.vwv, VWV(1), io->search_next.in.search_attrib); smbcli_req_append_ascii4(req, "", STR_TERMINATE); SCVAL(var_block, 0, io->search_next.in.id.reserved); memcpy(&var_block[1], io->search_next.in.id.name, 11); SCVAL(var_block, 12, io->search_next.in.id.handle); SIVAL(var_block, 13, io->search_next.in.id.server_cookie); SIVAL(var_block, 17, io->search_next.in.id.client_cookie); smbcli_req_append_var_block(req, var_block, 21); if (!smbcli_request_send(req) || !smbcli_request_receive(req)) { return smbcli_request_destroy(req); } if (NT_STATUS_IS_OK(req->status)) { io->search_next.out.count = SVAL(req->in.vwv, VWV(0)); smb_raw_search_backend(req, mem_ctx, io->search_next.out.count, private, callback); } return smbcli_request_destroy(req);}/**************************************************************************** Old style search next.****************************************************************************/static NTSTATUS smb_raw_search_close_old(struct smbcli_tree *tree, union smb_search_close *io){ struct smbcli_request *req; uint8_t var_block[21]; req = smbcli_request_setup(tree, SMBfclose, 2, 0); if (!req) { return NT_STATUS_NO_MEMORY; } SSVAL(req->out.vwv, VWV(0), io->fclose.in.max_count); SSVAL(req->out.vwv, VWV(1), io->fclose.in.search_attrib); smbcli_req_append_ascii4(req, "", STR_TERMINATE); SCVAL(var_block, 0, io->fclose.in.id.reserved); memcpy(&var_block[1], io->fclose.in.id.name, 11); SCVAL(var_block, 12, io->fclose.in.id.handle); SIVAL(var_block, 13, io->fclose.in.id.server_cookie); SIVAL(var_block, 17, io->fclose.in.id.client_cookie); smbcli_req_append_var_block(req, var_block, 21); if (!smbcli_request_send(req) || !smbcli_request_receive(req)) { return smbcli_request_destroy(req); } return smbcli_request_destroy(req);}/**************************************************************************** Very raw search first - returns param/data blobs.****************************************************************************/static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, /* used to allocate output blobs */ union smb_search_first *io, DATA_BLOB *out_param_blob, DATA_BLOB *out_data_blob){ struct smb_trans2 tp; uint16_t setup = TRANSACT2_FINDFIRST; NTSTATUS status; tp.in.max_setup = 0; tp.in.flags = 0; tp.in.timeout = 0; tp.in.setup_count = 1; tp.in.data = data_blob(NULL, 0); tp.in.max_param = 10; tp.in.max_data = 0xFFFF; tp.in.setup = &setup; if (io->t2ffirst.level != RAW_SEARCH_TRANS2) { return NT_STATUS_INVALID_LEVEL; } if (io->t2ffirst.data_level >= RAW_SEARCH_DATA_GENERIC) { return NT_STATUS_INVALID_LEVEL; } if (io->t2ffirst.data_level == RAW_SEARCH_DATA_EA_LIST) { if (!ea_push_name_list(mem_ctx, &tp.in.data, io->t2ffirst.in.num_names, io->t2ffirst.in.ea_names)) { return NT_STATUS_NO_MEMORY; } } tp.in.params = data_blob_talloc(mem_ctx, NULL, 12); if (!tp.in.params.data) { return NT_STATUS_NO_MEMORY; } SSVAL(tp.in.params.data, 0, io->t2ffirst.in.search_attrib); SSVAL(tp.in.params.data, 2, io->t2ffirst.in.max_count); SSVAL(tp.in.params.data, 4, io->t2ffirst.in.flags); SSVAL(tp.in.params.data, 6, io->t2ffirst.data_level); SIVAL(tp.in.params.data, 8, io->t2ffirst.in.storage_type); smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params, io->t2ffirst.in.pattern, STR_TERMINATE); status = smb_raw_trans2(tree, mem_ctx, &tp); if (!NT_STATUS_IS_OK(status)) { return status; } out_param_blob->length = tp.out.params.length; out_param_blob->data = tp.out.params.data; out_data_blob->length = tp.out.data.length; out_data_blob->data = tp.out.data.data; return NT_STATUS_OK;}/**************************************************************************** Very raw search first - returns param/data blobs. Used in CIFS-on-CIFS NTVFS.****************************************************************************/static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_search_next *io, DATA_BLOB *out_param_blob, DATA_BLOB *out_data_blob){ struct smb_trans2 tp; uint16_t setup = TRANSACT2_FINDNEXT; NTSTATUS status; tp.in.max_setup = 0; tp.in.flags = 0; tp.in.timeout = 0; tp.in.setup_count = 1; tp.in.data = data_blob(NULL, 0); tp.in.max_param = 10; tp.in.max_data = 0xFFFF; tp.in.setup = &setup; if (io->t2fnext.level != RAW_SEARCH_TRANS2) { return NT_STATUS_INVALID_LEVEL; } if (io->t2fnext.data_level >= RAW_SEARCH_DATA_GENERIC) { return NT_STATUS_INVALID_LEVEL; } if (io->t2fnext.data_level == RAW_SEARCH_DATA_EA_LIST) { if (!ea_push_name_list(mem_ctx, &tp.in.data, io->t2fnext.in.num_names, io->t2fnext.in.ea_names)) { return NT_STATUS_NO_MEMORY; } } tp.in.params = data_blob_talloc(mem_ctx, NULL, 12); if (!tp.in.params.data) { return NT_STATUS_NO_MEMORY; } SSVAL(tp.in.params.data, 0, io->t2fnext.in.handle); SSVAL(tp.in.params.data, 2, io->t2fnext.in.max_count); SSVAL(tp.in.params.data, 4, io->t2fnext.data_level); SIVAL(tp.in.params.data, 6, io->t2fnext.in.resume_key); SSVAL(tp.in.params.data, 10, io->t2fnext.in.flags); smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params, io->t2fnext.in.last_name, STR_TERMINATE); status = smb_raw_trans2(tree, mem_ctx, &tp); if (!NT_STATUS_IS_OK(status)) { return status; } out_param_blob->length = tp.out.params.length; out_param_blob->data = tp.out.params.data; out_data_blob->length = tp.out.data.length; out_data_blob->data = tp.out.data.data; return NT_STATUS_OK;}/* parse the wire search formats that are in common between SMB and SMB2*/NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, enum smb_search_data_level level, const DATA_BLOB *blob, union smb_search_data *data, uint_t *next_ofs, uint_t str_flags){ uint_t len, blen; if (blob->length < 4) { return NT_STATUS_INFO_LENGTH_MISMATCH; } *next_ofs = IVAL(blob->data, 0); if (*next_ofs != 0) { blen = *next_ofs; } else { blen = blob->length; } switch (level) { case RAW_SEARCH_DATA_DIRECTORY_INFO: if (blen < 65) return NT_STATUS_INFO_LENGTH_MISMATCH; data->directory_info.file_index = IVAL(blob->data, 4); data->directory_info.create_time = smbcli_pull_nttime(blob->data, 8); data->directory_info.access_time = smbcli_pull_nttime(blob->data, 16); data->directory_info.write_time = smbcli_pull_nttime(blob->data, 24); data->directory_info.change_time = smbcli_pull_nttime(blob->data, 32); data->directory_info.size = BVAL(blob->data, 40); data->directory_info.alloc_size = BVAL(blob->data, 48); data->directory_info.attrib = IVAL(blob->data, 56); len = smbcli_blob_pull_string(NULL, mem_ctx, blob, &data->directory_info.name, 60, 64, str_flags); if (*next_ofs != 0 && *next_ofs < 64+len) { return NT_STATUS_INFO_LENGTH_MISMATCH; } return NT_STATUS_OK; case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: if (blen < 69) return NT_STATUS_INFO_LENGTH_MISMATCH; data->full_directory_info.file_index = IVAL(blob->data, 4); data->full_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); data->full_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); data->full_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); data->full_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); data->full_directory_info.size = BVAL(blob->data, 40); data->full_directory_info.alloc_size = BVAL(blob->data, 48); data->full_directory_info.attrib = IVAL(blob->data, 56); data->full_directory_info.ea_size = IVAL(blob->data, 64); len = smbcli_blob_pull_string(NULL, mem_ctx, blob, &data->full_directory_info.name, 60, 68, str_flags); if (*next_ofs != 0 && *next_ofs < 68+len) { return NT_STATUS_INFO_LENGTH_MISMATCH; } return NT_STATUS_OK; case RAW_SEARCH_DATA_NAME_INFO: if (blen < 13) return NT_STATUS_INFO_LENGTH_MISMATCH; data->name_info.file_index = IVAL(blob->data, 4); len = smbcli_blob_pull_string(NULL, mem_ctx, blob, &data->name_info.name, 8, 12, str_flags); if (*next_ofs != 0 && *next_ofs < 12+len) { return NT_STATUS_INFO_LENGTH_MISMATCH; } return NT_STATUS_OK; case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: if (blen < 95) return NT_STATUS_INFO_LENGTH_MISMATCH; data->both_directory_info.file_index = IVAL(blob->data, 4); data->both_directory_info.create_time = smbcli_pull_nttime(blob->data, 8); data->both_directory_info.access_time = smbcli_pull_nttime(blob->data, 16); data->both_directory_info.write_time = smbcli_pull_nttime(blob->data, 24); data->both_directory_info.change_time = smbcli_pull_nttime(blob->data, 32); data->both_directory_info.size = BVAL(blob->data, 40); data->both_directory_info.alloc_size = BVAL(blob->data, 48); data->both_directory_info.attrib = IVAL(blob->data, 56); data->both_directory_info.ea_size = IVAL(blob->data, 64); smbcli_blob_pull_string(NULL, mem_ctx, blob, &data->both_directory_info.short_name, 68, 70, STR_LEN8BIT | STR_UNICODE); len = smbcli_blob_pull_string(NULL, mem_ctx, blob, &data->both_directory_info.name, 60, 94, str_flags); if (*next_ofs != 0 && *next_ofs < 94+len) { return NT_STATUS_INFO_LENGTH_MISMATCH; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?