⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 search.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    Unix SMB/CIFS implementation.   RAW_SEARCH_* individual test suite   Copyright (C) Andrew Tridgell 2003      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 "torture/torture.h"#include "system/filesys.h"#include "libcli/raw/libcliraw.h"#include "libcli/raw/raw_proto.h"#include "libcli/libcli.h"#include "torture/util.h"#define BASEDIR "\\testsearch"/*  callback function for single_search*/static bool single_search_callback(void *private, const union smb_search_data *file){	union smb_search_data *data = (union smb_search_data *)private;	*data = *file;	return true;}/*  do a single file (non-wildcard) search */NTSTATUS torture_single_search(struct smbcli_state *cli, 			       TALLOC_CTX *tctx,			       const char *pattern,			       enum smb_search_level level,			       enum smb_search_data_level data_level,			       uint16_t attrib,			       union smb_search_data *data){	union smb_search_first io;	union smb_search_close c;	NTSTATUS status;	switch (level) {	case RAW_SEARCH_SEARCH:	case RAW_SEARCH_FFIRST:	case RAW_SEARCH_FUNIQUE:		io.search_first.level = level;		io.search_first.data_level = RAW_SEARCH_DATA_SEARCH;		io.search_first.in.max_count = 1;		io.search_first.in.search_attrib = attrib;		io.search_first.in.pattern = pattern;		break;	case RAW_SEARCH_TRANS2:		io.t2ffirst.level = RAW_SEARCH_TRANS2;		io.t2ffirst.data_level = data_level;		io.t2ffirst.in.search_attrib = attrib;		io.t2ffirst.in.max_count = 1;		io.t2ffirst.in.flags = FLAG_TRANS2_FIND_CLOSE;		io.t2ffirst.in.storage_type = 0;		io.t2ffirst.in.pattern = pattern;		break;	case RAW_SEARCH_SMB2:		return NT_STATUS_INVALID_LEVEL;	}	status = smb_raw_search_first(cli->tree, tctx,				      &io, (void *)data, single_search_callback);	if (NT_STATUS_IS_OK(status) && level == RAW_SEARCH_FFIRST) {		c.fclose.level = RAW_FINDCLOSE_FCLOSE;		c.fclose.in.max_count = 1;		c.fclose.in.search_attrib = 0;		c.fclose.in.id = data->search.id;		status = smb_raw_search_close(cli->tree, &c);	}		return status;}static struct {	const char *name;	enum smb_search_level level;	enum smb_search_data_level data_level;	int name_offset;	int resume_key_offset;	uint32_t capability_mask;	NTSTATUS status;	union smb_search_data data;} levels[] = {	{"FFIRST",	 RAW_SEARCH_FFIRST, RAW_SEARCH_DATA_SEARCH,	 offsetof(union smb_search_data, search.name),	 -1,	},	{"FUNIQUE",	 RAW_SEARCH_FUNIQUE, RAW_SEARCH_DATA_SEARCH,	 offsetof(union smb_search_data, search.name),	 -1,	},	{"SEARCH",	 RAW_SEARCH_SEARCH, RAW_SEARCH_DATA_SEARCH,	 offsetof(union smb_search_data, search.name),	 -1,	},	{"STANDARD",	 RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_STANDARD, 	 offsetof(union smb_search_data, standard.name.s),	 offsetof(union smb_search_data, standard.resume_key),	},	{"EA_SIZE",	 RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_EA_SIZE, 	 offsetof(union smb_search_data, ea_size.name.s),	 offsetof(union smb_search_data, ea_size.resume_key),	},	{"DIRECTORY_INFO",	 RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_DIRECTORY_INFO, 	 offsetof(union smb_search_data, directory_info.name.s),	 offsetof(union smb_search_data, directory_info.file_index),	},	{"FULL_DIRECTORY_INFO",	 RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, 	 offsetof(union smb_search_data, full_directory_info.name.s),	 offsetof(union smb_search_data, full_directory_info.file_index),	},	{"NAME_INFO",	 RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_NAME_INFO, 	 offsetof(union smb_search_data, name_info.name.s),	 offsetof(union smb_search_data, name_info.file_index),	},	{"BOTH_DIRECTORY_INFO",	 RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, 	 offsetof(union smb_search_data, both_directory_info.name.s),	 offsetof(union smb_search_data, both_directory_info.file_index),	},	{"ID_FULL_DIRECTORY_INFO",	 RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, 	 offsetof(union smb_search_data, id_full_directory_info.name.s),	 offsetof(union smb_search_data, id_full_directory_info.file_index),	},	{"ID_BOTH_DIRECTORY_INFO",	 RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, 	 offsetof(union smb_search_data, id_both_directory_info.name.s),	 offsetof(union smb_search_data, id_both_directory_info.file_index),	},	{"UNIX_INFO",	 RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_UNIX_INFO, 	 offsetof(union smb_search_data, unix_info.name),	 offsetof(union smb_search_data, unix_info.file_index),	 CAP_UNIX}};/*  return level name*/static const char *level_name(enum smb_search_level level,			      enum smb_search_data_level data_level){	int i;	for (i=0;i<ARRAY_SIZE(levels);i++) {		if (level == levels[i].level &&		    data_level == levels[i].data_level) {			return levels[i].name;		}	}	return NULL;}/*  extract the name from a smb_data structure and level*/static const char *extract_name(void *data, enum smb_search_level level,				enum smb_search_data_level data_level){	int i;	for (i=0;i<ARRAY_SIZE(levels);i++) {		if (level == levels[i].level &&		    data_level == levels[i].data_level) {			return *(const char **)(levels[i].name_offset + (char *)data);		}	}	return NULL;}/*  extract the name from a smb_data structure and level*/static uint32_t extract_resume_key(void *data, enum smb_search_level level,				   enum smb_search_data_level data_level){	int i;	for (i=0;i<ARRAY_SIZE(levels);i++) {		if (level == levels[i].level &&		    data_level == levels[i].data_level) {			return *(uint32_t *)(levels[i].resume_key_offset + (char *)data);		}	}	return 0;}/* find a level in the table by name */static union smb_search_data *find(const char *name){	int i;	for (i=0;i<ARRAY_SIZE(levels);i++) {		if (NT_STATUS_IS_OK(levels[i].status) && 		    strcmp(levels[i].name, name) == 0) {			return &levels[i].data;		}	}	return NULL;}/*    basic testing of all RAW_SEARCH_* calls using a single file*/static bool test_one_file(struct torture_context *tctx, 			  struct smbcli_state *cli){	bool ret = true;	int fnum;	const char *fname = "\\torture_search.txt";	const char *fname2 = "\\torture_search-NOTEXIST.txt";	NTSTATUS status;	int i;	union smb_fileinfo all_info, alt_info, name_info, internal_info;	union smb_search_data *s;	fnum = create_complex_file(cli, tctx, fname);	if (fnum == -1) {		printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));		ret = false;		goto done;	}	/* call all the levels */	for (i=0;i<ARRAY_SIZE(levels);i++) {		NTSTATUS expected_status;		uint32_t cap = cli->transport->negotiate.capabilities;		torture_comment(tctx, "testing %s\n", levels[i].name);		levels[i].status = torture_single_search(cli, tctx, fname, 							 levels[i].level,							 levels[i].data_level,							 0,							 &levels[i].data);		/* see if this server claims to support this level */		if ((cap & levels[i].capability_mask) != levels[i].capability_mask) {			printf("search level %s(%d) not supported by server\n",			       levels[i].name, (int)levels[i].level);			continue;		}		if (!NT_STATUS_IS_OK(levels[i].status)) {			printf("search level %s(%d) failed - %s\n",			       levels[i].name, (int)levels[i].level, 			       nt_errstr(levels[i].status));			ret = false;			continue;		}		status = torture_single_search(cli, tctx, fname2, 					       levels[i].level,					       levels[i].data_level,					       0,					       &levels[i].data);				expected_status = NT_STATUS_NO_SUCH_FILE;		if (levels[i].level == RAW_SEARCH_SEARCH ||		    levels[i].level == RAW_SEARCH_FFIRST ||		    levels[i].level == RAW_SEARCH_FUNIQUE) {			expected_status = STATUS_NO_MORE_FILES;		}		if (!NT_STATUS_EQUAL(status, expected_status)) {			printf("search level %s(%d) should fail with %s - %s\n",			       levels[i].name, (int)levels[i].level, 			       nt_errstr(expected_status),			       nt_errstr(status));			ret = false;		}	}	/* get the all_info file into to check against */	all_info.generic.level = RAW_FILEINFO_ALL_INFO;	all_info.generic.in.file.path = fname;	status = smb_raw_pathinfo(cli->tree, tctx, &all_info);	torture_assert_ntstatus_ok(tctx, status, "RAW_FILEINFO_ALL_INFO failed");	alt_info.generic.level = RAW_FILEINFO_ALT_NAME_INFO;	alt_info.generic.in.file.path = fname;	status = smb_raw_pathinfo(cli->tree, tctx, &alt_info);	torture_assert_ntstatus_ok(tctx, status, "RAW_FILEINFO_ALT_NAME_INFO failed");	internal_info.generic.level = RAW_FILEINFO_INTERNAL_INFORMATION;	internal_info.generic.in.file.path = fname;	status = smb_raw_pathinfo(cli->tree, tctx, &internal_info);	torture_assert_ntstatus_ok(tctx, status, "RAW_FILEINFO_INTERNAL_INFORMATION failed");	name_info.generic.level = RAW_FILEINFO_NAME_INFO;	name_info.generic.in.file.path = fname;	status = smb_raw_pathinfo(cli->tree, tctx, &name_info);	torture_assert_ntstatus_ok(tctx, status, "RAW_FILEINFO_NAME_INFO failed");#define CHECK_VAL(name, sname1, field1, v, sname2, field2) do { \	s = find(name); \	if (s) { \		if ((s->sname1.field1) != (v.sname2.out.field2)) { \			printf("(%s) %s/%s [0x%x] != %s/%s [0x%x]\n", \			       __location__, \				#sname1, #field1, (int)s->sname1.field1, \				#sname2, #field2, (int)v.sname2.out.field2); \			ret = false; \		} \	}} while (0)#define CHECK_TIME(name, sname1, field1, v, sname2, field2) do { \	s = find(name); \	if (s) { \		if (s->sname1.field1 != (~1 & nt_time_to_unix(v.sname2.out.field2))) { \			printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \			       __location__, \				#sname1, #field1, timestring(tctx, s->sname1.field1), \				#sname2, #field2, nt_time_string(tctx, v.sname2.out.field2)); \			ret = false; \		} \	}} while (0)#define CHECK_NTTIME(name, sname1, field1, v, sname2, field2) do { \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -