r11699: use create_complex_file() to setup a file with a wide range of
[kamenim/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/raw/libcliraw.h"
25 #include "libcli/smb2/smb2.h"
26 #include "libcli/smb2/smb2_calls.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "lib/events/events.h"
29
30
31 /*
32   create a complex file using the old SMB protocol, to make it easier to 
33   find fields in SMB2 getinfo levels
34 */
35 static BOOL setup_complex_file(const char *fname)
36 {
37         struct smbcli_state *cli;
38         int fnum;
39
40         if (!torture_open_connection(&cli)) {
41                 return False;
42         }
43
44         fnum = create_complex_file(cli, cli, fname);
45
46         if (DEBUGLVL(1)) {
47                 torture_all_info(cli->tree, fname);
48         }
49         
50         talloc_free(cli);
51         return fnum != -1;
52 }
53
54
55
56 /* 
57    scan for valid SMB2 getinfo levels
58 */
59 BOOL torture_smb2_getinfo_scan(void)
60 {
61         TALLOC_CTX *mem_ctx = talloc_new(NULL);
62         struct smb2_tree *tree;
63         const char *host = lp_parm_string(-1, "torture", "host");
64         const char *share = lp_parm_string(-1, "torture", "share");
65         struct cli_credentials *credentials = cmdline_credentials;
66         NTSTATUS status;
67         struct smb2_getinfo io;
68         struct smb2_create cr;
69         struct smb2_handle handle;
70         int c, i;
71         const char *fname = "scan-getinfo.dat";
72
73         status = smb2_connect(mem_ctx, host, share, credentials, &tree, 
74                               event_context_find(mem_ctx));
75         if (!NT_STATUS_IS_OK(status)) {
76                 printf("Connection failed - %s\n", nt_errstr(status));
77                 return False;
78         }
79
80         if (!setup_complex_file(fname)) {
81                 printf("Failed to setup complex file '%s'\n", fname);
82         }
83
84         ZERO_STRUCT(cr);
85         cr.in.buffer_code = 0x39;
86         cr.in.oplock_flags = 0;
87         cr.in.access_mask = SEC_RIGHTS_FILE_ALL;
88         cr.in.file_attr   = FILE_ATTRIBUTE_NORMAL;
89         cr.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
90         cr.in.share_access = 
91                 NTCREATEX_SHARE_ACCESS_DELETE|
92                 NTCREATEX_SHARE_ACCESS_READ|
93                 NTCREATEX_SHARE_ACCESS_WRITE;
94         cr.in.create_options = NTCREATEX_OPTIONS_WRITE_THROUGH;
95         cr.in.fname = fname;
96
97         status = smb2_create(tree, &cr);
98         if (!NT_STATUS_IS_OK(status)) {
99                 printf("create of '%s' failed - %s\n", fname, nt_errstr(status));
100                 return False;
101         }
102
103         handle = cr.out.handle;
104
105
106         ZERO_STRUCT(io);
107         io.in.buffer_code       = 0x29;
108         io.in.max_response_size = 0xFFFF;
109         io.in.handle            = handle;
110
111         for (c=0;c<5;c++) {
112                 for (i=0;i<0x100;i++) {
113                         io.in.level = (i<<8) | c;
114                         status = smb2_getinfo(tree, mem_ctx, &io);
115                         if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) ||
116                             NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) ||
117                             NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
118                                 continue;
119                         }
120                         if (NT_STATUS_IS_OK(status)) {
121                                 printf("level 0x%04x is %d bytes\n", 
122                                        io.in.level, io.out.blob.length);
123                                 dump_data(1, io.out.blob.data, io.out.blob.length);
124                         }
125                 }
126         }
127
128         talloc_free(mem_ctx);
129
130         return True;
131 }
132
133 /* 
134    scan for valid SMB2 opcodes
135 */
136 BOOL torture_smb2_scan(void)
137 {
138         TALLOC_CTX *mem_ctx = talloc_new(NULL);
139         struct smb2_tree *tree;
140         const char *host = lp_parm_string(-1, "torture", "host");
141         const char *share = lp_parm_string(-1, "torture", "share");
142         struct cli_credentials *credentials = cmdline_credentials;
143         NTSTATUS status;
144         int opcode;
145         struct smb2_request *req;
146
147         status = smb2_connect(mem_ctx, host, share, credentials, &tree, 
148                               event_context_find(mem_ctx));
149         if (!NT_STATUS_IS_OK(status)) {
150                 printf("Connection failed - %s\n", nt_errstr(status));
151                 return False;
152         }
153
154         tree->session->transport->options.timeout = 3;
155
156         for (opcode=0;opcode<1000;opcode++) {
157                 req = smb2_request_init_tree(tree, opcode, 2);
158                 SSVAL(req->out.body, 0, 0);
159                 smb2_transport_send(req);
160                 if (!smb2_request_receive(req)) {
161                         talloc_free(tree);
162                         status = smb2_connect(mem_ctx, host, share, credentials, &tree, 
163                                               event_context_find(mem_ctx));
164                         if (!NT_STATUS_IS_OK(status)) {
165                                 printf("Connection failed - %s\n", nt_errstr(status));
166                                 return False;
167                         }
168                         tree->session->transport->options.timeout = 3;
169                 } else {
170                         status = smb2_request_destroy(req);
171                         printf("active opcode %4d gave status %s\n", opcode, nt_errstr(status));
172                 }
173         }
174
175         talloc_free(mem_ctx);
176
177         return True;
178 }