0a200016c450cd41436a5d14b19024735ee2aecc
[samba.git] / source4 / torture / smb2 / scan.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    SMB2 opcode scanner
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 "lib/cmdline/popt_common.h"
27 #include "lib/events/events.h"
28 #include "torture/torture.h"
29
30 #include "torture/smb2/proto.h"
31
32 #define FNAME "scan-getinfo.dat"
33 #define DNAME "scan-getinfo.dir"
34
35
36 /* 
37    scan for valid SMB2 getinfo levels
38 */
39 BOOL torture_smb2_getinfo_scan(struct torture_context *torture)
40 {
41         TALLOC_CTX *mem_ctx = talloc_new(NULL);
42         struct smb2_tree *tree;
43         NTSTATUS status;
44         struct smb2_getinfo io;
45         struct smb2_handle fhandle, dhandle;
46         int c, i;
47
48         if (!torture_smb2_connection(mem_ctx, &tree)) {
49                 return False;
50         }
51
52         status = torture_setup_complex_file(tree, FNAME);
53         if (!NT_STATUS_IS_OK(status)) {
54                 printf("Failed to setup complex file '%s'\n", FNAME);
55                 return False;
56         }
57         torture_setup_complex_file(tree, FNAME ":2ndstream");
58
59         status = torture_setup_complex_dir(tree, DNAME);
60         if (!NT_STATUS_IS_OK(status)) {
61                 printf("Failed to setup complex dir  '%s'\n", DNAME);
62                 return False;
63         }
64         torture_setup_complex_file(tree, DNAME ":2ndstream");
65
66         torture_smb2_testfile(tree, FNAME, &fhandle);
67         torture_smb2_testdir(tree, DNAME, &dhandle);
68
69
70         ZERO_STRUCT(io);
71         io.in.max_response_size = 0xFFFF;
72
73         for (c=1;c<5;c++) {
74                 for (i=0;i<0x100;i++) {
75                         io.in.level = (i<<8) | c;
76
77                         io.in.file.handle = fhandle;
78                         status = smb2_getinfo(tree, mem_ctx, &io);
79                         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
80                             !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
81                             !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
82                                 printf("file level 0x%04x is %ld bytes - %s\n", 
83                                        io.in.level, (long)io.out.blob.length, nt_errstr(status));
84                                 dump_data(1, io.out.blob.data, io.out.blob.length);
85                         }
86
87                         io.in.file.handle = dhandle;
88                         status = smb2_getinfo(tree, mem_ctx, &io);
89                         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
90                             !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
91                             !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
92                                 printf("dir  level 0x%04x is %ld bytes - %s\n", 
93                                        io.in.level, (long)io.out.blob.length, nt_errstr(status));
94                                 dump_data(1, io.out.blob.data, io.out.blob.length);
95                         }
96                 }
97         }
98
99         talloc_free(mem_ctx);
100
101         return True;
102 }
103
104 /* 
105    scan for valid SMB2 setinfo levels
106 */
107 BOOL torture_smb2_setinfo_scan(struct torture_context *torture)
108 {
109         TALLOC_CTX *mem_ctx = talloc_new(NULL);
110         struct smb2_tree *tree;
111         NTSTATUS status;
112         struct smb2_setinfo io;
113         struct smb2_handle handle;
114         int c, i;
115
116         if (!torture_smb2_connection(mem_ctx, &tree)) {
117                 return False;
118         }
119
120         status = torture_setup_complex_file(tree, FNAME);
121         if (!NT_STATUS_IS_OK(status)) {
122                 printf("Failed to setup complex file '%s'\n", FNAME);
123                 return False;
124         }
125         torture_setup_complex_file(tree, FNAME ":2ndstream");
126
127         torture_smb2_testfile(tree, FNAME, &handle);
128
129         ZERO_STRUCT(io);
130         io.in.blob = data_blob_talloc_zero(mem_ctx, 1024);
131
132         for (c=1;c<5;c++) {
133                 for (i=0;i<0x100;i++) {
134                         io.in.level = (i<<8) | c;
135                         io.in.file.handle = handle;
136                         status = smb2_setinfo(tree, &io);
137                         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
138                             !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
139                                 printf("file level 0x%04x - %s\n", 
140                                        io.in.level, nt_errstr(status));
141                         }
142                 }
143         }
144
145         talloc_free(mem_ctx);
146
147         return True;
148 }
149
150
151 /* 
152    scan for valid SMB2 scan levels
153 */
154 BOOL torture_smb2_find_scan(struct torture_context *torture)
155 {
156         TALLOC_CTX *mem_ctx = talloc_new(NULL);
157         struct smb2_tree *tree;
158         NTSTATUS status;
159         struct smb2_find io;
160         struct smb2_handle handle;
161         int i;
162
163         if (!torture_smb2_connection(mem_ctx, &tree)) {
164                 return False;
165         }
166
167         status = smb2_util_roothandle(tree, &handle);
168         if (!NT_STATUS_IS_OK(status)) {
169                 printf("Failed to open roothandle - %s\n", nt_errstr(status));
170                 return False;
171         }
172
173         ZERO_STRUCT(io);
174         io.in.file.handle       = handle;
175         io.in.pattern           = "*";
176         io.in.continue_flags    = SMB2_CONTINUE_FLAG_RESTART;
177         io.in.max_response_size = 0x10000;
178
179         for (i=1;i<0x100;i++) {
180                 io.in.level = i;
181
182                 io.in.file.handle = handle;
183                 status = smb2_find(tree, mem_ctx, &io);
184                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) &&
185                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
186                     !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
187                         printf("find level 0x%04x is %ld bytes - %s\n", 
188                                io.in.level, (long)io.out.blob.length, nt_errstr(status));
189                         dump_data(1, io.out.blob.data, io.out.blob.length);
190                 }
191         }
192
193         talloc_free(mem_ctx);
194
195         return True;
196 }
197
198 /* 
199    scan for valid SMB2 opcodes
200 */
201 BOOL torture_smb2_scan(struct torture_context *torture)
202 {
203         TALLOC_CTX *mem_ctx = talloc_new(NULL);
204         struct smb2_tree *tree;
205         const char *host = torture_setting_string(torture, "host", NULL);
206         const char *share = torture_setting_string(torture, "share", NULL);
207         struct cli_credentials *credentials = cmdline_credentials;
208         NTSTATUS status;
209         int opcode;
210         struct smb2_request *req;
211
212         status = smb2_connect(mem_ctx, host, share, credentials, &tree, 
213                               event_context_find(mem_ctx));
214         if (!NT_STATUS_IS_OK(status)) {
215                 printf("Connection failed - %s\n", nt_errstr(status));
216                 return False;
217         }
218
219         tree->session->transport->options.timeout = 3;
220
221         for (opcode=0;opcode<1000;opcode++) {
222                 req = smb2_request_init_tree(tree, opcode, 2, False, 0);
223                 SSVAL(req->out.body, 0, 0);
224                 smb2_transport_send(req);
225                 if (!smb2_request_receive(req)) {
226                         talloc_free(tree);
227                         status = smb2_connect(mem_ctx, host, share, credentials, &tree, 
228                                               event_context_find(mem_ctx));
229                         if (!NT_STATUS_IS_OK(status)) {
230                                 printf("Connection failed - %s\n", nt_errstr(status));
231                                 return False;
232                         }
233                         tree->session->transport->options.timeout = 3;
234                 } else {
235                         status = smb2_request_destroy(req);
236                         printf("active opcode %4d gave status %s\n", opcode, nt_errstr(status));
237                 }
238         }
239
240         talloc_free(mem_ctx);
241
242         return True;
243 }