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 : union smb_open io;
164 : union smb_fileinfo finfo;
165 6 : const char *fname = BASEDIR "\\torture_open.txt";
166 : 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 11 : 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 : union smb_open io;
275 : union smb_fileinfo finfo;
276 6 : const char *fname = BASEDIR "\\torture_openx.txt";
277 6 : const char *fname_exe = BASEDIR "\\torture_openx.exe";
278 : NTSTATUS status;
279 6 : int fnum = -1, fnum2;
280 6 : bool ret = true;
281 : int i;
282 : struct timeval tv;
283 : 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 : union smb_open io;
511 : 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 : NTSTATUS status;
516 : int fnum;
517 6 : bool ret = true;
518 : int i;
519 : 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 78 : 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 11 : 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 : union smb_open io;
683 : union smb_fileinfo finfo;
684 6 : const char *fname = BASEDIR "\\torture_ntcreatex.txt";
685 6 : const char *dname = BASEDIR "\\torture_ntcreatex.dir";
686 : NTSTATUS status;
687 6 : int fnum = -1;
688 6 : bool ret = true;
689 : int i;
690 : 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 5 : 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.alloc_size, 0);
844 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
845 6 : smbcli_unlink(cli->tree, fname);
846 :
847 :
848 6 : done:
849 6 : smbcli_close(cli->tree, fnum);
850 6 : smbcli_deltree(cli->tree, BASEDIR);
851 :
852 6 : return ret;
853 : }
854 :
855 :
856 : /*
857 : test RAW_OPEN_NTTRANS_CREATE
858 : */
859 6 : static bool test_nttrans_create(struct torture_context *tctx, struct smbcli_state *cli)
860 : {
861 : union smb_open io;
862 : union smb_fileinfo finfo;
863 6 : const char *fname = BASEDIR "\\torture_ntcreatex.txt";
864 6 : const char *dname = BASEDIR "\\torture_ntcreatex.dir";
865 : NTSTATUS status;
866 6 : int fnum = -1;
867 6 : bool ret = true;
868 : int i;
869 : uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
870 : uint32_t not_a_directory_mask, unexpected_mask;
871 : struct {
872 : uint32_t open_disp;
873 : bool with_file;
874 : NTSTATUS correct_status;
875 6 : } open_funcs[] = {
876 : { NTCREATEX_DISP_SUPERSEDE, true, NT_STATUS_OK },
877 : { NTCREATEX_DISP_SUPERSEDE, false, NT_STATUS_OK },
878 : { NTCREATEX_DISP_OPEN, true, NT_STATUS_OK },
879 : { NTCREATEX_DISP_OPEN, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
880 : { NTCREATEX_DISP_CREATE, true, NT_STATUS_OBJECT_NAME_COLLISION },
881 : { NTCREATEX_DISP_CREATE, false, NT_STATUS_OK },
882 : { NTCREATEX_DISP_OPEN_IF, true, NT_STATUS_OK },
883 : { NTCREATEX_DISP_OPEN_IF, false, NT_STATUS_OK },
884 : { NTCREATEX_DISP_OVERWRITE, true, NT_STATUS_OK },
885 : { NTCREATEX_DISP_OVERWRITE, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
886 : { NTCREATEX_DISP_OVERWRITE_IF, true, NT_STATUS_OK },
887 : { NTCREATEX_DISP_OVERWRITE_IF, false, NT_STATUS_OK },
888 : { 6, true, NT_STATUS_INVALID_PARAMETER },
889 : { 6, false, NT_STATUS_INVALID_PARAMETER },
890 : };
891 :
892 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
893 :
894 : /* reasonable default parameters */
895 6 : io.generic.level = RAW_OPEN_NTTRANS_CREATE;
896 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
897 6 : io.ntcreatex.in.root_fid.fnum = 0;
898 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
899 6 : io.ntcreatex.in.alloc_size = 1024*1024;
900 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
901 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
902 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
903 6 : io.ntcreatex.in.create_options = 0;
904 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
905 6 : io.ntcreatex.in.security_flags = 0;
906 6 : io.ntcreatex.in.fname = fname;
907 6 : io.ntcreatex.in.sec_desc = NULL;
908 6 : io.ntcreatex.in.ea_list = NULL;
909 :
910 : /* test the open disposition */
911 90 : for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
912 84 : if (open_funcs[i].with_file) {
913 42 : fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
914 42 : if (fnum == -1) {
915 0 : torture_result(tctx, TORTURE_FAIL,
916 : "Failed to create file %s - %s\n",
917 : fname, smbcli_errstr(cli->tree));
918 0 : ret = false;
919 0 : goto done;
920 : }
921 42 : smbcli_close(cli->tree, fnum);
922 : }
923 84 : io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
924 84 : status = smb_raw_open(cli->tree, tctx, &io);
925 84 : if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
926 0 : torture_result(tctx, TORTURE_FAIL,
927 : "(%s) incorrect status %s should be %s "
928 : "(i=%d with_file=%d open_disp=%d)\n",
929 : __location__, nt_errstr(status),
930 : nt_errstr(open_funcs[i].correct_status),
931 0 : i, (int)open_funcs[i].with_file,
932 0 : (int)open_funcs[i].open_disp);
933 0 : ret = false;
934 : }
935 84 : if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
936 66 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
937 66 : smbcli_unlink(cli->tree, fname);
938 : }
939 : }
940 :
941 : /* basic field testing */
942 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
943 :
944 6 : status = smb_raw_open(cli->tree, tctx, &io);
945 6 : CHECK_STATUS(status, NT_STATUS_OK);
946 6 : fnum = io.ntcreatex.out.file.fnum;
947 :
948 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
949 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
950 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
951 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
952 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
953 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
954 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
955 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
956 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
957 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
958 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
959 :
960 : /* check fields when the file already existed */
961 6 : smbcli_close(cli->tree, fnum);
962 6 : smbcli_unlink(cli->tree, fname);
963 6 : fnum = create_complex_file(cli, tctx, fname);
964 6 : if (fnum == -1) {
965 0 : ret = false;
966 0 : goto done;
967 : }
968 6 : smbcli_close(cli->tree, fnum);
969 :
970 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
971 6 : status = smb_raw_open(cli->tree, tctx, &io);
972 6 : CHECK_STATUS(status, NT_STATUS_OK);
973 6 : fnum = io.ntcreatex.out.file.fnum;
974 :
975 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
976 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
977 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
978 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
979 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
980 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
981 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
982 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
983 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
984 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
985 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
986 6 : smbcli_close(cli->tree, fnum);
987 :
988 : /* check no-recall - don't pull a file from tape on a HSM */
989 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NO_RECALL;
990 6 : status = smb_raw_open(cli->tree, tctx, &io);
991 6 : CHECK_STATUS(status, NT_STATUS_OK);
992 6 : fnum = io.ntcreatex.out.file.fnum;
993 :
994 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
995 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
996 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
997 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
998 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
999 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
1000 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1001 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1002 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1003 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1004 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1005 6 : smbcli_close(cli->tree, fnum);
1006 :
1007 : /* Check some create options (these all should be ignored) */
1008 198 : for (i=0; i < 32; i++) {
1009 192 : uint32_t create_option =
1010 192 : ((uint32_t)1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
1011 192 : if (create_option == 0) {
1012 150 : continue;
1013 : }
1014 42 : io.ntcreatex.in.create_options = create_option;
1015 42 : status = smb_raw_open(cli->tree, tctx, &io);
1016 42 : if (!NT_STATUS_IS_OK(status)) {
1017 0 : torture_warning(tctx, "ntcreatex create option 0x%08x "
1018 : "gave %s - should give NT_STATUS_OK\n",
1019 : create_option, nt_errstr(status));
1020 : }
1021 42 : CHECK_STATUS(status, NT_STATUS_OK);
1022 42 : fnum = io.ntcreatex.out.file.fnum;
1023 :
1024 42 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1025 42 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
1026 42 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
1027 42 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
1028 42 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
1029 42 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
1030 42 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1031 42 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1032 42 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1033 42 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1034 42 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1035 42 : smbcli_close(cli->tree, fnum);
1036 : }
1037 :
1038 6 : io.ntcreatex.in.file_attr = 0;
1039 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1040 6 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1041 :
1042 : /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */
1043 6 : ok_mask = 0;
1044 6 : not_supported_mask = 0;
1045 6 : invalid_parameter_mask = 0;
1046 6 : not_a_directory_mask = 0;
1047 6 : unexpected_mask = 0;
1048 198 : for (i=0; i < 32; i++) {
1049 192 : uint32_t create_option = (uint32_t)1<<i;
1050 192 : if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
1051 6 : continue;
1052 : }
1053 186 : io.ntcreatex.in.create_options = create_option;
1054 186 : status = smb_raw_open(cli->tree, tctx, &io);
1055 186 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1056 6 : not_supported_mask |= create_option;
1057 180 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1058 108 : ok_mask |= create_option;
1059 108 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1060 72 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1061 66 : invalid_parameter_mask |= create_option;
1062 6 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1063 6 : not_a_directory_mask |= 1<<i;
1064 : } else {
1065 0 : unexpected_mask |= 1<<i;
1066 0 : torture_comment(tctx, "create option 0x%08x returned %s\n",
1067 : create_option, nt_errstr(status));
1068 : }
1069 : }
1070 :
1071 6 : CHECK_VAL(ok_mask, 0x00efcfce);
1072 6 : CHECK_VAL(not_a_directory_mask, 0x00000001);
1073 6 : CHECK_VAL(not_supported_mask, 0x00002000);
1074 6 : CHECK_VAL(invalid_parameter_mask, 0xff100030);
1075 6 : CHECK_VAL(unexpected_mask, 0x00000000);
1076 :
1077 6 : smbcli_unlink(cli->tree, fname);
1078 :
1079 :
1080 : /* create a directory */
1081 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1082 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1083 6 : io.ntcreatex.in.alloc_size = 0;
1084 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1085 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1086 5 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1087 6 : io.ntcreatex.in.create_options = 0;
1088 6 : io.ntcreatex.in.fname = dname;
1089 6 : fname = dname;
1090 :
1091 6 : smbcli_rmdir(cli->tree, fname);
1092 6 : smbcli_unlink(cli->tree, fname);
1093 :
1094 6 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1095 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1096 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1097 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1098 6 : status = smb_raw_open(cli->tree, tctx, &io);
1099 6 : CHECK_STATUS(status, NT_STATUS_OK);
1100 6 : fnum = io.ntcreatex.out.file.fnum;
1101 :
1102 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1103 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
1104 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
1105 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
1106 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
1107 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
1108 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1109 6 : CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
1110 : FILE_ATTRIBUTE_DIRECTORY);
1111 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1112 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1113 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1114 6 : CHECK_VAL(io.ntcreatex.out.is_directory, 1);
1115 6 : CHECK_VAL(io.ntcreatex.out.size, 0);
1116 6 : CHECK_VAL(io.ntcreatex.out.alloc_size, 0);
1117 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1118 6 : smbcli_unlink(cli->tree, fname);
1119 :
1120 :
1121 6 : done:
1122 6 : smbcli_close(cli->tree, fnum);
1123 6 : smbcli_deltree(cli->tree, BASEDIR);
1124 :
1125 6 : return ret;
1126 : }
1127 :
1128 : /*
1129 : test RAW_OPEN_NTCREATEX with an already opened and byte range locked file
1130 :
1131 : I've got an application that does a similar sequence of ntcreate&x,
1132 : locking&x and another ntcreate&x with
1133 : open_disposition==NTCREATEX_DISP_OVERWRITE_IF. Windows 2003 allows the
1134 : second open.
1135 : */
1136 6 : static bool test_ntcreatex_brlocked(struct torture_context *tctx, struct smbcli_state *cli)
1137 : {
1138 : union smb_open io, io1;
1139 : union smb_lock io2;
1140 : struct smb_lock_entry lock[1];
1141 6 : const char *fname = BASEDIR "\\torture_ntcreatex.txt";
1142 : NTSTATUS status;
1143 6 : bool ret = true;
1144 :
1145 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1146 :
1147 6 : torture_comment(tctx, "Testing ntcreatex with a byte range locked file\n");
1148 :
1149 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1150 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1151 6 : io.ntcreatex.in.root_fid.fnum = 0;
1152 6 : io.ntcreatex.in.access_mask = 0x2019f;
1153 6 : io.ntcreatex.in.alloc_size = 0;
1154 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1155 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1156 : NTCREATEX_SHARE_ACCESS_WRITE;
1157 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1158 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
1159 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1160 6 : io.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
1161 : NTCREATEX_SECURITY_ALL;
1162 6 : io.ntcreatex.in.fname = fname;
1163 :
1164 6 : status = smb_raw_open(cli->tree, tctx, &io);
1165 6 : CHECK_STATUS(status, NT_STATUS_OK);
1166 :
1167 6 : io2.lockx.level = RAW_LOCK_LOCKX;
1168 6 : io2.lockx.in.file.fnum = io.ntcreatex.out.file.fnum;
1169 6 : io2.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
1170 6 : io2.lockx.in.timeout = 0;
1171 6 : io2.lockx.in.ulock_cnt = 0;
1172 6 : io2.lockx.in.lock_cnt = 1;
1173 6 : lock[0].pid = cli->session->pid;
1174 6 : lock[0].offset = 0;
1175 6 : lock[0].count = 0x1;
1176 6 : io2.lockx.in.locks = &lock[0];
1177 6 : status = smb_raw_lock(cli->tree, &io2);
1178 6 : CHECK_STATUS(status, NT_STATUS_OK);
1179 :
1180 6 : io1.generic.level = RAW_OPEN_NTCREATEX;
1181 6 : io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1182 6 : io1.ntcreatex.in.root_fid.fnum = 0;
1183 6 : io1.ntcreatex.in.access_mask = 0x20196;
1184 6 : io1.ntcreatex.in.alloc_size = 0;
1185 6 : io1.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1186 6 : io1.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1187 : NTCREATEX_SHARE_ACCESS_WRITE;
1188 6 : io1.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1189 6 : io1.ntcreatex.in.create_options = 0;
1190 6 : io1.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1191 6 : io1.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
1192 : NTCREATEX_SECURITY_ALL;
1193 6 : io1.ntcreatex.in.fname = fname;
1194 :
1195 6 : status = smb_raw_open(cli->tree, tctx, &io1);
1196 6 : CHECK_STATUS(status, NT_STATUS_OK);
1197 :
1198 11 : done:
1199 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1200 6 : smbcli_close(cli->tree, io1.ntcreatex.out.file.fnum);
1201 6 : smbcli_deltree(cli->tree, BASEDIR);
1202 6 : return ret;
1203 : }
1204 :
1205 : /*
1206 : test RAW_OPEN_MKNEW
1207 : */
1208 6 : static bool test_mknew(struct torture_context *tctx, struct smbcli_state *cli)
1209 : {
1210 : union smb_open io;
1211 6 : const char *fname = BASEDIR "\\torture_mknew.txt";
1212 : NTSTATUS status;
1213 6 : int fnum = -1;
1214 6 : bool ret = true;
1215 6 : time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1216 : union smb_fileinfo finfo;
1217 :
1218 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1219 :
1220 6 : io.mknew.level = RAW_OPEN_MKNEW;
1221 6 : io.mknew.in.attrib = 0;
1222 6 : io.mknew.in.write_time = 0;
1223 6 : io.mknew.in.fname = fname;
1224 6 : status = smb_raw_open(cli->tree, tctx, &io);
1225 6 : CHECK_STATUS(status, NT_STATUS_OK);
1226 6 : fnum = io.mknew.out.file.fnum;
1227 :
1228 6 : status = smb_raw_open(cli->tree, tctx, &io);
1229 6 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
1230 :
1231 6 : smbcli_close(cli->tree, fnum);
1232 6 : smbcli_unlink(cli->tree, fname);
1233 :
1234 : /* make sure write_time works */
1235 6 : io.mknew.in.write_time = basetime;
1236 6 : status = smb_raw_open(cli->tree, tctx, &io);
1237 6 : CHECK_STATUS(status, NT_STATUS_OK);
1238 6 : fnum = io.mknew.out.file.fnum;
1239 6 : CHECK_TIME(basetime, write_time);
1240 :
1241 6 : smbcli_close(cli->tree, fnum);
1242 6 : smbcli_unlink(cli->tree, fname);
1243 :
1244 : /* make sure file_attrs works */
1245 6 : io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1246 6 : status = smb_raw_open(cli->tree, tctx, &io);
1247 6 : CHECK_STATUS(status, NT_STATUS_OK);
1248 6 : fnum = io.mknew.out.file.fnum;
1249 6 : CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE,
1250 : attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1251 :
1252 11 : done:
1253 6 : smbcli_close(cli->tree, fnum);
1254 6 : smbcli_deltree(cli->tree, BASEDIR);
1255 :
1256 6 : return ret;
1257 : }
1258 :
1259 :
1260 : /*
1261 : test RAW_OPEN_CREATE
1262 : */
1263 6 : static bool test_create(struct torture_context *tctx, struct smbcli_state *cli)
1264 : {
1265 : union smb_open io;
1266 6 : const char *fname = BASEDIR "\\torture_create.txt";
1267 : NTSTATUS status;
1268 6 : int fnum = -1;
1269 6 : bool ret = true;
1270 6 : time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1271 : union smb_fileinfo finfo;
1272 :
1273 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1274 :
1275 6 : io.create.level = RAW_OPEN_CREATE;
1276 6 : io.create.in.attrib = 0;
1277 6 : io.create.in.write_time = 0;
1278 6 : io.create.in.fname = fname;
1279 6 : status = smb_raw_open(cli->tree, tctx, &io);
1280 6 : CHECK_STATUS(status, NT_STATUS_OK);
1281 6 : fnum = io.create.out.file.fnum;
1282 :
1283 6 : status = smb_raw_open(cli->tree, tctx, &io);
1284 6 : CHECK_STATUS(status, NT_STATUS_OK);
1285 :
1286 6 : smbcli_close(cli->tree, io.create.out.file.fnum);
1287 6 : smbcli_close(cli->tree, fnum);
1288 6 : smbcli_unlink(cli->tree, fname);
1289 :
1290 : /* make sure write_time works */
1291 6 : io.create.in.write_time = basetime;
1292 6 : status = smb_raw_open(cli->tree, tctx, &io);
1293 6 : CHECK_STATUS(status, NT_STATUS_OK);
1294 6 : fnum = io.create.out.file.fnum;
1295 6 : CHECK_TIME(basetime, write_time);
1296 :
1297 6 : smbcli_close(cli->tree, fnum);
1298 6 : smbcli_unlink(cli->tree, fname);
1299 :
1300 : /* make sure file_attrs works */
1301 6 : io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1302 6 : status = smb_raw_open(cli->tree, tctx, &io);
1303 6 : CHECK_STATUS(status, NT_STATUS_OK);
1304 6 : fnum = io.create.out.file.fnum;
1305 6 : CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE,
1306 : attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1307 :
1308 11 : done:
1309 6 : smbcli_close(cli->tree, fnum);
1310 6 : smbcli_deltree(cli->tree, BASEDIR);
1311 :
1312 6 : return ret;
1313 : }
1314 :
1315 :
1316 : /*
1317 : test RAW_OPEN_CTEMP
1318 : */
1319 6 : static bool test_ctemp(struct torture_context *tctx, struct smbcli_state *cli)
1320 : {
1321 : union smb_open io;
1322 : NTSTATUS status;
1323 6 : int fnum = -1;
1324 6 : bool ret = true;
1325 6 : time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1326 : union smb_fileinfo finfo;
1327 6 : const char *name, *fname = NULL;
1328 :
1329 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1330 :
1331 6 : io.ctemp.level = RAW_OPEN_CTEMP;
1332 6 : io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1333 6 : io.ctemp.in.write_time = basetime;
1334 6 : io.ctemp.in.directory = BASEDIR;
1335 6 : status = smb_raw_open(cli->tree, tctx, &io);
1336 6 : CHECK_STATUS(status, NT_STATUS_OK);
1337 6 : fnum = io.ctemp.out.file.fnum;
1338 :
1339 6 : name = io.ctemp.out.name;
1340 :
1341 6 : finfo.generic.level = RAW_FILEINFO_NAME_INFO;
1342 6 : finfo.generic.in.file.fnum = fnum;
1343 6 : status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1344 6 : CHECK_STATUS(status, NT_STATUS_OK);
1345 :
1346 6 : fname = finfo.name_info.out.fname.s;
1347 6 : torture_comment(tctx, "ctemp name=%s real name=%s\n", name, fname);
1348 :
1349 6 : done:
1350 6 : smbcli_close(cli->tree, fnum);
1351 6 : smbcli_deltree(cli->tree, BASEDIR);
1352 :
1353 6 : return ret;
1354 : }
1355 :
1356 :
1357 : /*
1358 : test chained RAW_OPEN_OPENX_READX
1359 : */
1360 6 : static bool test_chained(struct torture_context *tctx, struct smbcli_state *cli)
1361 : {
1362 : union smb_open io;
1363 6 : const char *fname = BASEDIR "\\torture_chained.txt";
1364 : NTSTATUS status;
1365 6 : int fnum = -1;
1366 6 : bool ret = true;
1367 6 : const char buf[] = "test";
1368 : char buf2[4];
1369 :
1370 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1371 :
1372 6 : fnum = create_complex_file(cli, tctx, fname);
1373 :
1374 6 : smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1375 :
1376 6 : smbcli_close(cli->tree, fnum);
1377 :
1378 6 : io.openxreadx.level = RAW_OPEN_OPENX_READX;
1379 6 : io.openxreadx.in.fname = fname;
1380 6 : io.openxreadx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1381 6 : io.openxreadx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1382 6 : io.openxreadx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1383 6 : io.openxreadx.in.search_attrs = 0;
1384 6 : io.openxreadx.in.file_attrs = 0;
1385 6 : io.openxreadx.in.write_time = 0;
1386 6 : io.openxreadx.in.size = 1024*1024;
1387 6 : io.openxreadx.in.timeout = 0;
1388 :
1389 6 : io.openxreadx.in.offset = 0;
1390 6 : io.openxreadx.in.mincnt = sizeof(buf2);
1391 6 : io.openxreadx.in.maxcnt = sizeof(buf2);
1392 6 : io.openxreadx.in.remaining = 0;
1393 6 : io.openxreadx.out.data = (uint8_t *)buf2;
1394 :
1395 6 : status = smb_raw_open(cli->tree, tctx, &io);
1396 6 : CHECK_STATUS(status, NT_STATUS_OK);
1397 6 : fnum = io.openxreadx.out.file.fnum;
1398 :
1399 6 : if (memcmp(buf, buf2, MIN(sizeof(buf), sizeof(buf2))) != 0) {
1400 0 : torture_result(tctx, TORTURE_FAIL,
1401 : "wrong data in reply buffer\n");
1402 0 : ret = false;
1403 : }
1404 :
1405 11 : done:
1406 6 : smbcli_close(cli->tree, fnum);
1407 6 : smbcli_deltree(cli->tree, BASEDIR);
1408 :
1409 6 : return ret;
1410 : }
1411 :
1412 : /*
1413 : test RAW_OPEN_OPENX without a leading slash on the path.
1414 : NetApp filers are known to fail on this.
1415 :
1416 : */
1417 6 : static bool test_no_leading_slash(struct torture_context *tctx, struct smbcli_state *cli)
1418 : {
1419 : union smb_open io;
1420 6 : const char *fname = BASEDIR "\\torture_no_leading_slash.txt";
1421 : NTSTATUS status;
1422 6 : int fnum = -1;
1423 6 : bool ret = true;
1424 6 : const char buf[] = "test";
1425 :
1426 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1427 :
1428 6 : smbcli_unlink(cli->tree, fname);
1429 :
1430 : /* Create the file */
1431 6 : fnum = create_complex_file(cli, tctx, fname);
1432 6 : smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1433 6 : smbcli_close(cli->tree, fnum);
1434 :
1435 : /* Prepare to open the file using path without leading slash */
1436 6 : io.openx.level = RAW_OPEN_OPENX;
1437 6 : io.openx.in.fname = fname + 1;
1438 6 : io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1439 6 : io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1440 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1441 6 : io.openx.in.search_attrs = 0;
1442 6 : io.openx.in.file_attrs = 0;
1443 6 : io.openx.in.write_time = 0;
1444 6 : io.openx.in.size = 1024*1024;
1445 6 : io.openx.in.timeout = 0;
1446 :
1447 6 : status = smb_raw_open(cli->tree, tctx, &io);
1448 6 : CHECK_STATUS(status, NT_STATUS_OK);
1449 6 : fnum = io.openx.out.file.fnum;
1450 :
1451 6 : done:
1452 6 : smbcli_close(cli->tree, fnum);
1453 6 : smbcli_deltree(cli->tree, BASEDIR);
1454 :
1455 6 : return ret;
1456 : }
1457 :
1458 : /*
1459 : test RAW_OPEN_OPENX against an existing directory to
1460 : ensure it returns NT_STATUS_FILE_IS_A_DIRECTORY.
1461 : Samba 3.2.0 - 3.2.6 are known to fail this.
1462 :
1463 : */
1464 6 : static bool test_openx_over_dir(struct torture_context *tctx, struct smbcli_state *cli)
1465 : {
1466 : union smb_open io;
1467 6 : const char *fname = BASEDIR "\\openx_over_dir";
1468 : NTSTATUS status;
1469 6 : int d_fnum = -1;
1470 6 : int fnum = -1;
1471 6 : bool ret = true;
1472 :
1473 6 : ZERO_STRUCT(io);
1474 :
1475 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1476 :
1477 : /* Create the Directory */
1478 6 : status = create_directory_handle(cli->tree, fname, &d_fnum);
1479 6 : smbcli_close(cli->tree, d_fnum);
1480 :
1481 : /* Prepare to open the file over the directory. */
1482 6 : io.openx.level = RAW_OPEN_OPENX;
1483 6 : io.openx.in.fname = fname;
1484 6 : io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1485 6 : io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1486 6 : io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1487 6 : io.openx.in.search_attrs = 0;
1488 6 : io.openx.in.file_attrs = 0;
1489 6 : io.openx.in.write_time = 0;
1490 6 : io.openx.in.size = 1024*1024;
1491 6 : io.openx.in.timeout = 0;
1492 :
1493 6 : status = smb_raw_open(cli->tree, tctx, &io);
1494 6 : CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
1495 6 : fnum = io.openx.out.file.fnum;
1496 :
1497 6 : done:
1498 6 : smbcli_close(cli->tree, fnum);
1499 6 : smbcli_deltree(cli->tree, BASEDIR);
1500 :
1501 6 : return ret;
1502 : }
1503 :
1504 :
1505 : /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
1506 :
1507 6 : static bool test_raw_open_multi(struct torture_context *tctx, struct smbcli_state *cli_ignored)
1508 : {
1509 : struct smbcli_state *cli;
1510 6 : TALLOC_CTX *mem_ctx = talloc_init("torture_test_oplock_multi");
1511 6 : const char *fname = "\\test_oplock.dat";
1512 : NTSTATUS status;
1513 6 : bool ret = true;
1514 : union smb_open io;
1515 : struct smbcli_state **clients;
1516 : struct smbcli_request **requests;
1517 : union smb_open *ios;
1518 6 : const char *host = torture_setting_string(tctx, "host", NULL);
1519 6 : const char *share = torture_setting_string(tctx, "share", NULL);
1520 6 : int i, num_files = 3;
1521 6 : int num_ok = 0;
1522 6 : int num_collision = 0;
1523 :
1524 6 : clients = talloc_array(mem_ctx, struct smbcli_state *, num_files);
1525 6 : requests = talloc_array(mem_ctx, struct smbcli_request *, num_files);
1526 6 : ios = talloc_array(mem_ctx, union smb_open, num_files);
1527 6 : if ((tctx->ev == NULL) || (clients == NULL) || (requests == NULL) ||
1528 : (ios == NULL)) {
1529 0 : torture_result(tctx, TORTURE_FAIL, "(%s): talloc failed\n",
1530 : __location__);
1531 0 : return false;
1532 : }
1533 :
1534 6 : if (!torture_open_connection_share(mem_ctx, &cli, tctx, host, share, tctx->ev)) {
1535 0 : return false;
1536 : }
1537 :
1538 6 : cli->tree->session->transport->options.request_timeout = 60;
1539 :
1540 24 : for (i=0; i<num_files; i++) {
1541 18 : if (!torture_open_connection_share(mem_ctx, &(clients[i]),
1542 : tctx, host, share, tctx->ev)) {
1543 0 : torture_result(tctx, TORTURE_FAIL,
1544 : "(%s): Could not open %d'th connection\n",
1545 : __location__, i);
1546 0 : return false;
1547 : }
1548 18 : clients[i]->tree->session->transport->options.request_timeout = 60;
1549 : }
1550 :
1551 : /* cleanup */
1552 6 : smbcli_unlink(cli->tree, fname);
1553 :
1554 : /*
1555 : base ntcreatex parms
1556 : */
1557 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1558 6 : io.ntcreatex.in.root_fid.fnum = 0;
1559 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1560 6 : io.ntcreatex.in.alloc_size = 0;
1561 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1562 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1563 : NTCREATEX_SHARE_ACCESS_WRITE|
1564 : NTCREATEX_SHARE_ACCESS_DELETE;
1565 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1566 6 : io.ntcreatex.in.create_options = 0;
1567 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1568 6 : io.ntcreatex.in.security_flags = 0;
1569 6 : io.ntcreatex.in.fname = fname;
1570 6 : io.ntcreatex.in.flags = 0;
1571 :
1572 24 : for (i=0; i<num_files; i++) {
1573 18 : ios[i] = io;
1574 18 : requests[i] = smb_raw_open_send(clients[i]->tree, &ios[i]);
1575 18 : if (requests[i] == NULL) {
1576 0 : torture_result(tctx, TORTURE_FAIL,
1577 : "(%s): could not send %d'th request\n",
1578 : __location__, i);
1579 0 : return false;
1580 : }
1581 : }
1582 :
1583 6 : torture_comment(tctx, "waiting for replies\n");
1584 45 : while (1) {
1585 60 : bool unreplied = false;
1586 94 : for (i=0; i<num_files; i++) {
1587 88 : if (requests[i] == NULL) {
1588 16 : continue;
1589 : }
1590 72 : if (requests[i]->state < SMBCLI_REQUEST_DONE) {
1591 45 : unreplied = true;
1592 45 : break;
1593 : }
1594 18 : status = smb_raw_open_recv(requests[i], mem_ctx,
1595 18 : &ios[i]);
1596 :
1597 18 : torture_comment(tctx, "File %d returned status %s\n", i,
1598 : nt_errstr(status));
1599 :
1600 18 : if (NT_STATUS_IS_OK(status)) {
1601 6 : num_ok += 1;
1602 : }
1603 :
1604 18 : if (NT_STATUS_EQUAL(status,
1605 : NT_STATUS_OBJECT_NAME_COLLISION)) {
1606 12 : num_collision += 1;
1607 : }
1608 :
1609 18 : requests[i] = NULL;
1610 : }
1611 60 : if (!unreplied) {
1612 5 : break;
1613 : }
1614 :
1615 54 : if (tevent_loop_once(tctx->ev) != 0) {
1616 0 : torture_result(tctx, TORTURE_FAIL,
1617 : "(%s): tevent_loop_once failed\n", __location__);
1618 0 : return false;
1619 : }
1620 : }
1621 :
1622 6 : if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
1623 0 : ret = false;
1624 : }
1625 :
1626 24 : for (i=0; i<num_files; i++) {
1627 18 : torture_close_connection(clients[i]);
1628 : }
1629 6 : talloc_free(mem_ctx);
1630 6 : return ret;
1631 : }
1632 :
1633 : /*
1634 : test opening for delete on a read-only attribute file.
1635 : */
1636 6 : static bool test_open_for_delete(struct torture_context *tctx, struct smbcli_state *cli)
1637 : {
1638 : union smb_open io;
1639 : union smb_fileinfo finfo;
1640 6 : const char *fname = BASEDIR "\\torture_open_for_delete.txt";
1641 : NTSTATUS status;
1642 6 : int fnum = -1;
1643 6 : bool ret = true;
1644 :
1645 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1646 :
1647 : /* reasonable default parameters */
1648 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1649 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1650 6 : io.ntcreatex.in.root_fid.fnum = 0;
1651 6 : io.ntcreatex.in.alloc_size = 0;
1652 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1653 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_READONLY;
1654 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1655 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1656 6 : io.ntcreatex.in.create_options = 0;
1657 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1658 6 : io.ntcreatex.in.security_flags = 0;
1659 6 : io.ntcreatex.in.fname = fname;
1660 :
1661 : /* Create the readonly file. */
1662 :
1663 6 : status = smb_raw_open(cli->tree, tctx, &io);
1664 6 : CHECK_STATUS(status, NT_STATUS_OK);
1665 6 : fnum = io.ntcreatex.out.file.fnum;
1666 :
1667 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1668 6 : io.ntcreatex.in.create_options = 0;
1669 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
1670 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1671 6 : smbcli_close(cli->tree, fnum);
1672 :
1673 : /* Now try and open for delete only - should succeed. */
1674 6 : io.ntcreatex.in.access_mask = SEC_STD_DELETE;
1675 6 : io.ntcreatex.in.file_attr = 0;
1676 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
1677 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1678 6 : status = smb_raw_open(cli->tree, tctx, &io);
1679 6 : CHECK_STATUS(status, NT_STATUS_OK);
1680 :
1681 6 : smbcli_unlink(cli->tree, fname);
1682 :
1683 6 : done:
1684 6 : smbcli_close(cli->tree, fnum);
1685 6 : smbcli_deltree(cli->tree, BASEDIR);
1686 :
1687 6 : return ret;
1688 : }
1689 :
1690 : /*
1691 : test chained RAW_OPEN_NTCREATEX_READX
1692 : Send chained NTCREATEX_READX on a file that doesn't exist, then create
1693 : the file and try again.
1694 : */
1695 6 : static bool test_chained_ntcreatex_readx(struct torture_context *tctx, struct smbcli_state *cli)
1696 : {
1697 6 : TALLOC_CTX *mem_ctx = talloc_new(tctx);
1698 : union smb_open io;
1699 6 : const char *fname = BASEDIR "\\torture_chained.txt";
1700 : NTSTATUS status;
1701 6 : int fnum = -1;
1702 6 : bool ret = true;
1703 6 : const char buf[] = "test";
1704 : char buf2[4];
1705 :
1706 6 : ZERO_STRUCT(io);
1707 :
1708 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1709 :
1710 6 : torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
1711 : "non-existent file \n");
1712 :
1713 : /* ntcreatex parameters */
1714 6 : io.generic.level = RAW_OPEN_NTCREATEX_READX;
1715 6 : io.ntcreatexreadx.in.flags = 0;
1716 6 : io.ntcreatexreadx.in.root_fid.fnum = 0;
1717 6 : io.ntcreatexreadx.in.access_mask = SEC_FILE_READ_DATA;
1718 6 : io.ntcreatexreadx.in.alloc_size = 0;
1719 6 : io.ntcreatexreadx.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1720 6 : io.ntcreatexreadx.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1721 : NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
1722 6 : io.ntcreatexreadx.in.open_disposition = NTCREATEX_DISP_OPEN;
1723 6 : io.ntcreatexreadx.in.create_options = 0;
1724 6 : io.ntcreatexreadx.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1725 6 : io.ntcreatexreadx.in.security_flags = 0;
1726 6 : io.ntcreatexreadx.in.fname = fname;
1727 :
1728 : /* readx parameters */
1729 6 : io.ntcreatexreadx.in.offset = 0;
1730 6 : io.ntcreatexreadx.in.mincnt = sizeof(buf2);
1731 6 : io.ntcreatexreadx.in.maxcnt = sizeof(buf2);
1732 6 : io.ntcreatexreadx.in.remaining = 0;
1733 6 : io.ntcreatexreadx.out.data = (uint8_t *)buf2;
1734 :
1735 : /* try to open the non-existent file */
1736 6 : status = smb_raw_open(cli->tree, mem_ctx, &io);
1737 6 : CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1738 6 : fnum = io.ntcreatexreadx.out.file.fnum;
1739 :
1740 6 : smbcli_close(cli->tree, fnum);
1741 6 : smbcli_unlink(cli->tree, fname);
1742 :
1743 6 : torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
1744 : "existing file \n");
1745 :
1746 6 : fnum = create_complex_file(cli, mem_ctx, fname);
1747 6 : smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1748 6 : smbcli_close(cli->tree, fnum);
1749 :
1750 6 : status = smb_raw_open(cli->tree, mem_ctx, &io);
1751 6 : CHECK_STATUS(status, NT_STATUS_OK);
1752 6 : fnum = io.ntcreatexreadx.out.file.fnum;
1753 :
1754 6 : if (memcmp(buf, buf2, MIN(sizeof(buf), sizeof(buf2))) != 0) {
1755 0 : torture_result(tctx, TORTURE_FAIL,
1756 : "(%s): wrong data in reply buffer\n", __location__);
1757 0 : ret = false;
1758 : }
1759 :
1760 11 : done:
1761 6 : smbcli_close(cli->tree, fnum);
1762 6 : smbcli_deltree(cli->tree, BASEDIR);
1763 6 : talloc_free(mem_ctx);
1764 :
1765 6 : return ret;
1766 : }
1767 :
1768 6 : static bool test_ntcreatex_opendisp_dir(struct torture_context *tctx,
1769 : struct smbcli_state *cli)
1770 : {
1771 6 : const char *dname = BASEDIR "\\torture_ntcreatex_opendisp_dir";
1772 : NTSTATUS status;
1773 6 : bool ret = true;
1774 : int i;
1775 : struct {
1776 : uint32_t open_disp;
1777 : bool dir_exists;
1778 : NTSTATUS correct_status;
1779 6 : } open_funcs_dir[] = {
1780 : { NTCREATEX_DISP_SUPERSEDE, true, NT_STATUS_INVALID_PARAMETER },
1781 : { NTCREATEX_DISP_SUPERSEDE, false, NT_STATUS_INVALID_PARAMETER },
1782 : { NTCREATEX_DISP_OPEN, true, NT_STATUS_OK },
1783 : { NTCREATEX_DISP_OPEN, false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
1784 : { NTCREATEX_DISP_CREATE, true, NT_STATUS_OBJECT_NAME_COLLISION },
1785 : { NTCREATEX_DISP_CREATE, false, NT_STATUS_OK },
1786 : { NTCREATEX_DISP_OPEN_IF, true, NT_STATUS_OK },
1787 : { NTCREATEX_DISP_OPEN_IF, false, NT_STATUS_OK },
1788 : { NTCREATEX_DISP_OVERWRITE, true, NT_STATUS_INVALID_PARAMETER },
1789 : { NTCREATEX_DISP_OVERWRITE, false, NT_STATUS_INVALID_PARAMETER },
1790 : { NTCREATEX_DISP_OVERWRITE_IF, true, NT_STATUS_INVALID_PARAMETER },
1791 : { NTCREATEX_DISP_OVERWRITE_IF, false, NT_STATUS_INVALID_PARAMETER },
1792 : { 6, true, NT_STATUS_INVALID_PARAMETER },
1793 : { 6, false, NT_STATUS_INVALID_PARAMETER },
1794 : };
1795 : union smb_open io;
1796 :
1797 6 : ZERO_STRUCT(io);
1798 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1799 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1800 6 : io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1801 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1802 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1803 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1804 6 : io.ntcreatex.in.fname = dname;
1805 :
1806 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1807 :
1808 6 : smbcli_rmdir(cli->tree, dname);
1809 6 : smbcli_unlink(cli->tree, dname);
1810 :
1811 : /* test the open disposition for directories */
1812 6 : torture_comment(tctx, "Testing open dispositions for directories...\n");
1813 :
1814 90 : for (i=0; i<ARRAY_SIZE(open_funcs_dir); i++) {
1815 84 : if (open_funcs_dir[i].dir_exists) {
1816 42 : status = smbcli_mkdir(cli->tree, dname);
1817 42 : if (!NT_STATUS_IS_OK(status)) {
1818 0 : torture_result(tctx, TORTURE_FAIL,
1819 : "(%s): Failed to make directory "
1820 : "%s - %s\n", __location__, dname,
1821 : smbcli_errstr(cli->tree));
1822 0 : ret = false;
1823 0 : goto done;
1824 : }
1825 : }
1826 :
1827 84 : io.ntcreatex.in.open_disposition = open_funcs_dir[i].open_disp;
1828 84 : status = smb_raw_open(cli->tree, tctx, &io);
1829 84 : if (!NT_STATUS_EQUAL(status, open_funcs_dir[i].correct_status)) {
1830 0 : torture_result(tctx, TORTURE_FAIL,
1831 : "(%s) incorrect status %s should be %s "
1832 : "(i=%d dir_exists=%d open_disp=%d)\n",
1833 : __location__, nt_errstr(status),
1834 : nt_errstr(open_funcs_dir[i].correct_status),
1835 0 : i, (int)open_funcs_dir[i].dir_exists,
1836 0 : (int)open_funcs_dir[i].open_disp);
1837 0 : ret = false;
1838 : }
1839 84 : if (NT_STATUS_IS_OK(status) || open_funcs_dir[i].dir_exists) {
1840 54 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1841 54 : smbcli_rmdir(cli->tree, dname);
1842 : }
1843 : }
1844 :
1845 6 : done:
1846 6 : smbcli_deltree(cli->tree, BASEDIR);
1847 :
1848 6 : return ret;
1849 : }
1850 :
1851 : /**
1852 : * Test what happens when trying to open a file with directory parameters and
1853 : * vice-versa. Also test that NTCREATEX_OPTIONS_DIRECTORY is treated as
1854 : * mandatory and FILE_ATTRIBUTE_DIRECTORY is advisory for directory
1855 : * creation/opening.
1856 : */
1857 6 : static bool test_ntcreatexdir(struct torture_context *tctx,
1858 : struct smbcli_state *cli)
1859 : {
1860 : union smb_open io;
1861 6 : const char *fname = BASEDIR "\\torture_ntcreatex.txt";
1862 6 : const char *dname = BASEDIR "\\torture_ntcreatex_dir";
1863 : NTSTATUS status;
1864 : int i;
1865 :
1866 : struct {
1867 : uint32_t open_disp;
1868 : uint32_t file_attr;
1869 : uint32_t create_options;
1870 : NTSTATUS correct_status;
1871 6 : } open_funcs[] = {
1872 : { NTCREATEX_DISP_SUPERSEDE, 0, NTCREATEX_OPTIONS_DIRECTORY,
1873 : NT_STATUS_INVALID_PARAMETER },
1874 : { NTCREATEX_DISP_OPEN, 0, NTCREATEX_OPTIONS_DIRECTORY,
1875 : NT_STATUS_OBJECT_NAME_NOT_FOUND },
1876 : { NTCREATEX_DISP_CREATE, 0, NTCREATEX_OPTIONS_DIRECTORY,
1877 : NT_STATUS_OK },
1878 : { NTCREATEX_DISP_OPEN_IF, 0, NTCREATEX_OPTIONS_DIRECTORY,
1879 : NT_STATUS_OK },
1880 : { NTCREATEX_DISP_OVERWRITE, 0, NTCREATEX_OPTIONS_DIRECTORY,
1881 : NT_STATUS_INVALID_PARAMETER },
1882 : { NTCREATEX_DISP_OVERWRITE_IF, 0, NTCREATEX_OPTIONS_DIRECTORY,
1883 : NT_STATUS_INVALID_PARAMETER },
1884 : { NTCREATEX_DISP_SUPERSEDE, FILE_ATTRIBUTE_DIRECTORY, 0,
1885 : NT_STATUS_OK },
1886 : { NTCREATEX_DISP_OPEN, FILE_ATTRIBUTE_DIRECTORY, 0,
1887 : NT_STATUS_OBJECT_NAME_NOT_FOUND },
1888 : { NTCREATEX_DISP_CREATE, FILE_ATTRIBUTE_DIRECTORY, 0,
1889 : NT_STATUS_OK },
1890 : { NTCREATEX_DISP_OPEN_IF, FILE_ATTRIBUTE_DIRECTORY, 0,
1891 : NT_STATUS_OK },
1892 : { NTCREATEX_DISP_OVERWRITE, FILE_ATTRIBUTE_DIRECTORY, 0,
1893 : NT_STATUS_OBJECT_NAME_NOT_FOUND },
1894 : { NTCREATEX_DISP_OVERWRITE_IF, FILE_ATTRIBUTE_DIRECTORY, 0,
1895 : NT_STATUS_OK },
1896 :
1897 : };
1898 :
1899 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
1900 :
1901 : /* setup some base params. */
1902 6 : io.generic.level = RAW_OPEN_NTCREATEX;
1903 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1904 6 : io.ntcreatex.in.root_fid.fnum = 0;
1905 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1906 6 : io.ntcreatex.in.alloc_size = 0;
1907 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1908 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1909 6 : io.ntcreatex.in.security_flags = 0;
1910 6 : io.ntcreatex.in.fname = fname;
1911 :
1912 : /*
1913 : * Test the validity checking for create dispositions, which is done
1914 : * against the requested parameters rather than what's actually on
1915 : * disk.
1916 : */
1917 78 : for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
1918 72 : io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
1919 72 : io.ntcreatex.in.file_attr = open_funcs[i].file_attr;
1920 72 : io.ntcreatex.in.create_options = open_funcs[i].create_options;
1921 72 : status = smb_raw_open(cli->tree, tctx, &io);
1922 72 : if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
1923 0 : torture_result(tctx, TORTURE_FAIL,
1924 : "(%s) incorrect status %s should be %s "
1925 : "(i=%d open_disp=%d)\n",
1926 : __location__, nt_errstr(status),
1927 : nt_errstr(open_funcs[i].correct_status),
1928 0 : i, (int)open_funcs[i].open_disp);
1929 0 : return false;
1930 : }
1931 : /* Close and delete the file. */
1932 72 : if (NT_STATUS_IS_OK(status)) {
1933 36 : if (open_funcs[i].create_options != 0) {
1934 : /* out attrib should be a directory. */
1935 12 : torture_assert_int_equal(tctx,
1936 : io.ntcreatex.out.attrib,
1937 : FILE_ATTRIBUTE_DIRECTORY, "should have "
1938 : "created a directory");
1939 :
1940 12 : smbcli_close(cli->tree,
1941 12 : io.ntcreatex.out.file.fnum);
1942 :
1943 : /* Make sure unlink fails. */
1944 12 : status = smbcli_unlink(cli->tree, fname);
1945 12 : torture_assert_ntstatus_equal(tctx, status,
1946 : NT_STATUS_FILE_IS_A_DIRECTORY,
1947 : "unlink should fail for a directory");
1948 :
1949 12 : status = smbcli_rmdir(cli->tree, fname);
1950 12 : torture_assert_ntstatus_ok(tctx, status,
1951 : "rmdir failed");
1952 : } else {
1953 24 : torture_assert_int_equal(tctx,
1954 : io.ntcreatex.out.attrib,
1955 : FILE_ATTRIBUTE_ARCHIVE, "should not have "
1956 : "created a directory");
1957 :
1958 24 : smbcli_close(cli->tree,
1959 24 : io.ntcreatex.out.file.fnum);
1960 :
1961 : /* Make sure rmdir fails. */
1962 24 : status = smbcli_rmdir(cli->tree, fname);
1963 24 : torture_assert_ntstatus_equal(tctx, status,
1964 : NT_STATUS_NOT_A_DIRECTORY,
1965 : "rmdir should fail for a file");
1966 :
1967 24 : status = smbcli_unlink(cli->tree, fname);
1968 24 : torture_assert_ntstatus_ok(tctx, status,
1969 : "unlink failed");
1970 : }
1971 : }
1972 : }
1973 :
1974 : /* Create a file. */
1975 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1976 6 : io.ntcreatex.in.create_options = 0;
1977 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1978 6 : status = smb_raw_open(cli->tree, tctx, &io);
1979 6 : torture_assert_ntstatus_ok(tctx, status, "Failed to create file.");
1980 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1981 :
1982 : /* Try and open the file with file_attr_dir and check the error. */
1983 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1984 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1985 :
1986 6 : status = smb_raw_open(cli->tree, tctx, &io);
1987 6 : torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_DIRECTORY "
1988 : "doesn't produce a hard failure.");
1989 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1990 :
1991 : /* Try and open file with createx_option_dir and check the error. */
1992 6 : io.ntcreatex.in.file_attr = 0;
1993 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1994 :
1995 6 : status = smb_raw_open(cli->tree, tctx, &io);
1996 6 : torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_A_DIRECTORY,
1997 : "NTCREATEX_OPTIONS_DIRECTORY will a file from being opened.");
1998 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1999 :
2000 : /* Delete the file and move onto directory testing. */
2001 6 : smbcli_unlink(cli->tree, fname);
2002 :
2003 : /* Now try some tests on a directory. */
2004 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2005 6 : io.ntcreatex.in.file_attr = 0;
2006 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
2007 6 : io.ntcreatex.in.fname = dname;
2008 :
2009 6 : status = smb_raw_open(cli->tree, tctx, &io);
2010 6 : torture_assert_ntstatus_ok(tctx, status, "Failed to create dir.");
2011 :
2012 : /* out attrib should be a directory. */
2013 6 : torture_assert_int_equal(tctx, io.ntcreatex.out.attrib,
2014 : FILE_ATTRIBUTE_DIRECTORY, "should have created a directory");
2015 :
2016 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2017 :
2018 : /* Try and open it with normal attr and check the error. */
2019 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2020 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2021 :
2022 6 : status = smb_raw_open(cli->tree, tctx, &io);
2023 6 : torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_NORMAL "
2024 : "doesn't produce a hard failure.");
2025 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2026 :
2027 : /* Try and open it with file create_options and check the error. */
2028 6 : io.ntcreatex.in.file_attr = 0;
2029 6 : io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
2030 :
2031 6 : status = smb_raw_open(cli->tree, tctx, &io);
2032 6 : torture_assert_ntstatus_equal(tctx, status,
2033 : NT_STATUS_FILE_IS_A_DIRECTORY,
2034 : "NTCREATEX_OPTIONS_NON_DIRECTORY_FILE should be returned ");
2035 6 : smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
2036 :
2037 6 : smbcli_deltree(cli->tree, BASEDIR);
2038 :
2039 6 : return true;
2040 : }
2041 :
2042 : /*
2043 : test opening with truncate on an already open file
2044 : returns share violation and doesn't truncate the file.
2045 : Regression test for bug #10671.
2046 : */
2047 6 : static bool test_open_for_truncate(struct torture_context *tctx, struct smbcli_state *cli)
2048 : {
2049 : union smb_open io;
2050 : union smb_fileinfo finfo;
2051 6 : const char *fname = BASEDIR "\\torture_open_for_truncate.txt";
2052 : NTSTATUS status;
2053 6 : int fnum = -1;
2054 6 : ssize_t val = 0;
2055 6 : char c = '\0';
2056 6 : bool ret = true;
2057 :
2058 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR),
2059 : "Failed to setup up test directory: " BASEDIR);
2060 :
2061 6 : torture_comment(tctx, "Testing open truncate disposition.\n");
2062 :
2063 : /* reasonable default parameters */
2064 6 : ZERO_STRUCT(io);
2065 6 : io.generic.level = RAW_OPEN_NTCREATEX;
2066 6 : io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
2067 6 : io.ntcreatex.in.root_fid.fnum = 0;
2068 6 : io.ntcreatex.in.alloc_size = 0;
2069 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2070 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2071 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2072 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2073 6 : io.ntcreatex.in.create_options = 0;
2074 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2075 6 : io.ntcreatex.in.security_flags = 0;
2076 6 : io.ntcreatex.in.fname = fname;
2077 :
2078 6 : status = smb_raw_open(cli->tree, tctx, &io);
2079 6 : CHECK_STATUS(status, NT_STATUS_OK);
2080 6 : fnum = io.ntcreatex.out.file.fnum;
2081 :
2082 : /* Write a byte at offset 1k-1. */
2083 6 : val =smbcli_write(cli->tree, fnum, 0, &c, 1023, 1);
2084 6 : torture_assert_int_equal(tctx, val, 1, "write failed\n");
2085 :
2086 : /* Now try and open for read/write with truncate - should fail. */
2087 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE|SEC_RIGHTS_FILE_READ;
2088 6 : io.ntcreatex.in.file_attr = 0;
2089 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
2090 : NTCREATEX_SHARE_ACCESS_WRITE |
2091 : NTCREATEX_SHARE_ACCESS_DELETE;
2092 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
2093 6 : status = smb_raw_open(cli->tree, tctx, &io);
2094 6 : CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
2095 :
2096 : /* Ensure file size is still 1k */
2097 6 : finfo.generic.level = RAW_FILEINFO_GETATTRE;
2098 6 : finfo.generic.in.file.fnum = fnum;
2099 6 : status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
2100 6 : CHECK_STATUS(status, NT_STATUS_OK);
2101 6 : CHECK_VAL(finfo.getattre.out.size, 1024);
2102 :
2103 6 : smbcli_close(cli->tree, fnum);
2104 :
2105 6 : status = smb_raw_open(cli->tree, tctx, &io);
2106 6 : CHECK_STATUS(status, NT_STATUS_OK);
2107 6 : fnum = io.ntcreatex.out.file.fnum;
2108 :
2109 : /* Ensure truncate actually works */
2110 6 : finfo.generic.level = RAW_FILEINFO_GETATTRE;
2111 6 : finfo.generic.in.file.fnum = fnum;
2112 6 : status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
2113 6 : CHECK_STATUS(status, NT_STATUS_OK);
2114 6 : CHECK_VAL(finfo.getattre.out.size, 0);
2115 :
2116 6 : smbcli_close(cli->tree, fnum);
2117 6 : smbcli_unlink(cli->tree, fname);
2118 :
2119 6 : done:
2120 6 : smbcli_close(cli->tree, fnum);
2121 6 : smbcli_deltree(cli->tree, BASEDIR);
2122 :
2123 6 : return ret;
2124 : }
2125 :
2126 : /**
2127 : * Test for file size to be 0 after create with FILE_SUPERSEDE
2128 : */
2129 6 : static bool test_ntcreatex_supersede(struct torture_context *tctx, struct smbcli_state *cli)
2130 : {
2131 : union smb_open io;
2132 : union smb_setfileinfo sfi;
2133 : union smb_fileinfo finfo;
2134 6 : const char *fname = BASEDIR "\\torture_ntcreatex_supersede.txt";
2135 : NTSTATUS status;
2136 6 : int fnum = -1;
2137 6 : bool ret = true;
2138 :
2139 6 : torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
2140 :
2141 : /* reasonable default parameters */
2142 6 : io.generic.level = RAW_OPEN_NTCREATEX;
2143 6 : io.ntcreatex.in.flags = 0;
2144 6 : io.ntcreatex.in.root_fid.fnum = 0;
2145 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2146 6 : io.ntcreatex.in.alloc_size = 0;
2147 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2148 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2149 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
2150 6 : io.ntcreatex.in.create_options = 0;
2151 6 : io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2152 6 : io.ntcreatex.in.security_flags = 0;
2153 6 : io.ntcreatex.in.fname = fname;
2154 :
2155 6 : status = smb_raw_open(cli->tree, tctx, &io);
2156 6 : CHECK_STATUS(status, NT_STATUS_OK);
2157 6 : fnum = io.ntcreatex.out.file.fnum;
2158 :
2159 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
2160 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
2161 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
2162 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
2163 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
2164 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
2165 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
2166 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
2167 6 : CHECK_ALL_INFO(io.ntcreatex.out.size, size);
2168 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
2169 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
2170 :
2171 : /* extend the file size */
2172 6 : ZERO_STRUCT(sfi);
2173 6 : sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
2174 6 : sfi.generic.in.file.fnum = fnum;
2175 6 : sfi.end_of_file_info.in.size = 512;
2176 6 : status = smb_raw_setfileinfo(cli->tree, &sfi);
2177 6 : CHECK_STATUS(status, NT_STATUS_OK);
2178 :
2179 : /* close the file and re-open with to verify new size */
2180 6 : smbcli_close(cli->tree, fnum);
2181 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
2182 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
2183 6 : status = smb_raw_open(cli->tree, tctx, &io);
2184 6 : CHECK_STATUS(status, NT_STATUS_OK);
2185 6 : fnum = io.ntcreatex.out.file.fnum;
2186 :
2187 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
2188 6 : CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
2189 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
2190 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
2191 6 : CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
2192 6 : CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
2193 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
2194 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
2195 6 : CHECK_VAL(io.ntcreatex.out.size, 512);
2196 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
2197 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
2198 :
2199 : /* close and re-open the file with SUPERSEDE flag */
2200 6 : smbcli_close(cli->tree, fnum);
2201 6 : io.ntcreatex.in.open_disposition = NTCREATEX_DISP_SUPERSEDE;
2202 6 : io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
2203 6 : io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2204 6 : io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2205 6 : io.ntcreatex.in.create_options = 0;
2206 :
2207 6 : status = smb_raw_open(cli->tree, tctx, &io);
2208 6 : CHECK_STATUS(status, NT_STATUS_OK);
2209 6 : fnum = io.ntcreatex.out.file.fnum;
2210 :
2211 : /* The file size in the superseded create response should be 0 */
2212 6 : CHECK_VAL(io.ntcreatex.out.size, 0);
2213 6 : CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
2214 6 : CHECK_VAL(io.ntcreatex.out.create_action, FILE_WAS_SUPERSEDED);
2215 6 : CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
2216 6 : CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
2217 6 : CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
2218 6 : CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
2219 6 : CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
2220 6 : CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
2221 11 : done:
2222 6 : smbcli_close(cli->tree, fnum);
2223 6 : smbcli_deltree(cli->tree, BASEDIR);
2224 :
2225 6 : return ret;
2226 : }
2227 :
2228 : /* basic testing of all RAW_OPEN_* calls
2229 : */
2230 2355 : struct torture_suite *torture_raw_open(TALLOC_CTX *mem_ctx)
2231 : {
2232 2355 : struct torture_suite *suite = torture_suite_create(mem_ctx, "open");
2233 :
2234 2355 : torture_suite_add_1smb_test(suite, "brlocked", test_ntcreatex_brlocked);
2235 2355 : torture_suite_add_1smb_test(suite, "open", test_open);
2236 2355 : torture_suite_add_1smb_test(suite, "open-multi", test_raw_open_multi);
2237 2355 : torture_suite_add_1smb_test(suite, "openx", test_openx);
2238 2355 : torture_suite_add_1smb_test(suite, "ntcreatex", test_ntcreatex);
2239 2355 : torture_suite_add_1smb_test(suite, "nttrans-create", test_nttrans_create);
2240 2355 : torture_suite_add_1smb_test(suite, "t2open", test_t2open);
2241 2355 : torture_suite_add_1smb_test(suite, "mknew", test_mknew);
2242 2355 : torture_suite_add_1smb_test(suite, "create", test_create);
2243 2355 : torture_suite_add_1smb_test(suite, "ctemp", test_ctemp);
2244 2355 : torture_suite_add_1smb_test(suite, "chained-openx", test_chained);
2245 2355 : torture_suite_add_1smb_test(suite, "chained-ntcreatex", test_chained_ntcreatex_readx);
2246 2355 : torture_suite_add_1smb_test(suite, "no-leading-slash", test_no_leading_slash);
2247 2355 : torture_suite_add_1smb_test(suite, "openx-over-dir", test_openx_over_dir);
2248 2355 : torture_suite_add_1smb_test(suite, "open-for-delete", test_open_for_delete);
2249 2355 : torture_suite_add_1smb_test(suite, "opendisp-dir", test_ntcreatex_opendisp_dir);
2250 2355 : torture_suite_add_1smb_test(suite, "ntcreatedir", test_ntcreatexdir);
2251 2355 : torture_suite_add_1smb_test(suite, "open-for-truncate", test_open_for_truncate);
2252 2355 : torture_suite_add_1smb_test(suite, "ntcreatex_supersede", test_ntcreatex_supersede);
2253 :
2254 2355 : return suite;
2255 : }
|