diff options
-rw-r--r-- | source4/torture/raw/search.c | 213 |
1 files changed, 123 insertions, 90 deletions
diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c index ef415bc60b..e90cbdfbf9 100644 --- a/source4/torture/raw/search.c +++ b/source4/torture/raw/search.c @@ -87,24 +87,105 @@ NTSTATUS torture_single_search(struct smbcli_state *cli, static struct { const char *name; enum smb_search_level level; + int name_offset; + int resume_key_offset; uint32_t capability_mask; NTSTATUS status; union smb_search_data data; } levels[] = { - {"FFIRST", RAW_SEARCH_FFIRST, }, - {"FUNIQUE", RAW_SEARCH_FUNIQUE, }, - {"SEARCH", RAW_SEARCH_SEARCH, }, - {"STANDARD", RAW_SEARCH_STANDARD, }, - {"EA_SIZE", RAW_SEARCH_EA_SIZE, }, - {"DIRECTORY_INFO", RAW_SEARCH_DIRECTORY_INFO, }, - {"FULL_DIRECTORY_INFO", RAW_SEARCH_FULL_DIRECTORY_INFO, }, - {"NAME_INFO", RAW_SEARCH_NAME_INFO, }, - {"BOTH_DIRECTORY_INFO", RAW_SEARCH_BOTH_DIRECTORY_INFO, }, - {"ID_FULL_DIRECTORY_INFO", RAW_SEARCH_ID_FULL_DIRECTORY_INFO, }, - {"ID_BOTH_DIRECTORY_INFO", RAW_SEARCH_ID_BOTH_DIRECTORY_INFO, }, - {"UNIX_INFO", RAW_SEARCH_UNIX_INFO, CAP_UNIX} + {"FFIRST", RAW_SEARCH_FFIRST, + offsetof(union smb_search_data, search.name), + -1, + }, + {"FUNIQUE", RAW_SEARCH_FUNIQUE, + offsetof(union smb_search_data, search.name), + -1, + }, + {"SEARCH", RAW_SEARCH_SEARCH, + offsetof(union smb_search_data, search.name), + -1, + }, + {"STANDARD", RAW_SEARCH_STANDARD, + offsetof(union smb_search_data, standard.name.s), + offsetof(union smb_search_data, standard.resume_key), + }, + {"EA_SIZE", RAW_SEARCH_EA_SIZE, + offsetof(union smb_search_data, ea_size.name.s), + offsetof(union smb_search_data, ea_size.resume_key), + }, + {"DIRECTORY_INFO", RAW_SEARCH_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_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_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_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_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_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_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) +{ + int i; + for (i=0;i<ARRAY_SIZE(levels);i++) { + if (level == levels[i].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) +{ + int i; + for (i=0;i<ARRAY_SIZE(levels);i++) { + if (level == levels[i].level) { + return *(const char **)(levels[i].name_offset + (char *)data); + } + } + return NULL; +} + +/* + extract the name from a smb_data structure and level +*/ +static int extract_resume_key(void *data, enum smb_search_level level) +{ + int i; + for (i=0;i<ARRAY_SIZE(levels);i++) { + if (level == levels[i].level) { + return (int)*(uint32_t *)(levels[i].resume_key_offset + (char *)data); + } + } + return -1; +} + /* find a level in the table by name */ static union smb_search_data *find(const char *name) { @@ -481,40 +562,17 @@ static NTSTATUS multiple_search(struct smbcli_state *cli, io2.t2fnext.in.last_name = ""; switch (cont_type) { case CONT_RESUME_KEY: - if (level == RAW_SEARCH_STANDARD) { - io2.t2fnext.in.resume_key = - result->list[result->count-1].standard.resume_key; - } else if (level == RAW_SEARCH_EA_SIZE) { - io2.t2fnext.in.resume_key = - result->list[result->count-1].ea_size.resume_key; - } else if (level == RAW_SEARCH_DIRECTORY_INFO) { - io2.t2fnext.in.resume_key = - result->list[result->count-1].directory_info.file_index; - } else { - io2.t2fnext.in.resume_key = - result->list[result->count-1].both_directory_info.file_index; - } - if (io2.t2fnext.in.resume_key == 0) { - printf("Server does not support resume by key\n"); + io2.t2fnext.in.resume_key = extract_resume_key(&result->list[result->count-1], level); + if (io2.t2fnext.in.resume_key <= 0) { + printf("Server does not support resume by key for level %s\n", + level_name(level)); return NT_STATUS_NOT_SUPPORTED; } io2.t2fnext.in.flags |= FLAG_TRANS2_FIND_REQUIRE_RESUME | FLAG_TRANS2_FIND_BACKUP_INTENT; break; case CONT_NAME: - if (level == RAW_SEARCH_STANDARD) { - io2.t2fnext.in.last_name = - result->list[result->count-1].standard.name.s; - } else if (level == RAW_SEARCH_EA_SIZE) { - io2.t2fnext.in.last_name = - result->list[result->count-1].ea_size.name.s; - } else if (level == RAW_SEARCH_DIRECTORY_INFO) { - io2.t2fnext.in.last_name = - result->list[result->count-1].directory_info.name.s; - } else { - io2.t2fnext.in.last_name = - result->list[result->count-1].both_directory_info.name.s; - } + io2.t2fnext.in.last_name = extract_name(&result->list[result->count-1], level); break; case CONT_FLAGS: io2.t2fnext.in.flags |= FLAG_TRANS2_FIND_CONTINUE; @@ -564,30 +622,16 @@ static NTSTATUS multiple_search(struct smbcli_state *cli, }} while (0) -static int search_both_compare(union smb_search_data *d1, union smb_search_data *d2) -{ - return strcmp_safe(d1->both_directory_info.name.s, d2->both_directory_info.name.s); -} - -static int search_standard_compare(union smb_search_data *d1, union smb_search_data *d2) -{ - return strcmp_safe(d1->standard.name.s, d2->standard.name.s); -} - -static int search_ea_size_compare(union smb_search_data *d1, union smb_search_data *d2) -{ - return strcmp_safe(d1->ea_size.name.s, d2->ea_size.name.s); -} +static enum smb_search_level compare_level; -static int search_directory_info_compare(union smb_search_data *d1, union smb_search_data *d2) +static int search_compare(union smb_search_data *d1, union smb_search_data *d2) { - return strcmp_safe(d1->directory_info.name.s, d2->directory_info.name.s); + const char *s1, *s2; + s1 = extract_name(d1, compare_level); + s2 = extract_name(d2, compare_level); + return strcmp_safe(s1, s2); } -static int search_old_compare(union smb_search_data *d1, union smb_search_data *d2) -{ - return strcmp_safe(d1->search.name, d2->search.name); -} /* @@ -619,14 +663,23 @@ static BOOL test_many_files(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) {"EA_SIZE", "NAME", RAW_SEARCH_EA_SIZE, CONT_NAME}, {"DIRECTORY_INFO", "FLAGS", RAW_SEARCH_DIRECTORY_INFO, CONT_FLAGS}, {"DIRECTORY_INFO", "KEY", RAW_SEARCH_DIRECTORY_INFO, CONT_RESUME_KEY}, - {"DIRECTORY_INFO", "NAME", RAW_SEARCH_DIRECTORY_INFO, CONT_NAME} + {"DIRECTORY_INFO", "NAME", RAW_SEARCH_DIRECTORY_INFO, CONT_NAME}, + {"FULL_DIRECTORY_INFO", "FLAGS", RAW_SEARCH_FULL_DIRECTORY_INFO, CONT_FLAGS}, + {"FULL_DIRECTORY_INFO", "KEY", RAW_SEARCH_FULL_DIRECTORY_INFO, CONT_RESUME_KEY}, + {"FULL_DIRECTORY_INFO", "NAME", RAW_SEARCH_FULL_DIRECTORY_INFO, CONT_NAME}, + {"ID_FULL_DIRECTORY_INFO", "FLAGS", RAW_SEARCH_ID_FULL_DIRECTORY_INFO, CONT_FLAGS}, + {"ID_FULL_DIRECTORY_INFO", "KEY", RAW_SEARCH_ID_FULL_DIRECTORY_INFO, CONT_RESUME_KEY}, + {"ID_FULL_DIRECTORY_INFO", "NAME", RAW_SEARCH_ID_FULL_DIRECTORY_INFO, CONT_NAME}, + {"ID_BOTH_DIRECTORY_INFO", "NAME", RAW_SEARCH_ID_BOTH_DIRECTORY_INFO, CONT_NAME}, + {"ID_BOTH_DIRECTORY_INFO", "FLAGS", RAW_SEARCH_ID_BOTH_DIRECTORY_INFO, CONT_FLAGS}, + {"ID_BOTH_DIRECTORY_INFO", "KEY", RAW_SEARCH_ID_BOTH_DIRECTORY_INFO, CONT_RESUME_KEY} }; if (!torture_setup_dir(cli, BASEDIR)) { return False; } - printf("Creating %d files\n", num_files); + printf("Testing with %d files\n", num_files); for (i=0;i<num_files;i++) { fname = talloc_asprintf(cli, BASEDIR "\\t%03d-%d.txt", i, i); @@ -653,42 +706,22 @@ static BOOL test_many_files(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) &result); if (!NT_STATUS_IS_OK(status)) { - printf("search failed - %s\n", nt_errstr(status)); + printf("search type %s failed - %s\n", + search_types[t].name, + nt_errstr(status)); ret = False; continue; } CHECK_VALUE(result.count, num_files); - if (search_types[t].level == RAW_SEARCH_BOTH_DIRECTORY_INFO) { - qsort(result.list, result.count, sizeof(result.list[0]), - QSORT_CAST search_both_compare); - } else if (search_types[t].level == RAW_SEARCH_STANDARD) { - qsort(result.list, result.count, sizeof(result.list[0]), - QSORT_CAST search_standard_compare); - } else if (search_types[t].level == RAW_SEARCH_EA_SIZE) { - qsort(result.list, result.count, sizeof(result.list[0]), - QSORT_CAST search_ea_size_compare); - } else if (search_types[t].level == RAW_SEARCH_DIRECTORY_INFO) { - qsort(result.list, result.count, sizeof(result.list[0]), - QSORT_CAST search_directory_info_compare); - } else { - qsort(result.list, result.count, sizeof(result.list[0]), - QSORT_CAST search_old_compare); - } + compare_level = search_types[t].level; + + qsort(result.list, result.count, sizeof(result.list[0]), + QSORT_CAST search_compare); for (i=0;i<result.count;i++) { const char *s; - if (search_types[t].level == RAW_SEARCH_BOTH_DIRECTORY_INFO) { - s = result.list[i].both_directory_info.name.s; - } else if (search_types[t].level == RAW_SEARCH_STANDARD) { - s = result.list[i].standard.name.s; - } else if (search_types[t].level == RAW_SEARCH_EA_SIZE) { - s = result.list[i].ea_size.name.s; - } else if (search_types[t].level == RAW_SEARCH_DIRECTORY_INFO) { - s = result.list[i].directory_info.name.s; - } else { - s = result.list[i].search.name; - } + s = extract_name(&result.list[i], compare_level); fname = talloc_asprintf(cli, "t%03d-%d.txt", i, i); if (strcmp(fname, s)) { printf("Incorrect name %s at entry %d\n", s, i); |