r14720: Add torture_context argument to all torture tests
[samba.git] / source4 / torture / smb2 / find.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    SMB2 find test suite
5
6    Copyright (C) Andrew Tridgell 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "libcli/smb2/smb2.h"
25 #include "libcli/smb2/smb2_calls.h"
26
27 #include "torture/torture.h"
28 #include "torture/smb2/proto.h"
29
30 static struct {
31         const char *name;
32         uint16_t level;
33         NTSTATUS status;
34         union smb_search_data data;
35 } levels[] = {
36 #define LEVEL(x) #x, x
37  { LEVEL(SMB2_FIND_ID_BOTH_DIRECTORY_INFO) },
38  { LEVEL(SMB2_FIND_DIRECTORY_INFO) },
39  { LEVEL(SMB2_FIND_FULL_DIRECTORY_INFO) },
40  { LEVEL(SMB2_FIND_NAME_INFO) },
41  { LEVEL(SMB2_FIND_BOTH_DIRECTORY_INFO) },
42  { LEVEL(SMB2_FIND_ID_FULL_DIRECTORY_INFO) },
43 };
44
45 #define FNAME "smb2-find.dat"
46
47 #define CHECK_VALUE(call_name, stype, field) do { \
48         union smb_search_data *d = find_level("SMB2_FIND_" #call_name); \
49         if (io.all_info2.out.field != d->stype.field) { \
50                 printf("(%s) %s/%s should be 0x%llx - 0x%llx\n", __location__, \
51                        #call_name, #field, \
52                        (long long)io.all_info2.out.field, (long long)d->stype.field); \
53                 ret = False; \
54         }} while (0)
55
56 #define CHECK_STRING(call_name, stype, field1, field2) do { \
57         union smb_search_data *d = find_level("SMB2_FIND_" #call_name); \
58         if (strcmp(io.all_info2.out.field2.s, d->stype.field1.s) != 0) { \
59                 printf("(%s) %s/%s should be '%s' - '%s'\n", __location__, \
60                        #call_name, #field2, \
61                        io.all_info2.out.field2.s, d->stype.field1.s); \
62                 ret = False; \
63         }} while (0)
64
65 #define CHECK_CONST_STRING(call_name, stype, field, str) do { \
66         union smb_search_data *d = find_level("SMB2_FIND_" #call_name); \
67         if (strcmp(str, d->stype.field.s) != 0) { \
68                 printf("(%s) %s/%s should be '%s' - '%s'\n", __location__, \
69                        #call_name, #field, \
70                        str, d->stype.field.s); \
71                 ret = False; \
72         }} while (0)
73
74 static union smb_search_data *find_level(const char *name)
75 {
76         int i;
77         for (i=0;i<ARRAY_SIZE(levels);i++) {
78                 if (strcmp(name, levels[i].name) == 0) {
79                         return &levels[i].data;
80                 }
81         }
82         return NULL;
83 }
84
85 /*
86   test find levels
87 */
88 static BOOL torture_smb2_find_levels(struct smb2_tree *tree)
89 {
90         struct smb2_handle handle;
91         NTSTATUS status;
92         int i;
93         struct smb2_find f;
94         BOOL ret = True;
95         union smb_fileinfo io;
96         const char *alt_name;
97
98         status = smb2_create_complex_file(tree, FNAME, &handle);
99         if (!NT_STATUS_IS_OK(status)) {
100                 return False;
101         }
102
103         io.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
104         io.generic.in.file.handle = handle;
105         status = smb2_getinfo_file(tree, tree, &io);
106         if (!NT_STATUS_IS_OK(status)) {
107                 return False;
108         }
109         alt_name = talloc_strdup(tree, io.alt_name_info.out.fname.s);   
110
111         io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
112         io.generic.in.file.handle = handle;
113         status = smb2_getinfo_file(tree, tree, &io);
114         if (!NT_STATUS_IS_OK(status)) {
115                 return False;
116         }
117
118         status = smb2_util_roothandle(tree, &handle);
119         if (!NT_STATUS_IS_OK(status)) {
120                 return False;
121         }
122
123         ZERO_STRUCT(f);
124         f.in.handle = handle;
125         f.in.pattern = FNAME;
126         f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
127         f.in.max_response_size = 0x10000;
128
129         for (i=0;i<ARRAY_SIZE(levels);i++) {
130                 union smb_search_data *d;
131                 uint_t count;
132
133                 f.in.level = levels[i].level - 0x100;
134
135                 levels[i].status = smb2_find_level(tree, tree, &f, &count, &d);
136                 if (!NT_STATUS_IS_OK(levels[i].status)) {
137                         printf("%s failed - %s\n", levels[i].name, 
138                                nt_errstr(levels[i].status));
139                 }
140
141                 if (count != 1) {
142                         printf("Expected count 1 - got %d in %s\n", count, levels[i].name);
143                         ret = False;
144                 }
145
146                 levels[i].data = d[0];
147         }
148
149         CHECK_VALUE(DIRECTORY_INFO, directory_info, create_time);
150         CHECK_VALUE(DIRECTORY_INFO, directory_info, access_time);
151         CHECK_VALUE(DIRECTORY_INFO, directory_info, write_time);
152         CHECK_VALUE(DIRECTORY_INFO, directory_info, change_time);
153         CHECK_VALUE(DIRECTORY_INFO, directory_info, size);
154         CHECK_VALUE(DIRECTORY_INFO, directory_info, alloc_size);
155         CHECK_VALUE(DIRECTORY_INFO, directory_info, attrib);
156         CHECK_CONST_STRING(DIRECTORY_INFO, directory_info, name, FNAME);
157
158         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, create_time);
159         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, access_time);
160         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, write_time);
161         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, change_time);
162         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, size);
163         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, alloc_size);
164         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, attrib);
165         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, ea_size);
166         CHECK_CONST_STRING(FULL_DIRECTORY_INFO, full_directory_info, name, FNAME);
167
168         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, create_time);
169         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, access_time);
170         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, write_time);
171         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, change_time);
172         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, size);
173         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, alloc_size);
174         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, attrib);
175         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, ea_size);
176         CHECK_CONST_STRING(BOTH_DIRECTORY_INFO, both_directory_info, short_name, alt_name);
177         CHECK_CONST_STRING(BOTH_DIRECTORY_INFO, both_directory_info, name, FNAME);
178
179         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, create_time);
180         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, access_time);
181         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, write_time);
182         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, change_time);
183         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, size);
184         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, alloc_size);
185         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, attrib);
186         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, ea_size);
187         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, file_id);
188         CHECK_CONST_STRING(ID_FULL_DIRECTORY_INFO, id_full_directory_info, name, FNAME);
189
190         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, create_time);
191         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, access_time);
192         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, write_time);
193         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, change_time);
194         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, size);
195         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, alloc_size);
196         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, attrib);
197         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, ea_size);
198         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, file_id);
199         CHECK_CONST_STRING(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, name, FNAME);
200
201
202         return ret;
203 }
204
205
206 /* basic testing of all SMB2 find levels
207 */
208 BOOL torture_smb2_find(struct torture_context *torture)
209 {
210         TALLOC_CTX *mem_ctx = talloc_new(NULL);
211         struct smb2_tree *tree;
212         BOOL ret = True;
213         NTSTATUS status;
214
215         if (!torture_smb2_connection(mem_ctx, &tree)) {
216                 return False;
217         }
218
219         status = torture_setup_complex_file(tree, FNAME);
220         if (!NT_STATUS_IS_OK(status)) {
221                 return False;
222         }
223         torture_setup_complex_file(tree, FNAME ":streamtwo");
224
225         ret &= torture_smb2_find_levels(tree);
226
227         talloc_free(mem_ctx);
228
229         return ret;
230 }