2
Unix SMB/CIFS implementation.
6
Copyright (C) Andrew Tridgell 2008
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"
26
#include "torture/torture.h"
27
#include "torture/smb2/proto.h"
29
#include "librpc/gen_ndr/ndr_security.h"
31
#define CHECK_STATUS(status, correct) do { \
32
if (!NT_STATUS_EQUAL(status, correct)) { \
33
printf("(%s) Incorrect status %s - should be %s\n", \
34
__location__, nt_errstr(status), nt_errstr(correct)); \
39
#define CHECK_VALUE(v, correct) do { \
40
if ((v) != (correct)) { \
41
printf("(%s) Incorrect value %s=%u - should be %u\n", \
42
__location__, #v, (unsigned)v, (unsigned)correct); \
47
#define FNAME "smb2_readtest.dat"
48
#define DNAME "smb2_readtest.dir"
50
static bool test_read_eof(struct torture_context *torture, struct smb2_tree *tree)
57
TALLOC_CTX *tmp_ctx = talloc_new(tree);
61
status = torture_smb2_testfile(tree, FNAME, &h);
62
CHECK_STATUS(status, NT_STATUS_OK);
64
status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
65
CHECK_STATUS(status, NT_STATUS_OK);
68
rd.in.file.handle = h;
73
status = smb2_read(tree, tmp_ctx, &rd);
74
CHECK_STATUS(status, NT_STATUS_OK);
75
CHECK_VALUE(rd.out.data.length, 10);
79
rd.in.offset = sizeof(buf);
80
status = smb2_read(tree, tmp_ctx, &rd);
81
CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
85
rd.in.offset = sizeof(buf);
86
status = smb2_read(tree, tmp_ctx, &rd);
87
CHECK_STATUS(status, NT_STATUS_OK);
88
CHECK_VALUE(rd.out.data.length, 0);
92
rd.in.offset = sizeof(buf);
93
status = smb2_read(tree, tmp_ctx, &rd);
94
CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
98
rd.in.offset = sizeof(buf) - 1;
99
status = smb2_read(tree, tmp_ctx, &rd);
100
CHECK_STATUS(status, NT_STATUS_OK);
101
CHECK_VALUE(rd.out.data.length, 1);
105
rd.in.offset = sizeof(buf) - 1;
106
status = smb2_read(tree, tmp_ctx, &rd);
107
CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
109
rd.in.min_count = 0x10000;
112
status = smb2_read(tree, tmp_ctx, &rd);
113
CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
115
rd.in.min_count = 0x10000 - 2;
118
status = smb2_read(tree, tmp_ctx, &rd);
119
CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
121
rd.in.min_count = 10;
124
status = smb2_read(tree, tmp_ctx, &rd);
125
CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
128
talloc_free(tmp_ctx);
133
static bool test_read_position(struct torture_context *torture, struct smb2_tree *tree)
137
struct smb2_handle h;
140
TALLOC_CTX *tmp_ctx = talloc_new(tree);
141
union smb_fileinfo info;
145
status = torture_smb2_testfile(tree, FNAME, &h);
146
CHECK_STATUS(status, NT_STATUS_OK);
148
status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
149
CHECK_STATUS(status, NT_STATUS_OK);
152
rd.in.file.handle = h;
157
status = smb2_read(tree, tmp_ctx, &rd);
158
CHECK_STATUS(status, NT_STATUS_OK);
159
CHECK_VALUE(rd.out.data.length, 10);
161
info.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
162
info.generic.in.file.handle = h;
164
status = smb2_getinfo_file(tree, tmp_ctx, &info);
165
CHECK_STATUS(status, NT_STATUS_OK);
166
if (torture_setting_bool(torture, "windows", false)) {
167
CHECK_VALUE(info.all_info2.out.position, 0);
169
CHECK_VALUE(info.all_info2.out.position, 10);
174
talloc_free(tmp_ctx);
178
static bool test_read_dir(struct torture_context *torture, struct smb2_tree *tree)
182
struct smb2_handle h;
184
TALLOC_CTX *tmp_ctx = talloc_new(tree);
186
status = torture_smb2_testdir(tree, DNAME, &h);
187
if (!NT_STATUS_IS_OK(status)) {
188
printf(__location__ " Unable to create test directory '%s' - %s\n", DNAME, nt_errstr(status));
193
rd.in.file.handle = h;
198
status = smb2_read(tree, tmp_ctx, &rd);
199
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
201
rd.in.min_count = 11;
202
status = smb2_read(tree, tmp_ctx, &rd);
203
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
206
rd.in.min_count = 2592;
207
status = smb2_read(tree, tmp_ctx, &rd);
208
if (torture_setting_bool(torture, "windows", false)) {
209
CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
211
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
217
status = smb2_read(tree, tmp_ctx, &rd);
218
if (torture_setting_bool(torture, "windows", false)) {
219
CHECK_STATUS(status, NT_STATUS_OK);
221
CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
225
talloc_free(tmp_ctx);
231
basic testing of SMB2 read
233
struct torture_suite *torture_smb2_read_init(void)
235
struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "READ");
237
torture_suite_add_1smb2_test(suite, "EOF", test_read_eof);
238
torture_suite_add_1smb2_test(suite, "POSITION", test_read_position);
239
torture_suite_add_1smb2_test(suite, "DIR", test_read_dir);
241
suite->description = talloc_strdup(suite, "SMB2-READ tests");