1 /*
2    Unix SMB/CIFS implementation.
3    RAW_SFILEINFO_* 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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 
21 #include "includes.h"
22 #include "torture/torture.h"
23 #include "system/time.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
27 
28 #define BASEDIR "\\testsfileinfo"
29 
30 /* basic testing of all RAW_SFILEINFO_* calls
31    for each call we test that it succeeds, and where possible test
32    for consistency between the calls.
33 */
torture_raw_sfileinfo(struct torture_context * torture)34 BOOL torture_raw_sfileinfo(struct torture_context *torture)
35 {
36 	struct smbcli_state *cli;
37 	BOOL ret = True;
38 	TALLOC_CTX *mem_ctx;
39 	int fnum_saved, d_fnum, fnum2, fnum = -1;
40 	char *fnum_fname;
41 	char *fnum_fname_new;
42 	char *path_fname;
43 	char *path_fname_new;
44 	union smb_fileinfo finfo1, finfo2;
45 	union smb_setfileinfo sfinfo;
46 	NTSTATUS status, status2;
47 	const char *call_name;
48 	time_t basetime = (time(NULL) - 86400) & ~1;
49 	BOOL check_fnum;
50 	int n = time(NULL) % 100;
51 
52 	asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n);
53 	asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
54 	asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
55 	asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
56 
57 	if (!torture_open_connection(&cli, 0)) {
58 		return False;
59 	}
60 
61 	mem_ctx = talloc_init("torture_sfileinfo");
62 
63 	if (!torture_setup_dir(cli, BASEDIR)) {
64 		return False;
65 	}
66 
67 #define RECREATE_FILE(fname) do { \
68 	if (fnum != -1) smbcli_close(cli->tree, fnum); \
69 	fnum = create_complex_file(cli, mem_ctx, fname); \
70 	if (fnum == -1) { \
71 		printf("(%s) ERROR: open of %s failed (%s)\n", \
72 		       __location__, fname, smbcli_errstr(cli->tree)); \
73 		ret = False; \
74 		goto done; \
75 	}} while (0)
76 
77 #define RECREATE_BOTH do { \
78 		RECREATE_FILE(path_fname); \
79 		smbcli_close(cli->tree, fnum); \
80 		RECREATE_FILE(fnum_fname); \
81 	} while (0)
82 
83 	RECREATE_BOTH;
84 
85 #define CHECK_CALL_FNUM(call, rightstatus) do { \
86 	check_fnum = True; \
87 	call_name = #call; \
88 	sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
89 	sfinfo.generic.in.file.fnum = fnum; \
90 	status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
91 	if (!NT_STATUS_EQUAL(status, rightstatus)) { \
92 		printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
93 			nt_errstr(status), nt_errstr(rightstatus)); \
94 		ret = False; \
95 	} \
96 	finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
97 	finfo1.generic.in.file.fnum = fnum; \
98 	status2 = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1); \
99 	if (!NT_STATUS_IS_OK(status2)) { \
100 		printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
101 		ret = False; \
102 	}} while (0)
103 
104 #define CHECK_CALL_PATH(call, rightstatus) do { \
105 	check_fnum = False; \
106 	call_name = #call; \
107 	sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
108 	sfinfo.generic.in.file.path = path_fname; \
109 	status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
110 	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
111 		sfinfo.generic.in.file.path = path_fname_new; \
112 		status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
113 	} \
114 	if (!NT_STATUS_EQUAL(status, rightstatus)) { \
115 		printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
116 			nt_errstr(status), nt_errstr(rightstatus)); \
117 		ret = False; \
118 	} \
119 	finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
120 	finfo1.generic.in.file.path = path_fname; \
121 	status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo1); \
122 	if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
123 		finfo1.generic.in.file.path = path_fname_new; \
124 		status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo1); \
125 	} \
126 	if (!NT_STATUS_IS_OK(status2)) { \
127 		printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
128 		ret = False; \
129 	}} while (0)
130 
131 #define CHECK1(call) \
132 	do { if (NT_STATUS_IS_OK(status)) { \
133 		finfo2.generic.level = RAW_FILEINFO_ ## call; \
134 		if (check_fnum) { \
135 			finfo2.generic.in.file.fnum = fnum; \
136 			status2 = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo2); \
137 		} else { \
138 			finfo2.generic.in.file.path = path_fname; \
139 			status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2); \
140 			if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
141 				finfo2.generic.in.file.path = path_fname_new; \
142 				status2 = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2); \
143 			} \
144 		} \
145 		if (!NT_STATUS_IS_OK(status2)) { \
146 			printf("%s - %s\n", #call, nt_errstr(status2)); \
147 			ret = False; \
148 		} \
149 	}} while (0)
150 
151 #define CHECK_VALUE(call, stype, field, value) do { \
152  	CHECK1(call); \
153 	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
154 		printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
155 		       call_name, #stype, #field, \
156 		       (uint_t)value, (uint_t)finfo2.stype.out.field); \
157 		dump_all_info(mem_ctx, &finfo1); \
158 		ret = False; \
159 	}} while (0)
160 
161 #define CHECK_TIME(call, stype, field, value) do { \
162  	CHECK1(call); \
163 	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
164 		printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
165 		        call_name, #stype, #field, \
166 		        (uint_t)value, \
167 			(uint_t)nt_time_to_unix(finfo2.stype.out.field)); \
168 		printf("\t%s", timestring(mem_ctx, value)); \
169 		printf("\t%s\n", nt_time_string(mem_ctx, finfo2.stype.out.field)); \
170 		dump_all_info(mem_ctx, &finfo1); \
171 		ret = False; \
172 	}} while (0)
173 
174 #define CHECK_STR(call, stype, field, value) do { \
175  	CHECK1(call); \
176 	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \
177 		printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \
178 		        call_name, #stype, #field, \
179 		        value, \
180 			finfo2.stype.out.field); \
181 		dump_all_info(mem_ctx, &finfo1); \
182 		ret = False; \
183 	}} while (0)
184 
185 #define CHECK_STATUS(status, correct) do { \
186 	if (!NT_STATUS_EQUAL(status, correct)) { \
187 		printf("(%s) Incorrect status %s - should be %s\n", \
188 		       __location__, nt_errstr(status), nt_errstr(correct)); \
189 		ret = False; \
190 		goto done; \
191 	}} while (0)
192 
193 
194 	printf("test setattr\n");
195 	sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY;
196 	sfinfo.setattr.in.write_time = basetime;
197 	CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
198 	CHECK_VALUE  (ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
199 	CHECK_TIME   (ALL_INFO, all_info, write_time, basetime);
200 
201 	printf("setting to NORMAL doesn't do anything\n");
202 	sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_NORMAL;
203 	sfinfo.setattr.in.write_time = 0;
204 	CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
205 	CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
206 	CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
207 
208 	printf("a zero write_time means don't change\n");
209 	sfinfo.setattr.in.attrib = 0;
210 	sfinfo.setattr.in.write_time = 0;
211 	CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
212 	CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
213 	CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
214 
215 	printf("test setattre\n");
216 	sfinfo.setattre.in.create_time = basetime + 20;
217 	sfinfo.setattre.in.access_time = basetime + 30;
218 	sfinfo.setattre.in.write_time  = basetime + 40;
219 	CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
220 	CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
221 	CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
222 	CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 40);
223 
224 	sfinfo.setattre.in.create_time = 0;
225 	sfinfo.setattre.in.access_time = 0;
226 	sfinfo.setattre.in.write_time  = 0;
227 	CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
228 	CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
229 	CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
230 	CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 40);
231 
232 	printf("test standard level\n");
233 	sfinfo.standard.in.create_time = basetime + 100;
234 	sfinfo.standard.in.access_time = basetime + 200;
235 	sfinfo.standard.in.write_time  = basetime + 300;
236 	CHECK_CALL_FNUM(STANDARD, NT_STATUS_OK);
237 	CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
238 	CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
239 	CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
240 
241 	printf("test basic_info level\n");
242 	basetime += 86400;
243 	unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
244 	unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
245 	unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
246 	unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
247 	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
248 	CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
249 	CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
250 	CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
251 	CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
252 	CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
253 	CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
254 
255 	printf("a zero time means don't change\n");
256 	unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
257 	unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
258 	unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
259 	unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
260 	sfinfo.basic_info.in.attrib = 0;
261 	CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
262 	CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
263 	CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
264 	CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
265 	CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
266 	CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
267 
268 	printf("test basic_information level\n");
269 	basetime += 86400;
270 	unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
271 	unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
272 	unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
273 	unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
274 	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
275 	CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
276 	CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
277 	CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
278 	CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
279 	CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
280 	CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
281 
282 	CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
283 	CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
284 	CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
285 	CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
286 	CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
287 	CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
288 
289 	printf("a zero time means don't change\n");
290 	unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
291 	unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
292 	unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
293 	unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
294 	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
295 	CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
296 	CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
297 	CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
298 	CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
299 	CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
300 	CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
301 
302 	CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
303 	CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
304 	CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
305 	CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
306 
307 	/* interesting - w2k3 leaves change_time as current time for 0 change time
308 	   in setpathinfo
309 	  CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
310 	*/
311 	CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
312 
313 	printf("test disposition_info level\n");
314 	sfinfo.disposition_info.in.delete_on_close = 1;
315 	CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
316 	CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
317 	CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
318 
319 	sfinfo.disposition_info.in.delete_on_close = 0;
320 	CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
321 	CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
322 	CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
323 
324 	printf("test disposition_information level\n");
325 	sfinfo.disposition_info.in.delete_on_close = 1;
326 	CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
327 	CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
328 	CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
329 
330 	/* this would delete the file! */
331 	/*
332 	  CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
333 	  CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
334 	  CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
335 	*/
336 
337 	sfinfo.disposition_info.in.delete_on_close = 0;
338 	CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
339 	CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
340 	CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
341 
342 	CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
343 	CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
344 	CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
345 
346 	printf("test allocation_info level\n");
347 	sfinfo.allocation_info.in.alloc_size = 0;
348 	CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
349 	CHECK_VALUE(ALL_INFO, all_info, size, 0);
350 	CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
351 
352 	sfinfo.allocation_info.in.alloc_size = 4096;
353 	CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
354 	CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
355 	CHECK_VALUE(ALL_INFO, all_info, size, 0);
356 
357 	RECREATE_BOTH;
358 	sfinfo.allocation_info.in.alloc_size = 0;
359 	CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
360 	CHECK_VALUE(ALL_INFO, all_info, size, 0);
361 	CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
362 
363 	CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
364 	CHECK_VALUE(ALL_INFO, all_info, size, 0);
365 	CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
366 
367 	sfinfo.allocation_info.in.alloc_size = 4096;
368 	CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
369 	CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
370 	CHECK_VALUE(ALL_INFO, all_info, size, 0);
371 
372 	/* setting the allocation size up via setpathinfo seems
373 	   to be broken in w2k3 */
374 	CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
375 	CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
376 	CHECK_VALUE(ALL_INFO, all_info, size, 0);
377 
378 	printf("test end_of_file_info level\n");
379 	sfinfo.end_of_file_info.in.size = 37;
380 	CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
381 	CHECK_VALUE(ALL_INFO, all_info, size, 37);
382 
383 	sfinfo.end_of_file_info.in.size = 7;
384 	CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
385 	CHECK_VALUE(ALL_INFO, all_info, size, 7);
386 
387 	sfinfo.end_of_file_info.in.size = 37;
388 	CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
389 	CHECK_VALUE(ALL_INFO, all_info, size, 37);
390 
391 	CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
392 	CHECK_VALUE(ALL_INFO, all_info, size, 37);
393 
394 	sfinfo.end_of_file_info.in.size = 7;
395 	CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
396 	CHECK_VALUE(ALL_INFO, all_info, size, 7);
397 
398 	CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
399 	CHECK_VALUE(ALL_INFO, all_info, size, 7);
400 
401 	printf("test position_information level\n");
402 	sfinfo.position_information.in.position = 123456;
403 	CHECK_CALL_FNUM(POSITION_INFORMATION, NT_STATUS_OK);
404 	CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
405 
406 	CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
407 	CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
408 
409 	printf("test mode_information level\n");
410 	sfinfo.mode_information.in.mode = 2;
411 	CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
412 	CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
413 
414 	CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
415 	CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
416 
417 	sfinfo.mode_information.in.mode = 1;
418 	CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
419 	CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
420 
421 	sfinfo.mode_information.in.mode = 0;
422 	CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
423 	CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
424 
425 	CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
426 	CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
427 #if 1
428 	printf("finally the rename_information level\n");
429 	smbcli_close(cli->tree, create_complex_file(cli, mem_ctx, fnum_fname_new));
430 	smbcli_close(cli->tree, create_complex_file(cli, mem_ctx, path_fname_new));
431 
432 	sfinfo.rename_information.in.overwrite = 0;
433 	sfinfo.rename_information.in.root_fid  = 0;
434 	sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
435 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
436 
437 	sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
438 	CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
439 
440 	sfinfo.rename_information.in.new_name  = fnum_fname_new;
441 	sfinfo.rename_information.in.overwrite = 1;
442 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED);
443 
444 	sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
445 	sfinfo.rename_information.in.overwrite = 1;
446 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
447 	CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
448 
449 	printf("Trying rename with dest file open\n");
450 	fnum2 = create_complex_file(cli, mem_ctx, fnum_fname);
451 	sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
452 	sfinfo.rename_information.in.overwrite = 1;
453 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
454 	CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
455 
456 	fnum_saved = fnum;
457 	fnum = fnum2;
458 	sfinfo.disposition_info.in.delete_on_close = 1;
459 	CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
460 	fnum = fnum_saved;
461 
462 	printf("Trying rename with dest file open and delete_on_close\n");
463 	sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
464 	sfinfo.rename_information.in.overwrite = 1;
465 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
466 
467 	smbcli_close(cli->tree, fnum2);
468 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
469 	CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
470 
471 	printf("Trying rename with source file open twice\n");
472 	sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
473 	sfinfo.rename_information.in.overwrite = 1;
474 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
475 	CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
476 
477 	fnum2 = create_complex_file(cli, mem_ctx, fnum_fname);
478 	sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
479 	sfinfo.rename_information.in.overwrite = 0;
480 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
481 	CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
482 	smbcli_close(cli->tree, fnum2);
483 
484 	sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
485 	sfinfo.rename_information.in.overwrite = 0;
486 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
487 	CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
488 
489 	sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
490 	sfinfo.rename_information.in.overwrite = 1;
491 	CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
492 	CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
493 
494 	sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
495 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
496 	CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
497 
498 	sfinfo.rename_information.in.new_name  = path_fname+strlen(BASEDIR)+1;
499 	CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
500 	CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
501 
502 	printf("Trying rename with a root fid\n");
503 	status = create_directory_handle(cli->tree, BASEDIR, &d_fnum);
504 	CHECK_STATUS(status, NT_STATUS_OK);
505 	sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
506 	sfinfo.rename_information.in.root_fid = d_fnum;
507 	CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
508 	CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
509 #endif
510 
511 #if 0
512 	printf("test unix_basic level\n");
513 	CHECK_CALL_FNUM(UNIX_BASIC, NT_STATUS_OK);
514 	CHECK_CALL_PATH(UNIX_BASIC, NT_STATUS_OK);
515 
516 	printf("test unix_link level\n");
517 	CHECK_CALL_FNUM(UNIX_LINK, NT_STATUS_OK);
518 	CHECK_CALL_PATH(UNIX_LINK, NT_STATUS_OK);
519 #endif
520 
521 done:
522 	smb_raw_exit(cli->session);
523 	smbcli_close(cli->tree, fnum);
524 	if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
525 		printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
526 	}
527 	if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
528 		printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
529 	}
530 
531 	torture_close_connection(cli);
532 	talloc_free(mem_ctx);
533 	return ret;
534 }
535 
536 
537 /*
538    look for the w2k3 setpathinfo STANDARD bug
539 */
torture_raw_sfileinfo_bug(struct torture_context * torture)540 BOOL torture_raw_sfileinfo_bug(struct torture_context *torture)
541 {
542 	struct smbcli_state *cli;
543 	TALLOC_CTX *mem_ctx;
544 	const char *fname = "\\bug3.txt";
545 	union smb_setfileinfo sfinfo;
546 	NTSTATUS status;
547 	int fnum;
548 
549 	if (!torture_setting_bool(torture, "dangerous", False)) {
550 		printf("torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
551 		return True;
552 	}
553 
554 	if (!torture_open_connection(&cli, 0)) {
555 		return False;
556 	}
557 
558 	mem_ctx = talloc_init("torture_sfileinfo");
559 
560 	fnum = create_complex_file(cli, mem_ctx, fname);
561 	smbcli_close(cli->tree, fnum);
562 
563 	sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
564 	sfinfo.generic.in.file.path = fname;
565 
566 	sfinfo.standard.in.create_time = 0;
567 	sfinfo.standard.in.access_time = 0;
568 	sfinfo.standard.in.write_time  = 0;
569 
570 	status = smb_raw_setpathinfo(cli->tree, &sfinfo);
571 	printf("%s - %s\n", fname, nt_errstr(status));
572 
573 	printf("now try and delete %s\n", fname);
574 
575 	return True;
576 }
577