/* look for the w2k3 setpathinfo STANDARD bug */ static bool torture_raw_sfileinfo_bug(struct torture_context *torture, struct smbcli_state *cli) { const char *fname = "\\bug3.txt"; union smb_setfileinfo sfinfo; NTSTATUS status; int fnum; if (!torture_setting_bool(torture, "dangerous", false)) torture_skip(torture, "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n"); fnum = create_complex_file(cli, torture, fname); smbcli_close(cli->tree, fnum); sfinfo.generic.level = RAW_SFILEINFO_STANDARD; sfinfo.generic.in.file.path = fname; sfinfo.standard.in.create_time = 0; sfinfo.standard.in.access_time = 0; sfinfo.standard.in.write_time = 0; status = smb_raw_setpathinfo(cli->tree, &sfinfo); printf("%s - %s\n", fname, nt_errstr(status)); printf("now try and delete %s\n", fname); return true; }
/* basic testing of all RAW_FILEINFO_* calls for each call we test that it succeeds, and where possible test for consistency between the calls. */ BOOL torture_raw_qfileinfo(struct torture_context *torture) { struct smbcli_state *cli; BOOL ret = True; TALLOC_CTX *mem_ctx; int fnum; const char *fname = "\\torture_qfileinfo.txt"; if (!torture_open_connection(&cli, 0)) { return False; } mem_ctx = talloc_init("torture_qfileinfo"); fnum = create_complex_file(cli, mem_ctx, fname); if (fnum == -1) { printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)); ret = False; goto done; } ret = torture_raw_qfileinfo_internals(torture, mem_ctx, cli->tree, fnum, fname, False /* is_ipc */); smbcli_close(cli->tree, fnum); smbcli_unlink(cli->tree, fname); done: torture_close_connection(cli); talloc_free(mem_ctx); return ret; }
/* basic testing of all RAW_FILEINFO_* calls for each call we test that it succeeds, and where possible test for consistency between the calls. */ bool torture_raw_qfileinfo(struct torture_context *torture, struct smbcli_state *cli) { int fnum; bool ret; const char *fname = "\\torture_qfileinfo.txt"; fnum = create_complex_file(cli, torture, fname); if (fnum == -1) { printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)); return false; } ret = torture_raw_qfileinfo_internals(torture, torture, cli->tree, fnum, fname, false /* is_ipc */); smbcli_close(cli->tree, fnum); smbcli_unlink(cli->tree, fname); return ret; }
/* test SMBntrename ops */ static bool test_ntrename(struct torture_context *tctx, struct smbcli_state *cli) { union smb_rename io; NTSTATUS status; bool ret = true; int fnum, i; const char *fname1 = BASEDIR "\\test1.txt"; const char *fname2 = BASEDIR "\\test2.txt"; union smb_fileinfo finfo; torture_comment(tctx, "Testing SMBntrename\n"); if (!torture_setup_dir(cli, BASEDIR)) { return false; } torture_comment(tctx, "Trying simple rename\n"); fnum = create_complex_file(cli, tctx, fname1); io.generic.level = RAW_RENAME_NTRENAME; io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.cluster_size = 0; io.ntrename.in.flags = RENAME_FLAG_RENAME; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION); smbcli_close(cli->tree, fnum); status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_comment(tctx, "Trying self rename\n"); io.ntrename.in.old_name = fname2; io.ntrename.in.new_name = fname2; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); torture_comment(tctx, "trying wildcard rename\n"); io.ntrename.in.old_name = BASEDIR "\\*.txt"; io.ntrename.in.new_name = fname1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD); torture_comment(tctx, "Checking attrib handling\n"); torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN); io.ntrename.in.old_name = fname2; io.ntrename.in.new_name = fname1; io.ntrename.in.attrib = 0; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL); torture_comment(tctx, "Checking hard link\n"); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.flags = RENAME_FLAG_HARD_LINK; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM); finfo.generic.level = RAW_FILEINFO_ALL_INFO; finfo.generic.in.file.path = fname2; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 2); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM); finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 2); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL); smbcli_unlink(cli->tree, fname2); finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL); torture_comment(tctx, "Checking copy\n"); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.flags = RENAME_FLAG_COPY; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); finfo.generic.level = RAW_FILEINFO_ALL_INFO; finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL); finfo.generic.level = RAW_FILEINFO_ALL_INFO; finfo.generic.in.file.path = fname2; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM); finfo.generic.level = RAW_FILEINFO_ALL_INFO; finfo.generic.in.file.path = fname2; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL); finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL); smbcli_unlink(cli->tree, fname2); finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); torture_comment(tctx, "Checking invalid flags\n"); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.flags = 0; status = smb_raw_rename(cli->tree, &io); if (TARGET_IS_WIN7(tctx)) { CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); } else { CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); } io.ntrename.in.flags = 300; status = smb_raw_rename(cli->tree, &io); if (TARGET_IS_WIN7(tctx)) { CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); } else { CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); } io.ntrename.in.flags = 0x106; status = smb_raw_rename(cli->tree, &io); if (TARGET_IS_WIN7(tctx)) { CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); } else { CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); } torture_comment(tctx, "Checking unknown field\n"); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.flags = RENAME_FLAG_RENAME; io.ntrename.in.cluster_size = 0xff; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_comment(tctx, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n"); io.ntrename.in.old_name = fname2; io.ntrename.in.new_name = fname1; io.ntrename.in.attrib = 0; io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION; io.ntrename.in.cluster_size = 1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); io.ntrename.in.flags = RENAME_FLAG_COPY; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); #if 0 { char buf[16384]; fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE); memset(buf, 1, sizeof(buf)); smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)); smbcli_close(cli->tree, fnum); fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE); memset(buf, 1, sizeof(buf)); smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1); smbcli_close(cli->tree, fnum); torture_all_info(cli->tree, fname1); torture_all_info(cli->tree, fname2); } io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); for (i=0; i<20000; i++) { io.ntrename.in.cluster_size = i; status = smb_raw_rename(cli->tree, &io); if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { torture_warning(tctx, "i=%d status=%s\n", i, nt_errstr(status)); } } #endif torture_comment(tctx, "Checking other flags\n"); for (i=0; i<0xFFF; i++) { if (i == RENAME_FLAG_RENAME || i == RENAME_FLAG_HARD_LINK || i == RENAME_FLAG_COPY) { continue; } io.ntrename.in.old_name = fname2; io.ntrename.in.new_name = fname1; io.ntrename.in.flags = i; io.ntrename.in.attrib = 0; io.ntrename.in.cluster_size = 0; status = smb_raw_rename(cli->tree, &io); if (TARGET_IS_WIN7(tctx)) { if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { torture_warning(tctx, "flags=0x%x status=%s\n", i, nt_errstr(status)); } } else { if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { torture_warning(tctx, "flags=0x%x status=%s\n", i, nt_errstr(status)); } } } done: smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret; }
/* * basic testing of all RAW_SFILEINFO_RENAME call */ static bool torture_raw_sfileinfo_rename(struct torture_context *torture, struct smbcli_state *cli) { bool ret = true; int fnum_saved, d_fnum, fnum2, fnum = -1; char *fnum_fname; char *fnum_fname_new; char *path_fname; char *path_fname_new; char *path_dname; char *path_dname_new; char *saved_name; char *saved_name_new; union smb_fileinfo finfo1, finfo2; union smb_setfileinfo sfinfo; NTSTATUS status, status2; const char *call_name; 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); asprintf(&path_dname, BASEDIR "\\dname_test_%d", n); asprintf(&path_dname_new, BASEDIR "\\dname_test_new_%d", n); if (!torture_setup_dir(cli, BASEDIR)) { return false; } RECREATE_BOTH; ZERO_STRUCT(sfinfo); smbcli_close(cli->tree, create_complex_file(cli, torture, fnum_fname_new)); smbcli_close(cli->tree, create_complex_file(cli, torture, path_fname_new)); sfinfo.rename_information.in.overwrite = 0; sfinfo.rename_information.in.root_fid = 0; sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION); sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1; CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION); sfinfo.rename_information.in.new_name = fnum_fname_new; sfinfo.rename_information.in.overwrite = 1; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED); sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 1; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new); printf("Trying rename with dest file open\n"); fnum2 = create_complex_file(cli, torture, fnum_fname); sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 1; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED); CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new); fnum_saved = fnum; fnum = fnum2; sfinfo.disposition_info.in.delete_on_close = 1; CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK); fnum = fnum_saved; printf("Trying rename with dest file open and delete_on_close\n"); sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 1; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED); smbcli_close(cli->tree, fnum2); CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname); printf("Trying rename with source file open twice\n"); sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 1; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname); fnum2 = create_complex_file(cli, torture, fnum_fname); sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 0; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new); smbcli_close(cli->tree, fnum2); sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 0; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname); sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 1; CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new); sfinfo.rename_information.in.new_name = fnum_fname+strlen(BASEDIR)+1; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname); sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1; CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, path_fname); printf("Trying rename with a root fid\n"); status = create_directory_handle(cli->tree, BASEDIR, &d_fnum); CHECK_STATUS(status, NT_STATUS_OK); sfinfo.rename_information.in.new_name = fnum_fname_new+strlen(BASEDIR)+1; sfinfo.rename_information.in.root_fid = d_fnum; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER); CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname); smbcli_close(cli->tree, d_fnum); printf("Trying rename directory\n"); if (!torture_setup_dir(cli, path_dname)) { ret = false; goto done; } saved_name = path_fname; saved_name_new = path_fname_new; path_fname = path_dname; path_fname_new = path_dname_new; sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 0; sfinfo.rename_information.in.root_fid = 0; CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new); path_fname = saved_name; path_fname_new = saved_name_new; if (torture_setting_bool(torture, "samba3", false)) { printf("SKIP: Trying rename directory with a handle\n"); printf("SKIP: Trying rename by path while a handle is open\n"); printf("SKIP: Trying rename directory by path while a handle is open\n"); goto done; } printf("Trying rename directory with a handle\n"); status = create_directory_handle(cli->tree, path_dname_new, &d_fnum); fnum_saved = fnum; fnum = d_fnum; saved_name = fnum_fname; saved_name_new = fnum_fname_new; fnum_fname = path_dname; fnum_fname_new = path_dname_new; sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 0; sfinfo.rename_information.in.root_fid = 0; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, path_dname); smbcli_close(cli->tree, d_fnum); fnum = fnum_saved; fnum_fname = saved_name; fnum_fname_new = saved_name_new; printf("Trying rename by path while a handle is open\n"); fnum_saved = fnum; fnum = create_complex_file(cli, torture, path_fname); sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 0; sfinfo.rename_information.in.root_fid = 0; CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new); /* check that the handle returns the same name */ check_fnum = true; CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new); /* rename it back on the handle */ sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, path_fname); check_fnum = false; CHECK_STR(NAME_INFO, name_info, fname.s, path_fname); smbcli_close(cli->tree, fnum); fnum = fnum_saved; printf("Trying rename directory by path while a handle is open\n"); status = create_directory_handle(cli->tree, path_dname, &d_fnum); fnum_saved = fnum; fnum = d_fnum; saved_name = path_fname; saved_name_new = path_fname_new; path_fname = path_dname; path_fname_new = path_dname_new; sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1; sfinfo.rename_information.in.overwrite = 0; sfinfo.rename_information.in.root_fid = 0; CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new); path_fname = saved_name; path_fname_new = saved_name_new; saved_name = fnum_fname; saved_name_new = fnum_fname_new; fnum_fname = path_dname; fnum_fname_new = path_dname_new; /* check that the handle returns the same name */ check_fnum = true; CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new); /* rename it back on the handle */ sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1; CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK); CHECK_STR(NAME_INFO, name_info, fname.s, path_dname); fnum_fname = saved_name; fnum_fname_new = saved_name_new; saved_name = path_fname; saved_name_new = path_fname_new; path_fname = path_dname; path_fname_new = path_dname_new; check_fnum = false; CHECK_STR(NAME_INFO, name_info, fname.s, path_dname); smbcli_close(cli->tree, d_fnum); fnum = fnum_saved; path_fname = saved_name; path_fname_new = saved_name_new; done: smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret; }
/* 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 { \ s = find(name); \ if (s) { \ if (s->sname1.field1 != v.sname2.out.field2) { \ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ __location__, \ #sname1, #field1, nt_time_string(tctx, s->sname1.field1), \ #sname2, #field2, nt_time_string(tctx, v.sname2.out.field2)); \ ret = false; \ } \ }} while (0) #define CHECK_STR(name, sname1, field1, v, sname2, field2) do { \ s = find(name); \ if (s) { \ if (!s->sname1.field1 || strcmp(s->sname1.field1, v.sname2.out.field2.s)) { \ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ __location__, \ #sname1, #field1, s->sname1.field1, \ #sname2, #field2, v.sname2.out.field2.s); \ ret = false; \ } \ }} while (0) #define CHECK_WSTR(name, sname1, field1, v, sname2, field2, flags) do { \ s = find(name); \ if (s) { \ if (!s->sname1.field1.s || \ strcmp(s->sname1.field1.s, v.sname2.out.field2.s) || \ wire_bad_flags(&s->sname1.field1, flags, cli->transport)) { \ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \ __location__, \ #sname1, #field1, s->sname1.field1.s, \ #sname2, #field2, v.sname2.out.field2.s); \ ret = false; \ } \ }} while (0) #define CHECK_NAME(name, sname1, field1, fname, flags) do { \ s = find(name); \ if (s) { \ if (!s->sname1.field1.s || \ strcmp(s->sname1.field1.s, fname) || \ wire_bad_flags(&s->sname1.field1, flags, cli->transport)) { \ printf("(%s) %s/%s [%s] != %s\n", \ __location__, \ #sname1, #field1, s->sname1.field1.s, \ fname); \ ret = false; \ } \ }} while (0) #define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \ s = find(name); \ if (s) { \ if (!s->sname1.field1 || \ strcmp(s->sname1.field1, fname)) { \ printf("(%s) %s/%s [%s] != %s\n", \ __location__, \ #sname1, #field1, s->sname1.field1, \ fname); \ ret = false; \ } \ }} while (0) /* check that all the results are as expected */ CHECK_VAL("SEARCH", search, attrib, all_info, all_info, attrib&0xFFF); CHECK_VAL("STANDARD", standard, attrib, all_info, all_info, attrib&0xFFF); CHECK_VAL("EA_SIZE", ea_size, attrib, all_info, all_info, attrib&0xFFF); CHECK_VAL("DIRECTORY_INFO", directory_info, attrib, all_info, all_info, attrib); CHECK_VAL("FULL_DIRECTORY_INFO", full_directory_info, attrib, all_info, all_info, attrib); CHECK_VAL("BOTH_DIRECTORY_INFO", both_directory_info, attrib, all_info, all_info, attrib); CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info, attrib, all_info, all_info, attrib); CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, attrib, all_info, all_info, attrib); CHECK_TIME("SEARCH", search, write_time, all_info, all_info, write_time); CHECK_TIME("STANDARD", standard, write_time, all_info, all_info, write_time); CHECK_TIME("EA_SIZE", ea_size, write_time, all_info, all_info, write_time); CHECK_TIME("STANDARD", standard, create_time, all_info, all_info, create_time); CHECK_TIME("EA_SIZE", ea_size, create_time, all_info, all_info, create_time); CHECK_TIME("STANDARD", standard, access_time, all_info, all_info, access_time); CHECK_TIME("EA_SIZE", ea_size, access_time, all_info, all_info, access_time); CHECK_NTTIME("DIRECTORY_INFO", directory_info, write_time, all_info, all_info, write_time); CHECK_NTTIME("FULL_DIRECTORY_INFO", full_directory_info, write_time, all_info, all_info, write_time); CHECK_NTTIME("BOTH_DIRECTORY_INFO", both_directory_info, write_time, all_info, all_info, write_time); CHECK_NTTIME("ID_FULL_DIRECTORY_INFO", id_full_directory_info, write_time, all_info, all_info, write_time); CHECK_NTTIME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, write_time, all_info, all_info, write_time); CHECK_NTTIME("DIRECTORY_INFO", directory_info, create_time, all_info, all_info, create_time); CHECK_NTTIME("FULL_DIRECTORY_INFO", full_directory_info, create_time, all_info, all_info, create_time); CHECK_NTTIME("BOTH_DIRECTORY_INFO", both_directory_info, create_time, all_info, all_info, create_time); CHECK_NTTIME("ID_FULL_DIRECTORY_INFO", id_full_directory_info, create_time, all_info, all_info, create_time); CHECK_NTTIME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, create_time, all_info, all_info, create_time); CHECK_NTTIME("DIRECTORY_INFO", directory_info, access_time, all_info, all_info, access_time); CHECK_NTTIME("FULL_DIRECTORY_INFO", full_directory_info, access_time, all_info, all_info, access_time); CHECK_NTTIME("BOTH_DIRECTORY_INFO", both_directory_info, access_time, all_info, all_info, access_time); CHECK_NTTIME("ID_FULL_DIRECTORY_INFO", id_full_directory_info, access_time, all_info, all_info, access_time); CHECK_NTTIME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, access_time, all_info, all_info, access_time); CHECK_NTTIME("DIRECTORY_INFO", directory_info, change_time, all_info, all_info, change_time); CHECK_NTTIME("FULL_DIRECTORY_INFO", full_directory_info, change_time, all_info, all_info, change_time); CHECK_NTTIME("BOTH_DIRECTORY_INFO", both_directory_info, change_time, all_info, all_info, change_time); CHECK_NTTIME("ID_FULL_DIRECTORY_INFO", id_full_directory_info, change_time, all_info, all_info, change_time); CHECK_NTTIME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, change_time, all_info, all_info, change_time); CHECK_VAL("SEARCH", search, size, all_info, all_info, size); CHECK_VAL("STANDARD", standard, size, all_info, all_info, size); CHECK_VAL("EA_SIZE", ea_size, size, all_info, all_info, size); CHECK_VAL("DIRECTORY_INFO", directory_info, size, all_info, all_info, size); CHECK_VAL("FULL_DIRECTORY_INFO", full_directory_info, size, all_info, all_info, size); CHECK_VAL("BOTH_DIRECTORY_INFO", both_directory_info, size, all_info, all_info, size); CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info, size, all_info, all_info, size); CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, size, all_info, all_info, size); CHECK_VAL("UNIX_INFO", unix_info, size, all_info, all_info, size); CHECK_VAL("STANDARD", standard, alloc_size, all_info, all_info, alloc_size); CHECK_VAL("EA_SIZE", ea_size, alloc_size, all_info, all_info, alloc_size); CHECK_VAL("DIRECTORY_INFO", directory_info, alloc_size, all_info, all_info, alloc_size); CHECK_VAL("FULL_DIRECTORY_INFO", full_directory_info, alloc_size, all_info, all_info, alloc_size); CHECK_VAL("BOTH_DIRECTORY_INFO", both_directory_info, alloc_size, all_info, all_info, alloc_size); CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info, alloc_size, all_info, all_info, alloc_size); CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, alloc_size, all_info, all_info, alloc_size); CHECK_VAL("UNIX_INFO", unix_info, alloc_size, all_info, all_info, alloc_size); CHECK_VAL("EA_SIZE", ea_size, ea_size, all_info, all_info, ea_size); CHECK_VAL("FULL_DIRECTORY_INFO", full_directory_info, ea_size, all_info, all_info, ea_size); CHECK_VAL("BOTH_DIRECTORY_INFO", both_directory_info, ea_size, all_info, all_info, ea_size); CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info, ea_size, all_info, all_info, ea_size); CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, ea_size, all_info, all_info, ea_size); CHECK_STR("SEARCH", search, name, alt_info, alt_name_info, fname); CHECK_WSTR("BOTH_DIRECTORY_INFO", both_directory_info, short_name, alt_info, alt_name_info, fname, STR_UNICODE); CHECK_NAME("STANDARD", standard, name, fname+1, 0); CHECK_NAME("EA_SIZE", ea_size, name, fname+1, 0); CHECK_NAME("DIRECTORY_INFO", directory_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_NAME("FULL_DIRECTORY_INFO", full_directory_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_NAME("NAME_INFO", name_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_NAME("BOTH_DIRECTORY_INFO", both_directory_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_NAME("ID_FULL_DIRECTORY_INFO", id_full_directory_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_NAME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_UNIX_NAME("UNIX_INFO", unix_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info, file_id, internal_info, internal_information, file_id); CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, file_id, internal_info, internal_information, file_id); done: smb_raw_exit(cli->session); smbcli_unlink(cli->tree, fname); return ret; }