s4:torture: add some SMB2 renaming tests
[samba.git] / source4 / torture / smb2 / rename.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    SMB2 rename test suite
5
6    Copyright (C) Christian Ambach 2012
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
28
29 #include "librpc/gen_ndr/security.h"
30
31 #define CHECK_STATUS(status, correct) do { \
32         if (!NT_STATUS_EQUAL(status, correct)) { \
33                 torture_result(torture, TORTURE_FAIL, \
34                        "(%s) Incorrect status %s - should be %s\n", \
35                        __location__, nt_errstr(status), nt_errstr(correct)); \
36                 ret = false; \
37                 goto done; \
38         }} while (0)
39
40 #define BASEDIR "test_rename"
41
42 /*
43  * basic testing of rename: open file with DELETE access
44  * this should pass
45  */
46
47 static bool torture_smb2_rename_simple(struct torture_context *torture,
48                 struct smb2_tree *tree1)
49 {
50         bool ret = true;
51         NTSTATUS status;
52         union smb_open io;
53         union smb_close cl;
54         union smb_setfileinfo sinfo;
55         union smb_fileinfo fi;
56         struct smb2_handle h1;
57
58         smb2_deltree(tree1, BASEDIR);
59         smb2_util_rmdir(tree1, BASEDIR);
60
61         torture_comment(torture, "Creating base directory\n");
62
63         smb2_util_mkdir(tree1, BASEDIR);
64
65
66         torture_comment(torture, "Creating test file\n");
67
68         ZERO_STRUCT(io.smb2);
69         io.generic.level = RAW_OPEN_SMB2;
70         io.smb2.in.create_flags = 0;
71         io.smb2.in.desired_access = SEC_FILE_ALL|SEC_STD_DELETE;
72         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
73         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
74         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
75                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
76         io.smb2.in.alloc_size = 0;
77         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
78         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
79         io.smb2.in.security_flags = 0;
80         io.smb2.in.fname = BASEDIR "\\file.txt";
81
82         status = smb2_create(tree1, torture, &(io.smb2));
83         CHECK_STATUS(status, NT_STATUS_OK);
84         h1 = io.smb2.out.file.handle;
85
86         torture_comment(torture, "Renaming test file\n");
87
88         ZERO_STRUCT(sinfo);
89         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
90         sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
91         sinfo.rename_information.in.overwrite = 0;
92         sinfo.rename_information.in.root_fid = 0;
93         sinfo.rename_information.in.new_name =
94                 BASEDIR "\\newname.txt";
95         status = smb2_setinfo_file(tree1, &sinfo);
96         CHECK_STATUS(status, NT_STATUS_OK);
97
98         torture_comment(torture, "Checking for new filename\n");
99
100         ZERO_STRUCT(fi);
101         fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
102         fi.generic.in.file.handle = h1;
103         status = smb2_getinfo_file(tree1, torture, &fi);
104         CHECK_STATUS(status, NT_STATUS_OK);
105
106
107         torture_comment(torture, "Closing test file\n");
108
109         ZERO_STRUCT(cl.smb2);
110         cl.smb2.level = RAW_CLOSE_SMB2;
111         cl.smb2.in.file.handle = h1;
112         status = smb2_close(tree1, &(cl.smb2));
113         CHECK_STATUS(status, NT_STATUS_OK);
114
115         ZERO_STRUCT(h1);
116
117 done:
118
119         torture_comment(torture, "Cleaning up\n");
120
121         if (h1.data) {
122                 ZERO_STRUCT(cl.smb2);
123                 cl.smb2.level = RAW_CLOSE_SMB2;
124                 cl.smb2.in.file.handle = h1;
125                 status = smb2_close(tree1, &(cl.smb2));
126         }
127         smb2_deltree(tree1, BASEDIR);
128         return ret;
129 }
130
131 /*
132  * basic testing of rename, this time do not request DELETE access
133  * for the file, this should fail
134  */
135
136 static bool torture_smb2_rename_simple2(struct torture_context *torture,
137                 struct smb2_tree *tree1)
138 {
139         bool ret = true;
140         NTSTATUS status;
141         union smb_open io;
142         union smb_close cl;
143         union smb_setfileinfo sinfo;
144         struct smb2_handle h1;
145
146         smb2_deltree(tree1, BASEDIR);
147         smb2_util_rmdir(tree1, BASEDIR);
148
149         torture_comment(torture, "Creating base directory\n");
150
151         smb2_util_mkdir(tree1, BASEDIR);
152
153
154         torture_comment(torture, "Creating test file\n");
155
156         ZERO_STRUCT(io.smb2);
157         io.generic.level = RAW_OPEN_SMB2;
158         io.smb2.in.create_flags = 0;
159         io.smb2.in.desired_access = SEC_FILE_ALL;
160         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
161         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
162         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
163                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
164         io.smb2.in.alloc_size = 0;
165         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
166         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
167         io.smb2.in.security_flags = 0;
168         io.smb2.in.fname = BASEDIR "\\file.txt";
169
170         status = smb2_create(tree1, torture, &(io.smb2));
171         CHECK_STATUS(status, NT_STATUS_OK);
172         h1 = io.smb2.out.file.handle;
173
174         torture_comment(torture, "Renaming test file\n");
175
176         ZERO_STRUCT(sinfo);
177         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
178         sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
179         sinfo.rename_information.in.overwrite = 0;
180         sinfo.rename_information.in.root_fid = 0;
181         sinfo.rename_information.in.new_name =
182                 BASEDIR "\\newname.txt";
183         status = smb2_setinfo_file(tree1, &sinfo);
184         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
185
186         torture_comment(torture, "Closing test file\n");
187
188         ZERO_STRUCT(cl.smb2);
189         cl.smb2.level = RAW_CLOSE_SMB2;
190         cl.smb2.in.file.handle = h1;
191         status = smb2_close(tree1, &(cl.smb2));
192         CHECK_STATUS(status, NT_STATUS_OK);
193
194         ZERO_STRUCT(h1);
195
196 done:
197
198         torture_comment(torture, "Cleaning up\n");
199
200         if (h1.data) {
201                 ZERO_STRUCT(cl.smb2);
202                 cl.smb2.level = RAW_CLOSE_SMB2;
203                 cl.smb2.in.file.handle = h1;
204                 status = smb2_close(tree1, &(cl.smb2));
205         }
206         smb2_deltree(tree1, BASEDIR);
207         return ret;
208 }
209
210
211 /*
212  * testing of rename with no sharing allowed on file
213  * this should work
214  */
215
216 static bool torture_smb2_rename_no_sharemode(struct torture_context *torture,
217                 struct smb2_tree *tree1)
218 {
219         bool ret = true;
220         NTSTATUS status;
221         union smb_open io;
222         union smb_close cl;
223         union smb_setfileinfo sinfo;
224         union smb_fileinfo fi;
225         struct smb2_handle h1;
226
227         smb2_deltree(tree1, BASEDIR);
228         smb2_util_rmdir(tree1, BASEDIR);
229
230         torture_comment(torture, "Creating base directory\n");
231
232         smb2_util_mkdir(tree1, BASEDIR);
233
234
235         torture_comment(torture, "Creating test file\n");
236
237         ZERO_STRUCT(io.smb2);
238         io.generic.level = RAW_OPEN_SMB2;
239         io.smb2.in.create_flags = 0;
240         io.smb2.in.desired_access = 0x0017019f;
241         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
242         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
243         io.smb2.in.share_access = 0;
244         io.smb2.in.alloc_size = 0;
245         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
246         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
247         io.smb2.in.security_flags = 0;
248         io.smb2.in.fname = BASEDIR "\\file.txt";
249
250         status = smb2_create(tree1, torture, &(io.smb2));
251         CHECK_STATUS(status, NT_STATUS_OK);
252         h1 = io.smb2.out.file.handle;
253
254         torture_comment(torture, "Renaming test file\n");
255
256         ZERO_STRUCT(sinfo);
257         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
258         sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
259         sinfo.rename_information.in.overwrite = 0;
260         sinfo.rename_information.in.root_fid = 0;
261         sinfo.rename_information.in.new_name =
262                 BASEDIR "\\newname.txt";
263         status = smb2_setinfo_file(tree1, &sinfo);
264         CHECK_STATUS(status, NT_STATUS_OK);
265
266         torture_comment(torture, "Checking for new filename\n");
267
268         ZERO_STRUCT(fi);
269         fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
270         fi.generic.in.file.handle = h1;
271         status = smb2_getinfo_file(tree1, torture, &fi);
272         CHECK_STATUS(status, NT_STATUS_OK);
273
274
275         torture_comment(torture, "Closing test file\n");
276
277         ZERO_STRUCT(cl.smb2);
278         cl.smb2.level = RAW_CLOSE_SMB2;
279         cl.smb2.in.file.handle = h1;
280         status = smb2_close(tree1, &(cl.smb2));
281         CHECK_STATUS(status, NT_STATUS_OK);
282
283         ZERO_STRUCT(h1);
284
285 done:
286
287         torture_comment(torture, "Cleaning up\n");
288
289         if (h1.data) {
290                 ZERO_STRUCT(cl.smb2);
291                 cl.smb2.level = RAW_CLOSE_SMB2;
292                 cl.smb2.in.file.handle = h1;
293                 status = smb2_close(tree1, &(cl.smb2));
294         }
295         smb2_deltree(tree1, BASEDIR);
296         return ret;
297 }
298
299 /*
300  * testing of rename when opening parent dir with delete access and delete
301  * sharing allowed
302  * should result in sharing violation
303  */
304
305 static bool torture_smb2_rename_with_delete_access(struct torture_context *torture,
306                 struct smb2_tree *tree1)
307 {
308         bool ret = true;
309         NTSTATUS status;
310         union smb_open io;
311         union smb_close cl;
312         union smb_setfileinfo sinfo;
313         struct smb2_handle fh, dh;
314
315         smb2_deltree(tree1, BASEDIR);
316         smb2_util_rmdir(tree1, BASEDIR);
317
318         torture_comment(torture, "Creating base directory\n");
319
320         smb2_util_mkdir(tree1, BASEDIR);
321
322         torture_comment(torture, "Opening parent directory\n");
323
324         ZERO_STRUCT(io.smb2);
325         io.generic.level = RAW_OPEN_SMB2;
326         io.smb2.in.create_flags = 0;
327         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
328                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
329                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
330                 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
331                 SEC_FILE_WRITE_DATA;
332         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
333         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
334         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
335                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
336         io.smb2.in.alloc_size = 0;
337         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
338         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
339         io.smb2.in.security_flags = 0;
340         io.smb2.in.fname = BASEDIR;
341
342         status = smb2_create(tree1, torture, &(io.smb2));
343         CHECK_STATUS(status, NT_STATUS_OK);
344         dh = io.smb2.out.file.handle;
345
346
347         torture_comment(torture, "Creating test file\n");
348
349         ZERO_STRUCT(io.smb2);
350         io.generic.level = RAW_OPEN_SMB2;
351         io.smb2.in.create_flags = 0;
352         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
353                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
354                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
355                 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
356         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
357         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
358         io.smb2.in.share_access = 0;
359         io.smb2.in.alloc_size = 0;
360         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
361         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
362         io.smb2.in.security_flags = 0;
363         io.smb2.in.fname = BASEDIR "\\file.txt";
364
365         status = smb2_create(tree1, torture, &(io.smb2));
366         CHECK_STATUS(status, NT_STATUS_OK);
367         fh = io.smb2.out.file.handle;
368
369         torture_comment(torture, "Renaming test file\n");
370
371         ZERO_STRUCT(sinfo);
372         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
373         sinfo.rename_information.in.file.handle = fh;
374         sinfo.rename_information.in.overwrite = 0;
375         sinfo.rename_information.in.root_fid = 0;
376         sinfo.rename_information.in.new_name =
377                 BASEDIR "\\newname.txt";
378         status = smb2_setinfo_file(tree1, &sinfo);
379         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
380
381         torture_comment(torture, "Closing test file\n");
382
383         ZERO_STRUCT(cl.smb2);
384         cl.smb2.level = RAW_CLOSE_SMB2;
385         cl.smb2.in.file.handle = fh;
386         status = smb2_close(tree1, &(cl.smb2));
387         CHECK_STATUS(status, NT_STATUS_OK);
388
389         ZERO_STRUCT(fh);
390
391         torture_comment(torture, "Closing directory\n");
392
393         ZERO_STRUCT(cl.smb2);
394         cl.smb2.level = RAW_CLOSE_SMB2;
395         cl.smb2.in.file.handle = dh;
396         status = smb2_close(tree1, &(cl.smb2));
397         CHECK_STATUS(status, NT_STATUS_OK);
398
399         ZERO_STRUCT(dh);
400
401
402 done:
403
404         torture_comment(torture, "Cleaning up\n");
405
406         if (fh.data) {
407                 ZERO_STRUCT(cl.smb2);
408                 cl.smb2.level = RAW_CLOSE_SMB2;
409                 cl.smb2.in.file.handle = fh;
410                 status = smb2_close(tree1, &(cl.smb2));
411         }
412         if (dh.data) {
413                 ZERO_STRUCT(cl.smb2);
414                 cl.smb2.level = RAW_CLOSE_SMB2;
415                 cl.smb2.in.file.handle = dh;
416                 status = smb2_close(tree1, &(cl.smb2));
417         }
418
419         smb2_deltree(tree1, BASEDIR);
420         return ret;
421 }
422
423
424 /*
425  * testing of rename with delete access on parent dir
426  * this is a variation of the test above: parent dir is opened
427  * without share_delete, so rename must fail
428  */
429
430 static bool torture_smb2_rename_with_delete_access2(struct torture_context *torture,
431                 struct smb2_tree *tree1)
432 {
433         bool ret = true;
434         NTSTATUS status;
435         union smb_open io;
436         union smb_close cl;
437         union smb_setfileinfo sinfo;
438         struct smb2_handle fh, dh;
439
440         smb2_deltree(tree1, BASEDIR);
441         smb2_util_rmdir(tree1, BASEDIR);
442
443         torture_comment(torture, "Creating base directory\n");
444
445         smb2_util_mkdir(tree1, BASEDIR);
446
447         torture_comment(torture, "Opening parent directory\n");
448
449         ZERO_STRUCT(io.smb2);
450         io.generic.level = RAW_OPEN_SMB2;
451         io.smb2.in.create_flags = 0;
452         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
453                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
454                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
455                 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
456                 SEC_FILE_WRITE_DATA;
457         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
458         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
459         io.smb2.in.share_access = 0;
460         io.smb2.in.alloc_size = 0;
461         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
462         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
463         io.smb2.in.security_flags = 0;
464         io.smb2.in.fname = BASEDIR;
465
466         status = smb2_create(tree1, torture, &(io.smb2));
467         CHECK_STATUS(status, NT_STATUS_OK);
468         dh = io.smb2.out.file.handle;
469
470
471         torture_comment(torture, "Creating test file\n");
472
473         ZERO_STRUCT(io.smb2);
474         io.generic.level = RAW_OPEN_SMB2;
475         io.smb2.in.create_flags = 0;
476         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
477                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
478                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
479                 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
480         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
481         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
482         io.smb2.in.share_access = 0;
483         io.smb2.in.alloc_size = 0;
484         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
485         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
486         io.smb2.in.security_flags = 0;
487         io.smb2.in.fname = BASEDIR "\\file.txt";
488
489         status = smb2_create(tree1, torture, &(io.smb2));
490         CHECK_STATUS(status, NT_STATUS_OK);
491         fh = io.smb2.out.file.handle;
492
493         torture_comment(torture, "Renaming test file\n");
494
495         ZERO_STRUCT(sinfo);
496         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
497         sinfo.rename_information.in.file.handle = fh;
498         sinfo.rename_information.in.overwrite = 0;
499         sinfo.rename_information.in.root_fid = 0;
500         sinfo.rename_information.in.new_name =
501                 BASEDIR "\\newname.txt";
502         status = smb2_setinfo_file(tree1, &sinfo);
503         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
504
505         torture_comment(torture, "Closing test file\n");
506
507         ZERO_STRUCT(cl.smb2);
508         cl.smb2.level = RAW_CLOSE_SMB2;
509         cl.smb2.in.file.handle = fh;
510         status = smb2_close(tree1, &(cl.smb2));
511         CHECK_STATUS(status, NT_STATUS_OK);
512
513         ZERO_STRUCT(fh);
514
515         torture_comment(torture, "Closing directory\n");
516
517         ZERO_STRUCT(cl.smb2);
518         cl.smb2.level = RAW_CLOSE_SMB2;
519         cl.smb2.in.file.handle = dh;
520         status = smb2_close(tree1, &(cl.smb2));
521         CHECK_STATUS(status, NT_STATUS_OK);
522
523         ZERO_STRUCT(dh);
524
525
526 done:
527
528         torture_comment(torture, "Cleaning up\n");
529
530         if (fh.data) {
531                 ZERO_STRUCT(cl.smb2);
532                 cl.smb2.level = RAW_CLOSE_SMB2;
533                 cl.smb2.in.file.handle = fh;
534                 status = smb2_close(tree1, &(cl.smb2));
535         }
536         if (dh.data) {
537                 ZERO_STRUCT(cl.smb2);
538                 cl.smb2.level = RAW_CLOSE_SMB2;
539                 cl.smb2.in.file.handle = dh;
540                 status = smb2_close(tree1, &(cl.smb2));
541         }
542
543         smb2_deltree(tree1, BASEDIR);
544         return ret;
545 }
546
547 /*
548  * testing of rename when opening parent dir with no delete access and delete
549  * sharing allowed
550  * this should pass
551  */
552
553 static bool torture_smb2_rename_no_delete_access(struct torture_context *torture,
554                 struct smb2_tree *tree1)
555 {
556         bool ret = true;
557         NTSTATUS status;
558         union smb_open io;
559         union smb_close cl;
560         union smb_setfileinfo sinfo;
561         union smb_fileinfo fi;
562         struct smb2_handle fh, dh;
563
564         smb2_deltree(tree1, BASEDIR);
565         smb2_util_rmdir(tree1, BASEDIR);
566
567         torture_comment(torture, "Creating base directory\n");
568
569         smb2_util_mkdir(tree1, BASEDIR);
570
571         torture_comment(torture, "Opening parent directory\n");
572
573         ZERO_STRUCT(io.smb2);
574         io.generic.level = RAW_OPEN_SMB2;
575         io.smb2.in.create_flags = 0;
576         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
577                 SEC_STD_READ_CONTROL | SEC_FILE_WRITE_ATTRIBUTE |
578                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
579                 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
580                 SEC_FILE_WRITE_DATA;
581         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
582         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
583         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
584                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
585         io.smb2.in.alloc_size = 0;
586         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
587         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
588         io.smb2.in.security_flags = 0;
589         io.smb2.in.fname = BASEDIR;
590
591         status = smb2_create(tree1, torture, &(io.smb2));
592         CHECK_STATUS(status, NT_STATUS_OK);
593         dh = io.smb2.out.file.handle;
594
595
596         torture_comment(torture, "Creating test file\n");
597
598         ZERO_STRUCT(io.smb2);
599         io.generic.level = RAW_OPEN_SMB2;
600         io.smb2.in.create_flags = 0;
601         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
602                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
603                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
604                 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
605         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
606         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
607         io.smb2.in.share_access = 0;
608         io.smb2.in.alloc_size = 0;
609         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
610         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
611         io.smb2.in.security_flags = 0;
612         io.smb2.in.fname = BASEDIR "\\file.txt";
613
614         status = smb2_create(tree1, torture, &(io.smb2));
615         CHECK_STATUS(status, NT_STATUS_OK);
616         fh = io.smb2.out.file.handle;
617
618         torture_comment(torture, "Renaming test file\n");
619
620         ZERO_STRUCT(sinfo);
621         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
622         sinfo.rename_information.in.file.handle = fh;
623         sinfo.rename_information.in.overwrite = 0;
624         sinfo.rename_information.in.root_fid = 0;
625         sinfo.rename_information.in.new_name =
626                 BASEDIR "\\newname.txt";
627         status = smb2_setinfo_file(tree1, &sinfo);
628         CHECK_STATUS(status, NT_STATUS_OK);
629
630         torture_comment(torture, "Checking for new filename\n");
631
632         ZERO_STRUCT(fi);
633         fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
634         fi.generic.in.file.handle = fh;
635         status = smb2_getinfo_file(tree1, torture, &fi);
636         CHECK_STATUS(status, NT_STATUS_OK);
637
638
639         torture_comment(torture, "Closing test file\n");
640
641         ZERO_STRUCT(cl.smb2);
642         cl.smb2.level = RAW_CLOSE_SMB2;
643         cl.smb2.in.file.handle = fh;
644         status = smb2_close(tree1, &(cl.smb2));
645         CHECK_STATUS(status, NT_STATUS_OK);
646
647         ZERO_STRUCT(fh);
648
649         torture_comment(torture, "Closing directory\n");
650
651         ZERO_STRUCT(cl.smb2);
652         cl.smb2.level = RAW_CLOSE_SMB2;
653         cl.smb2.in.file.handle = dh;
654         status = smb2_close(tree1, &(cl.smb2));
655         CHECK_STATUS(status, NT_STATUS_OK);
656
657         ZERO_STRUCT(dh);
658
659
660 done:
661
662         torture_comment(torture, "Cleaning up\n");
663
664         if (fh.data) {
665                 ZERO_STRUCT(cl.smb2);
666                 cl.smb2.level = RAW_CLOSE_SMB2;
667                 cl.smb2.in.file.handle = fh;
668                 status = smb2_close(tree1, &(cl.smb2));
669         }
670         if (dh.data) {
671                 ZERO_STRUCT(cl.smb2);
672                 cl.smb2.level = RAW_CLOSE_SMB2;
673                 cl.smb2.in.file.handle = dh;
674                 status = smb2_close(tree1, &(cl.smb2));
675         }
676
677         smb2_deltree(tree1, BASEDIR);
678         return ret;
679 }
680
681
682 /*
683  * testing of rename with no delete access on parent dir
684  * this is the negative case of the test above: parent dir is opened
685  * without share_delete, so rename must fail
686  */
687
688 static bool torture_smb2_rename_no_delete_access2(struct torture_context *torture,
689                 struct smb2_tree *tree1)
690 {
691         bool ret = true;
692         NTSTATUS status;
693         union smb_open io;
694         union smb_close cl;
695         union smb_setfileinfo sinfo;
696         struct smb2_handle fh, dh;
697
698         smb2_deltree(tree1, BASEDIR);
699         smb2_util_rmdir(tree1, BASEDIR);
700
701         torture_comment(torture, "Creating base directory\n");
702
703         smb2_util_mkdir(tree1, BASEDIR);
704
705         torture_comment(torture, "Opening parent directory\n");
706
707         ZERO_STRUCT(io.smb2);
708         io.generic.level = RAW_OPEN_SMB2;
709         io.smb2.in.create_flags = 0;
710         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
711                 SEC_STD_READ_CONTROL | SEC_FILE_WRITE_ATTRIBUTE |
712                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
713                 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
714                 SEC_FILE_WRITE_DATA;
715         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
716         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
717         io.smb2.in.share_access = 0;
718         io.smb2.in.alloc_size = 0;
719         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
720         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
721         io.smb2.in.security_flags = 0;
722         io.smb2.in.fname = BASEDIR;
723
724         status = smb2_create(tree1, torture, &(io.smb2));
725         CHECK_STATUS(status, NT_STATUS_OK);
726         dh = io.smb2.out.file.handle;
727
728
729         torture_comment(torture, "Creating test file\n");
730
731         ZERO_STRUCT(io.smb2);
732         io.generic.level = RAW_OPEN_SMB2;
733         io.smb2.in.create_flags = 0;
734         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
735                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
736                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
737                 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
738         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
739         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
740         io.smb2.in.share_access = 0;
741         io.smb2.in.alloc_size = 0;
742         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
743         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
744         io.smb2.in.security_flags = 0;
745         io.smb2.in.fname = BASEDIR "\\file.txt";
746
747         status = smb2_create(tree1, torture, &(io.smb2));
748         CHECK_STATUS(status, NT_STATUS_OK);
749         fh = io.smb2.out.file.handle;
750
751         torture_comment(torture, "Renaming test file\n");
752
753         ZERO_STRUCT(sinfo);
754         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
755         sinfo.rename_information.in.file.handle = fh;
756         sinfo.rename_information.in.overwrite = 0;
757         sinfo.rename_information.in.root_fid = 0;
758         sinfo.rename_information.in.new_name =
759                 BASEDIR "\\newname.txt";
760         status = smb2_setinfo_file(tree1, &sinfo);
761         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
762
763         torture_comment(torture, "Closing test file\n");
764
765         ZERO_STRUCT(cl.smb2);
766         cl.smb2.level = RAW_CLOSE_SMB2;
767         cl.smb2.in.file.handle = fh;
768         status = smb2_close(tree1, &(cl.smb2));
769         CHECK_STATUS(status, NT_STATUS_OK);
770
771         ZERO_STRUCT(fh);
772
773         torture_comment(torture, "Closing directory\n");
774
775         ZERO_STRUCT(cl.smb2);
776         cl.smb2.level = RAW_CLOSE_SMB2;
777         cl.smb2.in.file.handle = dh;
778         status = smb2_close(tree1, &(cl.smb2));
779         CHECK_STATUS(status, NT_STATUS_OK);
780
781         ZERO_STRUCT(dh);
782
783
784 done:
785
786         torture_comment(torture, "Cleaning up\n");
787
788         if (fh.data) {
789                 ZERO_STRUCT(cl.smb2);
790                 cl.smb2.level = RAW_CLOSE_SMB2;
791                 cl.smb2.in.file.handle = fh;
792                 status = smb2_close(tree1, &(cl.smb2));
793         }
794         if (dh.data) {
795                 ZERO_STRUCT(cl.smb2);
796                 cl.smb2.level = RAW_CLOSE_SMB2;
797                 cl.smb2.in.file.handle = dh;
798                 status = smb2_close(tree1, &(cl.smb2));
799         }
800
801         smb2_deltree(tree1, BASEDIR);
802         return ret;
803 }
804
805 /*
806    basic testing of SMB2 rename
807  */
808 struct torture_suite *torture_smb2_rename_init(void)
809 {
810         struct torture_suite *suite =
811                 torture_suite_create(talloc_autofree_context(), "rename");
812
813         torture_suite_add_1smb2_test(suite, "simple",
814                 torture_smb2_rename_simple);
815
816         torture_suite_add_1smb2_test(suite, "simple_nodelete)",
817                 torture_smb2_rename_simple2);
818
819         torture_suite_add_1smb2_test(suite, "no_sharing",
820                 torture_smb2_rename_no_sharemode);
821
822         torture_suite_add_1smb2_test(suite,
823                 "share_delete_and_delete_access",
824                 torture_smb2_rename_with_delete_access);
825
826         torture_suite_add_1smb2_test(suite,
827                 "no_share_delete_but_delete_access",
828                 torture_smb2_rename_with_delete_access2);
829
830         torture_suite_add_1smb2_test(suite,
831                 "share_delete_no_delete_access",
832                 torture_smb2_rename_no_delete_access);
833
834         torture_suite_add_1smb2_test(suite,
835                 "no_share_delete_no_delete_access",
836                 torture_smb2_rename_no_delete_access2);
837
838         suite->description = talloc_strdup(suite, "smb2.rename tests");
839
840         return suite;
841 }