LCOV - code coverage report
Current view: top level - source4/torture/smb2 - rename.c (source / functions) Hit Total Coverage
Test: coverage report for recycleplus df22b230 Lines: 16 924 1.7 %
Date: 2024-02-14 10:14:15 Functions: 1 25 4.0 %

          Line data    Source code
       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             : #include <tevent.h>
      26             : #include "lib/util/tevent_ntstatus.h"
      27             : 
      28             : #include "torture/torture.h"
      29             : #include "torture/util.h"
      30             : #include "torture/smb2/proto.h"
      31             : 
      32             : #include "librpc/gen_ndr/security.h"
      33             : 
      34             : #define CHECK_VAL(v, correct) \
      35             :         do { \
      36             :                 if ((v) != (correct)) { \
      37             :                         torture_result(torture, \
      38             :                                 TORTURE_FAIL, \
      39             :                                 "(%s): wrong value for %s got " \
      40             :                                 "0x%llx - should be 0x%llx\n", \
      41             :                                 __location__, #v, \
      42             :                                 (unsigned long long)v, \
      43             :                                 (unsigned long long)correct); \
      44             :                         ret = false; \
      45             :                         goto done; \
      46             :         }} while (0)
      47             : 
      48             : #define CHECK_CREATED(__io, __created, __attribute)                     \
      49             :         do {                                                            \
      50             :                 CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \
      51             :                 CHECK_VAL((__io)->out.size, 0);                         \
      52             :                 CHECK_VAL((__io)->out.file_attr, (__attribute));        \
      53             :                 CHECK_VAL((__io)->out.reserved2, 0);                    \
      54             :         } while(0)
      55             : 
      56             : #define CHECK_STATUS(status, correct) do { \
      57             :         if (!NT_STATUS_EQUAL(status, correct)) { \
      58             :                 torture_result(torture, TORTURE_FAIL, \
      59             :                        "(%s) Incorrect status %s - should be %s\n", \
      60             :                        __location__, nt_errstr(status), nt_errstr(correct)); \
      61             :                 ret = false; \
      62             :                 goto done; \
      63             :         }} while (0)
      64             : 
      65             : #define BASEDIR "test_rename"
      66             : 
      67             : /*
      68             :  * basic testing of rename: open file with DELETE access
      69             :  * this should pass
      70             :  */
      71             : 
      72           0 : static bool torture_smb2_rename_simple(struct torture_context *torture,
      73             :                 struct smb2_tree *tree1)
      74             : {
      75           0 :         bool ret = true;
      76             :         NTSTATUS status;
      77             :         union smb_open io;
      78             :         union smb_close cl;
      79             :         union smb_setfileinfo sinfo;
      80             :         union smb_fileinfo fi;
      81             :         struct smb2_handle h1;
      82             : 
      83           0 :         ZERO_STRUCT(h1);
      84             : 
      85           0 :         smb2_deltree(tree1, BASEDIR);
      86           0 :         smb2_util_rmdir(tree1, BASEDIR);
      87             : 
      88           0 :         torture_comment(torture, "Creating base directory\n");
      89             : 
      90           0 :         smb2_util_mkdir(tree1, BASEDIR);
      91             : 
      92             : 
      93           0 :         torture_comment(torture, "Creating test file\n");
      94             : 
      95           0 :         ZERO_STRUCT(io.smb2);
      96           0 :         io.generic.level = RAW_OPEN_SMB2;
      97           0 :         io.smb2.in.create_flags = 0;
      98           0 :         io.smb2.in.desired_access = SEC_FILE_ALL|SEC_STD_DELETE;
      99           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     100           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     101           0 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     102             :                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
     103           0 :         io.smb2.in.alloc_size = 0;
     104           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     105           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     106           0 :         io.smb2.in.security_flags = 0;
     107           0 :         io.smb2.in.fname = BASEDIR "\\file.txt";
     108             : 
     109           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     110           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     111           0 :         h1 = io.smb2.out.file.handle;
     112             : 
     113           0 :         torture_comment(torture, "Renaming test file\n");
     114             : 
     115           0 :         ZERO_STRUCT(sinfo);
     116           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     117           0 :         sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
     118           0 :         sinfo.rename_information.in.overwrite = 0;
     119           0 :         sinfo.rename_information.in.root_fid = 0;
     120           0 :         sinfo.rename_information.in.new_name =
     121             :                 BASEDIR "\\newname.txt";
     122           0 :         status = smb2_setinfo_file(tree1, &sinfo);
     123           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     124             : 
     125           0 :         torture_comment(torture, "Checking for new filename\n");
     126             : 
     127           0 :         ZERO_STRUCT(fi);
     128           0 :         fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     129           0 :         fi.generic.in.file.handle = h1;
     130           0 :         status = smb2_getinfo_file(tree1, torture, &fi);
     131           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     132             : 
     133             : 
     134           0 :         torture_comment(torture, "Closing test file\n");
     135             : 
     136           0 :         ZERO_STRUCT(cl.smb2);
     137           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     138           0 :         cl.smb2.in.file.handle = h1;
     139           0 :         status = smb2_close(tree1, &(cl.smb2));
     140           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     141             : 
     142           0 :         ZERO_STRUCT(h1);
     143             : 
     144           0 : done:
     145             : 
     146           0 :         torture_comment(torture, "Cleaning up\n");
     147             : 
     148           0 :         if (h1.data[0] || h1.data[1]) {
     149           0 :                 ZERO_STRUCT(cl.smb2);
     150           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     151           0 :                 cl.smb2.in.file.handle = h1;
     152           0 :                 status = smb2_close(tree1, &(cl.smb2));
     153             :         }
     154           0 :         smb2_deltree(tree1, BASEDIR);
     155           0 :         return ret;
     156             : }
     157             : 
     158             : /*
     159             :  * basic testing of rename, this time do not request DELETE access
     160             :  * for the file, this should fail
     161             :  */
     162             : 
     163           0 : static bool torture_smb2_rename_simple2(struct torture_context *torture,
     164             :                 struct smb2_tree *tree1)
     165             : {
     166           0 :         bool ret = true;
     167             :         NTSTATUS status;
     168             :         union smb_open io;
     169             :         union smb_close cl;
     170             :         union smb_setfileinfo sinfo;
     171             :         struct smb2_handle h1;
     172             : 
     173           0 :         ZERO_STRUCT(h1);
     174             : 
     175           0 :         smb2_deltree(tree1, BASEDIR);
     176           0 :         smb2_util_rmdir(tree1, BASEDIR);
     177             : 
     178           0 :         torture_comment(torture, "Creating base directory\n");
     179             : 
     180           0 :         smb2_util_mkdir(tree1, BASEDIR);
     181             : 
     182             : 
     183           0 :         torture_comment(torture, "Creating test file\n");
     184             : 
     185           0 :         ZERO_STRUCT(io.smb2);
     186           0 :         io.generic.level = RAW_OPEN_SMB2;
     187           0 :         io.smb2.in.create_flags = 0;
     188           0 :         io.smb2.in.desired_access = SEC_FILE_ALL;
     189           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     190           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     191           0 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     192             :                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
     193           0 :         io.smb2.in.alloc_size = 0;
     194           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     195           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     196           0 :         io.smb2.in.security_flags = 0;
     197           0 :         io.smb2.in.fname = BASEDIR "\\file.txt";
     198             : 
     199           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     200           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     201           0 :         h1 = io.smb2.out.file.handle;
     202             : 
     203           0 :         torture_comment(torture, "Renaming test file\n");
     204             : 
     205           0 :         ZERO_STRUCT(sinfo);
     206           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     207           0 :         sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
     208           0 :         sinfo.rename_information.in.overwrite = 0;
     209           0 :         sinfo.rename_information.in.root_fid = 0;
     210           0 :         sinfo.rename_information.in.new_name =
     211             :                 BASEDIR "\\newname.txt";
     212           0 :         status = smb2_setinfo_file(tree1, &sinfo);
     213           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     214             : 
     215           0 :         torture_comment(torture, "Closing test file\n");
     216             : 
     217           0 :         ZERO_STRUCT(cl.smb2);
     218           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     219           0 :         cl.smb2.in.file.handle = h1;
     220           0 :         status = smb2_close(tree1, &(cl.smb2));
     221           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     222             : 
     223           0 :         ZERO_STRUCT(h1);
     224             : 
     225           0 : done:
     226             : 
     227           0 :         torture_comment(torture, "Cleaning up\n");
     228             : 
     229           0 :         if (h1.data[0] || h1.data[1]) {
     230           0 :                 ZERO_STRUCT(cl.smb2);
     231           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     232           0 :                 cl.smb2.in.file.handle = h1;
     233           0 :                 status = smb2_close(tree1, &(cl.smb2));
     234             :         }
     235           0 :         smb2_deltree(tree1, BASEDIR);
     236           0 :         return ret;
     237             : }
     238             : 
     239             : 
     240             : /*
     241             :  * testing of rename with no sharing allowed on file
     242             :  * this should work
     243             :  */
     244             : 
     245           0 : static bool torture_smb2_rename_no_sharemode(struct torture_context *torture,
     246             :                 struct smb2_tree *tree1)
     247             : {
     248           0 :         bool ret = true;
     249             :         NTSTATUS status;
     250             :         union smb_open io;
     251             :         union smb_close cl;
     252             :         union smb_setfileinfo sinfo;
     253             :         union smb_fileinfo fi;
     254             :         struct smb2_handle h1;
     255             : 
     256           0 :         ZERO_STRUCT(h1);
     257             : 
     258           0 :         smb2_deltree(tree1, BASEDIR);
     259           0 :         smb2_util_rmdir(tree1, BASEDIR);
     260             : 
     261           0 :         torture_comment(torture, "Creating base directory\n");
     262             : 
     263           0 :         smb2_util_mkdir(tree1, BASEDIR);
     264             : 
     265             : 
     266           0 :         torture_comment(torture, "Creating test file\n");
     267             : 
     268           0 :         ZERO_STRUCT(io.smb2);
     269           0 :         io.generic.level = RAW_OPEN_SMB2;
     270           0 :         io.smb2.in.create_flags = 0;
     271           0 :         io.smb2.in.desired_access = 0x0017019f;
     272           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     273           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     274           0 :         io.smb2.in.share_access = 0;
     275           0 :         io.smb2.in.alloc_size = 0;
     276           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     277           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     278           0 :         io.smb2.in.security_flags = 0;
     279           0 :         io.smb2.in.fname = BASEDIR "\\file.txt";
     280             : 
     281           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     282           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     283           0 :         h1 = io.smb2.out.file.handle;
     284             : 
     285           0 :         torture_comment(torture, "Renaming test file\n");
     286             : 
     287           0 :         ZERO_STRUCT(sinfo);
     288           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     289           0 :         sinfo.rename_information.in.file.handle = io.smb2.out.file.handle;
     290           0 :         sinfo.rename_information.in.overwrite = 0;
     291           0 :         sinfo.rename_information.in.root_fid = 0;
     292           0 :         sinfo.rename_information.in.new_name =
     293             :                 BASEDIR "\\newname.txt";
     294           0 :         status = smb2_setinfo_file(tree1, &sinfo);
     295           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     296             : 
     297           0 :         torture_comment(torture, "Checking for new filename\n");
     298             : 
     299           0 :         ZERO_STRUCT(fi);
     300           0 :         fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     301           0 :         fi.generic.in.file.handle = h1;
     302           0 :         status = smb2_getinfo_file(tree1, torture, &fi);
     303           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     304             : 
     305             : 
     306           0 :         torture_comment(torture, "Closing test file\n");
     307             : 
     308           0 :         ZERO_STRUCT(cl.smb2);
     309           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     310           0 :         cl.smb2.in.file.handle = h1;
     311           0 :         status = smb2_close(tree1, &(cl.smb2));
     312           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     313             : 
     314           0 :         ZERO_STRUCT(h1);
     315             : 
     316           0 : done:
     317             : 
     318           0 :         torture_comment(torture, "Cleaning up\n");
     319             : 
     320           0 :         if (h1.data[0] || h1.data[1]) {
     321           0 :                 ZERO_STRUCT(cl.smb2);
     322           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     323           0 :                 cl.smb2.in.file.handle = h1;
     324           0 :                 status = smb2_close(tree1, &(cl.smb2));
     325             :         }
     326           0 :         smb2_deltree(tree1, BASEDIR);
     327           0 :         return ret;
     328             : }
     329             : 
     330             : /*
     331             :  * testing of rename when opening parent dir with delete access and delete
     332             :  * sharing allowed
     333             :  * should result in sharing violation
     334             :  */
     335             : 
     336           0 : static bool torture_smb2_rename_with_delete_access(struct torture_context *torture,
     337             :                 struct smb2_tree *tree1)
     338             : {
     339           0 :         bool ret = true;
     340             :         NTSTATUS status;
     341             :         union smb_open io;
     342             :         union smb_close cl;
     343             :         union smb_setfileinfo sinfo;
     344             :         struct smb2_handle fh, dh;
     345             : 
     346           0 :         ZERO_STRUCT(fh);
     347           0 :         ZERO_STRUCT(dh);
     348             : 
     349           0 :         smb2_deltree(tree1, BASEDIR);
     350           0 :         smb2_util_rmdir(tree1, BASEDIR);
     351             : 
     352           0 :         torture_comment(torture, "Creating base directory\n");
     353             : 
     354           0 :         smb2_util_mkdir(tree1, BASEDIR);
     355             : 
     356           0 :         torture_comment(torture, "Opening parent directory\n");
     357             : 
     358           0 :         ZERO_STRUCT(io.smb2);
     359           0 :         io.generic.level = RAW_OPEN_SMB2;
     360           0 :         io.smb2.in.create_flags = 0;
     361           0 :         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
     362             :                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
     363             :                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
     364             :                 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
     365             :                 SEC_FILE_WRITE_DATA;
     366           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     367           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     368           0 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     369             :                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
     370           0 :         io.smb2.in.alloc_size = 0;
     371           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     372           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     373           0 :         io.smb2.in.security_flags = 0;
     374           0 :         io.smb2.in.fname = BASEDIR;
     375             : 
     376           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     377           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     378           0 :         dh = io.smb2.out.file.handle;
     379             : 
     380             : 
     381           0 :         torture_comment(torture, "Creating test file\n");
     382             : 
     383           0 :         ZERO_STRUCT(io.smb2);
     384           0 :         io.generic.level = RAW_OPEN_SMB2;
     385           0 :         io.smb2.in.create_flags = 0;
     386           0 :         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
     387             :                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
     388             :                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
     389             :                 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
     390           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     391           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     392           0 :         io.smb2.in.share_access = 0;
     393           0 :         io.smb2.in.alloc_size = 0;
     394           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     395           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     396           0 :         io.smb2.in.security_flags = 0;
     397           0 :         io.smb2.in.fname = BASEDIR "\\file.txt";
     398             : 
     399           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     400           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     401           0 :         fh = io.smb2.out.file.handle;
     402             : 
     403           0 :         torture_comment(torture, "Renaming test file\n");
     404             : 
     405           0 :         ZERO_STRUCT(sinfo);
     406           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     407           0 :         sinfo.rename_information.in.file.handle = fh;
     408           0 :         sinfo.rename_information.in.overwrite = 0;
     409           0 :         sinfo.rename_information.in.root_fid = 0;
     410           0 :         sinfo.rename_information.in.new_name =
     411             :                 BASEDIR "\\newname.txt";
     412           0 :         status = smb2_setinfo_file(tree1, &sinfo);
     413           0 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     414             : 
     415           0 :         torture_comment(torture, "Closing test file\n");
     416             : 
     417           0 :         ZERO_STRUCT(cl.smb2);
     418           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     419           0 :         cl.smb2.in.file.handle = fh;
     420           0 :         status = smb2_close(tree1, &(cl.smb2));
     421           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     422             : 
     423           0 :         ZERO_STRUCT(fh);
     424             : 
     425           0 :         torture_comment(torture, "Closing directory\n");
     426             : 
     427           0 :         ZERO_STRUCT(cl.smb2);
     428           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     429           0 :         cl.smb2.in.file.handle = dh;
     430           0 :         status = smb2_close(tree1, &(cl.smb2));
     431           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     432             : 
     433           0 :         ZERO_STRUCT(dh);
     434             : 
     435             : 
     436           0 : done:
     437             : 
     438           0 :         torture_comment(torture, "Cleaning up\n");
     439             : 
     440           0 :         if (fh.data[0] || fh.data[1]) {
     441           0 :                 ZERO_STRUCT(cl.smb2);
     442           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     443           0 :                 cl.smb2.in.file.handle = fh;
     444           0 :                 status = smb2_close(tree1, &(cl.smb2));
     445             :         }
     446           0 :         if (dh.data[0] || dh.data[1]) {
     447           0 :                 ZERO_STRUCT(cl.smb2);
     448           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     449           0 :                 cl.smb2.in.file.handle = dh;
     450           0 :                 status = smb2_close(tree1, &(cl.smb2));
     451             :         }
     452             : 
     453           0 :         smb2_deltree(tree1, BASEDIR);
     454           0 :         return ret;
     455             : }
     456             : 
     457             : 
     458             : /*
     459             :  * testing of rename with delete access on parent dir
     460             :  * this is a variation of the test above: parent dir is opened
     461             :  * without share_delete, so rename must fail
     462             :  */
     463             : 
     464           0 : static bool torture_smb2_rename_with_delete_access2(struct torture_context *torture,
     465             :                 struct smb2_tree *tree1)
     466             : {
     467           0 :         bool ret = true;
     468             :         NTSTATUS status;
     469             :         union smb_open io;
     470             :         union smb_close cl;
     471             :         union smb_setfileinfo sinfo;
     472             :         struct smb2_handle fh, dh;
     473             : 
     474           0 :         ZERO_STRUCT(fh);
     475           0 :         ZERO_STRUCT(dh);
     476             : 
     477           0 :         smb2_deltree(tree1, BASEDIR);
     478           0 :         smb2_util_rmdir(tree1, BASEDIR);
     479             : 
     480           0 :         torture_comment(torture, "Creating base directory\n");
     481             : 
     482           0 :         smb2_util_mkdir(tree1, BASEDIR);
     483             : 
     484           0 :         torture_comment(torture, "Opening parent directory\n");
     485             : 
     486           0 :         ZERO_STRUCT(io.smb2);
     487           0 :         io.generic.level = RAW_OPEN_SMB2;
     488           0 :         io.smb2.in.create_flags = 0;
     489           0 :         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
     490             :                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
     491             :                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
     492             :                 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
     493             :                 SEC_FILE_WRITE_DATA;
     494           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     495           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     496           0 :         io.smb2.in.share_access = 0;
     497           0 :         io.smb2.in.alloc_size = 0;
     498           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     499           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     500           0 :         io.smb2.in.security_flags = 0;
     501           0 :         io.smb2.in.fname = BASEDIR;
     502             : 
     503           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     504           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     505           0 :         dh = io.smb2.out.file.handle;
     506             : 
     507             : 
     508           0 :         torture_comment(torture, "Creating test file\n");
     509             : 
     510           0 :         ZERO_STRUCT(io.smb2);
     511           0 :         io.generic.level = RAW_OPEN_SMB2;
     512           0 :         io.smb2.in.create_flags = 0;
     513           0 :         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
     514             :                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
     515             :                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
     516             :                 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
     517           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     518           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     519           0 :         io.smb2.in.share_access = 0;
     520           0 :         io.smb2.in.alloc_size = 0;
     521           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     522           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     523           0 :         io.smb2.in.security_flags = 0;
     524           0 :         io.smb2.in.fname = BASEDIR "\\file.txt";
     525             : 
     526           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     527           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     528           0 :         fh = io.smb2.out.file.handle;
     529             : 
     530           0 :         torture_comment(torture, "Renaming test file\n");
     531             : 
     532           0 :         ZERO_STRUCT(sinfo);
     533           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     534           0 :         sinfo.rename_information.in.file.handle = fh;
     535           0 :         sinfo.rename_information.in.overwrite = 0;
     536           0 :         sinfo.rename_information.in.root_fid = 0;
     537           0 :         sinfo.rename_information.in.new_name =
     538             :                 BASEDIR "\\newname.txt";
     539           0 :         status = smb2_setinfo_file(tree1, &sinfo);
     540           0 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     541             : 
     542           0 :         torture_comment(torture, "Closing test file\n");
     543             : 
     544           0 :         ZERO_STRUCT(cl.smb2);
     545           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     546           0 :         cl.smb2.in.file.handle = fh;
     547           0 :         status = smb2_close(tree1, &(cl.smb2));
     548           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     549             : 
     550           0 :         ZERO_STRUCT(fh);
     551             : 
     552           0 :         torture_comment(torture, "Closing directory\n");
     553             : 
     554           0 :         ZERO_STRUCT(cl.smb2);
     555           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     556           0 :         cl.smb2.in.file.handle = dh;
     557           0 :         status = smb2_close(tree1, &(cl.smb2));
     558           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     559             : 
     560           0 :         ZERO_STRUCT(dh);
     561             : 
     562             : 
     563           0 : done:
     564             : 
     565           0 :         torture_comment(torture, "Cleaning up\n");
     566             : 
     567           0 :         if (fh.data[0] || fh.data[1]) {
     568           0 :                 ZERO_STRUCT(cl.smb2);
     569           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     570           0 :                 cl.smb2.in.file.handle = fh;
     571           0 :                 status = smb2_close(tree1, &(cl.smb2));
     572             :         }
     573           0 :         if (dh.data[0] || dh.data[1]) {
     574           0 :                 ZERO_STRUCT(cl.smb2);
     575           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     576           0 :                 cl.smb2.in.file.handle = dh;
     577           0 :                 status = smb2_close(tree1, &(cl.smb2));
     578             :         }
     579             : 
     580           0 :         smb2_deltree(tree1, BASEDIR);
     581           0 :         return ret;
     582             : }
     583             : 
     584             : /*
     585             :  * testing of rename when opening parent dir with no delete access and delete
     586             :  * sharing allowed
     587             :  * this should pass
     588             :  */
     589             : 
     590           0 : static bool torture_smb2_rename_no_delete_access(struct torture_context *torture,
     591             :                 struct smb2_tree *tree1)
     592             : {
     593           0 :         bool ret = true;
     594             :         NTSTATUS status;
     595             :         union smb_open io;
     596             :         union smb_close cl;
     597             :         union smb_setfileinfo sinfo;
     598             :         union smb_fileinfo fi;
     599             :         struct smb2_handle fh, dh;
     600             : 
     601           0 :         ZERO_STRUCT(fh);
     602           0 :         ZERO_STRUCT(dh);
     603             : 
     604           0 :         smb2_deltree(tree1, BASEDIR);
     605           0 :         smb2_util_rmdir(tree1, BASEDIR);
     606             : 
     607           0 :         torture_comment(torture, "Creating base directory\n");
     608             : 
     609           0 :         smb2_util_mkdir(tree1, BASEDIR);
     610             : 
     611           0 :         torture_comment(torture, "Opening parent directory\n");
     612             : 
     613           0 :         ZERO_STRUCT(io.smb2);
     614           0 :         io.generic.level = RAW_OPEN_SMB2;
     615           0 :         io.smb2.in.create_flags = 0;
     616           0 :         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
     617             :                 SEC_STD_READ_CONTROL | SEC_FILE_WRITE_ATTRIBUTE |
     618             :                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
     619             :                 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
     620             :                 SEC_FILE_WRITE_DATA;
     621           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     622           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     623           0 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     624             :                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
     625           0 :         io.smb2.in.alloc_size = 0;
     626           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     627           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     628           0 :         io.smb2.in.security_flags = 0;
     629           0 :         io.smb2.in.fname = BASEDIR;
     630             : 
     631           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     632           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     633           0 :         dh = io.smb2.out.file.handle;
     634             : 
     635             : 
     636           0 :         torture_comment(torture, "Creating test file\n");
     637             : 
     638           0 :         ZERO_STRUCT(io.smb2);
     639           0 :         io.generic.level = RAW_OPEN_SMB2;
     640           0 :         io.smb2.in.create_flags = 0;
     641           0 :         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
     642             :                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
     643             :                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
     644             :                 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
     645           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     646           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     647           0 :         io.smb2.in.share_access = 0;
     648           0 :         io.smb2.in.alloc_size = 0;
     649           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     650           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     651           0 :         io.smb2.in.security_flags = 0;
     652           0 :         io.smb2.in.fname = BASEDIR "\\file.txt";
     653             : 
     654           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     655           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     656           0 :         fh = io.smb2.out.file.handle;
     657             : 
     658           0 :         torture_comment(torture, "Renaming test file\n");
     659             : 
     660           0 :         ZERO_STRUCT(sinfo);
     661           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     662           0 :         sinfo.rename_information.in.file.handle = fh;
     663           0 :         sinfo.rename_information.in.overwrite = 0;
     664           0 :         sinfo.rename_information.in.root_fid = 0;
     665           0 :         sinfo.rename_information.in.new_name =
     666             :                 BASEDIR "\\newname.txt";
     667           0 :         status = smb2_setinfo_file(tree1, &sinfo);
     668           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     669             : 
     670           0 :         torture_comment(torture, "Checking for new filename\n");
     671             : 
     672           0 :         ZERO_STRUCT(fi);
     673           0 :         fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     674           0 :         fi.generic.in.file.handle = fh;
     675           0 :         status = smb2_getinfo_file(tree1, torture, &fi);
     676           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     677             : 
     678             : 
     679           0 :         torture_comment(torture, "Closing test file\n");
     680             : 
     681           0 :         ZERO_STRUCT(cl.smb2);
     682           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     683           0 :         cl.smb2.in.file.handle = fh;
     684           0 :         status = smb2_close(tree1, &(cl.smb2));
     685           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     686             : 
     687           0 :         ZERO_STRUCT(fh);
     688             : 
     689           0 :         torture_comment(torture, "Closing directory\n");
     690             : 
     691           0 :         ZERO_STRUCT(cl.smb2);
     692           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     693           0 :         cl.smb2.in.file.handle = dh;
     694           0 :         status = smb2_close(tree1, &(cl.smb2));
     695           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     696             : 
     697           0 :         ZERO_STRUCT(dh);
     698             : 
     699             : 
     700           0 : done:
     701             : 
     702           0 :         torture_comment(torture, "Cleaning up\n");
     703             : 
     704           0 :         if (fh.data[0] || fh.data[1]) {
     705           0 :                 ZERO_STRUCT(cl.smb2);
     706           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     707           0 :                 cl.smb2.in.file.handle = fh;
     708           0 :                 status = smb2_close(tree1, &(cl.smb2));
     709             :         }
     710           0 :         if (dh.data[0] || dh.data[1]) {
     711           0 :                 ZERO_STRUCT(cl.smb2);
     712           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     713           0 :                 cl.smb2.in.file.handle = dh;
     714           0 :                 status = smb2_close(tree1, &(cl.smb2));
     715             :         }
     716             : 
     717           0 :         smb2_deltree(tree1, BASEDIR);
     718           0 :         return ret;
     719             : }
     720             : 
     721             : 
     722             : /*
     723             :  * testing of rename with no delete access on parent dir
     724             :  * this is the negative case of the test above: parent dir is opened
     725             :  * without share_delete, so rename must fail
     726             :  */
     727             : 
     728           0 : static bool torture_smb2_rename_no_delete_access2(struct torture_context *torture,
     729             :                 struct smb2_tree *tree1)
     730             : {
     731           0 :         bool ret = true;
     732             :         NTSTATUS status;
     733             :         union smb_open io;
     734             :         union smb_close cl;
     735             :         union smb_setfileinfo sinfo;
     736             :         struct smb2_handle fh, dh;
     737             : 
     738           0 :         ZERO_STRUCT(fh);
     739           0 :         ZERO_STRUCT(dh);
     740             : 
     741           0 :         smb2_deltree(tree1, BASEDIR);
     742           0 :         smb2_util_rmdir(tree1, BASEDIR);
     743             : 
     744           0 :         torture_comment(torture, "Creating base directory\n");
     745             : 
     746           0 :         smb2_util_mkdir(tree1, BASEDIR);
     747             : 
     748           0 :         torture_comment(torture, "Opening parent directory\n");
     749             : 
     750           0 :         ZERO_STRUCT(io.smb2);
     751           0 :         io.generic.level = RAW_OPEN_SMB2;
     752           0 :         io.smb2.in.create_flags = 0;
     753           0 :         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
     754             :                 SEC_STD_READ_CONTROL | SEC_FILE_WRITE_ATTRIBUTE |
     755             :                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_EXECUTE | SEC_FILE_WRITE_EA |
     756             :                 SEC_FILE_READ_EA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA |
     757             :                 SEC_FILE_WRITE_DATA;
     758           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     759           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     760           0 :         io.smb2.in.share_access = 0;
     761           0 :         io.smb2.in.alloc_size = 0;
     762           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     763           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     764           0 :         io.smb2.in.security_flags = 0;
     765           0 :         io.smb2.in.fname = BASEDIR;
     766             : 
     767           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     768           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     769           0 :         dh = io.smb2.out.file.handle;
     770             : 
     771             : 
     772           0 :         torture_comment(torture, "Creating test file\n");
     773             : 
     774           0 :         ZERO_STRUCT(io.smb2);
     775           0 :         io.generic.level = RAW_OPEN_SMB2;
     776           0 :         io.smb2.in.create_flags = 0;
     777           0 :         io.smb2.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_STD_WRITE_DAC |
     778             :                 SEC_STD_READ_CONTROL | SEC_STD_DELETE | SEC_FILE_WRITE_ATTRIBUTE |
     779             :                 SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_EA |
     780             :                 SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA;
     781           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     782           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     783           0 :         io.smb2.in.share_access = 0;
     784           0 :         io.smb2.in.alloc_size = 0;
     785           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     786           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     787           0 :         io.smb2.in.security_flags = 0;
     788           0 :         io.smb2.in.fname = BASEDIR "\\file.txt";
     789             : 
     790           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     791           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     792           0 :         fh = io.smb2.out.file.handle;
     793             : 
     794           0 :         torture_comment(torture, "Renaming test file\n");
     795             : 
     796           0 :         ZERO_STRUCT(sinfo);
     797           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     798           0 :         sinfo.rename_information.in.file.handle = fh;
     799           0 :         sinfo.rename_information.in.overwrite = 0;
     800           0 :         sinfo.rename_information.in.root_fid = 0;
     801           0 :         sinfo.rename_information.in.new_name =
     802             :                 BASEDIR "\\newname.txt";
     803           0 :         status = smb2_setinfo_file(tree1, &sinfo);
     804           0 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     805             : 
     806           0 :         torture_comment(torture, "Closing test file\n");
     807             : 
     808           0 :         ZERO_STRUCT(cl.smb2);
     809           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     810           0 :         cl.smb2.in.file.handle = fh;
     811           0 :         status = smb2_close(tree1, &(cl.smb2));
     812           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     813             : 
     814           0 :         ZERO_STRUCT(fh);
     815             : 
     816           0 :         torture_comment(torture, "Closing directory\n");
     817             : 
     818           0 :         ZERO_STRUCT(cl.smb2);
     819           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     820           0 :         cl.smb2.in.file.handle = dh;
     821           0 :         status = smb2_close(tree1, &(cl.smb2));
     822           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     823             : 
     824           0 :         ZERO_STRUCT(dh);
     825             : 
     826             : 
     827           0 : done:
     828             : 
     829           0 :         torture_comment(torture, "Cleaning up\n");
     830             : 
     831           0 :         if (fh.data[0] || fh.data[1]) {
     832           0 :                 ZERO_STRUCT(cl.smb2);
     833           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     834           0 :                 cl.smb2.in.file.handle = fh;
     835           0 :                 status = smb2_close(tree1, &(cl.smb2));
     836             :         }
     837           0 :         if (dh.data[0] || dh.data[1]) {
     838           0 :                 ZERO_STRUCT(cl.smb2);
     839           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     840           0 :                 cl.smb2.in.file.handle = dh;
     841           0 :                 status = smb2_close(tree1, &(cl.smb2));
     842             :         }
     843             : 
     844           0 :         smb2_deltree(tree1, BASEDIR);
     845           0 :         return ret;
     846             : }
     847             : 
     848             : /*
     849             :  * this is a replay of how Word 2010 saves a file
     850             :  * this should pass
     851             :  */
     852             : 
     853           0 : static bool torture_smb2_rename_msword(struct torture_context *torture,
     854             :                 struct smb2_tree *tree1)
     855             : {
     856           0 :         bool ret = true;
     857             :         NTSTATUS status;
     858             :         union smb_open io;
     859             :         union smb_close cl;
     860             :         union smb_setfileinfo sinfo;
     861             :         union smb_fileinfo fi;
     862             :         struct smb2_handle fh, dh;
     863             : 
     864           0 :         ZERO_STRUCT(fh);
     865           0 :         ZERO_STRUCT(dh);
     866             : 
     867           0 :         smb2_deltree(tree1, BASEDIR);
     868           0 :         smb2_util_rmdir(tree1, BASEDIR);
     869             : 
     870           0 :         torture_comment(torture, "Creating base directory\n");
     871             : 
     872           0 :         smb2_util_mkdir(tree1, BASEDIR);
     873             : 
     874           0 :         torture_comment(torture, "Creating test file\n");
     875             : 
     876           0 :         ZERO_STRUCT(io.smb2);
     877           0 :         io.generic.level = RAW_OPEN_SMB2;
     878           0 :         io.smb2.in.create_flags = 0;
     879           0 :         io.smb2.in.desired_access = 0x0017019f;
     880           0 :         io.smb2.in.create_options = 0x60;
     881           0 :         io.smb2.in.file_attributes = 0;
     882           0 :         io.smb2.in.share_access = 0;
     883           0 :         io.smb2.in.alloc_size = 0;
     884           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     885           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     886           0 :         io.smb2.in.security_flags = 0;
     887           0 :         io.smb2.in.fname = BASEDIR "\\file.txt";
     888             : 
     889           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     890           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     891           0 :         fh = io.smb2.out.file.handle;
     892             : 
     893           0 :         torture_comment(torture, "Opening parent directory\n");
     894             : 
     895           0 :         ZERO_STRUCT(io.smb2);
     896           0 :         io.generic.level = RAW_OPEN_SMB2;
     897           0 :         io.smb2.in.create_flags = 0;
     898           0 :         io.smb2.in.desired_access = 0x00100080;
     899           0 :         io.smb2.in.create_options = 0x00800021;
     900           0 :         io.smb2.in.file_attributes = 0;
     901           0 :         io.smb2.in.share_access = 0;
     902           0 :         io.smb2.in.alloc_size = 0;
     903           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     904           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     905           0 :         io.smb2.in.security_flags = 0;
     906           0 :         io.smb2.in.fname = BASEDIR;
     907             : 
     908           0 :         status = smb2_create(tree1, torture, &(io.smb2));
     909           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     910           0 :         dh = io.smb2.out.file.handle;
     911             : 
     912           0 :         torture_comment(torture, "Renaming test file\n");
     913             : 
     914           0 :         ZERO_STRUCT(sinfo);
     915           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
     916           0 :         sinfo.rename_information.in.file.handle = fh;
     917           0 :         sinfo.rename_information.in.overwrite = 0;
     918           0 :         sinfo.rename_information.in.root_fid = 0;
     919           0 :         sinfo.rename_information.in.new_name =
     920             :                 BASEDIR "\\newname.txt";
     921           0 :         status = smb2_setinfo_file(tree1, &sinfo);
     922           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     923             : 
     924           0 :         torture_comment(torture, "Checking for new filename\n");
     925             : 
     926           0 :         ZERO_STRUCT(fi);
     927           0 :         fi.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     928           0 :         fi.generic.in.file.handle = fh;
     929           0 :         status = smb2_getinfo_file(tree1, torture, &fi);
     930           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     931             : 
     932             : 
     933           0 :         torture_comment(torture, "Closing test file\n");
     934             : 
     935           0 :         ZERO_STRUCT(cl.smb2);
     936           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     937           0 :         cl.smb2.in.file.handle = fh;
     938           0 :         status = smb2_close(tree1, &(cl.smb2));
     939           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     940             : 
     941           0 :         ZERO_STRUCT(fh);
     942             : 
     943           0 :         torture_comment(torture, "Closing directory\n");
     944             : 
     945           0 :         ZERO_STRUCT(cl.smb2);
     946           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
     947           0 :         cl.smb2.in.file.handle = dh;
     948           0 :         status = smb2_close(tree1, &(cl.smb2));
     949           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     950             : 
     951           0 :         ZERO_STRUCT(dh);
     952             : 
     953             : 
     954           0 : done:
     955             : 
     956           0 :         torture_comment(torture, "Cleaning up\n");
     957             : 
     958           0 :         if (fh.data[0] || fh.data[1]) {
     959           0 :                 ZERO_STRUCT(cl.smb2);
     960           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     961           0 :                 cl.smb2.in.file.handle = fh;
     962           0 :                 status = smb2_close(tree1, &(cl.smb2));
     963             :         }
     964           0 :         if (dh.data[0] || dh.data[1]) {
     965           0 :                 ZERO_STRUCT(cl.smb2);
     966           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
     967           0 :                 cl.smb2.in.file.handle = dh;
     968           0 :                 status = smb2_close(tree1, &(cl.smb2));
     969             :         }
     970             : 
     971           0 :         smb2_deltree(tree1, BASEDIR);
     972           0 :         return ret;
     973             : }
     974             : 
     975           0 : static bool torture_smb2_rename_dir_openfile(struct torture_context *torture,
     976             :                                              struct smb2_tree *tree1)
     977             : {
     978           0 :         bool ret = true;
     979             :         NTSTATUS status;
     980             :         union smb_open io;
     981             :         union smb_close cl;
     982             :         union smb_setfileinfo sinfo;
     983             :         struct smb2_handle d1, h1;
     984             : 
     985           0 :         ZERO_STRUCT(d1);
     986           0 :         ZERO_STRUCT(h1);
     987             : 
     988           0 :         smb2_deltree(tree1, BASEDIR);
     989           0 :         smb2_util_rmdir(tree1, BASEDIR);
     990             : 
     991           0 :         torture_comment(torture, "Creating base directory\n");
     992             : 
     993           0 :         ZERO_STRUCT(io.smb2);
     994           0 :         io.generic.level = RAW_OPEN_SMB2;
     995           0 :         io.smb2.in.create_flags = 0;
     996           0 :         io.smb2.in.desired_access = 0x0017019f;
     997           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     998           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     999           0 :         io.smb2.in.share_access = 0;
    1000           0 :         io.smb2.in.alloc_size = 0;
    1001           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    1002           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    1003           0 :         io.smb2.in.security_flags = 0;
    1004           0 :         io.smb2.in.fname = BASEDIR;
    1005             : 
    1006           0 :         status = smb2_create(tree1, torture, &(io.smb2));
    1007           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1008           0 :         d1 = io.smb2.out.file.handle;
    1009             : 
    1010           0 :         torture_comment(torture, "Creating test file\n");
    1011             : 
    1012           0 :         ZERO_STRUCT(io.smb2);
    1013           0 :         io.generic.level = RAW_OPEN_SMB2;
    1014           0 :         io.smb2.in.create_flags = 0;
    1015           0 :         io.smb2.in.desired_access = 0x0017019f;
    1016           0 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
    1017           0 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1018           0 :         io.smb2.in.share_access = 0;
    1019           0 :         io.smb2.in.alloc_size = 0;
    1020           0 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    1021           0 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    1022           0 :         io.smb2.in.security_flags = 0;
    1023           0 :         io.smb2.in.fname = BASEDIR "\\file.txt";
    1024             : 
    1025           0 :         status = smb2_create(tree1, torture, &(io.smb2));
    1026           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1027           0 :         h1 = io.smb2.out.file.handle;
    1028             : 
    1029           0 :         torture_comment(torture, "Renaming directory\n");
    1030             : 
    1031           0 :         ZERO_STRUCT(sinfo);
    1032           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
    1033           0 :         sinfo.rename_information.in.file.handle = d1;
    1034           0 :         sinfo.rename_information.in.overwrite = 0;
    1035           0 :         sinfo.rename_information.in.root_fid = 0;
    1036           0 :         sinfo.rename_information.in.new_name =
    1037             :                 BASEDIR "-new";
    1038           0 :         status = smb2_setinfo_file(tree1, &sinfo);
    1039           0 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1040             : 
    1041           0 :         torture_comment(torture, "Closing directory\n");
    1042             : 
    1043           0 :         ZERO_STRUCT(cl.smb2);
    1044           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
    1045           0 :         cl.smb2.in.file.handle = d1;
    1046           0 :         status = smb2_close(tree1, &(cl.smb2));
    1047           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1048           0 :         ZERO_STRUCT(d1);
    1049             : 
    1050           0 :         torture_comment(torture, "Closing test file\n");
    1051             : 
    1052           0 :         cl.smb2.in.file.handle = h1;
    1053           0 :         status = smb2_close(tree1, &(cl.smb2));
    1054           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1055           0 :         ZERO_STRUCT(h1);
    1056             : 
    1057           0 : done:
    1058             : 
    1059           0 :         torture_comment(torture, "Cleaning up\n");
    1060             : 
    1061           0 :         if (h1.data[0] || h1.data[1]) {
    1062           0 :                 ZERO_STRUCT(cl.smb2);
    1063           0 :                 cl.smb2.level = RAW_CLOSE_SMB2;
    1064           0 :                 cl.smb2.in.file.handle = h1;
    1065           0 :                 status = smb2_close(tree1, &(cl.smb2));
    1066             :         }
    1067           0 :         smb2_deltree(tree1, BASEDIR);
    1068           0 :         return ret;
    1069             : }
    1070             : 
    1071             : struct rename_one_dir_cycle_state {
    1072             :         struct tevent_context *ev;
    1073             :         struct smb2_tree *tree;
    1074             :         struct smb2_handle file;
    1075             :         const char *base_name;
    1076             :         char *new_name;
    1077             :         unsigned *rename_counter;
    1078             : 
    1079             :         unsigned current;
    1080             :         unsigned max;
    1081             :         union smb_setfileinfo sinfo;
    1082             : };
    1083             : 
    1084             : static void rename_one_dir_cycle_done(struct smb2_request *subreq);
    1085             : 
    1086           0 : static struct tevent_req *rename_one_dir_cycle_send(TALLOC_CTX *mem_ctx,
    1087             :                                                     struct tevent_context *ev,
    1088             :                                                     struct smb2_tree *tree,
    1089             :                                                     struct smb2_handle file,
    1090             :                                                     unsigned max_renames,
    1091             :                                                     const char *base_name,
    1092             :                                                     unsigned *rename_counter)
    1093             : {
    1094             :         struct tevent_req *req;
    1095             :         struct rename_one_dir_cycle_state *state;
    1096             :         struct smb2_request *subreq;
    1097             : 
    1098           0 :         req = tevent_req_create(mem_ctx, &state,
    1099             :                                 struct rename_one_dir_cycle_state);
    1100           0 :         if (req == NULL) {
    1101           0 :                 return NULL;
    1102             :         }
    1103           0 :         state->ev = ev;
    1104           0 :         state->tree = tree;
    1105           0 :         state->file = file;
    1106           0 :         state->base_name = base_name;
    1107           0 :         state->rename_counter = rename_counter;
    1108           0 :         state->current = 0;
    1109           0 :         state->max = max_renames;
    1110             : 
    1111           0 :         ZERO_STRUCT(state->sinfo);
    1112           0 :         state->sinfo.rename_information.level =
    1113             :                 RAW_SFILEINFO_RENAME_INFORMATION;
    1114           0 :         state->sinfo.rename_information.in.file.handle = state->file;
    1115           0 :         state->sinfo.rename_information.in.overwrite = 0;
    1116           0 :         state->sinfo.rename_information.in.root_fid = 0;
    1117             : 
    1118           0 :         state->new_name = talloc_asprintf(
    1119           0 :                 state, "%s-%u", state->base_name, state->current);
    1120           0 :         if (tevent_req_nomem(state->new_name, req)) {
    1121           0 :                 return tevent_req_post(req, ev);
    1122             :         }
    1123           0 :         state->sinfo.rename_information.in.new_name = state->new_name;
    1124             : 
    1125           0 :         subreq = smb2_setinfo_file_send(state->tree, &state->sinfo);
    1126           0 :         if (tevent_req_nomem(subreq, req)) {
    1127           0 :                 return tevent_req_post(req, ev);
    1128             :         }
    1129           0 :         subreq->async.fn = rename_one_dir_cycle_done;
    1130           0 :         subreq->async.private_data = req;
    1131           0 :         return req;
    1132             : }
    1133             : 
    1134           0 : static void rename_one_dir_cycle_done(struct smb2_request *subreq)
    1135             : {
    1136           0 :         struct tevent_req *req = talloc_get_type_abort(
    1137             :                 subreq->async.private_data, struct tevent_req);
    1138           0 :         struct rename_one_dir_cycle_state *state = tevent_req_data(
    1139             :                 req, struct rename_one_dir_cycle_state);
    1140             :         NTSTATUS status;
    1141             : 
    1142           0 :         status = smb2_setinfo_recv(subreq);
    1143           0 :         if (tevent_req_nterror(req, status)) {
    1144           0 :                 return;
    1145             :         }
    1146           0 :         TALLOC_FREE(state->new_name);
    1147             : 
    1148           0 :         *state->rename_counter += 1;
    1149             : 
    1150           0 :         state->current += 1;
    1151           0 :         if (state->current >= state->max) {
    1152           0 :                 tevent_req_done(req);
    1153           0 :                 return;
    1154             :         }
    1155             : 
    1156           0 :         ZERO_STRUCT(state->sinfo);
    1157           0 :         state->sinfo.rename_information.level =
    1158             :                 RAW_SFILEINFO_RENAME_INFORMATION;
    1159           0 :         state->sinfo.rename_information.in.file.handle = state->file;
    1160           0 :         state->sinfo.rename_information.in.overwrite = 0;
    1161           0 :         state->sinfo.rename_information.in.root_fid = 0;
    1162             : 
    1163           0 :         state->new_name = talloc_asprintf(
    1164             :                 state, "%s-%u", state->base_name, state->current);
    1165           0 :         if (tevent_req_nomem(state->new_name, req)) {
    1166           0 :                 return;
    1167             :         }
    1168           0 :         state->sinfo.rename_information.in.new_name = state->new_name;
    1169             : 
    1170           0 :         subreq = smb2_setinfo_file_send(state->tree, &state->sinfo);
    1171           0 :         if (tevent_req_nomem(subreq, req)) {
    1172           0 :                 return;
    1173             :         }
    1174           0 :         subreq->async.fn = rename_one_dir_cycle_done;
    1175           0 :         subreq->async.private_data = req;
    1176             : }
    1177             : 
    1178           0 : static NTSTATUS rename_one_dir_cycle_recv(struct tevent_req *req)
    1179             : {
    1180           0 :         return tevent_req_simple_recv_ntstatus(req);
    1181             : }
    1182             : 
    1183             : struct rename_dir_bench_state {
    1184             :         struct tevent_context *ev;
    1185             :         struct smb2_tree *tree;
    1186             :         const char *base_name;
    1187             :         unsigned max_renames;
    1188             :         unsigned *rename_counter;
    1189             : 
    1190             :         struct smb2_create io;
    1191             :         union smb_setfileinfo sinfo;
    1192             :         struct smb2_close cl;
    1193             : 
    1194             :         struct smb2_handle file;
    1195             : };
    1196             : 
    1197             : static void rename_dir_bench_opened(struct smb2_request *subreq);
    1198             : static void rename_dir_bench_renamed(struct tevent_req *subreq);
    1199             : static void rename_dir_bench_set_doc(struct smb2_request *subreq);
    1200             : static void rename_dir_bench_closed(struct smb2_request *subreq);
    1201             : 
    1202           0 : static struct tevent_req *rename_dir_bench_send(TALLOC_CTX *mem_ctx,
    1203             :                                                 struct tevent_context *ev,
    1204             :                                                 struct smb2_tree *tree,
    1205             :                                                 const char *base_name,
    1206             :                                                 unsigned max_renames,
    1207             :                                                 unsigned *rename_counter)
    1208             : {
    1209             :         struct tevent_req *req;
    1210             :         struct rename_dir_bench_state *state;
    1211             :         struct smb2_request *subreq;
    1212             : 
    1213           0 :         req = tevent_req_create(mem_ctx, &state,
    1214             :                                 struct rename_dir_bench_state);
    1215           0 :         if (req == NULL) {
    1216           0 :                 return NULL;
    1217             :         }
    1218           0 :         state->ev = ev;
    1219           0 :         state->tree = tree;
    1220           0 :         state->base_name = base_name;
    1221           0 :         state->max_renames = max_renames;
    1222           0 :         state->rename_counter = rename_counter;
    1223             : 
    1224           0 :         ZERO_STRUCT(state->io);
    1225           0 :         state->io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
    1226           0 :         state->io.in.share_access =
    1227             :                 NTCREATEX_SHARE_ACCESS_READ|
    1228             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    1229           0 :         state->io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1230           0 :         state->io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1231           0 :         state->io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    1232           0 :         state->io.in.fname = state->base_name;
    1233             : 
    1234           0 :         subreq = smb2_create_send(state->tree, &state->io);
    1235           0 :         if (tevent_req_nomem(subreq, req)) {
    1236           0 :                 return tevent_req_post(req, ev);
    1237             :         }
    1238           0 :         subreq->async.fn = rename_dir_bench_opened;
    1239           0 :         subreq->async.private_data = req;
    1240           0 :         return req;
    1241             : }
    1242             : 
    1243           0 : static void rename_dir_bench_opened(struct smb2_request *subreq)
    1244             : {
    1245           0 :         struct tevent_req *req = talloc_get_type_abort(
    1246             :                 subreq->async.private_data, struct tevent_req);
    1247           0 :         struct rename_dir_bench_state *state = tevent_req_data(
    1248             :                 req, struct rename_dir_bench_state);
    1249             :         struct smb2_create *io;
    1250             :         struct tevent_req *subreq2;
    1251             :         NTSTATUS status;
    1252             : 
    1253           0 :         io = talloc(state, struct smb2_create);
    1254           0 :         if (tevent_req_nomem(io, req)) {
    1255           0 :                 return;
    1256             :         }
    1257             : 
    1258           0 :         status = smb2_create_recv(subreq, io, io);
    1259           0 :         if (tevent_req_nterror(req, status)) {
    1260           0 :                 return;
    1261             :         }
    1262           0 :         state->file = io->out.file.handle;
    1263           0 :         TALLOC_FREE(io);
    1264             : 
    1265           0 :         subreq2 = rename_one_dir_cycle_send(
    1266             :                 state, state->ev, state->tree, state->file,
    1267             :                 state->max_renames, state->base_name,
    1268             :                 state->rename_counter);
    1269           0 :         if (tevent_req_nomem(subreq2, req)) {
    1270           0 :                 return;
    1271             :         }
    1272           0 :         tevent_req_set_callback(subreq2, rename_dir_bench_renamed, req);
    1273             : }
    1274             : 
    1275           0 : static void rename_dir_bench_renamed(struct tevent_req *subreq)
    1276             : {
    1277           0 :         struct tevent_req *req = tevent_req_callback_data(
    1278             :                 subreq, struct tevent_req);
    1279           0 :         struct rename_dir_bench_state *state = tevent_req_data(
    1280             :                 req, struct rename_dir_bench_state);
    1281             :         struct smb2_request *subreq2;
    1282             :         NTSTATUS status;
    1283             : 
    1284           0 :         status = rename_one_dir_cycle_recv(subreq);
    1285           0 :         TALLOC_FREE(subreq);
    1286           0 :         if (tevent_req_nterror(req, status)) {
    1287           0 :                 return;
    1288             :         }
    1289             : 
    1290           0 :         ZERO_STRUCT(state->sinfo);
    1291           0 :         state->sinfo.disposition_info.level =
    1292             :                 RAW_SFILEINFO_DISPOSITION_INFORMATION;
    1293           0 :         state->sinfo.disposition_info.in.file.handle = state->file;
    1294           0 :         state->sinfo.disposition_info.in.delete_on_close = true;
    1295             : 
    1296           0 :         subreq2 = smb2_setinfo_file_send(state->tree, &state->sinfo);
    1297           0 :         if (tevent_req_nomem(subreq2, req)) {
    1298           0 :                 return;
    1299             :         }
    1300           0 :         subreq2->async.fn = rename_dir_bench_set_doc;
    1301           0 :         subreq2->async.private_data = req;
    1302             : }
    1303             : 
    1304           0 : static void rename_dir_bench_set_doc(struct smb2_request *subreq)
    1305             : {
    1306           0 :         struct tevent_req *req = talloc_get_type_abort(
    1307             :                 subreq->async.private_data, struct tevent_req);
    1308           0 :         struct rename_dir_bench_state *state = tevent_req_data(
    1309             :                 req, struct rename_dir_bench_state);
    1310             :         NTSTATUS status;
    1311             : 
    1312           0 :         status = smb2_setinfo_recv(subreq);
    1313           0 :         if (tevent_req_nterror(req, status)) {
    1314           0 :                 return;
    1315             :         }
    1316             : 
    1317           0 :         ZERO_STRUCT(state->cl);
    1318           0 :         state->cl.in.file.handle = state->file;
    1319             : 
    1320           0 :         subreq = smb2_close_send(state->tree, &state->cl);
    1321           0 :         if (tevent_req_nomem(subreq, req)) {
    1322           0 :                 return;
    1323             :         }
    1324           0 :         subreq->async.fn = rename_dir_bench_closed;
    1325           0 :         subreq->async.private_data = req;
    1326             : }
    1327             : 
    1328           0 : static void rename_dir_bench_closed(struct smb2_request *subreq)
    1329             : {
    1330           0 :         struct tevent_req *req = talloc_get_type_abort(
    1331             :                 subreq->async.private_data, struct tevent_req);
    1332             :         struct smb2_close cl;
    1333             :         NTSTATUS status;
    1334             : 
    1335           0 :         status = smb2_close_recv(subreq, &cl);
    1336           0 :         if (tevent_req_nterror(req, status)) {
    1337           0 :                 return;
    1338             :         }
    1339           0 :         tevent_req_done(req);
    1340             : }
    1341             : 
    1342           0 : static NTSTATUS rename_dir_bench_recv(struct tevent_req *req)
    1343             : {
    1344           0 :         return tevent_req_simple_recv_ntstatus(req);
    1345             : }
    1346             : 
    1347             : struct rename_dirs_bench_state {
    1348             :         unsigned num_reqs;
    1349             :         unsigned num_done;
    1350             : };
    1351             : 
    1352             : static void rename_dirs_bench_done(struct tevent_req *subreq);
    1353             : 
    1354           0 : static struct tevent_req *rename_dirs_bench_send(TALLOC_CTX *mem_ctx,
    1355             :                                                  struct tevent_context *ev,
    1356             :                                                  struct smb2_tree *tree,
    1357             :                                                  const char *base_name,
    1358             :                                                  unsigned num_parallel,
    1359             :                                                  unsigned max_renames,
    1360             :                                                  unsigned *rename_counter)
    1361             : {
    1362             :         struct tevent_req *req;
    1363             :         struct rename_dirs_bench_state *state;
    1364             :         unsigned i;
    1365             : 
    1366           0 :         req = tevent_req_create(mem_ctx, &state,
    1367             :                                 struct rename_dirs_bench_state);
    1368           0 :         if (req == NULL) {
    1369           0 :                 return NULL;
    1370             :         }
    1371           0 :         state->num_reqs = num_parallel;
    1372           0 :         state->num_done = 0;
    1373             : 
    1374           0 :         for (i=0; i<num_parallel; i++) {
    1375             :                 struct tevent_req *subreq;
    1376             :                 char *sub_base;
    1377             : 
    1378           0 :                 sub_base = talloc_asprintf(state, "%s-%u", base_name, i);
    1379           0 :                 if (tevent_req_nomem(sub_base, req)) {
    1380           0 :                         return tevent_req_post(req, ev);
    1381             :                 }
    1382             : 
    1383           0 :                 subreq = rename_dir_bench_send(state, ev, tree, sub_base,
    1384             :                                                max_renames, rename_counter);
    1385           0 :                 if (tevent_req_nomem(subreq, req)) {
    1386           0 :                         return tevent_req_post(req, ev);
    1387             :                 }
    1388           0 :                 tevent_req_set_callback(subreq, rename_dirs_bench_done, req);
    1389             :         }
    1390           0 :         return req;
    1391             : }
    1392             : 
    1393           0 : static void rename_dirs_bench_done(struct tevent_req *subreq)
    1394             : {
    1395           0 :         struct tevent_req *req = tevent_req_callback_data(
    1396             :                 subreq, struct tevent_req);
    1397           0 :         struct rename_dirs_bench_state *state = tevent_req_data(
    1398             :                 req, struct rename_dirs_bench_state);
    1399             :         NTSTATUS status;
    1400             : 
    1401           0 :         status = rename_dir_bench_recv(subreq);
    1402           0 :         TALLOC_FREE(subreq);
    1403           0 :         if (tevent_req_nterror(req, status)) {
    1404           0 :                 return;
    1405             :         }
    1406             : 
    1407           0 :         state->num_done += 1;
    1408           0 :         if (state->num_done >= state->num_reqs) {
    1409           0 :                 tevent_req_done(req);
    1410             :         }
    1411             : }
    1412             : 
    1413           0 : static NTSTATUS rename_dirs_bench_recv(struct tevent_req *req)
    1414             : {
    1415           0 :         return tevent_req_simple_recv_ntstatus(req);
    1416             : }
    1417             : 
    1418           0 : static bool torture_smb2_rename_dir_bench(struct torture_context *tctx,
    1419             :                                           struct smb2_tree *tree)
    1420             : {
    1421             :         struct tevent_req *req;
    1422             :         NTSTATUS status;
    1423           0 :         unsigned counter = 0;
    1424             :         bool ret;
    1425             : 
    1426           0 :         req = rename_dirs_bench_send(tctx, tctx->ev, tree, "dir", 3, 10,
    1427             :                                      &counter);
    1428           0 :         torture_assert(tctx, req != NULL, "rename_dirs_bench_send failed");
    1429             : 
    1430           0 :         ret = tevent_req_poll(req, tctx->ev);
    1431           0 :         torture_assert(tctx, ret, "tevent_req_poll failed");
    1432             : 
    1433           0 :         status = rename_dirs_bench_recv(req);
    1434           0 :         torture_comment(tctx, "rename_dirs_bench returned %s\n",
    1435             :                         nt_errstr(status));
    1436           0 :         TALLOC_FREE(req);
    1437           0 :         torture_assert_ntstatus_ok(tctx, status, "bench failed");
    1438           0 :         return true;
    1439             : }
    1440             : 
    1441             : /*
    1442             :  * This test basically verifies that modify and change timestamps are preserved
    1443             :  * after file rename with outstanding open file handles.
    1444             :  */
    1445             : 
    1446           0 : static bool torture_smb2_rename_simple_modtime(
    1447             :                         struct torture_context *torture,
    1448             :                         struct smb2_tree *tree1)
    1449             : {
    1450             :         struct smb2_create c1, c2;
    1451             :         union smb_fileinfo gi;
    1452             :         union smb_setfileinfo si;
    1453           0 :         struct smb2_handle h1 = {{0}};
    1454           0 :         struct smb2_handle h2 = {{0}};
    1455             :         NTSTATUS status;
    1456           0 :         bool ret = true;
    1457             : 
    1458           0 :         smb2_deltree(tree1, BASEDIR);
    1459           0 :         smb2_util_mkdir(tree1, BASEDIR);
    1460             : 
    1461           0 :         torture_comment(torture, "Creating test file: file1.txt\n");
    1462             : 
    1463           0 :         c1 = (struct smb2_create) {
    1464             :                 .in.desired_access = SEC_FILE_ALL|SEC_STD_DELETE,
    1465             :                 .in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
    1466             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    1467             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    1468             :                 .in.create_disposition = NTCREATEX_DISP_CREATE,
    1469             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
    1470             :                 .in.fname = BASEDIR "\\file1.txt",
    1471             :         };
    1472             : 
    1473           0 :         status = smb2_create(tree1, torture, &c1);
    1474           0 :         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
    1475             :                                         "smb2_create failed\n");
    1476           0 :         h1 = c1.out.file.handle;
    1477             : 
    1478           0 :         torture_comment(torture, "Waitig for 5 secs..\n");
    1479           0 :         sleep(5);
    1480             : 
    1481           0 :         torture_comment(torture, "Creating test file: file2.txt\n");
    1482             : 
    1483           0 :         c2 = (struct smb2_create) {
    1484             :                 .in.desired_access = SEC_FILE_ALL|SEC_STD_DELETE,
    1485             :                 .in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
    1486             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    1487             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    1488             :                 .in.create_disposition = NTCREATEX_DISP_CREATE,
    1489             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
    1490             :                 .in.fname = BASEDIR "\\file2.txt",
    1491             :         };
    1492             : 
    1493           0 :         status = smb2_create(tree1, torture, &c2);
    1494           0 :         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
    1495             :                                         "smb2_create failed\n");
    1496           0 :         h2 = c2.out.file.handle;
    1497             : 
    1498           0 :         torture_comment(torture, "Renaming file1.txt --> tmp1.txt\n");
    1499             : 
    1500           0 :         si = (union smb_setfileinfo) {
    1501             :                 .rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION,
    1502             :                 .rename_information.in.file.handle = h1,
    1503             :                 .rename_information.in.new_name =
    1504             :                         BASEDIR "\\tmp1.txt",
    1505             :         };
    1506             : 
    1507           0 :         status = smb2_setinfo_file(tree1, &si);
    1508           0 :         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
    1509             :                                         "smb2_setinfo_file failed\n");
    1510             : 
    1511           0 :         torture_comment(torture, "GetInfo of tmp1.txt\n");
    1512             : 
    1513           0 :         gi = (union smb_fileinfo) {
    1514             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    1515             :                 .generic.in.file.handle = h1,
    1516             :         };
    1517             : 
    1518           0 :         status = smb2_getinfo_file(tree1, torture, &gi);
    1519           0 :         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
    1520             :                                         "smb2_getinfo_file failed\n");
    1521             : 
    1522           0 :         torture_comment(torture, "Check if timestamps are good after rename(file1.txt --> tmp1.txt).\n");
    1523             : 
    1524           0 :         torture_assert_nttime_equal(
    1525             :                 torture, c1.out.write_time, gi.all_info.out.write_time,
    1526             :                 "Bad timestamp\n");
    1527           0 :         torture_assert_nttime_equal(
    1528             :                 torture, c1.out.change_time, gi.all_info.out.change_time,
    1529             :                 "Bad timestamp\n");
    1530             : 
    1531           0 :         torture_comment(torture, "Renaming file2.txt --> file1.txt\n");
    1532             : 
    1533           0 :         si = (union smb_setfileinfo) {
    1534             :                 .rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION,
    1535             :                 .rename_information.in.file.handle = h2,
    1536             :                 .rename_information.in.new_name =
    1537             :                         BASEDIR "\\file1.txt",
    1538             :         };
    1539           0 :         status = smb2_setinfo_file(tree1, &si);
    1540           0 :         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
    1541             :                                         "smb2_setinfo_file failed\n");
    1542             : 
    1543           0 :         torture_comment(torture, "GetInfo of file1.txt\n");
    1544             : 
    1545           0 :         gi = (union smb_fileinfo) {
    1546             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    1547             :                 .generic.in.file.handle = h2,
    1548             :         };
    1549             : 
    1550           0 :         status = smb2_getinfo_file(tree1, torture, &gi);
    1551           0 :         torture_assert_ntstatus_ok_goto(torture, status, ret, done,
    1552             :                                         "smb2_getinfo_file failed\n");
    1553             : 
    1554           0 :         torture_comment(torture, "Check if timestamps are good after rename(file2.txt --> file1.txt).\n");
    1555             : 
    1556           0 :         torture_assert_nttime_equal(
    1557             :                 torture, c2.out.write_time, gi.all_info.out.write_time,
    1558             :                 "Bad timestamp\n");
    1559           0 :         torture_assert_nttime_equal(
    1560             :                 torture, c2.out.change_time, gi.all_info.out.change_time,
    1561             :                 "Bad timestamp\n");
    1562             : 
    1563           0 : done:
    1564           0 :         if (!smb2_util_handle_empty(h1)) {
    1565           0 :                 smb2_util_close(tree1, h1);
    1566             :         }
    1567           0 :         if (!smb2_util_handle_empty(h2)) {
    1568           0 :                 smb2_util_close(tree1, h2);
    1569             :         }
    1570           0 :         smb2_deltree(tree1, BASEDIR);
    1571           0 :         return ret;
    1572             : }
    1573             : 
    1574           0 : static bool test_smb2_close_full_information(struct torture_context *torture,
    1575             :                                         struct smb2_tree *tree1,
    1576             :                                         struct smb2_tree *tree2)
    1577             : {
    1578             :         union smb_close cl;
    1579           0 :         struct smb2_create io = {0};
    1580           0 :         struct smb2_handle h1 = {{0}};
    1581           0 :         struct smb2_handle h2 = {{0}};
    1582           0 :         struct smb2_handle h3 = {{0}};
    1583             :         union smb_setfileinfo sinfo;
    1584             :         NTSTATUS status;
    1585           0 :         const char *fname_src = "request.dat";
    1586           0 :         const char *fname_dst = "renamed.dat";
    1587           0 :         bool ret = true;
    1588             : 
    1589             :         /* Start with a tidy share. */
    1590           0 :         smb2_util_unlink(tree1, fname_src);
    1591           0 :         smb2_util_unlink(tree1, fname_dst);
    1592             : 
    1593             :         /* Create the test file, and leave it open. */
    1594           0 :         io.in.fname = fname_src;
    1595           0 :         io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE;
    1596           0 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1597           0 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1598             :                                 NTCREATEX_SHARE_ACCESS_WRITE |
    1599             :                                 NTCREATEX_SHARE_ACCESS_DELETE;
    1600           0 :         status = smb2_create(tree1, tree1, &io);
    1601           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1602           0 :         h1 = io.out.file.handle;
    1603           0 :         CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    1604             : 
    1605             :         /* Open the test file on the second connection. */
    1606           0 :         ZERO_STRUCT(io);
    1607           0 :         io.in.fname = fname_src;
    1608           0 :         io.in.desired_access = SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE;
    1609           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1610           0 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1611             :                                 NTCREATEX_SHARE_ACCESS_WRITE |
    1612             :                                 NTCREATEX_SHARE_ACCESS_DELETE;
    1613           0 :         status = smb2_create(tree2, tree2, &io);
    1614           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1615           0 :         h2 = io.out.file.handle;
    1616             : 
    1617             :         /* Now open for rename on the first connection. */
    1618           0 :         ZERO_STRUCT(io);
    1619           0 :         io.in.fname = fname_src;
    1620           0 :         io.in.desired_access = SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE;
    1621           0 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1622           0 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1623             :                                 NTCREATEX_SHARE_ACCESS_WRITE |
    1624             :                                 NTCREATEX_SHARE_ACCESS_DELETE;
    1625           0 :         status = smb2_create(tree1, tree1, &io);
    1626           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1627           0 :         h3 = io.out.file.handle;
    1628             : 
    1629             :         /* Do the rename. */
    1630           0 :         ZERO_STRUCT(sinfo);
    1631           0 :         sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
    1632           0 :         sinfo.rename_information.in.file.handle = h3;
    1633           0 :         sinfo.rename_information.in.new_name = fname_dst;
    1634           0 :         status = smb2_setinfo_file(tree1, &sinfo);
    1635           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1636             : 
    1637             :         /* And close h3. */
    1638           0 :         ZERO_STRUCT(cl.smb2);
    1639           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
    1640           0 :         cl.smb2.in.file.handle = h3;
    1641           0 :         status = smb2_close(tree1, &cl.smb2);
    1642           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1643           0 :         ZERO_STRUCT(h3);
    1644             : 
    1645             :         /*
    1646             :          * Close h1 with SMB2_CLOSE_FLAGS_FULL_INFORMATION.
    1647             :          * Ensure we get data.
    1648             :          */
    1649           0 :         ZERO_STRUCT(cl.smb2);
    1650           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
    1651           0 :         cl.smb2.in.file.handle = h1;
    1652           0 :         cl.smb2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
    1653           0 :         status = smb2_close(tree1, &cl.smb2);
    1654           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1655           0 :         ZERO_STRUCT(h1);
    1656           0 :         CHECK_VAL(cl.smb2.out.file_attr, 0x20);
    1657             : 
    1658             :         /*
    1659             :          * Wait 3 seconds for name change to propagate
    1660             :          * to the other connection.
    1661             :          */
    1662           0 :         sleep(3);
    1663             : 
    1664             :         /*
    1665             :          * Close h2 with SMB2_CLOSE_FLAGS_FULL_INFORMATION.
    1666             :          * This is on connection2.
    1667             :          * Ensure we get data.
    1668             :          */
    1669           0 :         ZERO_STRUCT(cl.smb2);
    1670           0 :         cl.smb2.level = RAW_CLOSE_SMB2;
    1671           0 :         cl.smb2.in.file.handle = h2;
    1672           0 :         cl.smb2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
    1673           0 :         status = smb2_close(tree2, &cl.smb2);
    1674           0 :         CHECK_STATUS(status, NT_STATUS_OK);
    1675           0 :         ZERO_STRUCT(h2);
    1676           0 :         CHECK_VAL(cl.smb2.out.file_attr, 0x20);
    1677             : 
    1678           0 :   done:
    1679             : 
    1680           0 :         if (h1.data[0] != 0 || h1.data[1] != 0) {
    1681           0 :                 smb2_util_close(tree1, h1);
    1682             :         }
    1683           0 :         if (h2.data[0] != 0 || h2.data[1] != 0) {
    1684           0 :                 smb2_util_close(tree2, h2);
    1685             :         }
    1686           0 :         if (h3.data[0] != 0 || h3.data[1] != 0) {
    1687           0 :                 smb2_util_close(tree1, h3);
    1688             :         }
    1689             : 
    1690           0 :         smb2_util_unlink(tree1, fname_src);
    1691           0 :         smb2_util_unlink(tree1, fname_dst);
    1692             : 
    1693           0 :         return ret;
    1694             : }
    1695             : 
    1696             : /*
    1697             :    basic testing of SMB2 rename
    1698             :  */
    1699         966 : struct torture_suite *torture_smb2_rename_init(TALLOC_CTX *ctx)
    1700             : {
    1701             :         struct torture_suite *suite =
    1702         966 :                 torture_suite_create(ctx, "rename");
    1703             : 
    1704         966 :         torture_suite_add_1smb2_test(suite, "simple",
    1705             :                 torture_smb2_rename_simple);
    1706             : 
    1707         966 :         torture_suite_add_1smb2_test(suite, "simple_modtime",
    1708             :                 torture_smb2_rename_simple_modtime);
    1709             : 
    1710         966 :         torture_suite_add_1smb2_test(suite, "simple_nodelete",
    1711             :                 torture_smb2_rename_simple2);
    1712             : 
    1713         966 :         torture_suite_add_1smb2_test(suite, "no_sharing",
    1714             :                 torture_smb2_rename_no_sharemode);
    1715             : 
    1716         966 :         torture_suite_add_1smb2_test(suite,
    1717             :                 "share_delete_and_delete_access",
    1718             :                 torture_smb2_rename_with_delete_access);
    1719             : 
    1720         966 :         torture_suite_add_1smb2_test(suite,
    1721             :                 "no_share_delete_but_delete_access",
    1722             :                 torture_smb2_rename_with_delete_access2);
    1723             : 
    1724         966 :         torture_suite_add_1smb2_test(suite,
    1725             :                 "share_delete_no_delete_access",
    1726             :                 torture_smb2_rename_no_delete_access);
    1727             : 
    1728         966 :         torture_suite_add_1smb2_test(suite,
    1729             :                 "no_share_delete_no_delete_access",
    1730             :                 torture_smb2_rename_no_delete_access2);
    1731             : 
    1732         966 :         torture_suite_add_1smb2_test(suite,
    1733             :                 "msword",
    1734             :                 torture_smb2_rename_msword);
    1735             : 
    1736         966 :         torture_suite_add_1smb2_test(
    1737             :                 suite, "rename_dir_openfile",
    1738             :                 torture_smb2_rename_dir_openfile);
    1739             : 
    1740         966 :         torture_suite_add_1smb2_test(suite,
    1741             :                 "rename_dir_bench",
    1742             :                 torture_smb2_rename_dir_bench);
    1743             : 
    1744         966 :         torture_suite_add_2smb2_test(suite,
    1745             :                 "close-full-information",
    1746             :                 test_smb2_close_full_information);
    1747             : 
    1748         966 :         suite->description = talloc_strdup(suite, "smb2.rename tests");
    1749             : 
    1750         966 :         return suite;
    1751             : }

Generated by: LCOV version 1.14