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 + -
显示快捷键?