📄 setfileinfo.c
字号:
/* Unix SMB/CIFS implementation. RAW_SFILEINFO_* 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/time.h"#include "libcli/raw/libcliraw.h"#include "libcli/raw/raw_proto.h"#include "libcli/libcli.h"#include "torture/util.h"#include "torture/raw/proto.h"#define BASEDIR "\\testsfileinfo"/* basic testing of all RAW_SFILEINFO_* calls for each call we test that it succeeds, and where possible test for consistency between the calls. */bool torture_raw_sfileinfo(struct torture_context *torture, struct smbcli_state *cli){ bool ret = true; int fnum = -1; char *fnum_fname; char *fnum_fname_new; char *path_fname; char *path_fname_new; union smb_fileinfo finfo1, finfo2; union smb_setfileinfo sfinfo; NTSTATUS status, status2; const char *call_name; time_t basetime = (time(NULL) - 86400) & ~1; bool check_fnum; int n = time(NULL) % 100; asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n); asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n); asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n); asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n); if (!torture_setup_dir(cli, BASEDIR)) { return false; }#define RECREATE_FILE(fname) do { \ if (fnum != -1) smbcli_close(cli->tree, fnum); \ fnum = create_complex_file(cli, torture, fname); \ if (fnum == -1) { \ printf("(%s) ERROR: open of %s failed (%s)\n", \ __location__, fname, smbcli_errstr(cli->tree)); \ ret = false; \ goto done; \ }} while (0)#define RECREATE_BOTH do { \ RECREATE_FILE(path_fname); \ smbcli_close(cli->tree, fnum); \ RECREATE_FILE(fnum_fname); \ } while (0) RECREATE_BOTH; #define CHECK_CALL_FNUM(call, rightstatus) do { \ check_fnum = true; \ call_name = #call; \ sfinfo.generic.level = RAW_SFILEINFO_ ## call; \ sfinfo.generic.in.file.fnum = fnum; \ status = smb_raw_setfileinfo(cli->tree, &sfinfo); \ if (!NT_STATUS_EQUAL(status, rightstatus)) { \ printf("(%s) %s - %s (should be %s)\n", __location__, #call, \ nt_errstr(status), nt_errstr(rightstatus)); \ ret = false; \ } \ finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \ finfo1.generic.in.file.fnum = fnum; \ status2 = smb_raw_fileinfo(cli->tree, torture, &finfo1); \ if (!NT_STATUS_IS_OK(status2)) { \ printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \ ret = false; \ }} while (0)#define CHECK_CALL_PATH(call, rightstatus) do { \ check_fnum = false; \ call_name = #call; \ sfinfo.generic.level = RAW_SFILEINFO_ ## call; \ sfinfo.generic.in.file.path = path_fname; \ status = smb_raw_setpathinfo(cli->tree, &sfinfo); \ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \ sfinfo.generic.in.file.path = path_fname_new; \ status = smb_raw_setpathinfo(cli->tree, &sfinfo); \ } \ if (!NT_STATUS_EQUAL(status, rightstatus)) { \ printf("(%s) %s - %s (should be %s)\n", __location__, #call, \ nt_errstr(status), nt_errstr(rightstatus)); \ ret = false; \ } \ finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \ finfo1.generic.in.file.path = path_fname; \ status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \ if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \ finfo1.generic.in.file.path = path_fname_new; \ status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \ } \ if (!NT_STATUS_IS_OK(status2)) { \ printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \ ret = false; \ }} while (0)#define CHECK1(call) \ do { if (NT_STATUS_IS_OK(status)) { \ finfo2.generic.level = RAW_FILEINFO_ ## call; \ if (check_fnum) { \ finfo2.generic.in.file.fnum = fnum; \ status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \ } else { \ finfo2.generic.in.file.path = path_fname; \ status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \ if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \ finfo2.generic.in.file.path = path_fname_new; \ status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \ } \ } \ if (!NT_STATUS_IS_OK(status2)) { \ printf("%s - %s\n", #call, nt_errstr(status2)); \ ret = false; \ } \ }} while (0)#define CHECK_VALUE(call, stype, field, value) do { \ CHECK1(call); \ if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \ printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \ call_name, #stype, #field, \ (uint_t)value, (uint_t)finfo2.stype.out.field); \ dump_all_info(torture, &finfo1); \ ret = false; \ }} while (0)#define CHECK_TIME(call, stype, field, value) do { \ CHECK1(call); \ if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \ printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \ call_name, #stype, #field, \ (uint_t)value, \ (uint_t)nt_time_to_unix(finfo2.stype.out.field)); \ printf("\t%s", timestring(torture, value)); \ printf("\t%s\n", nt_time_string(torture, finfo2.stype.out.field)); \ dump_all_info(torture, &finfo1); \ ret = false; \ }} while (0)#define CHECK_STR(call, stype, field, value) do { \ CHECK1(call); \ if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \ printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \ call_name, #stype, #field, \ value, \ finfo2.stype.out.field); \ dump_all_info(torture, &finfo1); \ ret = false; \ }} while (0)#define CHECK_STATUS(status, correct) do { \ if (!NT_STATUS_EQUAL(status, correct)) { \ printf("(%s) Incorrect status %s - should be %s\n", \ __location__, nt_errstr(status), nt_errstr(correct)); \ ret = false; \ goto done; \ }} while (0) printf("test setattr\n"); sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY; sfinfo.setattr.in.write_time = basetime; CHECK_CALL_PATH(SETATTR, NT_STATUS_OK); CHECK_VALUE (ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY); CHECK_TIME (ALL_INFO, all_info, write_time, basetime); printf("setting to NORMAL doesn't do anything\n"); sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_NORMAL; sfinfo.setattr.in.write_time = 0; CHECK_CALL_PATH(SETATTR, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY); CHECK_TIME (ALL_INFO, all_info, write_time, basetime); printf("a zero write_time means don't change\n"); sfinfo.setattr.in.attrib = 0; sfinfo.setattr.in.write_time = 0; CHECK_CALL_PATH(SETATTR, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL); CHECK_TIME (ALL_INFO, all_info, write_time, basetime); printf("test setattre\n"); sfinfo.setattre.in.create_time = basetime + 20; sfinfo.setattre.in.access_time = basetime + 30; sfinfo.setattre.in.write_time = basetime + 40; CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK); CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20); CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30); CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40); sfinfo.setattre.in.create_time = 0; sfinfo.setattre.in.access_time = 0; sfinfo.setattre.in.write_time = 0; CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK); CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20); CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30); CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 40); printf("test standard level\n"); sfinfo.standard.in.create_time = basetime + 100; sfinfo.standard.in.access_time = basetime + 200; sfinfo.standard.in.write_time = basetime + 300; CHECK_CALL_FNUM(STANDARD, NT_STATUS_OK); CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100); CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200); CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300); printf("test basic_info level\n"); basetime += 86400; unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100); unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200); unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300); unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400); sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY; CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK); CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100); CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200); CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300); CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400); CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY); printf("a zero time means don't change\n"); unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0); unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0); unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0); unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0); sfinfo.basic_info.in.attrib = 0; CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK); CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100); CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200); CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300); CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400); CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_READONLY); printf("test basic_information level\n"); basetime += 86400; unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100); unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200); unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime + 300); unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400); sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL; CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK); CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100); CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200); CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300); CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400); CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL); CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK); CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100); CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200); CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300); CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400); CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL); printf("a zero time means don't change\n"); unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0); unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0); unix_to_nt_time(&sfinfo.basic_info.in.write_time, 0); unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0); sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL; CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK); CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100); CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200); CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300); CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400); CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL); CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK); CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100); CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200); CHECK_TIME(ALL_INFO, all_info, write_time, basetime + 300); /* interesting - w2k3 leaves change_time as current time for 0 change time in setpathinfo CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400); */ CHECK_VALUE(ALL_INFO, all_info, attrib, FILE_ATTRIBUTE_NORMAL); printf("test disposition_info level\n"); sfinfo.disposition_info.in.delete_on_close = 1; CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1); CHECK_VALUE(ALL_INFO, all_info, nlink, 0); sfinfo.disposition_info.in.delete_on_close = 0; CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0); CHECK_VALUE(ALL_INFO, all_info, nlink, 1); printf("test disposition_information level\n"); sfinfo.disposition_info.in.delete_on_close = 1; CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1); CHECK_VALUE(ALL_INFO, all_info, nlink, 0); /* this would delete the file! */ /* CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1); CHECK_VALUE(ALL_INFO, all_info, nlink, 0); */ sfinfo.disposition_info.in.delete_on_close = 0; CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0); CHECK_VALUE(ALL_INFO, all_info, nlink, 1); CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0); CHECK_VALUE(ALL_INFO, all_info, nlink, 1); printf("test allocation_info level\n"); sfinfo.allocation_info.in.alloc_size = 0; CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, size, 0); CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0); sfinfo.allocation_info.in.alloc_size = 4096; CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK); CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096); CHECK_VALUE(ALL_INFO, all_info, size, 0); RECREATE_BOTH; sfinfo.allocation_info.in.alloc_size = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -