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