2 Unix SMB/CIFS implementation.
4 test suite for SMB2 connection operations
6 Copyright (C) Andrew Tridgell 2005
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 3 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25 #include "torture/torture.h"
26 #include "torture/smb2/proto.h"
31 static NTSTATUS
torture_smb2_close(struct torture_context
*tctx
,
32 struct smb2_tree
*tree
,
33 struct smb2_handle handle
)
37 TALLOC_CTX
*tmp_ctx
= talloc_new(tree
);
40 io
.in
.file
.handle
= handle
;
41 io
.in
.flags
= SMB2_CLOSE_FLAGS_FULL_INFORMATION
;
42 status
= smb2_close(tree
, &io
);
43 if (!NT_STATUS_IS_OK(status
)) {
44 torture_comment(tctx
, "close failed - %s\n", nt_errstr(status
));
49 torture_comment(tctx
, "Close gave:\n");
50 torture_comment(tctx
, "create_time = %s\n", nt_time_string(tmp_ctx
, io
.out
.create_time
));
51 torture_comment(tctx
, "access_time = %s\n", nt_time_string(tmp_ctx
, io
.out
.access_time
));
52 torture_comment(tctx
, "write_time = %s\n", nt_time_string(tmp_ctx
, io
.out
.write_time
));
53 torture_comment(tctx
, "change_time = %s\n", nt_time_string(tmp_ctx
, io
.out
.change_time
));
54 torture_comment(tctx
, "alloc_size = %lld\n", (long long)io
.out
.alloc_size
);
55 torture_comment(tctx
, "size = %lld\n", (long long)io
.out
.size
);
56 torture_comment(tctx
, "file_attr = 0x%x\n", io
.out
.file_attr
);
68 static NTSTATUS
torture_smb2_write(struct torture_context
*tctx
, struct smb2_tree
*tree
, struct smb2_handle handle
)
76 uint32_t size
= torture_setting_int(tctx
, "smb2maxwrite", 64*1024);
78 data
= data_blob_talloc(tree
, NULL
, size
);
79 if (size
!= data
.length
) {
80 torture_comment(tctx
, "data_blob_talloc(%u) failed\n", (unsigned int)size
);
81 return NT_STATUS_NO_MEMORY
;
84 for (i
=0;i
<data
.length
;i
++) {
89 w
.in
.file
.handle
= handle
;
93 status
= smb2_write(tree
, &w
);
94 if (!NT_STATUS_IS_OK(status
)) {
95 torture_comment(tctx
, "write 1 failed - %s\n", nt_errstr(status
));
99 torture_smb2_all_info(tctx
, tree
, handle
);
101 status
= smb2_write(tree
, &w
);
102 if (!NT_STATUS_IS_OK(status
)) {
103 torture_comment(tctx
, "write 2 failed - %s\n", nt_errstr(status
));
107 torture_smb2_all_info(tctx
, tree
, handle
);
110 f
.in
.file
.handle
= handle
;
112 status
= smb2_flush(tree
, &f
);
113 if (!NT_STATUS_IS_OK(status
)) {
114 torture_comment(tctx
, "flush failed - %s\n", nt_errstr(status
));
119 r
.in
.file
.handle
= handle
;
120 r
.in
.length
= data
.length
;
123 status
= smb2_read(tree
, tree
, &r
);
124 if (!NT_STATUS_IS_OK(status
)) {
125 torture_comment(tctx
, "read failed - %s\n", nt_errstr(status
));
129 if (data
.length
!= r
.out
.data
.length
||
130 memcmp(data
.data
, r
.out
.data
.data
, data
.length
) != 0) {
131 torture_comment(tctx
, "read data mismatch\n");
132 return NT_STATUS_NET_WRITE_FAULT
;
142 NTSTATUS
torture_smb2_createfile(struct torture_context
*tctx
,
143 struct smb2_tree
*tree
,
145 struct smb2_handle
*handle
)
147 struct smb2_create io
;
149 TALLOC_CTX
*tmp_ctx
= talloc_new(tree
);
152 io
.in
.oplock_level
= 0;
153 io
.in
.desired_access
= SEC_RIGHTS_FILE_ALL
;
154 io
.in
.file_attributes
= FILE_ATTRIBUTE_NORMAL
;
155 io
.in
.create_disposition
= NTCREATEX_DISP_OPEN_IF
;
157 NTCREATEX_SHARE_ACCESS_DELETE
|
158 NTCREATEX_SHARE_ACCESS_READ
|
159 NTCREATEX_SHARE_ACCESS_WRITE
;
160 io
.in
.create_options
= NTCREATEX_OPTIONS_WRITE_THROUGH
;
163 status
= smb2_create(tree
, tmp_ctx
, &io
);
164 if (!NT_STATUS_IS_OK(status
)) {
165 TALLOC_FREE(tmp_ctx
);
166 torture_comment(tctx
, "create1 failed - %s\n", nt_errstr(status
));
171 torture_comment(tctx
, "Open gave:\n");
172 torture_comment(tctx
, "oplock_flags = 0x%x\n", io
.out
.oplock_level
);
173 torture_comment(tctx
, "create_action = 0x%x\n", io
.out
.create_action
);
174 torture_comment(tctx
, "create_time = %s\n", nt_time_string(tmp_ctx
, io
.out
.create_time
));
175 torture_comment(tctx
, "access_time = %s\n", nt_time_string(tmp_ctx
, io
.out
.access_time
));
176 torture_comment(tctx
, "write_time = %s\n", nt_time_string(tmp_ctx
, io
.out
.write_time
));
177 torture_comment(tctx
, "change_time = %s\n", nt_time_string(tmp_ctx
, io
.out
.change_time
));
178 torture_comment(tctx
, "alloc_size = %lld\n", (long long)io
.out
.alloc_size
);
179 torture_comment(tctx
, "size = %lld\n", (long long)io
.out
.size
);
180 torture_comment(tctx
, "file_attr = 0x%x\n", io
.out
.file_attr
);
181 torture_comment(tctx
, "handle = %016llx%016llx\n",
182 (long long)io
.out
.file
.handle
.data
[0],
183 (long long)io
.out
.file
.handle
.data
[1]);
186 talloc_free(tmp_ctx
);
188 *handle
= io
.out
.file
.handle
;
195 basic testing of SMB2 connection calls
197 bool torture_smb2_connect(struct torture_context
*tctx
)
199 TALLOC_CTX
*mem_ctx
= talloc_new(tctx
);
200 struct smb2_tree
*tree
;
201 struct smb2_request
*req
;
202 struct smb2_handle h1
, h2
;
206 ok
= torture_smb2_connection(tctx
, &tree
);
207 torture_assert(tctx
, ok
, "torture_smb2_connection failed");
209 smb2_util_unlink(tree
, "test9.dat");
211 status
= torture_smb2_createfile(tctx
, tree
, "test9.dat", &h1
);
212 torture_assert_ntstatus_ok(tctx
, status
, "create failed");
214 status
= torture_smb2_createfile(tctx
, tree
, "test9.dat", &h2
);
215 torture_assert_ntstatus_ok(tctx
, status
, "create failed");
217 status
= torture_smb2_write(tctx
, tree
, h1
);
218 torture_assert_ntstatus_ok(tctx
, status
, "write failed");
220 status
= torture_smb2_close(tctx
, tree
, h1
);
221 torture_assert_ntstatus_ok(tctx
, status
, "close failed");
223 status
= torture_smb2_close(tctx
, tree
, h2
);
224 torture_assert_ntstatus_ok(tctx
, status
, "close failed");
226 status
= smb2_util_close(tree
, h1
);
227 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_FILE_CLOSED
,
228 "close should have closed the handle");
230 status
= smb2_tdis(tree
);
231 torture_assert_ntstatus_ok(tctx
, status
, "tdis failed");
233 status
= smb2_tdis(tree
);
234 torture_assert_ntstatus_equal(tctx
, status
,
235 NT_STATUS_NETWORK_NAME_DELETED
,
236 "tdis should have closed the tcon");
238 status
= smb2_logoff(tree
->session
);
239 torture_assert_ntstatus_ok(tctx
, status
, "logoff failed");
241 req
= smb2_logoff_send(tree
->session
);
242 torture_assert_not_null(tctx
, req
, "smb2_logoff_send failed");
246 status
= smb2_logoff_recv(req
);
248 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_USER_SESSION_DELETED
,
249 "logoff should have disabled session");
251 status
= smb2_keepalive(tree
->session
->transport
);
252 torture_assert_ntstatus_ok(tctx
, status
, "keepalive failed");
254 talloc_free(mem_ctx
);