summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/torture/raw/search.c213
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);