📄 qfileinfo.c
字号:
/* Unix SMB/CIFS implementation. RAW_FILEINFO_* individual test suite Copyright (C) Andrew Tridgell 2003 Copyright (C) Andrew Bartlett <abartlet@samba.org> 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 "torture/torture.h"#include "libcli/raw/libcliraw.h"#include "libcli/raw/raw_proto.h"#include "libcli/libcli.h"#include "torture/util.h"#include "librpc/rpc/dcerpc.h"#include "torture/rpc/rpc.h"#include "torture/raw/proto.h"#include "param/param.h"static struct { const char *name; enum smb_fileinfo_level level; uint_t only_paths:1; uint_t only_handles:1; uint32_t capability_mask; uint_t expected_ipc_access_denied:1; NTSTATUS expected_ipc_fnum_status; NTSTATUS fnum_status, fname_status; union smb_fileinfo fnum_finfo, fname_finfo;} levels[] = { { .name = "GETATTR", .level = RAW_FILEINFO_GETATTR, .only_paths = 1, .only_handles = 0, .expected_ipc_access_denied = 1}, { .name ="GETATTRE", .level = RAW_FILEINFO_GETATTRE, .only_paths = 0, .only_handles = 1 }, { .name ="STANDARD", .level = RAW_FILEINFO_STANDARD, }, { .name ="EA_SIZE", .level = RAW_FILEINFO_EA_SIZE }, { .name ="ALL_EAS", .level = RAW_FILEINFO_ALL_EAS, .expected_ipc_fnum_status = NT_STATUS_ACCESS_DENIED, }, { .name ="IS_NAME_VALID", .level = RAW_FILEINFO_IS_NAME_VALID, .only_paths = 1, .only_handles = 0 }, { .name ="BASIC_INFO", .level = RAW_FILEINFO_BASIC_INFO }, { .name ="STANDARD_INFO", .level = RAW_FILEINFO_STANDARD_INFO }, { .name ="EA_INFO", .level = RAW_FILEINFO_EA_INFO }, { .name ="NAME_INFO", .level = RAW_FILEINFO_NAME_INFO }, { .name ="ALL_INFO", .level = RAW_FILEINFO_ALL_INFO }, { .name ="ALT_NAME_INFO", .level = RAW_FILEINFO_ALT_NAME_INFO, .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER }, { .name ="STREAM_INFO", .level = RAW_FILEINFO_STREAM_INFO, .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER }, { .name ="COMPRESSION_INFO", .level = RAW_FILEINFO_COMPRESSION_INFO, .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER }, { .name ="UNIX_BASIC_INFO", .level = RAW_FILEINFO_UNIX_BASIC, .only_paths = 0, .only_handles = 0, .capability_mask = CAP_UNIX}, { .name ="UNIX_LINK_INFO", .level = RAW_FILEINFO_UNIX_LINK, .only_paths = 0, .only_handles = 0, .capability_mask = CAP_UNIX}, { .name ="BASIC_INFORMATION", .level = RAW_FILEINFO_BASIC_INFORMATION }, { .name ="STANDARD_INFORMATION", .level = RAW_FILEINFO_STANDARD_INFORMATION }, { .name ="INTERNAL_INFORMATION", .level = RAW_FILEINFO_INTERNAL_INFORMATION }, { .name ="EA_INFORMATION", .level = RAW_FILEINFO_EA_INFORMATION }, { .name = "ACCESS_INFORMATION", .level = RAW_FILEINFO_ACCESS_INFORMATION }, { .name = "NAME_INFORMATION", .level = RAW_FILEINFO_NAME_INFORMATION }, { .name ="POSITION_INFORMATION", .level = RAW_FILEINFO_POSITION_INFORMATION }, { .name ="MODE_INFORMATION", .level = RAW_FILEINFO_MODE_INFORMATION }, { .name ="ALIGNMENT_INFORMATION", .level = RAW_FILEINFO_ALIGNMENT_INFORMATION }, { .name ="ALL_INFORMATION", .level = RAW_FILEINFO_ALL_INFORMATION }, { .name ="ALT_NAME_INFORMATION", .level = RAW_FILEINFO_ALT_NAME_INFORMATION, .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER }, { .name ="STREAM_INFORMATION", .level = RAW_FILEINFO_STREAM_INFORMATION, .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER }, { .name = "COMPRESSION_INFORMATION", .level = RAW_FILEINFO_COMPRESSION_INFORMATION, .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER }, { .name ="NETWORK_OPEN_INFORMATION", .level = RAW_FILEINFO_NETWORK_OPEN_INFORMATION, .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER }, { .name = "ATTRIBUTE_TAG_INFORMATION", .level = RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER }, { NULL }};/* compare a dos time (2 second resolution) to a nt time*/static int dos_nt_time_cmp(time_t t, NTTIME nt){ time_t t2 = nt_time_to_unix(nt); if (abs(t2 - t) <= 2) return 0; return t2 - t;}/* find a level in the levels[] table*/static union smb_fileinfo *fnum_find(const char *name){ int i; for (i=0; levels[i].name; i++) { if (NT_STATUS_IS_OK(levels[i].fnum_status) && strcmp(name, levels[i].name) == 0 && !levels[i].only_paths) { return &levels[i].fnum_finfo; } } return NULL;}/* find a level in the levels[] table*/static union smb_fileinfo *fname_find(bool is_ipc, const char *name){ int i; if (is_ipc) { return NULL; } for (i=0; levels[i].name; i++) { if (NT_STATUS_IS_OK(levels[i].fname_status) && strcmp(name, levels[i].name) == 0 && !levels[i].only_handles) { return &levels[i].fname_finfo; } } return NULL;}/* local macros to make the code below more readable */#define VAL_EQUAL(n1, v1, n2, v2) do {if (s1->n1.out.v1 != s2->n2.out.v2) { \ printf("%s/%s [%u] != %s/%s [%u] at %s(%d)\n", \ #n1, #v1, (uint_t)s1->n1.out.v1, \ #n2, #v2, (uint_t)s2->n2.out.v2, \ __FILE__, __LINE__); \ ret = false; \}} while(0)#define STR_EQUAL(n1, v1, n2, v2) do {if (strcmp_safe(s1->n1.out.v1.s, s2->n2.out.v2.s) || \ s1->n1.out.v1.private_length != s2->n2.out.v2.private_length) { \ printf("%s/%s [%s/%d] != %s/%s [%s/%d] at %s(%d)\n", \ #n1, #v1, s1->n1.out.v1.s, s1->n1.out.v1.private_length, \ #n2, #v2, s2->n2.out.v2.s, s2->n2.out.v2.private_length, \ __FILE__, __LINE__); \ ret = false; \}} while(0)#define STRUCT_EQUAL(n1, v1, n2, v2) do {if (memcmp(&s1->n1.out.v1,&s2->n2.out.v2,sizeof(s1->n1.out.v1))) { \ printf("%s/%s != %s/%s at %s(%d)\n", \ #n1, #v1, \ #n2, #v2, \ __FILE__, __LINE__); \ ret = false; \}} while(0)/* used to find hints on unknown values - and to make sure we zero-fill */#if 0 /* unused */#define VAL_UNKNOWN(n1, v1) do {if (s1->n1.out.v1 != 0) { \ printf("%s/%s non-zero unknown - %u (0x%x) at %s(%d)\n", \ #n1, #v1, \ (uint_t)s1->n1.out.v1, \ (uint_t)s1->n1.out.v1, \ __FILE__, __LINE__); \ ret = false; \}} while(0)#endif/* basic testing of all RAW_FILEINFO_* calls for each call we test that it succeeds, and where possible test for consistency between the calls. */static bool torture_raw_qfileinfo_internals(struct torture_context *torture, TALLOC_CTX *mem_ctx, struct smbcli_tree *tree, int fnum, const char *fname, bool is_ipc){ int i; bool ret = true; int count; union smb_fileinfo *s1, *s2; NTTIME correct_time; uint64_t correct_size; uint32_t correct_attrib; const char *correct_name; bool skip_streams = false; /* scan all the fileinfo and pathinfo levels */ for (i=0; levels[i].name; i++) { if (!levels[i].only_paths) { levels[i].fnum_finfo.generic.level = levels[i].level; levels[i].fnum_finfo.generic.in.file.fnum = fnum; levels[i].fnum_status = smb_raw_fileinfo(tree, mem_ctx, &levels[i].fnum_finfo); } if (!levels[i].only_handles) { levels[i].fname_finfo.generic.level = levels[i].level; levels[i].fname_finfo.generic.in.file.path = talloc_strdup(mem_ctx, fname); levels[i].fname_status = smb_raw_pathinfo(tree, mem_ctx, &levels[i].fname_finfo); } } /* check for completely broken levels */ for (count=i=0; levels[i].name; i++) { uint32_t cap = tree->session->transport->negotiate.capabilities; /* see if this server claims to support this level */ if ((cap & levels[i].capability_mask) != levels[i].capability_mask) { continue; } if (is_ipc) { if (levels[i].expected_ipc_access_denied && NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, levels[i].fname_status)) { } else if (!levels[i].only_handles && !NT_STATUS_EQUAL(NT_STATUS_INVALID_DEVICE_REQUEST, levels[i].fname_status)) { printf("ERROR: fname level %s failed, expected NT_STATUS_INVALID_DEVICE_REQUEST - %s\n", levels[i].name, nt_errstr(levels[i].fname_status)); count++; } if (!levels[i].only_paths && !NT_STATUS_EQUAL(levels[i].expected_ipc_fnum_status, levels[i].fnum_status)) { printf("ERROR: fnum level %s failed, expected %s - %s\n", levels[i].name, nt_errstr(levels[i].expected_ipc_fnum_status), nt_errstr(levels[i].fnum_status)); count++; } } else { if (!levels[i].only_paths && !NT_STATUS_IS_OK(levels[i].fnum_status)) { printf("ERROR: fnum level %s failed - %s\n", levels[i].name, nt_errstr(levels[i].fnum_status)); count++; } if (!levels[i].only_handles && !NT_STATUS_IS_OK(levels[i].fname_status)) { printf("ERROR: fname level %s failed - %s\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -