r14256: - rename smb_file -> smb_handle
[bbaumbach/samba-autobuild/.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/smb2/proto.h"
28
29 static struct {
30         const char *name;
31         uint16_t level;
32         NTSTATUS status;
33         union smb_search_data data;
34 } levels[] = {
35 #define LEVEL(x) #x, x
36  { LEVEL(SMB2_FIND_ID_BOTH_DIRECTORY_INFO) },
37  { LEVEL(SMB2_FIND_DIRECTORY_INFO) },
38  { LEVEL(SMB2_FIND_FULL_DIRECTORY_INFO) },
39  { LEVEL(SMB2_FIND_NAME_INFO) },
40  { LEVEL(SMB2_FIND_BOTH_DIRECTORY_INFO) },
41  { LEVEL(SMB2_FIND_ID_FULL_DIRECTORY_INFO) },
42 };
43
44 #define FNAME "smb2-find.dat"
45
46 #define CHECK_VALUE(call_name, stype, field) do { \
47         union smb_search_data *d = find_level("SMB2_FIND_" #call_name); \
48         if (io.all_info2.out.field != d->stype.field) { \
49                 printf("(%s) %s/%s should be 0x%llx - 0x%llx\n", __location__, \
50                        #call_name, #field, \
51                        (long long)io.all_info2.out.field, (long long)d->stype.field); \
52                 ret = False; \
53         }} while (0)
54
55 #define CHECK_STRING(call_name, stype, field1, field2) do { \
56         union smb_search_data *d = find_level("SMB2_FIND_" #call_name); \
57         if (strcmp(io.all_info2.out.field2.s, d->stype.field1.s) != 0) { \
58                 printf("(%s) %s/%s should be '%s' - '%s'\n", __location__, \
59                        #call_name, #field2, \
60                        io.all_info2.out.field2.s, d->stype.field1.s); \
61                 ret = False; \
62         }} while (0)
63
64 #define CHECK_CONST_STRING(call_name, stype, field, str) do { \
65         union smb_search_data *d = find_level("SMB2_FIND_" #call_name); \
66         if (strcmp(str, d->stype.field.s) != 0) { \
67                 printf("(%s) %s/%s should be '%s' - '%s'\n", __location__, \
68                        #call_name, #field, \
69                        str, d->stype.field.s); \
70                 ret = False; \
71         }} while (0)
72
73 static union smb_search_data *find_level(const char *name)
74 {
75         int i;
76         for (i=0;i<ARRAY_SIZE(levels);i++) {
77                 if (strcmp(name, levels[i].name) == 0) {
78                         return &levels[i].data;
79                 }
80         }
81         return NULL;
82 }
83
84 /*
85   test find levels
86 */
87 static BOOL torture_smb2_find_levels(struct smb2_tree *tree)
88 {
89         struct smb2_handle handle;
90         NTSTATUS status;
91         int i;
92         struct smb2_find f;
93         BOOL ret = True;
94         union smb_fileinfo io;
95         const char *alt_name;
96
97         status = smb2_create_complex_file(tree, FNAME, &handle);
98         if (!NT_STATUS_IS_OK(status)) {
99                 return False;
100         }
101
102         io.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
103         io.generic.in.file.handle = handle;
104         status = smb2_getinfo_file(tree, tree, &io);
105         if (!NT_STATUS_IS_OK(status)) {
106                 return False;
107         }
108         alt_name = talloc_strdup(tree, io.alt_name_info.out.fname.s);   
109
110         io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
111         io.generic.in.file.handle = handle;
112         status = smb2_getinfo_file(tree, tree, &io);
113         if (!NT_STATUS_IS_OK(status)) {
114                 return False;
115         }
116
117         status = smb2_util_roothandle(tree, &handle);
118         if (!NT_STATUS_IS_OK(status)) {
119                 return False;
120         }
121
122         ZERO_STRUCT(f);
123         f.in.handle = handle;
124         f.in.pattern = FNAME;
125         f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
126         f.in.max_response_size = 0x10000;
127
128         for (i=0;i<ARRAY_SIZE(levels);i++) {
129                 union smb_search_data *d;
130                 uint_t count;
131
132                 f.in.level = levels[i].level - 0x100;
133
134                 levels[i].status = smb2_find_level(tree, tree, &f, &count, &d);
135                 if (!NT_STATUS_IS_OK(levels[i].status)) {
136                         printf("%s failed - %s\n", levels[i].name, 
137                                nt_errstr(levels[i].status));
138                 }
139
140                 if (count != 1) {
141                         printf("Expected count 1 - got %d in %s\n", count, levels[i].name);
142                         ret = False;
143                 }
144
145                 levels[i].data = d[0];
146         }
147
148         CHECK_VALUE(DIRECTORY_INFO, directory_info, create_time);
149         CHECK_VALUE(DIRECTORY_INFO, directory_info, access_time);
150         CHECK_VALUE(DIRECTORY_INFO, directory_info, write_time);
151         CHECK_VALUE(DIRECTORY_INFO, directory_info, change_time);
152         CHECK_VALUE(DIRECTORY_INFO, directory_info, size);
153         CHECK_VALUE(DIRECTORY_INFO, directory_info, alloc_size);
154         CHECK_VALUE(DIRECTORY_INFO, directory_info, attrib);
155         CHECK_CONST_STRING(DIRECTORY_INFO, directory_info, name, FNAME);
156
157         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, create_time);
158         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, access_time);
159         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, write_time);
160         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, change_time);
161         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, size);
162         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, alloc_size);
163         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, attrib);
164         CHECK_VALUE(FULL_DIRECTORY_INFO, full_directory_info, ea_size);
165         CHECK_CONST_STRING(FULL_DIRECTORY_INFO, full_directory_info, name, FNAME);
166
167         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, create_time);
168         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, access_time);
169         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, write_time);
170         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, change_time);
171         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, size);
172         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, alloc_size);
173         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, attrib);
174         CHECK_VALUE(BOTH_DIRECTORY_INFO, both_directory_info, ea_size);
175         CHECK_CONST_STRING(BOTH_DIRECTORY_INFO, both_directory_info, short_name, alt_name);
176         CHECK_CONST_STRING(BOTH_DIRECTORY_INFO, both_directory_info, name, FNAME);
177
178         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, create_time);
179         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, access_time);
180         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, write_time);
181         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, change_time);
182         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, size);
183         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, alloc_size);
184         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, attrib);
185         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, ea_size);
186         CHECK_VALUE(ID_FULL_DIRECTORY_INFO, id_full_directory_info, file_id);
187         CHECK_CONST_STRING(ID_FULL_DIRECTORY_INFO, id_full_directory_info, name, FNAME);
188
189         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, create_time);
190         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, access_time);
191         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, write_time);
192         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, change_time);
193         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, size);
194         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, alloc_size);
195         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, attrib);
196         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, ea_size);
197         CHECK_VALUE(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, file_id);
198         CHECK_CONST_STRING(ID_BOTH_DIRECTORY_INFO, id_both_directory_info, name, FNAME);
199
200
201         return ret;
202 }
203
204
205 /* basic testing of all SMB2 find levels
206 */
207 BOOL torture_smb2_find(void)
208 {
209         TALLOC_CTX *mem_ctx = talloc_new(NULL);
210         struct smb2_tree *tree;
211         BOOL ret = True;
212         NTSTATUS status;
213
214         if (!torture_smb2_connection(mem_ctx, &tree)) {
215                 return False;
216         }
217
218         status = torture_setup_complex_file(tree, FNAME);
219         if (!NT_STATUS_IS_OK(status)) {
220                 return False;
221         }
222         torture_setup_complex_file(tree, FNAME ":streamtwo");
223
224         ret &= torture_smb2_find_levels(tree);
225
226         talloc_free(mem_ctx);
227
228         return ret;
229 }