X-Git-Url: http://git.samba.org/samba.git/?p=sfrench%2Fsamba-autobuild%2F.git;a=blobdiff_plain;f=source4%2Ftorture%2Fraw%2Fsearch.c;h=96ceaf0a02f224811056795dd6062c7a81938fb5;hp=0c3a724bf95ca53ddb8d5dce1ce15c18198fbbef;hb=b674411eb46c9e45f2740a1f9bac365e9a347e9c;hpb=9f1210a243654fd6d94acdef83f468a33c1b3b3f diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c index 0c3a724bf95..96ceaf0a02f 100644 --- a/source4/torture/raw/search.c +++ b/source4/torture/raw/search.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "system/filesys.h" #include "libcli/raw/libcliraw.h" @@ -39,11 +40,12 @@ static BOOL single_search_callback(void *private, union smb_search_data *file) /* do a single file (non-wildcard) search */ -static NTSTATUS single_search(struct smbcli_state *cli, - TALLOC_CTX *mem_ctx, - const char *pattern, - enum smb_search_level level, - union smb_search_data *data) +NTSTATUS torture_single_search(struct smbcli_state *cli, + TALLOC_CTX *mem_ctx, + const char *pattern, + enum smb_search_level level, + uint16_t attrib, + union smb_search_data *data) { union smb_search_first io; union smb_search_close c; @@ -54,10 +56,10 @@ static NTSTATUS single_search(struct smbcli_state *cli, level == RAW_SEARCH_FFIRST || level == RAW_SEARCH_FUNIQUE) { io.search_first.in.max_count = 1; - io.search_first.in.search_attrib = 0; + io.search_first.in.search_attrib = attrib; io.search_first.in.pattern = pattern; } else { - io.t2ffirst.in.search_attrib = 0; + 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; @@ -143,8 +145,9 @@ static BOOL test_one_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) printf("testing %s\n", levels[i].name); - levels[i].status = single_search(cli, mem_ctx, fname, - levels[i].level, &levels[i].data); + levels[i].status = torture_single_search(cli, mem_ctx, fname, + levels[i].level, 0, + &levels[i].data); /* see if this server claims to support this level */ if ((cap & levels[i].capability_mask) != levels[i].capability_mask) { @@ -161,8 +164,9 @@ static BOOL test_one_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) continue; } - status = single_search(cli, mem_ctx, fname2, - levels[i].level, &levels[i].data); + status = torture_single_search(cli, mem_ctx, fname2, + levels[i].level, 0, + &levels[i].data); expected_status = NT_STATUS_NO_SUCH_FILE; if (levels[i].level == RAW_SEARCH_SEARCH || @@ -411,7 +415,7 @@ static BOOL multiple_search_callback(void *private, union smb_search_data *file) data->count++; - data->list = talloc_realloc_p(data->mem_ctx, + data->list = talloc_realloc(data->mem_ctx, data->list, union smb_search_data, data->count); @@ -436,7 +440,7 @@ static NTSTATUS multiple_search(struct smbcli_state *cli, union smb_search_first io; union smb_search_next io2; NTSTATUS status; - const int per_search = 300; + const int per_search = 100; struct multiple_result *result = data; io.generic.level = level; @@ -544,6 +548,14 @@ static NTSTATUS multiple_search(struct smbcli_state *cli, #define CHECK_VALUE(v, correct) do { \ if ((v) != (correct)) { \ printf("(%s) Incorrect value %s=%d - should be %d\n", \ + __location__, #v, v, (int)correct); \ + ret = False; \ + goto done; \ + }} while (0) + +#define CHECK_STRING(v, correct) do { \ + if (strcasecmp_m(v, correct) != 0) { \ + printf("(%s) Incorrect value %s='%s' - should be '%s'\n", \ __location__, #v, v, correct); \ ret = False; \ }} while (0) @@ -607,30 +619,28 @@ static BOOL test_many_files(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) {"DIRECTORY_INFO", "NAME", RAW_SEARCH_DIRECTORY_INFO, CONT_NAME} }; - if (smbcli_deltree(cli->tree, BASEDIR) == -1 || - NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) { - printf("Failed to create " BASEDIR " - %s\n", smbcli_errstr(cli->tree)); + if (!torture_setup_dir(cli, BASEDIR)) { return False; } printf("Creating %d files\n", num_files); for (i=0;itree, fname, O_CREAT|O_RDWR, DENY_NONE); if (fnum == -1) { printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = False; goto done; } - free(fname); + talloc_free(fname); smbcli_close(cli->tree, fnum); } for (t=0;ttree, BASEDIR) == -1 || - NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) { - printf("Failed to create " BASEDIR " - %s\n", smbcli_errstr(cli->tree)); + if (!torture_setup_dir(cli, BASEDIR)) { return False; } printf("Creating %d files\n", num_files); for (i=num_files-1;i>=0;i--) { - asprintf(&fname, BASEDIR "\\t%03d-%d.txt", i, i); + fname = talloc_asprintf(cli, BASEDIR "\\t%03d-%d.txt", i, i); fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR, DENY_NONE); if (fnum == -1) { printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = False; goto done; } - free(fname); + talloc_free(fname); smbcli_close(cli->tree, fnum); } printf("pulling the first file\n"); ZERO_STRUCT(result); - result.mem_ctx = talloc(mem_ctx, 0); + result.mem_ctx = talloc_new(mem_ctx); io.generic.level = RAW_SEARCH_BOTH_DIRECTORY_INFO; io.t2ffirst.in.search_attrib = 0; @@ -784,17 +792,15 @@ static BOOL test_modify_search(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) io2.t2fnext.in.max_count = 1; io2.t2fnext.in.resume_key = 0; io2.t2fnext.in.flags = 0; - if (result.count == 0) { - io2.t2fnext.in.last_name = ""; - } else { - io2.t2fnext.in.last_name = result.list[result.count-1].both_directory_info.name.s; - } + io2.t2fnext.in.last_name = result.list[result.count-1].both_directory_info.name.s; status = smb_raw_search_next(cli->tree, mem_ctx, &io2, &result, multiple_search_callback); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(result.count, 2); + result.count = 0; + printf("Changing attributes and deleting\n"); smbcli_open(cli->tree, BASEDIR "\\T003-03.txt.2", O_CREAT|O_RDWR, DENY_NONE); smbcli_open(cli->tree, BASEDIR "\\T013-13.txt.2", O_CREAT|O_RDWR, DENY_NONE); @@ -812,15 +818,15 @@ static BOOL test_modify_search(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) io2.generic.level = RAW_SEARCH_BOTH_DIRECTORY_INFO; io2.t2fnext.in.handle = io.t2ffirst.out.handle; - io2.t2fnext.in.max_count = num_files - 1; + io2.t2fnext.in.max_count = num_files + 3; io2.t2fnext.in.resume_key = 0; io2.t2fnext.in.flags = 0; - io2.t2fnext.in.last_name = result.list[result.count-2].both_directory_info.name.s; + io2.t2fnext.in.last_name = "."; status = smb_raw_search_next(cli->tree, mem_ctx, &io2, &result, multiple_search_callback); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VALUE(result.count, 21); + CHECK_VALUE(result.count, 20); ret &= check_result(&result, "t009-9.txt", True, FILE_ATTRIBUTE_ARCHIVE); ret &= check_result(&result, "t014-14.txt", False, 0); @@ -862,23 +868,21 @@ static BOOL test_sorted(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) NTSTATUS status; struct multiple_result result; - if (smbcli_deltree(cli->tree, BASEDIR) == -1 || - NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) { - printf("Failed to create " BASEDIR " - %s\n", smbcli_errstr(cli->tree)); + if (!torture_setup_dir(cli, BASEDIR)) { return False; } printf("Creating %d files\n", num_files); for (i=0;itree, fname, O_CREAT|O_RDWR, DENY_NONE); if (fnum == -1) { printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = False; goto done; } - free(fname); + talloc_free(fname); smbcli_close(cli->tree, fnum); } @@ -896,7 +900,7 @@ static BOOL test_sorted(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) const char *name1, *name2; name1 = result.list[i].both_directory_info.name.s; name2 = result.list[i+1].both_directory_info.name.s; - if (StrCaseCmp(name1, name2) > 0) { + if (strcasecmp_m(name1, name2) > 0) { printf("non-alphabetical order at entry %d '%s' '%s'\n", i, name1, name2); printf("Server does not produce sorted directory listings (not an error)\n"); @@ -920,23 +924,21 @@ done: */ static BOOL test_many_dirs(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { - const int num_dirs = 300; + const int num_dirs = 100; int i, fnum, n; char *fname, *dname; BOOL ret = True; NTSTATUS status; union smb_search_data *file, *file2, *file3; - if (smbcli_deltree(cli->tree, BASEDIR) == -1 || - NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) { - printf("Failed to create " BASEDIR " - %s\n", smbcli_errstr(cli->tree)); + if (!torture_setup_dir(cli, BASEDIR)) { return False; } printf("Creating %d dirs\n", num_dirs); for (i=0;itree, dname); if (!NT_STATUS_IS_OK(status)) { printf("(%s) Failed to create %s - %s\n", @@ -946,7 +948,7 @@ static BOOL test_many_dirs(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) } for (n=0;n<3;n++) { - asprintf(&fname, BASEDIR "\\d%d\\f%d-%d.txt", i, i, n); + fname = talloc_asprintf(cli, BASEDIR "\\d%d\\f%d-%d.txt", i, i, n); fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR, DENY_NONE); if (fnum == -1) { printf("(%s) Failed to create %s - %s\n", @@ -954,16 +956,16 @@ static BOOL test_many_dirs(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) ret = False; goto done; } - free(fname); + talloc_free(fname); + smbcli_close(cli->tree, fnum); } - free(dname); - smbcli_close(cli->tree, fnum); + talloc_free(dname); } - file = talloc_zero_array_p(mem_ctx, union smb_search_data, num_dirs); - file2 = talloc_zero_array_p(mem_ctx, union smb_search_data, num_dirs); - file3 = talloc_zero_array_p(mem_ctx, union smb_search_data, num_dirs); + file = talloc_zero_array(mem_ctx, union smb_search_data, num_dirs); + file2 = talloc_zero_array(mem_ctx, union smb_search_data, num_dirs); + file3 = talloc_zero_array(mem_ctx, union smb_search_data, num_dirs); printf("Search first on %d dirs\n", num_dirs); @@ -1076,6 +1078,232 @@ done: return ret; } + +/* + testing of OS/2 style delete +*/ +static BOOL test_os2_delete(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) +{ + const int num_files = 700; + const int delete_count = 4; + int total_deleted = 0; + int i, fnum; + char *fname; + BOOL ret = True; + NTSTATUS status; + union smb_search_first io; + union smb_search_next io2; + struct multiple_result result; + + if (!torture_setup_dir(cli, BASEDIR)) { + return False; + } + + printf("Testing OS/2 style delete on %d files\n", num_files); + + for (i=0;itree, fname, O_CREAT|O_RDWR, DENY_NONE); + if (fnum == -1) { + printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); + ret = False; + goto done; + } + talloc_free(fname); + smbcli_close(cli->tree, fnum); + } + + + ZERO_STRUCT(result); + result.mem_ctx = mem_ctx; + + io.t2ffirst.level = RAW_SEARCH_EA_SIZE; + io.t2ffirst.in.search_attrib = 0; + io.t2ffirst.in.max_count = 100; + io.t2ffirst.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME; + io.t2ffirst.in.storage_type = 0; + io.t2ffirst.in.pattern = BASEDIR "\\*"; + + status = smb_raw_search_first(cli->tree, mem_ctx, + &io, &result, multiple_search_callback); + CHECK_STATUS(status, NT_STATUS_OK); + + for (i=0;itree, fname); + CHECK_STATUS(status, NT_STATUS_OK); + total_deleted++; + talloc_free(fname); + } + + io2.t2fnext.level = RAW_SEARCH_EA_SIZE; + io2.t2fnext.in.handle = io.t2ffirst.out.handle; + io2.t2fnext.in.max_count = 100; + io2.t2fnext.in.resume_key = result.list[i-1].ea_size.resume_key; + io2.t2fnext.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME; + io2.t2fnext.in.last_name = result.list[i-1].ea_size.name.s; + + do { + ZERO_STRUCT(result); + result.mem_ctx = mem_ctx; + + status = smb_raw_search_next(cli->tree, mem_ctx, + &io2, &result, multiple_search_callback); + if (!NT_STATUS_IS_OK(status)) { + break; + } + + for (i=0;itree, fname); + CHECK_STATUS(status, NT_STATUS_OK); + total_deleted++; + talloc_free(fname); + } + + if (i>0) { + io2.t2fnext.in.resume_key = result.list[i-1].ea_size.resume_key; + io2.t2fnext.in.last_name = result.list[i-1].ea_size.name.s; + } + } while (NT_STATUS_IS_OK(status) && result.count != 0); + + CHECK_STATUS(status, NT_STATUS_OK); + + if (total_deleted != num_files) { + printf("error: deleted %d - expected to delete %d\n", + total_deleted, num_files); + ret = False; + } + +done: + smb_raw_exit(cli->session); + smbcli_deltree(cli->tree, BASEDIR); + + return ret; +} + + +static int ealist_cmp(union smb_search_data *r1, union smb_search_data *r2) +{ + return strcmp(r1->ea_list.name.s, r2->ea_list.name.s); +} + +/* + testing of the rather strange ea_list level +*/ +static BOOL test_ea_list(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) +{ + int fnum; + BOOL ret = True; + NTSTATUS status; + union smb_search_first io; + union smb_search_next nxt; + struct multiple_result result; + union smb_setfileinfo setfile; + + if (!torture_setup_dir(cli, BASEDIR)) { + return False; + } + + printf("Testing RAW_SEARCH_EA_LIST level\n"); + + fnum = smbcli_open(cli->tree, BASEDIR "\\file1.txt", O_CREAT|O_RDWR, DENY_NONE); + smbcli_close(cli->tree, fnum); + + fnum = smbcli_open(cli->tree, BASEDIR "\\file2.txt", O_CREAT|O_RDWR, DENY_NONE); + smbcli_close(cli->tree, fnum); + + fnum = smbcli_open(cli->tree, BASEDIR "\\file3.txt", O_CREAT|O_RDWR, DENY_NONE); + smbcli_close(cli->tree, fnum); + + setfile.generic.level = RAW_SFILEINFO_EA_SET; + setfile.generic.file.fname = BASEDIR "\\file2.txt"; + setfile.ea_set.in.num_eas = 2; + setfile.ea_set.in.eas = talloc_array(mem_ctx, struct ea_struct, 2); + setfile.ea_set.in.eas[0].flags = 0; + setfile.ea_set.in.eas[0].name.s = "EA ONE"; + setfile.ea_set.in.eas[0].value = data_blob_string_const("VALUE 1"); + setfile.ea_set.in.eas[1].flags = 0; + setfile.ea_set.in.eas[1].name.s = "SECOND EA"; + setfile.ea_set.in.eas[1].value = data_blob_string_const("Value Two"); + + status = smb_raw_setpathinfo(cli->tree, &setfile); + CHECK_STATUS(status, NT_STATUS_OK); + + setfile.generic.file.fname = BASEDIR "\\file3.txt"; + status = smb_raw_setpathinfo(cli->tree, &setfile); + CHECK_STATUS(status, NT_STATUS_OK); + + ZERO_STRUCT(result); + result.mem_ctx = mem_ctx; + + io.t2ffirst.level = RAW_SEARCH_EA_LIST; + io.t2ffirst.in.search_attrib = 0; + io.t2ffirst.in.max_count = 2; + io.t2ffirst.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME; + io.t2ffirst.in.storage_type = 0; + io.t2ffirst.in.pattern = BASEDIR "\\*"; + io.t2ffirst.in.num_names = 2; + io.t2ffirst.in.ea_names = talloc_array(mem_ctx, struct ea_name, 2); + io.t2ffirst.in.ea_names[0].name.s = "SECOND EA"; + io.t2ffirst.in.ea_names[1].name.s = "THIRD EA"; + + status = smb_raw_search_first(cli->tree, mem_ctx, + &io, &result, multiple_search_callback); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VALUE(result.count, 2); + + nxt.t2fnext.level = RAW_SEARCH_EA_LIST; + nxt.t2fnext.in.handle = io.t2ffirst.out.handle; + nxt.t2fnext.in.max_count = 2; + nxt.t2fnext.in.resume_key = result.list[1].ea_list.resume_key; + nxt.t2fnext.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME | FLAG_TRANS2_FIND_CONTINUE; + nxt.t2fnext.in.last_name = result.list[1].ea_list.name.s; + nxt.t2fnext.in.num_names = 2; + nxt.t2fnext.in.ea_names = talloc_array(mem_ctx, struct ea_name, 2); + nxt.t2fnext.in.ea_names[0].name.s = "SECOND EA"; + nxt.t2fnext.in.ea_names[1].name.s = "THIRD EA"; + + status = smb_raw_search_next(cli->tree, mem_ctx, + &nxt, &result, multiple_search_callback); + CHECK_STATUS(status, NT_STATUS_OK); + + /* we have to sort the result as different servers can return directories + in different orders */ + qsort(result.list, result.count, sizeof(result.list[0]), + (comparison_fn_t)ealist_cmp); + + CHECK_VALUE(result.count, 3); + CHECK_VALUE(result.list[0].ea_list.eas.num_eas, 2); + CHECK_STRING(result.list[0].ea_list.name.s, "file1.txt"); + CHECK_STRING(result.list[0].ea_list.eas.eas[0].name.s, "SECOND EA"); + CHECK_VALUE(result.list[0].ea_list.eas.eas[0].value.length, 0); + CHECK_STRING(result.list[0].ea_list.eas.eas[1].name.s, "THIRD EA"); + CHECK_VALUE(result.list[0].ea_list.eas.eas[1].value.length, 0); + + CHECK_STRING(result.list[1].ea_list.name.s, "file2.txt"); + CHECK_STRING(result.list[1].ea_list.eas.eas[0].name.s, "SECOND EA"); + CHECK_VALUE(result.list[1].ea_list.eas.eas[0].value.length, 9); + CHECK_STRING(result.list[1].ea_list.eas.eas[0].value.data, "Value Two"); + CHECK_STRING(result.list[1].ea_list.eas.eas[1].name.s, "THIRD EA"); + CHECK_VALUE(result.list[1].ea_list.eas.eas[1].value.length, 0); + + CHECK_STRING(result.list[2].ea_list.name.s, "file3.txt"); + CHECK_STRING(result.list[2].ea_list.eas.eas[0].name.s, "SECOND EA"); + CHECK_VALUE(result.list[2].ea_list.eas.eas[0].value.length, 9); + CHECK_STRING(result.list[2].ea_list.eas.eas[0].value.data, "Value Two"); + CHECK_STRING(result.list[2].ea_list.eas.eas[1].name.s, "THIRD EA"); + CHECK_VALUE(result.list[2].ea_list.eas.eas[1].value.length, 0); + +done: + smb_raw_exit(cli->session); + smbcli_deltree(cli->tree, BASEDIR); + + return ret; +} + + + /* basic testing of all RAW_SEARCH_* calls using a single file */ @@ -1096,9 +1324,11 @@ BOOL torture_raw_search(void) ret &= test_sorted(cli, mem_ctx); ret &= test_modify_search(cli, mem_ctx); ret &= test_many_dirs(cli, mem_ctx); + ret &= test_os2_delete(cli, mem_ctx); + ret &= test_ea_list(cli, mem_ctx); torture_close_connection(cli); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return ret; }