62240f35baed78333fcdd882439c3bb668654183
[kai/samba.git] / source4 / torture / smb2 / read.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    SMB2 read test suite
5
6    Copyright (C) Andrew Tridgell 2008
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 3 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, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
28
29 #include "librpc/gen_ndr/ndr_security.h"
30
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)); \
35                 ret = false; \
36                 goto done; \
37         }} while (0)
38
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); \
43                 ret = false; \
44                 goto done; \
45         }} while (0)
46
47 static bool test_read_eof(struct torture_context *torture, struct smb2_tree *tree)
48 {
49         bool ret = true;
50         NTSTATUS status;
51         struct smb2_handle h;
52         uint8_t buf[70000];
53         struct smb2_read rd;
54         TALLOC_CTX *tmp_ctx = talloc_new(tree);
55
56         ZERO_STRUCT(buf);
57
58         status = torture_smb2_testfile(tree, "lock1.txt", &h);
59         CHECK_STATUS(status, NT_STATUS_OK);
60
61         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
62         CHECK_STATUS(status, NT_STATUS_OK);
63
64         ZERO_STRUCT(rd);
65         rd.in.file.handle = h;
66         rd.in.length = 10;
67         rd.in.offset = 0;
68         rd.in.min_count = 1;
69
70         status = smb2_read(tree, tmp_ctx, &rd);
71         CHECK_STATUS(status, NT_STATUS_OK);
72         CHECK_VALUE(rd.out.data.length, 10);
73
74         rd.in.min_count = 0;
75         rd.in.length = 10;
76         rd.in.offset = sizeof(buf);
77         status = smb2_read(tree, tmp_ctx, &rd);
78         CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
79
80         rd.in.min_count = 0;
81         rd.in.length = 0;
82         rd.in.offset = sizeof(buf);
83         status = smb2_read(tree, tmp_ctx, &rd);
84         CHECK_STATUS(status, NT_STATUS_OK);
85         CHECK_VALUE(rd.out.data.length, 0);
86
87         rd.in.min_count = 1;
88         rd.in.length = 0;
89         rd.in.offset = sizeof(buf);
90         status = smb2_read(tree, tmp_ctx, &rd);
91         CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
92
93         rd.in.min_count = 0;
94         rd.in.length = 2;
95         rd.in.offset = sizeof(buf) - 1;
96         status = smb2_read(tree, tmp_ctx, &rd);
97         CHECK_STATUS(status, NT_STATUS_OK);
98         CHECK_VALUE(rd.out.data.length, 1);
99
100         rd.in.min_count = 2;
101         rd.in.length = 1;
102         rd.in.offset = sizeof(buf) - 1;
103         status = smb2_read(tree, tmp_ctx, &rd);
104         CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
105
106         rd.in.min_count = 0x10000;
107         rd.in.length = 1;
108         rd.in.offset = 0;
109         status = smb2_read(tree, tmp_ctx, &rd);
110         CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
111
112         rd.in.min_count = 0x10000 - 2;
113         rd.in.length = 1;
114         rd.in.offset = 0;
115         status = smb2_read(tree, tmp_ctx, &rd);
116         CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
117
118         rd.in.min_count = 10;
119         rd.in.length = 5;
120         rd.in.offset = 0;
121         status = smb2_read(tree, tmp_ctx, &rd);
122         CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
123
124 done:
125         talloc_free(tmp_ctx);
126         return ret;
127 }
128
129
130 static bool test_read_position(struct torture_context *torture, struct smb2_tree *tree)
131 {
132         bool ret = true;
133         NTSTATUS status;
134         struct smb2_handle h;
135         uint8_t buf[70000];
136         struct smb2_read rd;
137         TALLOC_CTX *tmp_ctx = talloc_new(tree);
138         union smb_fileinfo info;
139
140         ZERO_STRUCT(buf);
141
142         status = torture_smb2_testfile(tree, "lock1.txt", &h);
143         CHECK_STATUS(status, NT_STATUS_OK);
144
145         status = smb2_util_write(tree, h, buf, 0, ARRAY_SIZE(buf));
146         CHECK_STATUS(status, NT_STATUS_OK);
147
148         ZERO_STRUCT(rd);
149         rd.in.file.handle = h;
150         rd.in.length = 10;
151         rd.in.offset = 0;
152         rd.in.min_count = 1;
153
154         status = smb2_read(tree, tmp_ctx, &rd);
155         CHECK_STATUS(status, NT_STATUS_OK);
156         CHECK_VALUE(rd.out.data.length, 10);
157
158         info.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
159         info.generic.in.file.handle = h;
160
161         status = smb2_getinfo_file(tree, tmp_ctx, &info);
162         CHECK_STATUS(status, NT_STATUS_OK);
163         if (torture_setting_bool(torture, "windows", false)) {
164                 CHECK_VALUE(info.all_info2.out.position, 0);
165         } else {
166                 CHECK_VALUE(info.all_info2.out.position, 10);
167         }
168
169         
170 done:
171         talloc_free(tmp_ctx);
172         return ret;
173 }
174
175 /* basic testing of SMB2 read
176 */
177 struct torture_suite *torture_smb2_read_init(void)
178 {
179         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "READ");
180
181         torture_suite_add_1smb2_test(suite, "EOF", test_read_eof);
182         torture_suite_add_1smb2_test(suite, "POSITION", test_read_position);
183
184         suite->description = talloc_strdup(suite, "SMB2-READ tests");
185
186         return suite;
187 }
188