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