Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : RAW_OPEN_* individual test suite
4 : Copyright (C) Andrew Tridgell 2003
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "libcli/raw/libcliraw.h"
22 : #include "system/time.h"
23 : #include "system/filesys.h"
24 : #include "lib/events/events.h"
25 : #include "libcli/libcli.h"
26 : #include "torture/util.h"
27 : #include "torture/raw/proto.h"
28 :
29 : /* enum for whether reads/writes are possible on a file */
30 : enum rdwr_mode {RDWR_NONE, RDWR_RDONLY, RDWR_WRONLY, RDWR_RDWR};
31 :
32 : #define BASEDIR "\\rawopen"
33 :
34 : /*
35 : check if a open file can be read/written
36 : */
37 48 : static enum rdwr_mode check_rdwr(struct smbcli_tree *tree, int fnum)
38 : {
39 48 : uint8_t c = 1;
40 48 : bool can_read = (smbcli_read(tree, fnum, &c, 0, 1) == 1);
41 48 : bool can_write = (smbcli_write(tree, fnum, 0, &c, 0, 1) == 1);
42 48 : if ( can_read && can_write) return RDWR_RDWR;
43 24 : if ( can_read && !can_write) return RDWR_RDONLY;
44 6 : if (!can_read && can_write) return RDWR_WRONLY;
45 0 : return RDWR_NONE;
46 : }
47 :
48 : /*
49 : describe a RDWR mode as a string
50 : */
51 0 : static const char *rdwr_string(enum rdwr_mode m)
52 : {
53 0 : switch (m) {
54 0 : case RDWR_NONE: return "NONE";
55 0 : case RDWR_RDONLY: return "RDONLY";
56 0 : case RDWR_WRONLY: return "WRONLY";
57 0 : case RDWR_RDWR: return "RDWR";
58 : }
59 0 : return "-";
60 : }
61 :
62 : #define CHECK_STATUS(status, correct) do { \
63 : if (!NT_STATUS_EQUAL(status, correct)) { \
64 : torture_result(tctx, TORTURE_FAIL, \
65 : "(%s) Incorrect status %s - should be %s\n", \
66 : __location__, nt_errstr(status), nt_errstr(correct)); \
67 : ret = false; \
68 : goto done; \
69 : }} while (0)
70 :
71 : #define CREATE_FILE do { \
72 : fnum = create_complex_file(cli, tctx, fname); \
73 : if (fnum == -1) { \
74 : torture_result(tctx, TORTURE_FAIL, \
75 : "(%s) Failed to create %s - %s\n", \
76 : __location__, fname, smbcli_errstr(cli->tree)); \
77 : ret = false; \
78 : goto done; \
79 : }} while (0)
80 :
81 : #define CHECK_RDWR(fnum, correct) do { \
82 : enum rdwr_mode m = check_rdwr(cli->tree, fnum); \
83 : if (m != correct) { \
84 : torture_result(tctx, TORTURE_FAIL, \
85 : "(%s) Incorrect readwrite mode %s - expected %s\n", \
86 : __location__, rdwr_string(m), rdwr_string(correct)); \
87 : ret = false; \
88 : }} while (0)
89 :
90 : #define CHECK_TIME(t, field) do { \
91 : time_t t1, t2; \
92 : finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
93 : finfo.all_info.in.file.path = fname; \
94 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
95 : CHECK_STATUS(status, NT_STATUS_OK); \
96 : t1 = t & ~1; \
97 : t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
98 : if (labs(t1-t2) > 2) { \
99 : torture_result(tctx, TORTURE_FAIL, \
100 : "(%s) wrong time for field %s %s - %s\n", \
101 : __location__, #field, \
102 : timestring(tctx, t1), \
103 : timestring(tctx, t2)); \
104 : dump_all_info(tctx, &finfo); \
105 : ret = false; \
106 : }} while (0)
107 :
108 : #define CHECK_NTTIME(t, field) do { \
109 : NTTIME t2; \
110 : finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
111 : finfo.all_info.in.file.path = fname; \
112 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
113 : CHECK_STATUS(status, NT_STATUS_OK); \
114 : t2 = finfo.all_info.out.field; \
115 : if (llabs((int64_t)(t-t2)) > 20000) { \
116 : torture_result(tctx, TORTURE_FAIL, \
117 : "(%s) wrong time for field %s %s - %s\n", \
118 : __location__, #field, \
119 : nt_time_string(tctx, t), \
120 : nt_time_string(tctx, t2)); \
121 : dump_all_info(tctx, &finfo); \
122 : ret = false; \
123 : }} while (0)
124 :
125 : #define CHECK_ALL_INFO(v, field) do { \
126 : finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
127 : finfo.all_info.in.file.path = fname; \
128 : status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
129 : CHECK_STATUS(status, NT_STATUS_OK); \
130 : if ((v) != (finfo.all_info.out.field)) { \
131 : torture_result(tctx, TORTURE_FAIL, \
132 : "(%s) wrong value for field %s 0x%x - 0x%x\n", \
133 : __location__, #field, (unsigned int)(v), (unsigned int)(finfo.all_info.out.field)); \
134 : dump_all_info(tctx, &finfo); \
135 : ret = false; \
136 : }} while (0)
137 :
138 : #define CHECK_VAL(v, correct) do { \
139 : if ((v) != (correct)) { \
140 : torture_result(tctx, TORTURE_FAIL, \
141 : "(%s) wrong value for %s 0x%x - should be 0x%x\n", \
142 : __location__, #v, (unsigned int)(v), (unsigned int)(correct)); \
143 : ret = false; \
144 : }} while (0)
145 :
146 : #define SET_ATTRIB(sattrib) do { \
147 : union smb_setfileinfo sfinfo; \
148 : ZERO_STRUCT(sfinfo.basic_info.in); \
149 : sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION; \
150 : sfinfo.basic_info.in.file.path = fname; \
151 : sfinfo.basic_info.in.attrib = sattrib; \
152 : status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
153 : if (!NT_STATUS_IS_OK(status)) { \
154 : torture_warning(tctx, "(%s) Failed to set attrib 0x%x on %s\n", \
155 : __location__, (unsigned int)(sattrib), fname); \
156 : }} while (0)
157 :
158 : /*
159 : test RAW_OPEN_OPEN
160 : */
161 6 : static bool test_open(struct torture_context *tctx, struct smbcli_state *cli)
162 : {
163 1 : union smb_open io;
164 1 : union smb_fileinfo finfo;
165 6 : const char *fname = BASEDIR "\\torture_open.txt";
166 1 : NTSTATUS status;
167 6 : int fnum = -1, fnum2;
168 6 : bool ret = true;
169 :
170 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
171 :
172 6 : io.openold.level = RAW_OPEN_OPEN;
173 6 : io.openold.in.fname = fname;
174 6 : io.openold.in.open_mode = OPEN_FLAGS_FCB;
175 6 : io.openold.in.search_attrs = 0;
176 6 : status = smb_raw_open(cli->tree, tctx, &io);
177 6 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
178 6 : fnum = io.openold.out.file.fnum;
179 :
180 6 : smbcli_unlink(cli->tree, fname);
181 6 : CREATE_FILE;
182 6 : smbcli_close(cli->tree, fnum);
183 :
184 6 : status = smb_raw_open(cli->tree, tctx, &io);
185 6 : CHECK_STATUS(status, NT_STATUS_OK);
186 6 : fnum = io.openold.out.file.fnum;
187 6 : CHECK_RDWR(fnum, RDWR_RDWR);
188 :
189 6 : status = smb_raw_open(cli->tree, tctx, &io);
190 6 : CHECK_STATUS(status, NT_STATUS_OK);
191 6 : fnum2 = io.openold.out.file.fnum;
192 6 : CHECK_RDWR(fnum2, RDWR_RDWR);
193 6 : smbcli_close(cli->tree, fnum2);
194 6 : smbcli_close(cli->tree, fnum);
195 :
196 : /* check the read/write modes */
197 6 : io.openold.level = RAW_OPEN_OPEN;
198 6 : io.openold.in.fname = fname;
199 6 : io.openold.in.search_attrs = 0;
200 :
201 6 : io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
202 6 : status = smb_raw_open(cli->tree, tctx, &io);
203 6 : CHECK_STATUS(status, NT_STATUS_OK);
204 6 : fnum = io.openold.out.file.fnum;
205 6 : CHECK_RDWR(fnum, RDWR_RDONLY);
206 6 : smbcli_close(cli->tree, fnum);
207 :
208 6 : io.openold.in.open_mode = OPEN_FLAGS_OPEN_WRITE;
209 6 : status = smb_raw_open(cli->tree, tctx, &io);
210 6 : CHECK_STATUS(status, NT_STATUS_OK);
211 6 : fnum = io.openold.out.file.fnum;
212 6 : CHECK_RDWR(fnum, RDWR_WRONLY);
213 6 : smbcli_close(cli->tree, fnum);
214 :
215 6 : io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR;
216 6 : status = smb_raw_open(cli->tree, tctx, &io);
217 6 : CHECK_STATUS(status, NT_STATUS_OK);
218 6 : fnum = io.openold.out.file.fnum;
219 6 : CHECK_RDWR(fnum, RDWR_RDWR);
220 6 : smbcli_close(cli->tree, fnum);
221 :
222 : /* check the share modes roughly - not a complete matrix */
223 6 : io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
224 6 : status = smb_raw_open(cli->tree, tctx, &io);
225 6 : CHECK_STATUS(status, NT_STATUS_OK);
226 6 : fnum = io.openold.out.file.fnum;
227 6 : CHECK_RDWR(fnum, RDWR_RDWR);
228 :
229 6 : if (io.openold.in.open_mode != io.openold.out.rmode) {
230 0 : torture_warning(tctx, "(%s) rmode should equal open_mode - 0x%x 0x%x\n",
231 0 : __location__, io.openold.out.rmode, io.openold.in.open_mode);
232 : }
233 :
234 6 : io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
235 6 : status = smb_raw_open(cli->tree, tctx, &io);
236 6 : CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
237 :
238 6 : io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
239 6 : status = smb_raw_open(cli->tree, tctx, &io);
240 6 : CHECK_STATUS(status, NT_STATUS_OK);
241 6 : fnum2 = io.openold.out.file.fnum;
242 6 : CHECK_RDWR(fnum2, RDWR_RDONLY);
243 6 : smbcli_close(cli->tree, fnum);
244 6 : smbcli_close(cli->tree, fnum2);
245 :
246 :
247 : /* check the returned write time */
248 6 : io.openold.level = RAW_OPEN_OPEN;
249 6 : io.openold.in.fname = fname;
250 6 : io.openold.in.search_attrs = 0;
251 6 : io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
252 6 : status = smb_raw_open(cli->tree, tctx, &io);
253 6 : CHECK_STATUS(status, NT_STATUS_OK);
254 6 : fnum = io.openold.out.file.fnum;
255 :
256 : /* check other reply fields */
257 6 : CHECK_TIME(io.openold.out.write_time, write_time);
258 6 : CHECK_ALL_INFO(io.openold.out.size, size);
259 6 : CHECK_ALL_INFO(io.openold.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
260 :
261 6 : done:
262 6 : smbcli_close(cli->tree, fnum);
263 6 : smbcli_deltree(cli->tree, BASEDIR);
264 :
265 6 : return ret;
266 : }
267 :
268 :
269 : /*
270 : test RAW_OPEN_OPENX
271 : */
272 6 : static bool test_openx(struct torture_context *tctx, struct smbcli_state *cli)
273 : {
274 1 : union smb_open io;
275 1 : union smb_fileinfo finfo;
276 6 : const char *fname = BASEDIR "\\torture_openx.txt";
277 6 : const char *fname_exe = BASEDIR "\\torture_openx.exe";
278 1 : NTSTATUS status;
279 6 : int fnum = -1, fnum2;
280 6 : bool ret = true;
281 1 : int i;
282 1 : struct timeval tv;
283 1 : struct {
284 : uint16_t open_func;
285 : bool with_file;
286 : NTSTATUS correct_status;
287 6 : } open_funcs[] = {
288 : { OPENX_OPEN_FUNC_OPEN, true, NT_STATUS_OK },
289 : { OPENX_OPEN_FUNC_OPEN, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
290 : { OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE, true, NT_STATUS_OK },
291 : { OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
292 : { OPENX_OPEN_FUNC_FAIL, true, NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
293 : { OPENX_OPEN_FUNC_FAIL, false, NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
294 : { OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE, true, NT_STATUS_OBJECT_NAME_COLLISION },
295 : { OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
296 : { OPENX_OPEN_FUNC_TRUNC, true, NT_STATUS_OK },
297 : { OPENX_OPEN_FUNC_TRUNC, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
298 : { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true, NT_STATUS_OK },
299 : { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
300 : };
301 :
302 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
303 :
304 6 : io.openx.level = RAW_OPEN_OPENX;
305 6 : io.openx.in.fname = fname;
306 6 : io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
307 6 : io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
308 6 : io.openx.in.search_attrs = 0;
309 6 : io.openx.in.file_attrs = 0;
310 6 : io.openx.in.write_time = 0;
311 6 : io.openx.in.size = 1024*1024;
312 6 : io.openx.in.timeout = 0;
313 :
314 : /* check all combinations of open_func */
315 78 : for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
316 72 : if (open_funcs[i].with_file) {
317 36 : fnum = create_complex_file(cli, tctx, fname);
318 36 : if (fnum == -1) {
319 0 : torture_result(tctx, TORTURE_FAIL,
320 : "Failed to create file %s - %s\n",
321 : fname, smbcli_errstr(cli->tree));
322 0 : ret = false;
323 0 : goto done;
324 : }
325 36 : smbcli_close(cli->tree, fnum);
326 : }
327 72 : io.openx.in.open_func = open_funcs[i].open_func;
328 72 : status = smb_raw_open(cli->tree, tctx, &io);
329 72 : if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
330 0 : torture_result(tctx, TORTURE_FAIL,
331 : "(%s) incorrect status %s should be %s "
332 : "(i=%d with_file=%d open_func=0x%x)\n",
333 : __location__, nt_errstr(status),
334 : nt_errstr(open_funcs[i].correct_status),
335 0 : i, (int)open_funcs[i].with_file,
336 0 : open_funcs[i].open_func);
337 0 : ret = false;
338 : }
339 72 : if (NT_STATUS_IS_OK(status)) {
340 42 : smbcli_close(cli->tree, io.openx.out.file.fnum);
341 : }
342 72 : if (open_funcs[i].with_file) {
343 36 : smbcli_unlink(cli->tree, fname);
344 : }
345 : }
346 :
347 6 : smbcli_unlink(cli->tree, fname);
348 :
349 : /* check the basic return fields */
350 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
351 6 : status = smb_raw_open(cli->tree, tctx, &io);
352 6 : CHECK_STATUS(status, NT_STATUS_OK);
353 6 : fnum = io.openx.out.file.fnum;
354 :
355 6 : CHECK_ALL_INFO(io.openx.out.size, size);
356 6 : CHECK_TIME(io.openx.out.write_time, write_time);
357 6 : CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
358 6 : CHECK_VAL(io.openx.out.access, OPENX_MODE_ACCESS_RDWR);
359 6 : CHECK_VAL(io.openx.out.ftype, 0);
360 6 : CHECK_VAL(io.openx.out.devstate, 0);
361 6 : CHECK_VAL(io.openx.out.action, OPENX_ACTION_CREATED);
362 6 : CHECK_VAL(io.openx.out.size, 1024*1024);
363 6 : CHECK_ALL_INFO(io.openx.in.size, size);
364 6 : smbcli_close(cli->tree, fnum);
365 6 : smbcli_unlink(cli->tree, fname);
366 :
367 : /* check the fields when the file already existed */
368 6 : fnum2 = create_complex_file(cli, tctx, fname);
369 6 : if (fnum2 == -1) {
370 0 : ret = false;
371 0 : goto done;
372 : }
373 6 : smbcli_close(cli->tree, fnum2);
374 :
375 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
376 6 : status = smb_raw_open(cli->tree, tctx, &io);
377 6 : CHECK_STATUS(status, NT_STATUS_OK);
378 6 : fnum = io.openx.out.file.fnum;
379 :
380 6 : CHECK_ALL_INFO(io.openx.out.size, size);
381 6 : CHECK_TIME(io.openx.out.write_time, write_time);
382 6 : CHECK_VAL(io.openx.out.action, OPENX_ACTION_EXISTED);
383 6 : CHECK_VAL(io.openx.out.unknown, 0);
384 6 : CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
385 6 : smbcli_close(cli->tree, fnum);
386 :
387 : /* now check the search attrib for hidden files - win2003 ignores this? */
388 6 : SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
389 6 : CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
390 :
391 6 : io.openx.in.search_attrs = FILE_ATTRIBUTE_HIDDEN;
392 6 : status = smb_raw_open(cli->tree, tctx, &io);
393 6 : CHECK_STATUS(status, NT_STATUS_OK);
394 6 : smbcli_close(cli->tree, io.openx.out.file.fnum);
395 :
396 6 : io.openx.in.search_attrs = 0;
397 6 : status = smb_raw_open(cli->tree, tctx, &io);
398 6 : CHECK_STATUS(status, NT_STATUS_OK);
399 6 : smbcli_close(cli->tree, io.openx.out.file.fnum);
400 :
401 6 : SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
402 6 : smbcli_unlink(cli->tree, fname);
403 :
404 : /* and check attrib on create */
405 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
406 6 : io.openx.in.search_attrs = 0;
407 6 : io.openx.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
408 6 : status = smb_raw_open(cli->tree, tctx, &io);
409 6 : CHECK_STATUS(status, NT_STATUS_OK);
410 6 : if (torture_setting_bool(tctx, "samba3", false)) {
411 5 : CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE,
412 : attrib & ~(FILE_ATTRIBUTE_NONINDEXED|
413 : FILE_ATTRIBUTE_SPARSE));
414 : }
415 : else {
416 1 : CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE,
417 : attrib & ~(FILE_ATTRIBUTE_NONINDEXED));
418 : }
419 6 : smbcli_close(cli->tree, io.openx.out.file.fnum);
420 6 : smbcli_unlink(cli->tree, fname);
421 :
422 : /* check timeout on create - win2003 ignores the timeout! */
423 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
424 6 : io.openx.in.file_attrs = 0;
425 6 : io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
426 6 : status = smb_raw_open(cli->tree, tctx, &io);
427 6 : CHECK_STATUS(status, NT_STATUS_OK);
428 6 : fnum = io.openx.out.file.fnum;
429 :
430 6 : io.openx.in.timeout = 20000;
431 6 : tv = timeval_current();
432 6 : io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
433 6 : status = smb_raw_open(cli->tree, tctx, &io);
434 6 : CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
435 6 : if (timeval_elapsed(&tv) > 3.0) {
436 0 : torture_result(tctx, TORTURE_FAIL,
437 : "(%s) Incorrect timing in openx with timeout "
438 : "- waited %.2f seconds\n",
439 : __location__, timeval_elapsed(&tv));
440 0 : ret = false;
441 : }
442 6 : smbcli_close(cli->tree, fnum);
443 6 : smbcli_unlink(cli->tree, fname);
444 :
445 : /* now this is a really weird one - open for execute implies create?! */
446 6 : io.openx.in.fname = fname;
447 6 : io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
448 6 : io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
449 6 : io.openx.in.search_attrs = 0;
450 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL;
451 6 : io.openx.in.file_attrs = 0;
452 6 : io.openx.in.write_time = 0;
453 6 : io.openx.in.size = 0;
454 6 : io.openx.in.timeout = 0;
455 6 : status = smb_raw_open(cli->tree, tctx, &io);
456 6 : CHECK_STATUS(status, NT_STATUS_OK);
457 6 : smbcli_close(cli->tree, io.openx.out.file.fnum);
458 :
459 : /* check the extended return flag */
460 6 : io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO | OPENX_FLAGS_EXTENDED_RETURN;
461 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
462 6 : status = smb_raw_open(cli->tree, tctx, &io);
463 6 : CHECK_STATUS(status, NT_STATUS_OK);
464 6 : CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
465 6 : smbcli_close(cli->tree, io.openx.out.file.fnum);
466 :
467 6 : io.openx.in.fname = "\\A.+,;=[].B";
468 6 : status = smb_raw_open(cli->tree, tctx, &io);
469 6 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
470 :
471 : /* Check the mapping for open exec. */
472 :
473 : /* First create an .exe file. */
474 6 : smbcli_unlink(cli->tree, fname_exe);
475 6 : fnum = create_complex_file(cli, tctx, fname_exe);
476 6 : smbcli_close(cli->tree, fnum);
477 :
478 6 : io.openx.level = RAW_OPEN_OPENX;
479 6 : io.openx.in.fname = fname_exe;
480 6 : io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
481 6 : io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
482 6 : io.openx.in.search_attrs = 0;
483 6 : io.openx.in.file_attrs = 0;
484 6 : io.openx.in.write_time = 0;
485 6 : io.openx.in.size = 0;
486 6 : io.openx.in.timeout = 0;
487 6 : status = smb_raw_open(cli->tree, tctx, &io);
488 6 : CHECK_STATUS(status, NT_STATUS_OK);
489 :
490 : /* Can we read and write ? */
491 6 : CHECK_RDWR(io.openx.out.file.fnum, RDWR_RDONLY);
492 6 : smbcli_close(cli->tree, io.openx.out.file.fnum);
493 6 : smbcli_unlink(cli->tree, fname);
494 :
495 6 : done:
496 6 : smbcli_close(cli->tree, fnum);
497 6 : smbcli_deltree(cli->tree, BASEDIR);
498 :
499 6 : return ret;
500 : }
501 :
502 :
503 : /*
504 : test RAW_OPEN_T2OPEN
505 :
506 : many thanks to kukks for a sniff showing how this works with os2->w2k
507 : */
508 6 : static bool test_t2open(struct torture_context *tctx, struct smbcli_state *cli)
509 : {
510 1 : union smb_open io;
511 1 : union smb_fileinfo finfo;
512 6 : const char *fname1 = BASEDIR "\\torture_t2open_yes.txt";
513 6 : const char *fname2 = BASEDIR "\\torture_t2open_no.txt";
514 6 : const char *fname = BASEDIR "\\torture_t2open_3.txt";
515 1 : NTSTATUS status;
516 1 : int fnum;
517 6 : bool ret = true;
518 1 : int i;
519 1 : struct {
520 : uint16_t open_func;
521 : bool with_file;
522 : NTSTATUS correct_status;
523 6 : } open_funcs[] = {
524 : { OPENX_OPEN_FUNC_OPEN, true, NT_STATUS_OK },
525 : { OPENX_OPEN_FUNC_OPEN, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
526 : { OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE, true, NT_STATUS_OK },
527 : { OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
528 : { OPENX_OPEN_FUNC_FAIL, true, NT_STATUS_OBJECT_NAME_COLLISION },
529 : { OPENX_OPEN_FUNC_FAIL, false, NT_STATUS_OBJECT_NAME_COLLISION },
530 : { OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE, true, NT_STATUS_OBJECT_NAME_COLLISION },
531 : { OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OBJECT_NAME_COLLISION },
532 : { OPENX_OPEN_FUNC_TRUNC, true, NT_STATUS_OK },
533 : { OPENX_OPEN_FUNC_TRUNC, false, NT_STATUS_OK },
534 : { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true, NT_STATUS_OK },
535 : { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
536 : };
537 :
538 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
539 :
540 6 : fnum = create_complex_file(cli, tctx, fname1);
541 6 : if (fnum == -1) {
542 0 : torture_result(tctx, TORTURE_FAIL,
543 : "(%s): Failed to create file %s - %s\n",
544 : __location__, fname1, smbcli_errstr(cli->tree));
545 0 : ret = false;
546 0 : goto done;
547 : }
548 6 : smbcli_close(cli->tree, fnum);
549 :
550 6 : io.t2open.level = RAW_OPEN_T2OPEN;
551 6 : io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
552 6 : io.t2open.in.open_mode = OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR;
553 6 : io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
554 6 : io.t2open.in.search_attrs = 0;
555 6 : io.t2open.in.file_attrs = 0;
556 6 : io.t2open.in.write_time = 0;
557 6 : io.t2open.in.size = 0;
558 6 : io.t2open.in.timeout = 0;
559 :
560 6 : io.t2open.in.num_eas = 3;
561 6 : io.t2open.in.eas = talloc_array(tctx, struct ea_struct, io.t2open.in.num_eas);
562 6 : io.t2open.in.eas[0].flags = 0;
563 6 : io.t2open.in.eas[0].name.s = ".CLASSINFO";
564 6 : io.t2open.in.eas[0].value = data_blob_talloc(tctx, "first value", 11);
565 6 : io.t2open.in.eas[1].flags = 0;
566 6 : io.t2open.in.eas[1].name.s = "EA TWO";
567 6 : io.t2open.in.eas[1].value = data_blob_talloc(tctx, "foo", 3);
568 6 : io.t2open.in.eas[2].flags = 0;
569 6 : io.t2open.in.eas[2].name.s = "X THIRD";
570 6 : io.t2open.in.eas[2].value = data_blob_talloc(tctx, "xy", 2);
571 :
572 : /* check all combinations of open_func */
573 79 : for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
574 72 : again:
575 72 : if (open_funcs[i].with_file) {
576 36 : io.t2open.in.fname = fname1;
577 : } else {
578 36 : io.t2open.in.fname = fname2;
579 : }
580 72 : io.t2open.in.open_func = open_funcs[i].open_func;
581 72 : status = smb_raw_open(cli->tree, tctx, &io);
582 72 : if ((io.t2open.in.num_eas != 0)
583 72 : && NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
584 0 : && torture_setting_bool(tctx, "samba3", false)) {
585 0 : torture_warning(tctx, "(%s) EAs not supported, not "
586 : "treating as fatal in Samba3 test\n",
587 : __location__);
588 0 : io.t2open.in.num_eas = 0;
589 0 : goto again;
590 : }
591 :
592 72 : if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
593 0 : torture_result(tctx, TORTURE_FAIL,
594 : "(%s) incorrect status %s should be %s "
595 : "(i=%d with_file=%d open_func=0x%x)\n",
596 : __location__, nt_errstr(status),
597 : nt_errstr(open_funcs[i].correct_status),
598 0 : i, (int)open_funcs[i].with_file,
599 0 : open_funcs[i].open_func);
600 0 : ret = false;
601 : }
602 72 : if (NT_STATUS_IS_OK(status)) {
603 42 : smbcli_close(cli->tree, io.t2open.out.file.fnum);
604 : }
605 : }
606 :
607 6 : smbcli_unlink(cli->tree, fname1);
608 6 : smbcli_unlink(cli->tree, fname2);
609 :
610 : /* check the basic return fields */
611 6 : io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
612 6 : io.t2open.in.write_time = 0;
613 6 : io.t2open.in.fname = fname;
614 6 : status = smb_raw_open(cli->tree, tctx, &io);
615 6 : CHECK_STATUS(status, NT_STATUS_OK);
616 6 : fnum = io.t2open.out.file.fnum;
617 :
618 6 : CHECK_ALL_INFO(io.t2open.out.size, size);
619 : #if 0
620 : /* windows appears to leak uninitialised memory here */
621 : CHECK_VAL(io.t2open.out.write_time, 0);
622 : #endif
623 6 : CHECK_ALL_INFO(io.t2open.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
624 6 : CHECK_VAL(io.t2open.out.access, OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR);
625 6 : CHECK_VAL(io.t2open.out.ftype, 0);
626 6 : CHECK_VAL(io.t2open.out.devstate, 0);
627 6 : CHECK_VAL(io.t2open.out.action, OPENX_ACTION_CREATED);
628 6 : smbcli_close(cli->tree, fnum);
629 :
630 6 : status = torture_check_ea(cli, fname, ".CLASSINFO", "first value");
631 6 : CHECK_STATUS(status, io.t2open.in.num_eas
632 : ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
633 6 : status = torture_check_ea(cli, fname, "EA TWO", "foo");
634 6 : CHECK_STATUS(status, io.t2open.in.num_eas
635 : ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
636 6 : status = torture_check_ea(cli, fname, "X THIRD", "xy");
637 6 : CHECK_STATUS(status, io.t2open.in.num_eas
638 : ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
639 :
640 : /* now check the search attrib for hidden files - win2003 ignores this? */
641 6 : SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
642 6 : CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
643 :
644 6 : status = smb_raw_open(cli->tree, tctx, &io);
645 6 : CHECK_STATUS(status, NT_STATUS_OK);
646 6 : smbcli_close(cli->tree, io.t2open.out.file.fnum);
647 :
648 6 : status = smb_raw_open(cli->tree, tctx, &io);
649 6 : CHECK_STATUS(status, NT_STATUS_OK);
650 6 : smbcli_close(cli->tree, io.t2open.out.file.fnum);
651 :
652 6 : SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
653 6 : smbcli_unlink(cli->tree, fname);
654 :
655 : /* and check attrib on create */
656 6 : io.t2open.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
657 6 : io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
658 6 : status = smb_raw_open(cli->tree, tctx, &io);
659 6 : CHECK_STATUS(status, NT_STATUS_OK);
660 :
661 : /* check timeout on create - win2003 ignores the timeout! */
662 6 : io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
663 6 : io.t2open.in.file_attrs = 0;
664 6 : io.t2open.in.timeout = 20000;
665 6 : io.t2open.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
666 6 : status = smb_raw_open(cli->tree, tctx, &io);
667 6 : CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
668 :
669 6 : done:
670 6 : smbcli_close(cli->tree, fnum);
671 6 : smbcli_deltree(cli->tree, BASEDIR);
672 :
673 6 : return ret;
674 : }
675 :
676 :
677 : /*
678 : test RAW_OPEN_NTCREATEX
679 : */
680 6 : static bool test_ntcreatex(struct torture_context *tctx, struct smbcli_state *cli)
681 : {
682 1 : union smb_open io;
683 1 : union smb_fileinfo finfo;
684 6 : const char *fname = BASEDIR "\\torture_ntcreatex.txt";
685 6 : const char *dname = BASEDIR "\\torture_ntcreatex.dir";
686 1 : NTSTATUS status;
687 6 : int fnum = -1;
688 6 : bool ret = true;
689 1 : int i;
690 1 : struct {
691 : uint32_t open_disp;
692 : bool with_file;
693 : NTSTATUS correct_status;
694 6 : } open_funcs[] = {
695 : { NTCREATEX_DISP_SUPERSEDE, true, NT_STATUS_OK },
696 : { NTCREATEX_DISP_SUPERSEDE, false, NT_STATUS_OK },
697 : { NTCREATEX_DISP_OPEN, true, NT_STATUS_OK },
698 : { NTCREATEX_DISP_OPEN, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
699 : { NTCREATEX_DISP_CREATE, true, NT_STATUS_OBJECT_NAME_COLLISION },
700 : { NTCREATEX_DISP_CREATE, false, NT_STATUS_OK },
701 : { NTCREATEX_DISP_OPEN_IF, true, NT_STATUS_OK },
702 : { NTCREATEX_DISP_OPEN_IF, false, NT_STATUS_OK },
703 : { NTCREATEX_DISP_OVERWRITE, true, NT_STATUS_OK },
704 : { NTCREATEX_DISP_OVERWRITE, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
705 : { NTCREATEX_DISP_OVERWRITE_IF, true, NT_STATUS_OK },
706 : { NTCREATEX_DISP_OVERWRITE_IF, false, NT_STATUS_OK },
707 : { 6, true, NT_STATUS_INVALID_PARAMETER },
708 : { 6, false, NT_STATUS_INVALID_PARAMETER },
709 : };
710 :
711 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
712 :
713 : /* reasonable default parameters */
714 6 : io.generic.level = RAW_OPEN_NTCREATEX;
715 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
716 6 : io.ntcreatex.in.root_fid.fnum = 0;
717 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
718 6 : io.ntcreatex.in.alloc_size = 1024*1024;
719 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
720 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
721 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
722 6 : io.ntcreatex.in.create_options = 0;
723 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
724 6 : io.ntcreatex.in.security_flags = 0;
725 6 : io.ntcreatex.in.fname = fname;
726 :
727 : /* test the open disposition */
728 90 : for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
729 84 : if (open_funcs[i].with_file) {
730 42 : fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
731 42 : if (fnum == -1) {
732 0 : torture_result(tctx, TORTURE_FAIL,
733 : "Failed to create file %s - %s\n",
734 : fname, smbcli_errstr(cli->tree));
735 0 : ret = false;
736 0 : goto done;
737 : }
738 42 : smbcli_close(cli->tree, fnum);
739 : }
740 84 : io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
741 84 : status = smb_raw_open(cli->tree, tctx, &io);
742 84 : if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
743 0 : torture_result(tctx, TORTURE_FAIL,
744 : "(%s) incorrect status %s should be %s "
745 : "(i=%d with_file=%d open_disp=%d)\n",
746 : __location__, nt_errstr(status),
747 : nt_errstr(open_funcs[i].correct_status),
748 0 : i, (int)open_funcs[i].with_file,
749 0 : (int)open_funcs[i].open_disp);
750 0 : ret = false;
751 : }
752 84 : if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
753 66 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
754 66 : smbcli_unlink(cli->tree, fname);
755 : }
756 : }
757 :
758 : /* basic field testing */
759 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
760 :
761 6 : status = smb_raw_open(cli->tree, tctx, &io);
762 6 : CHECK_STATUS(status, NT_STATUS_OK);
763 6 : fnum = io.ntcreatex.out.file.fnum;
764 :
765 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
766 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
767 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
768 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
769 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
770 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
771 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
772 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
773 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
774 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
775 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
776 :
777 : /* check fields when the file already existed */
778 6 : smbcli_close(cli->tree, fnum);
779 6 : smbcli_unlink(cli->tree, fname);
780 6 : fnum = create_complex_file(cli, tctx, fname);
781 6 : if (fnum == -1) {
782 0 : ret = false;
783 0 : goto done;
784 : }
785 6 : smbcli_close(cli->tree, fnum);
786 :
787 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
788 6 : status = smb_raw_open(cli->tree, tctx, &io);
789 6 : CHECK_STATUS(status, NT_STATUS_OK);
790 6 : fnum = io.ntcreatex.out.file.fnum;
791 :
792 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
793 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
794 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
795 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
796 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
797 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
798 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
799 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
800 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
801 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
802 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
803 6 : smbcli_close(cli->tree, fnum);
804 6 : smbcli_unlink(cli->tree, fname);
805 :
806 :
807 : /* create a directory */
808 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
809 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
810 6 : io.ntcreatex.in.alloc_size = 0;
811 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
812 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
813 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
814 6 : io.ntcreatex.in.create_options = 0;
815 6 : io.ntcreatex.in.fname = dname;
816 6 : fname = dname;
817 :
818 6 : smbcli_rmdir(cli->tree, fname);
819 6 : smbcli_unlink(cli->tree, fname);
820 :
821 6 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
822 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
823 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
824 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
825 6 : status = smb_raw_open(cli->tree, tctx, &io);
826 6 : CHECK_STATUS(status, NT_STATUS_OK);
827 6 : fnum = io.ntcreatex.out.file.fnum;
828 :
829 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
830 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
831 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
832 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
833 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
834 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
835 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
836 6 : CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
837 : FILE_ATTRIBUTE_DIRECTORY);
838 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
839 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
840 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
841 6 : CHECK_VAL(io.ntcreatex.out.is_directory, 1);
842 6 : CHECK_VAL(io.ntcreatex.out.size, 0);
843 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
844 6 : smbcli_unlink(cli->tree, fname);
845 :
846 :
847 6 : done:
848 6 : smbcli_close(cli->tree, fnum);
849 6 : smbcli_deltree(cli->tree, BASEDIR);
850 :
851 6 : return ret;
852 : }
853 :
854 :
855 : /*
856 : test RAW_OPEN_NTTRANS_CREATE
857 : */
858 6 : static bool test_nttrans_create(struct torture_context *tctx, struct smbcli_state *cli)
859 : {
860 1 : union smb_open io;
861 1 : union smb_fileinfo finfo;
862 6 : const char *fname = BASEDIR "\\torture_ntcreatex.txt";
863 6 : const char *dname = BASEDIR "\\torture_ntcreatex.dir";
864 1 : NTSTATUS status;
865 6 : int fnum = -1;
866 6 : bool ret = true;
867 1 : int i;
868 1 : uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
869 1 : uint32_t not_a_directory_mask, unexpected_mask;
870 1 : struct {
871 : uint32_t open_disp;
872 : bool with_file;
873 : NTSTATUS correct_status;
874 6 : } open_funcs[] = {
875 : { NTCREATEX_DISP_SUPERSEDE, true, NT_STATUS_OK },
876 : { NTCREATEX_DISP_SUPERSEDE, false, NT_STATUS_OK },
877 : { NTCREATEX_DISP_OPEN, true, NT_STATUS_OK },
878 : { NTCREATEX_DISP_OPEN, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
879 : { NTCREATEX_DISP_CREATE, true, NT_STATUS_OBJECT_NAME_COLLISION },
880 : { NTCREATEX_DISP_CREATE, false, NT_STATUS_OK },
881 : { NTCREATEX_DISP_OPEN_IF, true, NT_STATUS_OK },
882 : { NTCREATEX_DISP_OPEN_IF, false, NT_STATUS_OK },
883 : { NTCREATEX_DISP_OVERWRITE, true, NT_STATUS_OK },
884 : { NTCREATEX_DISP_OVERWRITE, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
885 : { NTCREATEX_DISP_OVERWRITE_IF, true, NT_STATUS_OK },
886 : { NTCREATEX_DISP_OVERWRITE_IF, false, NT_STATUS_OK },
887 : { 6, true, NT_STATUS_INVALID_PARAMETER },
888 : { 6, false, NT_STATUS_INVALID_PARAMETER },
889 : };
890 :
891 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
892 :
893 : /* reasonable default parameters */
894 6 : io.generic.level = RAW_OPEN_NTTRANS_CREATE;
895 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
896 6 : io.ntcreatex.in.root_fid.fnum = 0;
897 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
898 6 : io.ntcreatex.in.alloc_size = 1024*1024;
899 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
900 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
901 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
902 6 : io.ntcreatex.in.create_options = 0;
903 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
904 6 : io.ntcreatex.in.security_flags = 0;
905 6 : io.ntcreatex.in.fname = fname;
906 6 : io.ntcreatex.in.sec_desc = NULL;
907 6 : io.ntcreatex.in.ea_list = NULL;
908 :
909 : /* test the open disposition */
910 90 : for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
911 84 : if (open_funcs[i].with_file) {
912 42 : fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
913 42 : if (fnum == -1) {
914 0 : torture_result(tctx, TORTURE_FAIL,
915 : "Failed to create file %s - %s\n",
916 : fname, smbcli_errstr(cli->tree));
917 0 : ret = false;
918 0 : goto done;
919 : }
920 42 : smbcli_close(cli->tree, fnum);
921 : }
922 84 : io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
923 84 : status = smb_raw_open(cli->tree, tctx, &io);
924 84 : if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
925 0 : torture_result(tctx, TORTURE_FAIL,
926 : "(%s) incorrect status %s should be %s "
927 : "(i=%d with_file=%d open_disp=%d)\n",
928 : __location__, nt_errstr(status),
929 : nt_errstr(open_funcs[i].correct_status),
930 0 : i, (int)open_funcs[i].with_file,
931 0 : (int)open_funcs[i].open_disp);
932 0 : ret = false;
933 : }
934 84 : if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
935 66 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
936 66 : smbcli_unlink(cli->tree, fname);
937 : }
938 : }
939 :
940 : /* basic field testing */
941 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
942 :
943 6 : status = smb_raw_open(cli->tree, tctx, &io);
944 6 : CHECK_STATUS(status, NT_STATUS_OK);
945 6 : fnum = io.ntcreatex.out.file.fnum;
946 :
947 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
948 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
949 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
950 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
951 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
952 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
953 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
954 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
955 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
956 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
957 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
958 :
959 : /* check fields when the file already existed */
960 6 : smbcli_close(cli->tree, fnum);
961 6 : smbcli_unlink(cli->tree, fname);
962 6 : fnum = create_complex_file(cli, tctx, fname);
963 6 : if (fnum == -1) {
964 0 : ret = false;
965 0 : goto done;
966 : }
967 6 : smbcli_close(cli->tree, fnum);
968 :
969 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
970 6 : status = smb_raw_open(cli->tree, tctx, &io);
971 6 : CHECK_STATUS(status, NT_STATUS_OK);
972 6 : fnum = io.ntcreatex.out.file.fnum;
973 :
974 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
975 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
976 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
977 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
978 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
979 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
980 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
981 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
982 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
983 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
984 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
985 6 : smbcli_close(cli->tree, fnum);
986 :
987 : /* check no-recall - don't pull a file from tape on a HSM */
988 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NO_RECALL;
989 6 : status = smb_raw_open(cli->tree, tctx, &io);
990 6 : CHECK_STATUS(status, NT_STATUS_OK);
991 6 : fnum = io.ntcreatex.out.file.fnum;
992 :
993 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
994 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
995 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
996 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
997 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
998 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
999 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1000 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1001 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1002 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1003 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1004 6 : smbcli_close(cli->tree, fnum);
1005 :
1006 : /* Check some create options (these all should be ignored) */
1007 199 : for (i=0; i < 32; i++) {
1008 192 : uint32_t create_option =
1009 192 : ((uint32_t)1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
1010 192 : if (create_option == 0) {
1011 150 : continue;
1012 : }
1013 42 : io.ntcreatex.in.create_options = create_option;
1014 42 : status = smb_raw_open(cli->tree, tctx, &io);
1015 42 : if (!NT_STATUS_IS_OK(status)) {
1016 0 : torture_warning(tctx, "ntcreatex create option 0x%08x "
1017 : "gave %s - should give NT_STATUS_OK\n",
1018 : create_option, nt_errstr(status));
1019 : }
1020 42 : CHECK_STATUS(status, NT_STATUS_OK);
1021 42 : fnum = io.ntcreatex.out.file.fnum;
1022 :
1023 42 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1024 42 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
1025 42 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
1026 42 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
1027 42 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
1028 42 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
1029 42 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1030 42 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1031 42 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1032 42 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1033 42 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1034 42 : smbcli_close(cli->tree, fnum);
1035 : }
1036 :
1037 6 : io.ntcreatex.in.file_attr = 0;
1038 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1039 6 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1040 :
1041 : /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */
1042 6 : ok_mask = 0;
1043 6 : not_supported_mask = 0;
1044 6 : invalid_parameter_mask = 0;
1045 6 : not_a_directory_mask = 0;
1046 6 : unexpected_mask = 0;
1047 198 : for (i=0; i < 32; i++) {
1048 192 : uint32_t create_option = (uint32_t)1<<i;
1049 192 : if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
1050 6 : continue;
1051 : }
1052 186 : io.ntcreatex.in.create_options = create_option;
1053 186 : status = smb_raw_open(cli->tree, tctx, &io);
1054 186 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1055 6 : not_supported_mask |= create_option;
1056 180 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1057 108 : ok_mask |= create_option;
1058 108 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1059 72 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1060 66 : invalid_parameter_mask |= create_option;
1061 6 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1062 6 : not_a_directory_mask |= 1<<i;
1063 : } else {
1064 0 : unexpected_mask |= 1<<i;
1065 0 : torture_comment(tctx, "create option 0x%08x returned %s\n",
1066 : create_option, nt_errstr(status));
1067 : }
1068 : }
1069 :
1070 6 : CHECK_VAL(ok_mask, 0x00efcfce);
1071 6 : CHECK_VAL(not_a_directory_mask, 0x00000001);
1072 6 : CHECK_VAL(not_supported_mask, 0x00002000);
1073 6 : CHECK_VAL(invalid_parameter_mask, 0xff100030);
1074 6 : CHECK_VAL(unexpected_mask, 0x00000000);
1075 :
1076 6 : smbcli_unlink(cli->tree, fname);
1077 :
1078 :
1079 : /* create a directory */
1080 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1081 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1082 6 : io.ntcreatex.in.alloc_size = 0;
1083 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1084 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1085 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1086 6 : io.ntcreatex.in.create_options = 0;
1087 6 : io.ntcreatex.in.fname = dname;
1088 6 : fname = dname;
1089 :
1090 6 : smbcli_rmdir(cli->tree, fname);
1091 6 : smbcli_unlink(cli->tree, fname);
1092 :
1093 6 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1094 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1095 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1096 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1097 6 : status = smb_raw_open(cli->tree, tctx, &io);
1098 6 : CHECK_STATUS(status, NT_STATUS_OK);
1099 6 : fnum = io.ntcreatex.out.file.fnum;
1100 :
1101 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1102 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
1103 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
1104 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
1105 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
1106 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
1107 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1108 6 : CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1109 : FILE_ATTRIBUTE_DIRECTORY);
1110 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1111 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1112 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1113 6 : CHECK_VAL(io.ntcreatex.out.is_directory, 1);
1114 6 : CHECK_VAL(io.ntcreatex.out.size, 0);
1115 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1116 6 : smbcli_unlink(cli->tree, fname);
1117 :
1118 :
1119 6 : done:
1120 6 : smbcli_close(cli->tree, fnum);
1121 6 : smbcli_deltree(cli->tree, BASEDIR);
1122 :
1123 6 : return ret;
1124 : }
1125 :
1126 : /*
1127 : test RAW_OPEN_NTCREATEX with an already opened and byte range locked file
1128 :
1129 : I've got an application that does a similar sequence of ntcreate&x,
1130 : locking&x and another ntcreate&x with
1131 : open_disposition==NTCREATEX_DISP_OVERWRITE_IF. Windows 2003 allows the
1132 : second open.
1133 : */
1134 6 : static bool test_ntcreatex_brlocked(struct torture_context *tctx, struct smbcli_state *cli)
1135 : {
1136 1 : union smb_open io, io1;
1137 1 : union smb_lock io2;
1138 1 : struct smb_lock_entry lock[1];
1139 6 : const char *fname = BASEDIR "\\torture_ntcreatex.txt";
1140 1 : NTSTATUS status;
1141 6 : bool ret = true;
1142 :
1143 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1144 :
1145 6 : torture_comment(tctx, "Testing ntcreatex with a byte range locked file\n");
1146 :
1147 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1148 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1149 6 : io.ntcreatex.in.root_fid.fnum = 0;
1150 6 : io.ntcreatex.in.access_mask = 0x2019f;
1151 6 : io.ntcreatex.in.alloc_size = 0;
1152 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1153 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1154 : NTCREATEX_SHARE_ACCESS_WRITE;
1155 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1156 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
1157 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1158 6 : io.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
1159 : NTCREATEX_SECURITY_ALL;
1160 6 : io.ntcreatex.in.fname = fname;
1161 :
1162 6 : status = smb_raw_open(cli->tree, tctx, &io);
1163 6 : CHECK_STATUS(status, NT_STATUS_OK);
1164 :
1165 6 : io2.lockx.level = RAW_LOCK_LOCKX;
1166 6 : io2.lockx.in.file.fnum = io.ntcreatex.out.file.fnum;
1167 6 : io2.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
1168 6 : io2.lockx.in.timeout = 0;
1169 6 : io2.lockx.in.ulock_cnt = 0;
1170 6 : io2.lockx.in.lock_cnt = 1;
1171 6 : lock[0].pid = cli->session->pid;
1172 6 : lock[0].offset = 0;
1173 6 : lock[0].count = 0x1;
1174 6 : io2.lockx.in.locks = &lock[0];
1175 6 : status = smb_raw_lock(cli->tree, &io2);
1176 6 : CHECK_STATUS(status, NT_STATUS_OK);
1177 :
1178 6 : io1.generic.level = RAW_OPEN_NTCREATEX;
1179 6 : io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1180 6 : io1.ntcreatex.in.root_fid.fnum = 0;
1181 6 : io1.ntcreatex.in.access_mask = 0x20196;
1182 6 : io1.ntcreatex.in.alloc_size = 0;
1183 6 : io1.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1184 6 : io1.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1185 : NTCREATEX_SHARE_ACCESS_WRITE;
1186 6 : io1.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1187 6 : io1.ntcreatex.in.create_options = 0;
1188 6 : io1.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1189 6 : io1.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
1190 : NTCREATEX_SECURITY_ALL;
1191 6 : io1.ntcreatex.in.fname = fname;
1192 :
1193 6 : status = smb_raw_open(cli->tree, tctx, &io1);
1194 6 : CHECK_STATUS(status, NT_STATUS_OK);
1195 :
1196 6 : done:
1197 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1198 6 : smbcli_close(cli->tree, io1.ntcreatex.out.file.fnum);
1199 6 : smbcli_deltree(cli->tree, BASEDIR);
1200 6 : return ret;
1201 : }
1202 :
1203 : /*
1204 : test RAW_OPEN_MKNEW
1205 : */
1206 6 : static bool test_mknew(struct torture_context *tctx, struct smbcli_state *cli)
1207 : {
1208 1 : union smb_open io;
1209 6 : const char *fname = BASEDIR "\\torture_mknew.txt";
1210 1 : NTSTATUS status;
1211 6 : int fnum = -1;
1212 6 : bool ret = true;
1213 6 : time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1214 1 : union smb_fileinfo finfo;
1215 :
1216 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1217 :
1218 6 : io.mknew.level = RAW_OPEN_MKNEW;
1219 6 : io.mknew.in.attrib = 0;
1220 6 : io.mknew.in.write_time = 0;
1221 6 : io.mknew.in.fname = fname;
1222 6 : status = smb_raw_open(cli->tree, tctx, &io);
1223 6 : CHECK_STATUS(status, NT_STATUS_OK);
1224 6 : fnum = io.mknew.out.file.fnum;
1225 :
1226 6 : status = smb_raw_open(cli->tree, tctx, &io);
1227 6 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
1228 :
1229 6 : smbcli_close(cli->tree, fnum);
1230 6 : smbcli_unlink(cli->tree, fname);
1231 :
1232 : /* make sure write_time works */
1233 6 : io.mknew.in.write_time = basetime;
1234 6 : status = smb_raw_open(cli->tree, tctx, &io);
1235 6 : CHECK_STATUS(status, NT_STATUS_OK);
1236 6 : fnum = io.mknew.out.file.fnum;
1237 6 : CHECK_TIME(basetime, write_time);
1238 :
1239 6 : smbcli_close(cli->tree, fnum);
1240 6 : smbcli_unlink(cli->tree, fname);
1241 :
1242 : /* make sure file_attrs works */
1243 6 : io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1244 6 : status = smb_raw_open(cli->tree, tctx, &io);
1245 6 : CHECK_STATUS(status, NT_STATUS_OK);
1246 6 : fnum = io.mknew.out.file.fnum;
1247 6 : CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE,
1248 : attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1249 :
1250 6 : done:
1251 6 : smbcli_close(cli->tree, fnum);
1252 6 : smbcli_deltree(cli->tree, BASEDIR);
1253 :
1254 6 : return ret;
1255 : }
1256 :
1257 :
1258 : /*
1259 : test RAW_OPEN_CREATE
1260 : */
1261 6 : static bool test_create(struct torture_context *tctx, struct smbcli_state *cli)
1262 : {
1263 1 : union smb_open io;
1264 6 : const char *fname = BASEDIR "\\torture_create.txt";
1265 1 : NTSTATUS status;
1266 6 : int fnum = -1;
1267 6 : bool ret = true;
1268 6 : time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1269 1 : union smb_fileinfo finfo;
1270 :
1271 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1272 :
1273 6 : io.create.level = RAW_OPEN_CREATE;
1274 6 : io.create.in.attrib = 0;
1275 6 : io.create.in.write_time = 0;
1276 6 : io.create.in.fname = fname;
1277 6 : status = smb_raw_open(cli->tree, tctx, &io);
1278 6 : CHECK_STATUS(status, NT_STATUS_OK);
1279 6 : fnum = io.create.out.file.fnum;
1280 :
1281 6 : status = smb_raw_open(cli->tree, tctx, &io);
1282 6 : CHECK_STATUS(status, NT_STATUS_OK);
1283 :
1284 6 : smbcli_close(cli->tree, io.create.out.file.fnum);
1285 6 : smbcli_close(cli->tree, fnum);
1286 6 : smbcli_unlink(cli->tree, fname);
1287 :
1288 : /* make sure write_time works */
1289 6 : io.create.in.write_time = basetime;
1290 6 : status = smb_raw_open(cli->tree, tctx, &io);
1291 6 : CHECK_STATUS(status, NT_STATUS_OK);
1292 6 : fnum = io.create.out.file.fnum;
1293 6 : CHECK_TIME(basetime, write_time);
1294 :
1295 6 : smbcli_close(cli->tree, fnum);
1296 6 : smbcli_unlink(cli->tree, fname);
1297 :
1298 : /* make sure file_attrs works */
1299 6 : io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1300 6 : status = smb_raw_open(cli->tree, tctx, &io);
1301 6 : CHECK_STATUS(status, NT_STATUS_OK);
1302 6 : fnum = io.create.out.file.fnum;
1303 6 : CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE,
1304 : attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1305 :
1306 6 : done:
1307 6 : smbcli_close(cli->tree, fnum);
1308 6 : smbcli_deltree(cli->tree, BASEDIR);
1309 :
1310 6 : return ret;
1311 : }
1312 :
1313 :
1314 : /*
1315 : test RAW_OPEN_CTEMP
1316 : */
1317 6 : static bool test_ctemp(struct torture_context *tctx, struct smbcli_state *cli)
1318 : {
1319 1 : union smb_open io;
1320 1 : NTSTATUS status;
1321 6 : int fnum = -1;
1322 6 : bool ret = true;
1323 6 : time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1324 1 : union smb_fileinfo finfo;
1325 6 : const char *name, *fname = NULL;
1326 :
1327 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1328 :
1329 6 : io.ctemp.level = RAW_OPEN_CTEMP;
1330 6 : io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1331 6 : io.ctemp.in.write_time = basetime;
1332 6 : io.ctemp.in.directory = BASEDIR;
1333 6 : status = smb_raw_open(cli->tree, tctx, &io);
1334 6 : CHECK_STATUS(status, NT_STATUS_OK);
1335 6 : fnum = io.ctemp.out.file.fnum;
1336 :
1337 6 : name = io.ctemp.out.name;
1338 :
1339 6 : finfo.generic.level = RAW_FILEINFO_NAME_INFO;
1340 6 : finfo.generic.in.file.fnum = fnum;
1341 6 : status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1342 6 : CHECK_STATUS(status, NT_STATUS_OK);
1343 :
1344 6 : fname = finfo.name_info.out.fname.s;
1345 6 : torture_comment(tctx, "ctemp name=%s real name=%s\n", name, fname);
1346 :
1347 6 : done:
1348 6 : smbcli_close(cli->tree, fnum);
1349 6 : smbcli_deltree(cli->tree, BASEDIR);
1350 :
1351 6 : return ret;
1352 : }
1353 :
1354 :
1355 : /*
1356 : test chained RAW_OPEN_OPENX_READX
1357 : */
1358 6 : static bool test_chained(struct torture_context *tctx, struct smbcli_state *cli)
1359 : {
1360 1 : union smb_open io;
1361 6 : const char *fname = BASEDIR "\\torture_chained.txt";
1362 1 : NTSTATUS status;
1363 6 : int fnum = -1;
1364 6 : bool ret = true;
1365 6 : const char buf[] = "test";
1366 1 : char buf2[4];
1367 :
1368 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1369 :
1370 6 : fnum = create_complex_file(cli, tctx, fname);
1371 :
1372 6 : smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1373 :
1374 6 : smbcli_close(cli->tree, fnum);
1375 :
1376 6 : io.openxreadx.level = RAW_OPEN_OPENX_READX;
1377 6 : io.openxreadx.in.fname = fname;
1378 6 : io.openxreadx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1379 6 : io.openxreadx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1380 6 : io.openxreadx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1381 6 : io.openxreadx.in.search_attrs = 0;
1382 6 : io.openxreadx.in.file_attrs = 0;
1383 6 : io.openxreadx.in.write_time = 0;
1384 6 : io.openxreadx.in.size = 1024*1024;
1385 6 : io.openxreadx.in.timeout = 0;
1386 :
1387 6 : io.openxreadx.in.offset = 0;
1388 6 : io.openxreadx.in.mincnt = sizeof(buf2);
1389 6 : io.openxreadx.in.maxcnt = sizeof(buf2);
1390 6 : io.openxreadx.in.remaining = 0;
1391 6 : io.openxreadx.out.data = (uint8_t *)buf2;
1392 :
1393 6 : status = smb_raw_open(cli->tree, tctx, &io);
1394 6 : CHECK_STATUS(status, NT_STATUS_OK);
1395 6 : fnum = io.openxreadx.out.file.fnum;
1396 :
1397 6 : if (memcmp(buf, buf2, MIN(sizeof(buf), sizeof(buf2))) != 0) {
1398 0 : torture_result(tctx, TORTURE_FAIL,
1399 : "wrong data in reply buffer\n");
1400 0 : ret = false;
1401 : }
1402 :
1403 6 : done:
1404 6 : smbcli_close(cli->tree, fnum);
1405 6 : smbcli_deltree(cli->tree, BASEDIR);
1406 :
1407 6 : return ret;
1408 : }
1409 :
1410 : /*
1411 : test RAW_OPEN_OPENX without a leading slash on the path.
1412 : NetApp filers are known to fail on this.
1413 :
1414 : */
1415 6 : static bool test_no_leading_slash(struct torture_context *tctx, struct smbcli_state *cli)
1416 : {
1417 1 : union smb_open io;
1418 6 : const char *fname = BASEDIR "\\torture_no_leading_slash.txt";
1419 1 : NTSTATUS status;
1420 6 : int fnum = -1;
1421 6 : bool ret = true;
1422 6 : const char buf[] = "test";
1423 :
1424 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1425 :
1426 6 : smbcli_unlink(cli->tree, fname);
1427 :
1428 : /* Create the file */
1429 6 : fnum = create_complex_file(cli, tctx, fname);
1430 6 : smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1431 6 : smbcli_close(cli->tree, fnum);
1432 :
1433 : /* Prepare to open the file using path without leading slash */
1434 6 : io.openx.level = RAW_OPEN_OPENX;
1435 6 : io.openx.in.fname = fname + 1;
1436 6 : io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1437 6 : io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1438 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1439 6 : io.openx.in.search_attrs = 0;
1440 6 : io.openx.in.file_attrs = 0;
1441 6 : io.openx.in.write_time = 0;
1442 6 : io.openx.in.size = 1024*1024;
1443 6 : io.openx.in.timeout = 0;
1444 :
1445 6 : status = smb_raw_open(cli->tree, tctx, &io);
1446 6 : CHECK_STATUS(status, NT_STATUS_OK);
1447 6 : fnum = io.openx.out.file.fnum;
1448 :
1449 6 : done:
1450 6 : smbcli_close(cli->tree, fnum);
1451 6 : smbcli_deltree(cli->tree, BASEDIR);
1452 :
1453 6 : return ret;
1454 : }
1455 :
1456 : /*
1457 : test RAW_OPEN_OPENX against an existing directory to
1458 : ensure it returns NT_STATUS_FILE_IS_A_DIRECTORY.
1459 : Samba 3.2.0 - 3.2.6 are known to fail this.
1460 :
1461 : */
1462 6 : static bool test_openx_over_dir(struct torture_context *tctx, struct smbcli_state *cli)
1463 : {
1464 1 : union smb_open io;
1465 6 : const char *fname = BASEDIR "\\openx_over_dir";
1466 1 : NTSTATUS status;
1467 6 : int d_fnum = -1;
1468 6 : int fnum = -1;
1469 6 : bool ret = true;
1470 :
1471 6 : ZERO_STRUCT(io);
1472 :
1473 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1474 :
1475 : /* Create the Directory */
1476 6 : status = create_directory_handle(cli->tree, fname, &d_fnum);
1477 6 : smbcli_close(cli->tree, d_fnum);
1478 :
1479 : /* Prepare to open the file over the directory. */
1480 6 : io.openx.level = RAW_OPEN_OPENX;
1481 6 : io.openx.in.fname = fname;
1482 6 : io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1483 6 : io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1484 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1485 6 : io.openx.in.search_attrs = 0;
1486 6 : io.openx.in.file_attrs = 0;
1487 6 : io.openx.in.write_time = 0;
1488 6 : io.openx.in.size = 1024*1024;
1489 6 : io.openx.in.timeout = 0;
1490 :
1491 6 : status = smb_raw_open(cli->tree, tctx, &io);
1492 6 : CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
1493 6 : fnum = io.openx.out.file.fnum;
1494 :
1495 6 : done:
1496 6 : smbcli_close(cli->tree, fnum);
1497 6 : smbcli_deltree(cli->tree, BASEDIR);
1498 :
1499 6 : return ret;
1500 : }
1501 :
1502 :
1503 : /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
1504 :
1505 6 : static bool test_raw_open_multi(struct torture_context *tctx, struct smbcli_state *cli_ignored)
1506 : {
1507 1 : struct smbcli_state *cli;
1508 6 : TALLOC_CTX *mem_ctx = talloc_init("torture_test_oplock_multi");
1509 6 : const char *fname = "\\test_oplock.dat";
1510 1 : NTSTATUS status;
1511 6 : bool ret = true;
1512 1 : union smb_open io;
1513 1 : struct smbcli_state **clients;
1514 1 : struct smbcli_request **requests;
1515 1 : union smb_open *ios;
1516 6 : const char *host = torture_setting_string(tctx, "host", NULL);
1517 6 : const char *share = torture_setting_string(tctx, "share", NULL);
1518 6 : int i, num_files = 3;
1519 6 : int num_ok = 0;
1520 6 : int num_collision = 0;
1521 :
1522 6 : clients = talloc_array(mem_ctx, struct smbcli_state *, num_files);
1523 6 : requests = talloc_array(mem_ctx, struct smbcli_request *, num_files);
1524 6 : ios = talloc_array(mem_ctx, union smb_open, num_files);
1525 6 : if ((tctx->ev == NULL) || (clients == NULL) || (requests == NULL) ||
1526 : (ios == NULL)) {
1527 0 : torture_result(tctx, TORTURE_FAIL, "(%s): talloc failed\n",
1528 : __location__);
1529 0 : return false;
1530 : }
1531 :
1532 6 : if (!torture_open_connection_share(mem_ctx, &cli, tctx, host, share, tctx->ev)) {
1533 0 : return false;
1534 : }
1535 :
1536 6 : cli->tree->session->transport->options.request_timeout = 60;
1537 :
1538 24 : for (i=0; i<num_files; i++) {
1539 18 : if (!torture_open_connection_share(mem_ctx, &(clients[i]),
1540 : tctx, host, share, tctx->ev)) {
1541 0 : torture_result(tctx, TORTURE_FAIL,
1542 : "(%s): Could not open %d'th connection\n",
1543 : __location__, i);
1544 0 : return false;
1545 : }
1546 18 : clients[i]->tree->session->transport->options.request_timeout = 60;
1547 : }
1548 :
1549 : /* cleanup */
1550 6 : smbcli_unlink(cli->tree, fname);
1551 :
1552 : /*
1553 : base ntcreatex parms
1554 : */
1555 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1556 6 : io.ntcreatex.in.root_fid.fnum = 0;
1557 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1558 6 : io.ntcreatex.in.alloc_size = 0;
1559 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1560 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1561 : NTCREATEX_SHARE_ACCESS_WRITE|
1562 : NTCREATEX_SHARE_ACCESS_DELETE;
1563 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1564 6 : io.ntcreatex.in.create_options = 0;
1565 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1566 6 : io.ntcreatex.in.security_flags = 0;
1567 6 : io.ntcreatex.in.fname = fname;
1568 6 : io.ntcreatex.in.flags = 0;
1569 :
1570 25 : for (i=0; i<num_files; i++) {
1571 18 : ios[i] = io;
1572 18 : requests[i] = smb_raw_open_send(clients[i]->tree, &ios[i]);
1573 18 : if (requests[i] == NULL) {
1574 0 : torture_result(tctx, TORTURE_FAIL,
1575 : "(%s): could not send %d'th request\n",
1576 : __location__, i);
1577 0 : return false;
1578 : }
1579 : }
1580 :
1581 6 : torture_comment(tctx, "waiting for replies\n");
1582 55 : while (1) {
1583 60 : bool unreplied = false;
1584 83 : for (i=0; i<num_files; i++) {
1585 77 : if (requests[i] == NULL) {
1586 5 : continue;
1587 : }
1588 72 : if (requests[i]->state < SMBCLI_REQUEST_DONE) {
1589 45 : unreplied = true;
1590 45 : break;
1591 : }
1592 21 : status = smb_raw_open_recv(requests[i], mem_ctx,
1593 18 : &ios[i]);
1594 :
1595 18 : torture_comment(tctx, "File %d returned status %s\n", i,
1596 : nt_errstr(status));
1597 :
1598 18 : if (NT_STATUS_IS_OK(status)) {
1599 6 : num_ok += 1;
1600 : }
1601 :
1602 18 : if (NT_STATUS_EQUAL(status,
1603 : NT_STATUS_OBJECT_NAME_COLLISION)) {
1604 12 : num_collision += 1;
1605 : }
1606 :
1607 18 : requests[i] = NULL;
1608 : }
1609 60 : if (!unreplied) {
1610 5 : break;
1611 : }
1612 :
1613 54 : if (tevent_loop_once(tctx->ev) != 0) {
1614 0 : torture_result(tctx, TORTURE_FAIL,
1615 : "(%s): tevent_loop_once failed\n", __location__);
1616 0 : return false;
1617 : }
1618 : }
1619 :
1620 6 : if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
1621 0 : ret = false;
1622 : }
1623 :
1624 24 : for (i=0; i<num_files; i++) {
1625 18 : torture_close_connection(clients[i]);
1626 : }
1627 6 : talloc_free(mem_ctx);
1628 6 : return ret;
1629 : }
1630 :
1631 : /*
1632 : test opening for delete on a read-only attribute file.
1633 : */
1634 6 : static bool test_open_for_delete(struct torture_context *tctx, struct smbcli_state *cli)
1635 : {
1636 1 : union smb_open io;
1637 1 : union smb_fileinfo finfo;
1638 6 : const char *fname = BASEDIR "\\torture_open_for_delete.txt";
1639 1 : NTSTATUS status;
1640 6 : int fnum = -1;
1641 6 : bool ret = true;
1642 :
1643 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1644 :
1645 : /* reasonable default parameters */
1646 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1647 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1648 6 : io.ntcreatex.in.root_fid.fnum = 0;
1649 6 : io.ntcreatex.in.alloc_size = 0;
1650 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1651 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_READONLY;
1652 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1653 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1654 6 : io.ntcreatex.in.create_options = 0;
1655 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1656 6 : io.ntcreatex.in.security_flags = 0;
1657 6 : io.ntcreatex.in.fname = fname;
1658 :
1659 : /* Create the readonly file. */
1660 :
1661 6 : status = smb_raw_open(cli->tree, tctx, &io);
1662 6 : CHECK_STATUS(status, NT_STATUS_OK);
1663 6 : fnum = io.ntcreatex.out.file.fnum;
1664 :
1665 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1666 6 : io.ntcreatex.in.create_options = 0;
1667 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
1668 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1669 6 : smbcli_close(cli->tree, fnum);
1670 :
1671 : /* Now try and open for delete only - should succeed. */
1672 6 : io.ntcreatex.in.access_mask = SEC_STD_DELETE;
1673 6 : io.ntcreatex.in.file_attr = 0;
1674 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
1675 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1676 6 : status = smb_raw_open(cli->tree, tctx, &io);
1677 6 : CHECK_STATUS(status, NT_STATUS_OK);
1678 :
1679 6 : smbcli_unlink(cli->tree, fname);
1680 :
1681 6 : done:
1682 6 : smbcli_close(cli->tree, fnum);
1683 6 : smbcli_deltree(cli->tree, BASEDIR);
1684 :
1685 6 : return ret;
1686 : }
1687 :
1688 : /*
1689 : test chained RAW_OPEN_NTCREATEX_READX
1690 : Send chained NTCREATEX_READX on a file that doesn't exist, then create
1691 : the file and try again.
1692 : */
1693 6 : static bool test_chained_ntcreatex_readx(struct torture_context *tctx, struct smbcli_state *cli)
1694 : {
1695 6 : TALLOC_CTX *mem_ctx = talloc_new(tctx);
1696 1 : union smb_open io;
1697 6 : const char *fname = BASEDIR "\\torture_chained.txt";
1698 1 : NTSTATUS status;
1699 6 : int fnum = -1;
1700 6 : bool ret = true;
1701 6 : const char buf[] = "test";
1702 1 : char buf2[4];
1703 :
1704 6 : ZERO_STRUCT(io);
1705 :
1706 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1707 :
1708 6 : torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
1709 : "non-existent file \n");
1710 :
1711 : /* ntcreatex parameters */
1712 6 : io.generic.level = RAW_OPEN_NTCREATEX_READX;
1713 6 : io.ntcreatexreadx.in.flags = 0;
1714 6 : io.ntcreatexreadx.in.root_fid.fnum = 0;
1715 6 : io.ntcreatexreadx.in.access_mask = SEC_FILE_READ_DATA;
1716 6 : io.ntcreatexreadx.in.alloc_size = 0;
1717 6 : io.ntcreatexreadx.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1718 6 : io.ntcreatexreadx.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1719 : NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
1720 6 : io.ntcreatexreadx.in.open_disposition = NTCREATEX_DISP_OPEN;
1721 6 : io.ntcreatexreadx.in.create_options = 0;
1722 6 : io.ntcreatexreadx.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1723 6 : io.ntcreatexreadx.in.security_flags = 0;
1724 6 : io.ntcreatexreadx.in.fname = fname;
1725 :
1726 : /* readx parameters */
1727 6 : io.ntcreatexreadx.in.offset = 0;
1728 6 : io.ntcreatexreadx.in.mincnt = sizeof(buf2);
1729 6 : io.ntcreatexreadx.in.maxcnt = sizeof(buf2);
1730 6 : io.ntcreatexreadx.in.remaining = 0;
1731 6 : io.ntcreatexreadx.out.data = (uint8_t *)buf2;
1732 :
1733 : /* try to open the non-existent file */
1734 6 : status = smb_raw_open(cli->tree, mem_ctx, &io);
1735 6 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1736 6 : fnum = io.ntcreatexreadx.out.file.fnum;
1737 :
1738 6 : smbcli_close(cli->tree, fnum);
1739 6 : smbcli_unlink(cli->tree, fname);
1740 :
1741 6 : torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
1742 : "existing file \n");
1743 :
1744 6 : fnum = create_complex_file(cli, mem_ctx, fname);
1745 6 : smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1746 6 : smbcli_close(cli->tree, fnum);
1747 :
1748 6 : status = smb_raw_open(cli->tree, mem_ctx, &io);
1749 6 : CHECK_STATUS(status, NT_STATUS_OK);
1750 6 : fnum = io.ntcreatexreadx.out.file.fnum;
1751 :
1752 6 : if (memcmp(buf, buf2, MIN(sizeof(buf), sizeof(buf2))) != 0) {
1753 0 : torture_result(tctx, TORTURE_FAIL,
1754 : "(%s): wrong data in reply buffer\n", __location__);
1755 0 : ret = false;
1756 : }
1757 :
1758 6 : done:
1759 6 : smbcli_close(cli->tree, fnum);
1760 6 : smbcli_deltree(cli->tree, BASEDIR);
1761 6 : talloc_free(mem_ctx);
1762 :
1763 6 : return ret;
1764 : }
1765 :
1766 6 : static bool test_ntcreatex_opendisp_dir(struct torture_context *tctx,
1767 : struct smbcli_state *cli)
1768 : {
1769 6 : const char *dname = BASEDIR "\\torture_ntcreatex_opendisp_dir";
1770 1 : NTSTATUS status;
1771 6 : bool ret = true;
1772 1 : int i;
1773 1 : struct {
1774 : uint32_t open_disp;
1775 : bool dir_exists;
1776 : NTSTATUS correct_status;
1777 6 : } open_funcs_dir[] = {
1778 : { NTCREATEX_DISP_SUPERSEDE, true, NT_STATUS_INVALID_PARAMETER },
1779 : { NTCREATEX_DISP_SUPERSEDE, false, NT_STATUS_INVALID_PARAMETER },
1780 : { NTCREATEX_DISP_OPEN, true, NT_STATUS_OK },
1781 : { NTCREATEX_DISP_OPEN, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
1782 : { NTCREATEX_DISP_CREATE, true, NT_STATUS_OBJECT_NAME_COLLISION },
1783 : { NTCREATEX_DISP_CREATE, false, NT_STATUS_OK },
1784 : { NTCREATEX_DISP_OPEN_IF, true, NT_STATUS_OK },
1785 : { NTCREATEX_DISP_OPEN_IF, false, NT_STATUS_OK },
1786 : { NTCREATEX_DISP_OVERWRITE, true, NT_STATUS_INVALID_PARAMETER },
1787 : { NTCREATEX_DISP_OVERWRITE, false, NT_STATUS_INVALID_PARAMETER },
1788 : { NTCREATEX_DISP_OVERWRITE_IF, true, NT_STATUS_INVALID_PARAMETER },
1789 : { NTCREATEX_DISP_OVERWRITE_IF, false, NT_STATUS_INVALID_PARAMETER },
1790 : { 6, true, NT_STATUS_INVALID_PARAMETER },
1791 : { 6, false, NT_STATUS_INVALID_PARAMETER },
1792 : };
1793 1 : union smb_open io;
1794 :
1795 6 : ZERO_STRUCT(io);
1796 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1797 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1798 6 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1799 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1800 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1801 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1802 6 : io.ntcreatex.in.fname = dname;
1803 :
1804 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1805 :
1806 6 : smbcli_rmdir(cli->tree, dname);
1807 6 : smbcli_unlink(cli->tree, dname);
1808 :
1809 : /* test the open disposition for directories */
1810 6 : torture_comment(tctx, "Testing open dispositions for directories...\n");
1811 :
1812 91 : for (i=0; i<ARRAY_SIZE(open_funcs_dir); i++) {
1813 84 : if (open_funcs_dir[i].dir_exists) {
1814 42 : status = smbcli_mkdir(cli->tree, dname);
1815 42 : if (!NT_STATUS_IS_OK(status)) {
1816 0 : torture_result(tctx, TORTURE_FAIL,
1817 : "(%s): Failed to make directory "
1818 : "%s - %s\n", __location__, dname,
1819 : smbcli_errstr(cli->tree));
1820 0 : ret = false;
1821 0 : goto done;
1822 : }
1823 : }
1824 :
1825 84 : io.ntcreatex.in.open_disposition = open_funcs_dir[i].open_disp;
1826 84 : status = smb_raw_open(cli->tree, tctx, &io);
1827 84 : if (!NT_STATUS_EQUAL(status, open_funcs_dir[i].correct_status)) {
1828 0 : torture_result(tctx, TORTURE_FAIL,
1829 : "(%s) incorrect status %s should be %s "
1830 : "(i=%d dir_exists=%d open_disp=%d)\n",
1831 : __location__, nt_errstr(status),
1832 : nt_errstr(open_funcs_dir[i].correct_status),
1833 0 : i, (int)open_funcs_dir[i].dir_exists,
1834 0 : (int)open_funcs_dir[i].open_disp);
1835 0 : ret = false;
1836 : }
1837 84 : if (NT_STATUS_IS_OK(status) || open_funcs_dir[i].dir_exists) {
1838 54 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1839 54 : smbcli_rmdir(cli->tree, dname);
1840 : }
1841 : }
1842 :
1843 6 : done:
1844 6 : smbcli_deltree(cli->tree, BASEDIR);
1845 :
1846 6 : return ret;
1847 : }
1848 :
1849 : /**
1850 : * Test what happens when trying to open a file with directory parameters and
1851 : * vice-versa. Also test that NTCREATEX_OPTIONS_DIRECTORY is treated as
1852 : * mandatory and FILE_ATTRIBUTE_DIRECTORY is advisory for directory
1853 : * creation/opening.
1854 : */
1855 6 : static bool test_ntcreatexdir(struct torture_context *tctx,
1856 : struct smbcli_state *cli)
1857 : {
1858 1 : union smb_open io;
1859 6 : const char *fname = BASEDIR "\\torture_ntcreatex.txt";
1860 6 : const char *dname = BASEDIR "\\torture_ntcreatex_dir";
1861 1 : NTSTATUS status;
1862 1 : int i;
1863 :
1864 1 : struct {
1865 : uint32_t open_disp;
1866 : uint32_t file_attr;
1867 : uint32_t create_options;
1868 : NTSTATUS correct_status;
1869 6 : } open_funcs[] = {
1870 : { NTCREATEX_DISP_SUPERSEDE, 0, NTCREATEX_OPTIONS_DIRECTORY,
1871 : NT_STATUS_INVALID_PARAMETER },
1872 : { NTCREATEX_DISP_OPEN, 0, NTCREATEX_OPTIONS_DIRECTORY,
1873 : NT_STATUS_OBJECT_NAME_NOT_FOUND },
1874 : { NTCREATEX_DISP_CREATE, 0, NTCREATEX_OPTIONS_DIRECTORY,
1875 : NT_STATUS_OK },
1876 : { NTCREATEX_DISP_OPEN_IF, 0, NTCREATEX_OPTIONS_DIRECTORY,
1877 : NT_STATUS_OK },
1878 : { NTCREATEX_DISP_OVERWRITE, 0, NTCREATEX_OPTIONS_DIRECTORY,
1879 : NT_STATUS_INVALID_PARAMETER },
1880 : { NTCREATEX_DISP_OVERWRITE_IF, 0, NTCREATEX_OPTIONS_DIRECTORY,
1881 : NT_STATUS_INVALID_PARAMETER },
1882 : { NTCREATEX_DISP_SUPERSEDE, FILE_ATTRIBUTE_DIRECTORY, 0,
1883 : NT_STATUS_OK },
1884 : { NTCREATEX_DISP_OPEN, FILE_ATTRIBUTE_DIRECTORY, 0,
1885 : NT_STATUS_OBJECT_NAME_NOT_FOUND },
1886 : { NTCREATEX_DISP_CREATE, FILE_ATTRIBUTE_DIRECTORY, 0,
1887 : NT_STATUS_OK },
1888 : { NTCREATEX_DISP_OPEN_IF, FILE_ATTRIBUTE_DIRECTORY, 0,
1889 : NT_STATUS_OK },
1890 : { NTCREATEX_DISP_OVERWRITE, FILE_ATTRIBUTE_DIRECTORY, 0,
1891 : NT_STATUS_OBJECT_NAME_NOT_FOUND },
1892 : { NTCREATEX_DISP_OVERWRITE_IF, FILE_ATTRIBUTE_DIRECTORY, 0,
1893 : NT_STATUS_OK },
1894 :
1895 : };
1896 :
1897 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1898 :
1899 : /* setup some base params. */
1900 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1901 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1902 6 : io.ntcreatex.in.root_fid.fnum = 0;
1903 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1904 6 : io.ntcreatex.in.alloc_size = 0;
1905 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1906 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1907 6 : io.ntcreatex.in.security_flags = 0;
1908 6 : io.ntcreatex.in.fname = fname;
1909 :
1910 : /*
1911 : * Test the validity checking for create dispositions, which is done
1912 : * against the requested parameters rather than what's actually on
1913 : * disk.
1914 : */
1915 78 : for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
1916 72 : io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
1917 72 : io.ntcreatex.in.file_attr = open_funcs[i].file_attr;
1918 72 : io.ntcreatex.in.create_options = open_funcs[i].create_options;
1919 72 : status = smb_raw_open(cli->tree, tctx, &io);
1920 72 : if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
1921 0 : torture_result(tctx, TORTURE_FAIL,
1922 : "(%s) incorrect status %s should be %s "
1923 : "(i=%d open_disp=%d)\n",
1924 : __location__, nt_errstr(status),
1925 : nt_errstr(open_funcs[i].correct_status),
1926 0 : i, (int)open_funcs[i].open_disp);
1927 0 : return false;
1928 : }
1929 : /* Close and delete the file. */
1930 72 : if (NT_STATUS_IS_OK(status)) {
1931 36 : if (open_funcs[i].create_options != 0) {
1932 : /* out attrib should be a directory. */
1933 12 : torture_assert_int_equal(tctx,
1934 : io.ntcreatex.out.attrib,
1935 : FILE_ATTRIBUTE_DIRECTORY, "should have "
1936 : "created a directory");
1937 :
1938 12 : smbcli_close(cli->tree,
1939 12 : io.ntcreatex.out.file.fnum);
1940 :
1941 : /* Make sure unlink fails. */
1942 12 : status = smbcli_unlink(cli->tree, fname);
1943 12 : torture_assert_ntstatus_equal(tctx, status,
1944 : NT_STATUS_FILE_IS_A_DIRECTORY,
1945 : "unlink should fail for a directory");
1946 :
1947 12 : status = smbcli_rmdir(cli->tree, fname);
1948 12 : torture_assert_ntstatus_ok(tctx, status,
1949 : "rmdir failed");
1950 : } else {
1951 24 : torture_assert_int_equal(tctx,
1952 : io.ntcreatex.out.attrib,
1953 : FILE_ATTRIBUTE_ARCHIVE, "should not have "
1954 : "created a directory");
1955 :
1956 24 : smbcli_close(cli->tree,
1957 24 : io.ntcreatex.out.file.fnum);
1958 :
1959 : /* Make sure rmdir fails. */
1960 24 : status = smbcli_rmdir(cli->tree, fname);
1961 24 : torture_assert_ntstatus_equal(tctx, status,
1962 : NT_STATUS_NOT_A_DIRECTORY,
1963 : "rmdir should fail for a file");
1964 :
1965 24 : status = smbcli_unlink(cli->tree, fname);
1966 32 : torture_assert_ntstatus_ok(tctx, status,
1967 : "unlink failed");
1968 : }
1969 : }
1970 : }
1971 :
1972 : /* Create a file. */
1973 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1974 6 : io.ntcreatex.in.create_options = 0;
1975 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1976 6 : status = smb_raw_open(cli->tree, tctx, &io);
1977 6 : torture_assert_ntstatus_ok(tctx, status, "Failed to create file.");
1978 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1979 :
1980 : /* Try and open the file with file_attr_dir and check the error. */
1981 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1982 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1983 :
1984 6 : status = smb_raw_open(cli->tree, tctx, &io);
1985 6 : torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_DIRECTORY "
1986 : "doesn't produce a hard failure.");
1987 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1988 :
1989 : /* Try and open file with createx_option_dir and check the error. */
1990 6 : io.ntcreatex.in.file_attr = 0;
1991 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1992 :
1993 6 : status = smb_raw_open(cli->tree, tctx, &io);
1994 6 : torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_A_DIRECTORY,
1995 : "NTCREATEX_OPTIONS_DIRECTORY will a file from being opened.");
1996 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1997 :
1998 : /* Delete the file and move onto directory testing. */
1999 6 : smbcli_unlink(cli->tree, fname);
2000 :
2001 : /* Now try some tests on a directory. */
2002 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2003 6 : io.ntcreatex.in.file_attr = 0;
2004 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2005 6 : io.ntcreatex.in.fname = dname;
2006 :
2007 6 : status = smb_raw_open(cli->tree, tctx, &io);
2008 6 : torture_assert_ntstatus_ok(tctx, status, "Failed to create dir.");
2009 :
2010 : /* out attrib should be a directory. */
2011 6 : torture_assert_int_equal(tctx, io.ntcreatex.out.attrib,
2012 : FILE_ATTRIBUTE_DIRECTORY, "should have created a directory");
2013 :
2014 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2015 :
2016 : /* Try and open it with normal attr and check the error. */
2017 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2018 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2019 :
2020 6 : status = smb_raw_open(cli->tree, tctx, &io);
2021 6 : torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_NORMAL "
2022 : "doesn't produce a hard failure.");
2023 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2024 :
2025 : /* Try and open it with file create_options and check the error. */
2026 6 : io.ntcreatex.in.file_attr = 0;
2027 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2028 :
2029 6 : status = smb_raw_open(cli->tree, tctx, &io);
2030 6 : torture_assert_ntstatus_equal(tctx, status,
2031 : NT_STATUS_FILE_IS_A_DIRECTORY,
2032 : "NTCREATEX_OPTIONS_NON_DIRECTORY_FILE should be returned ");
2033 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2034 :
2035 6 : smbcli_deltree(cli->tree, BASEDIR);
2036 :
2037 6 : return true;
2038 : }
2039 :
2040 : /*
2041 : test opening with truncate on an already open file
2042 : returns share violation and doesn't truncate the file.
2043 : Regression test for bug #10671.
2044 : */
2045 6 : static bool test_open_for_truncate(struct torture_context *tctx, struct smbcli_state *cli)
2046 : {
2047 1 : union smb_open io;
2048 1 : union smb_fileinfo finfo;
2049 6 : const char *fname = BASEDIR "\\torture_open_for_truncate.txt";
2050 1 : NTSTATUS status;
2051 6 : int fnum = -1;
2052 6 : ssize_t val = 0;
2053 6 : char c = '\0';
2054 6 : bool ret = true;
2055 :
2056 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR),
2057 : "Failed to setup up test directory: " BASEDIR);
2058 :
2059 6 : torture_comment(tctx, "Testing open truncate disposition.\n");
2060 :
2061 : /* reasonable default parameters */
2062 6 : ZERO_STRUCT(io);
2063 6 : io.generic.level = RAW_OPEN_NTCREATEX;
2064 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
2065 6 : io.ntcreatex.in.root_fid.fnum = 0;
2066 6 : io.ntcreatex.in.alloc_size = 0;
2067 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2068 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2069 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2070 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2071 6 : io.ntcreatex.in.create_options = 0;
2072 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2073 6 : io.ntcreatex.in.security_flags = 0;
2074 6 : io.ntcreatex.in.fname = fname;
2075 :
2076 6 : status = smb_raw_open(cli->tree, tctx, &io);
2077 6 : CHECK_STATUS(status, NT_STATUS_OK);
2078 6 : fnum = io.ntcreatex.out.file.fnum;
2079 :
2080 : /* Write a byte at offset 1k-1. */
2081 6 : val =smbcli_write(cli->tree, fnum, 0, &c, 1023, 1);
2082 6 : torture_assert_int_equal(tctx, val, 1, "write failed\n");
2083 :
2084 : /* Now try and open for read/write with truncate - should fail. */
2085 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE|SEC_RIGHTS_FILE_READ;
2086 6 : io.ntcreatex.in.file_attr = 0;
2087 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
2088 : NTCREATEX_SHARE_ACCESS_WRITE |
2089 : NTCREATEX_SHARE_ACCESS_DELETE;
2090 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
2091 6 : status = smb_raw_open(cli->tree, tctx, &io);
2092 6 : CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
2093 :
2094 : /* Ensure file size is still 1k */
2095 6 : finfo.generic.level = RAW_FILEINFO_GETATTRE;
2096 6 : finfo.generic.in.file.fnum = fnum;
2097 6 : status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
2098 6 : CHECK_STATUS(status, NT_STATUS_OK);
2099 6 : CHECK_VAL(finfo.getattre.out.size, 1024);
2100 :
2101 6 : smbcli_close(cli->tree, fnum);
2102 :
2103 6 : status = smb_raw_open(cli->tree, tctx, &io);
2104 6 : CHECK_STATUS(status, NT_STATUS_OK);
2105 6 : fnum = io.ntcreatex.out.file.fnum;
2106 :
2107 : /* Ensure truncate actually works */
2108 6 : finfo.generic.level = RAW_FILEINFO_GETATTRE;
2109 6 : finfo.generic.in.file.fnum = fnum;
2110 6 : status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
2111 6 : CHECK_STATUS(status, NT_STATUS_OK);
2112 6 : CHECK_VAL(finfo.getattre.out.size, 0);
2113 :
2114 6 : smbcli_close(cli->tree, fnum);
2115 6 : smbcli_unlink(cli->tree, fname);
2116 :
2117 6 : done:
2118 6 : smbcli_close(cli->tree, fnum);
2119 6 : smbcli_deltree(cli->tree, BASEDIR);
2120 :
2121 6 : return ret;
2122 : }
2123 :
2124 : /**
2125 : * Test for file size to be 0 after create with FILE_SUPERSEDE
2126 : */
2127 6 : static bool test_ntcreatex_supersede(struct torture_context *tctx, struct smbcli_state *cli)
2128 : {
2129 1 : union smb_open io;
2130 1 : union smb_setfileinfo sfi;
2131 1 : union smb_fileinfo finfo;
2132 6 : const char *fname = BASEDIR "\\torture_ntcreatex_supersede.txt";
2133 1 : NTSTATUS status;
2134 6 : int fnum = -1;
2135 6 : bool ret = true;
2136 :
2137 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
2138 :
2139 : /* reasonable default parameters */
2140 6 : io.generic.level = RAW_OPEN_NTCREATEX;
2141 6 : io.ntcreatex.in.flags = 0;
2142 6 : io.ntcreatex.in.root_fid.fnum = 0;
2143 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2144 6 : io.ntcreatex.in.alloc_size = 0;
2145 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2146 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2147 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2148 6 : io.ntcreatex.in.create_options = 0;
2149 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2150 6 : io.ntcreatex.in.security_flags = 0;
2151 6 : io.ntcreatex.in.fname = fname;
2152 :
2153 6 : status = smb_raw_open(cli->tree, tctx, &io);
2154 6 : CHECK_STATUS(status, NT_STATUS_OK);
2155 6 : fnum = io.ntcreatex.out.file.fnum;
2156 :
2157 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
2158 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
2159 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
2160 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
2161 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
2162 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
2163 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
2164 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
2165 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
2166 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
2167 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
2168 :
2169 : /* extend the file size */
2170 6 : ZERO_STRUCT(sfi);
2171 6 : sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
2172 6 : sfi.generic.in.file.fnum = fnum;
2173 6 : sfi.end_of_file_info.in.size = 512;
2174 6 : status = smb_raw_setfileinfo(cli->tree, &sfi);
2175 6 : CHECK_STATUS(status, NT_STATUS_OK);
2176 :
2177 : /* close the file and re-open with to verify new size */
2178 6 : smbcli_close(cli->tree, fnum);
2179 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2180 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
2181 6 : status = smb_raw_open(cli->tree, tctx, &io);
2182 6 : CHECK_STATUS(status, NT_STATUS_OK);
2183 6 : fnum = io.ntcreatex.out.file.fnum;
2184 :
2185 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
2186 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
2187 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
2188 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
2189 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
2190 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
2191 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
2192 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
2193 6 : CHECK_VAL(io.ntcreatex.out.size, 512);
2194 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
2195 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
2196 :
2197 : /* close and re-open the file with SUPERSEDE flag */
2198 6 : smbcli_close(cli->tree, fnum);
2199 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_SUPERSEDE;
2200 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
2201 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2202 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2203 6 : io.ntcreatex.in.create_options = 0;
2204 :
2205 6 : status = smb_raw_open(cli->tree, tctx, &io);
2206 6 : CHECK_STATUS(status, NT_STATUS_OK);
2207 6 : fnum = io.ntcreatex.out.file.fnum;
2208 :
2209 : /* The file size in the superseded create response should be 0 */
2210 6 : CHECK_VAL(io.ntcreatex.out.size, 0);
2211 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
2212 6 : CHECK_VAL(io.ntcreatex.out.create_action, FILE_WAS_SUPERSEDED);
2213 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
2214 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
2215 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
2216 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
2217 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
2218 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
2219 6 : done:
2220 6 : smbcli_close(cli->tree, fnum);
2221 6 : smbcli_deltree(cli->tree, BASEDIR);
2222 :
2223 6 : return ret;
2224 : }
2225 :
2226 : /* basic testing of all RAW_OPEN_* calls
2227 : */
2228 2354 : struct torture_suite *torture_raw_open(TALLOC_CTX *mem_ctx)
2229 : {
2230 2354 : struct torture_suite *suite = torture_suite_create(mem_ctx, "open");
2231 :
2232 2354 : torture_suite_add_1smb_test(suite, "brlocked", test_ntcreatex_brlocked);
2233 2354 : torture_suite_add_1smb_test(suite, "open", test_open);
2234 2354 : torture_suite_add_1smb_test(suite, "open-multi", test_raw_open_multi);
2235 2354 : torture_suite_add_1smb_test(suite, "openx", test_openx);
2236 2354 : torture_suite_add_1smb_test(suite, "ntcreatex", test_ntcreatex);
2237 2354 : torture_suite_add_1smb_test(suite, "nttrans-create", test_nttrans_create);
2238 2354 : torture_suite_add_1smb_test(suite, "t2open", test_t2open);
2239 2354 : torture_suite_add_1smb_test(suite, "mknew", test_mknew);
2240 2354 : torture_suite_add_1smb_test(suite, "create", test_create);
2241 2354 : torture_suite_add_1smb_test(suite, "ctemp", test_ctemp);
2242 2354 : torture_suite_add_1smb_test(suite, "chained-openx", test_chained);
2243 2354 : torture_suite_add_1smb_test(suite, "chained-ntcreatex", test_chained_ntcreatex_readx);
2244 2354 : torture_suite_add_1smb_test(suite, "no-leading-slash", test_no_leading_slash);
2245 2354 : torture_suite_add_1smb_test(suite, "openx-over-dir", test_openx_over_dir);
2246 2354 : torture_suite_add_1smb_test(suite, "open-for-delete", test_open_for_delete);
2247 2354 : torture_suite_add_1smb_test(suite, "opendisp-dir", test_ntcreatex_opendisp_dir);
2248 2354 : torture_suite_add_1smb_test(suite, "ntcreatedir", test_ntcreatexdir);
2249 2354 : torture_suite_add_1smb_test(suite, "open-for-truncate", test_open_for_truncate);
2250 2354 : torture_suite_add_1smb_test(suite, "ntcreatex_supersede", test_ntcreatex_supersede);
2251 :
2252 2354 : return suite;
2253 : }
|