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"
25 #include "torture/torture.h"
26 #include "torture/smb2/proto.h"
27 #include "param/param.h"
28 #include "librpc/gen_ndr/ndr_security.h"
30 #define FNAME "test_create.dat"
32 #define CHECK_STATUS(status, correct) do { \
33 if (!NT_STATUS_EQUAL(status, correct)) { \
34 printf("(%s) Incorrect status %s - should be %s\n", \
35 __location__, nt_errstr(status), nt_errstr(correct)); \
39 #define CHECK_EQUAL(v, correct) do { \
41 printf("(%s) Incorrect value for %s 0x%08llx - should be 0x%08llx\n", \
42 __location__, #v, (unsigned long long)v, (unsigned long long)correct); \
47 test some interesting combinations found by gentest
49 bool torture_smb2_create_gentest(struct torture_context *torture, struct smb2_tree *tree)
51 struct smb2_create io;
53 TALLOC_CTX *tmp_ctx = talloc_new(tree);
54 uint32_t access_mask, file_attributes, denied_mask;
57 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
58 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
59 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
61 NTCREATEX_SHARE_ACCESS_DELETE|
62 NTCREATEX_SHARE_ACCESS_READ|
63 NTCREATEX_SHARE_ACCESS_WRITE;
64 io.in.create_options = 0;
67 status = smb2_create(tree, tmp_ctx, &io);
68 CHECK_STATUS(status, NT_STATUS_OK);
70 status = smb2_util_close(tree, io.out.file.handle);
71 CHECK_STATUS(status, NT_STATUS_OK);
73 io.in.create_options = 0xF0000000;
74 status = smb2_create(tree, tmp_ctx, &io);
75 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
77 io.in.create_options = 0x00100000;
78 status = smb2_create(tree, tmp_ctx, &io);
79 CHECK_STATUS(status, NT_STATUS_NOT_SUPPORTED);
81 io.in.create_options = 0xF0100000;
82 status = smb2_create(tree, tmp_ctx, &io);
83 CHECK_STATUS(status, NT_STATUS_NOT_SUPPORTED);
85 io.in.create_options = 0;
87 io.in.file_attributes = FILE_ATTRIBUTE_DEVICE;
88 status = smb2_create(tree, tmp_ctx, &io);
89 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
91 io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
92 status = smb2_create(tree, tmp_ctx, &io);
93 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
95 io.in.create_disposition = NTCREATEX_DISP_OPEN;
96 io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
97 status = smb2_create(tree, tmp_ctx, &io);
98 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
100 io.in.create_disposition = NTCREATEX_DISP_CREATE;
101 io.in.desired_access = 0x08000000;
102 status = smb2_create(tree, tmp_ctx, &io);
103 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
105 io.in.desired_access = 0x04000000;
106 status = smb2_create(tree, tmp_ctx, &io);
107 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
109 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
110 io.in.file_attributes = 0;
115 io.in.desired_access = 1<<i;
116 status = smb2_create(tree, tmp_ctx, &io);
117 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
118 access_mask |= io.in.desired_access;
120 CHECK_STATUS(status, NT_STATUS_OK);
121 status = smb2_util_close(tree, io.out.file.handle);
122 CHECK_STATUS(status, NT_STATUS_OK);
127 CHECK_EQUAL(access_mask, 0x0df0fe00);
129 io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
130 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
131 io.in.file_attributes = 0;
137 io.in.file_attributes = 1<<i;
138 smb2_deltree(tree, FNAME);
139 status = smb2_create(tree, tmp_ctx, &io);
140 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
141 file_attributes |= io.in.file_attributes;
142 } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
143 denied_mask |= io.in.file_attributes;
145 CHECK_STATUS(status, NT_STATUS_OK);
146 status = smb2_util_close(tree, io.out.file.handle);
147 CHECK_STATUS(status, NT_STATUS_OK);
152 CHECK_EQUAL(file_attributes, 0xffff8048);
153 CHECK_EQUAL(denied_mask, 0x4000);
155 smb2_deltree(tree, FNAME);
158 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
159 io.in.file_attributes = 0;
160 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
162 NTCREATEX_SHARE_ACCESS_READ|
163 NTCREATEX_SHARE_ACCESS_WRITE;
164 io.in.create_options = 0;
165 io.in.fname = FNAME ":stream1";
166 status = smb2_create(tree, tmp_ctx, &io);
167 CHECK_STATUS(status, NT_STATUS_OK);
169 status = smb2_util_close(tree, io.out.file.handle);
170 CHECK_STATUS(status, NT_STATUS_OK);
173 io.in.file_attributes = 0x8040;
175 NTCREATEX_SHARE_ACCESS_READ;
176 status = smb2_create(tree, tmp_ctx, &io);
177 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
179 talloc_free(tmp_ctx);
181 smb2_deltree(tree, FNAME);
188 try the various request blobs
190 bool torture_smb2_create_blob(struct torture_context *torture, struct smb2_tree *tree)
192 struct smb2_create io;
194 TALLOC_CTX *tmp_ctx = talloc_new(tree);
196 smb2_deltree(tree, FNAME);
199 io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
200 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
201 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
203 NTCREATEX_SHARE_ACCESS_DELETE|
204 NTCREATEX_SHARE_ACCESS_READ|
205 NTCREATEX_SHARE_ACCESS_WRITE;
206 io.in.create_options = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
207 NTCREATEX_OPTIONS_ASYNC_ALERT |
208 NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
210 io.in.security_flags = 0x00;
211 io.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
212 io.in.create_flags = 0x00000000;
213 io.in.reserved = 0x00000000;
214 io.in.desired_access = SEC_RIGHTS_FILE_ALL;
215 io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
216 io.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
217 NTCREATEX_SHARE_ACCESS_WRITE |
218 NTCREATEX_SHARE_ACCESS_DELETE;
219 io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
220 io.in.create_options = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
221 NTCREATEX_OPTIONS_ASYNC_ALERT |
222 NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
226 status = smb2_create(tree, tmp_ctx, &io);
227 CHECK_STATUS(status, NT_STATUS_OK);
229 status = smb2_util_close(tree, io.out.file.handle);
230 CHECK_STATUS(status, NT_STATUS_OK);
232 printf("testing alloc size\n");
233 io.in.alloc_size = 4096;
234 status = smb2_create(tree, tmp_ctx, &io);
235 CHECK_STATUS(status, NT_STATUS_OK);
236 CHECK_EQUAL(io.out.alloc_size, io.in.alloc_size);
238 status = smb2_util_close(tree, io.out.file.handle);
239 CHECK_STATUS(status, NT_STATUS_OK);
241 printf("testing durable open\n");
242 io.in.durable_open = true;
243 status = smb2_create(tree, tmp_ctx, &io);
244 CHECK_STATUS(status, NT_STATUS_OK);
246 status = smb2_util_close(tree, io.out.file.handle);
247 CHECK_STATUS(status, NT_STATUS_OK);
249 printf("testing query maximal access\n");
250 io.in.query_maximal_access = true;
251 status = smb2_create(tree, tmp_ctx, &io);
252 CHECK_STATUS(status, NT_STATUS_OK);
254 status = smb2_util_close(tree, io.out.file.handle);
255 CHECK_STATUS(status, NT_STATUS_OK);
257 printf("testing timewarp\n");
258 io.in.timewarp = 10000;
259 status = smb2_create(tree, tmp_ctx, &io);
260 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
263 printf("testing query_on_disk\n");
264 io.in.query_on_disk_id = true;
265 status = smb2_create(tree, tmp_ctx, &io);
266 CHECK_STATUS(status, NT_STATUS_OK);
268 status = smb2_util_close(tree, io.out.file.handle);
269 CHECK_STATUS(status, NT_STATUS_OK);
271 printf("testing unknown tag\n");
272 status = smb2_create_blob_add(tmp_ctx, &io.in.blobs,
273 "FooO", data_blob(NULL, 0));
274 CHECK_STATUS(status, NT_STATUS_OK);
276 status = smb2_create(tree, tmp_ctx, &io);
277 CHECK_STATUS(status, NT_STATUS_OK);
279 status = smb2_util_close(tree, io.out.file.handle);
280 CHECK_STATUS(status, NT_STATUS_OK);
282 printf("testing bad tag length\n");
283 status = smb2_create_blob_add(tmp_ctx, &io.in.blobs,
284 "xxx", data_blob(NULL, 0));
285 CHECK_STATUS(status, NT_STATUS_OK);
287 status = smb2_create(tree, tmp_ctx, &io);
288 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
290 talloc_free(tmp_ctx);
292 smb2_deltree(tree, FNAME);
298 basic testing of SMB2 create calls
300 bool torture_smb2_create(struct torture_context *torture)
302 TALLOC_CTX *mem_ctx = talloc_new(NULL);
303 struct smb2_tree *tree;
306 if (!torture_smb2_connection(torture, &tree)) {
310 ret &= torture_smb2_create_gentest(torture, tree);
311 ret &= torture_smb2_create_blob(torture, tree);
313 smb2_deltree(tree, FNAME);
315 talloc_free(mem_ctx);