LCOV - code coverage report
Current view: top level - source4/torture/raw - rename.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 355 404 87.9 %
Date: 2024-06-13 04:01:37 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    rename test suite
       4             :    Copyright (C) Andrew Tridgell 2003
       5             :    
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             :    
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             :    
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "libcli/libcli.h"
      22             : #include "torture/util.h"
      23             : #include "torture/raw/proto.h"
      24             : 
      25             : #define CHECK_STATUS(status, correct) do { \
      26             :         if (!NT_STATUS_EQUAL(status, correct)) { \
      27             :                 torture_result(tctx, TORTURE_FAIL, \
      28             :                         "(%s) Incorrect status %s - should be %s\n", \
      29             :                         __location__, nt_errstr(status), nt_errstr(correct)); \
      30             :                 ret = false; \
      31             :                 goto done; \
      32             :         }} while (0)
      33             : 
      34             : #define CHECK_VALUE(v, correct) do { \
      35             :         if ((v) != (correct)) { \
      36             :                 torture_result(tctx, TORTURE_FAIL, \
      37             :                         "(%s) Incorrect %s %d - should be %d\n", \
      38             :                         __location__, #v, (int)v, (int)correct); \
      39             :                 ret = false; \
      40             :         }} while (0)
      41             : 
      42             : #define BASEDIR "\\testrename"
      43             : 
      44             : /*
      45             :   test SMBmv ops
      46             : */
      47           1 : static bool test_mv(struct torture_context *tctx, 
      48             :                                         struct smbcli_state *cli)
      49             : {
      50             :         union smb_rename io;
      51             :         NTSTATUS status;
      52           1 :         bool ret = true;
      53           1 :         int fnum = -1;
      54           1 :         const char *fname1 = BASEDIR "\\test1.txt";
      55           1 :         const char *fname2 = BASEDIR "\\test2.txt";
      56           1 :         const char *Fname1 = BASEDIR "\\Test1.txt";
      57             :         union smb_fileinfo finfo;
      58             :         union smb_open op;
      59             : 
      60           1 :         torture_comment(tctx, "Testing SMBmv\n");
      61             : 
      62           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
      63             : 
      64           1 :         torture_comment(tctx, "Trying simple rename\n");
      65             : 
      66           1 :         op.generic.level = RAW_OPEN_NTCREATEX;
      67           1 :         op.ntcreatex.in.root_fid.fnum = 0;
      68           1 :         op.ntcreatex.in.flags = 0;
      69           1 :         op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
      70           1 :         op.ntcreatex.in.create_options = 0;
      71           1 :         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
      72           1 :         op.ntcreatex.in.share_access = 
      73             :                 NTCREATEX_SHARE_ACCESS_READ | 
      74             :                 NTCREATEX_SHARE_ACCESS_WRITE;
      75           1 :         op.ntcreatex.in.alloc_size = 0;
      76           1 :         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
      77           1 :         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
      78           1 :         op.ntcreatex.in.security_flags = 0;
      79           1 :         op.ntcreatex.in.fname = fname1;
      80             : 
      81           1 :         status = smb_raw_open(cli->tree, tctx, &op);
      82           1 :         CHECK_STATUS(status, NT_STATUS_OK);
      83           1 :         fnum = op.ntcreatex.out.file.fnum;
      84             : 
      85           1 :         io.generic.level = RAW_RENAME_RENAME;
      86           1 :         io.rename.in.pattern1 = fname1;
      87           1 :         io.rename.in.pattern2 = fname2;
      88           1 :         io.rename.in.attrib = 0;
      89             :         
      90           1 :         torture_comment(tctx, "trying rename while first file open\n");
      91           1 :         status = smb_raw_rename(cli->tree, &io);
      92           1 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
      93             : 
      94           1 :         smbcli_close(cli->tree, fnum);
      95             : 
      96           1 :         op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
      97           1 :         op.ntcreatex.in.share_access = 
      98             :                 NTCREATEX_SHARE_ACCESS_DELETE | 
      99             :                 NTCREATEX_SHARE_ACCESS_READ |
     100             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     101           1 :         status = smb_raw_open(cli->tree, tctx, &op);
     102           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     103           1 :         fnum = op.ntcreatex.out.file.fnum;
     104             : 
     105           1 :         torture_comment(tctx, "trying rename while first file open with SHARE_ACCESS_DELETE\n");
     106           1 :         status = smb_raw_rename(cli->tree, &io);
     107           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     108             : 
     109           1 :         io.rename.in.pattern1 = fname2;
     110           1 :         io.rename.in.pattern2 = fname1;
     111           1 :         status = smb_raw_rename(cli->tree, &io);
     112           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     113             : 
     114           1 :         torture_comment(tctx, "Trying case-changing rename\n");
     115           1 :         io.rename.in.pattern1 = fname1;
     116           1 :         io.rename.in.pattern2 = Fname1;
     117           1 :         status = smb_raw_rename(cli->tree, &io);
     118           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     119             : 
     120           1 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     121           1 :         finfo.all_info.in.file.path = fname1;
     122           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     123           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     124           1 :         if (strcmp(finfo.all_info.out.fname.s, Fname1) != 0) {
     125           1 :                 torture_warning(tctx, "(%s) Incorrect filename [%s] after case-changing "
     126             :                        "rename, should be [%s]\n", __location__,
     127             :                        finfo.all_info.out.fname.s, Fname1);
     128             :         }
     129             : 
     130           1 :         io.rename.in.pattern1 = fname1;
     131           1 :         io.rename.in.pattern2 = fname2;
     132             : 
     133           1 :         torture_comment(tctx, "trying rename while not open\n");
     134           1 :         smb_raw_exit(cli->session);
     135           1 :         status = smb_raw_rename(cli->tree, &io);
     136           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     137             :         
     138           1 :         torture_comment(tctx, "Trying self rename\n");
     139           1 :         io.rename.in.pattern1 = fname2;
     140           1 :         io.rename.in.pattern2 = fname2;
     141           1 :         status = smb_raw_rename(cli->tree, &io);
     142           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     143             : 
     144           1 :         io.rename.in.pattern1 = fname1;
     145           1 :         io.rename.in.pattern2 = fname1;
     146           1 :         status = smb_raw_rename(cli->tree, &io);
     147           1 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     148             : 
     149           2 : done:
     150           1 :         smbcli_close(cli->tree, fnum);
     151           1 :         smb_raw_exit(cli->session);
     152           1 :         smbcli_deltree(cli->tree, BASEDIR);
     153           1 :         return ret;
     154             : }
     155             : 
     156             : 
     157           1 : static bool test_osxrename(struct torture_context *tctx,
     158             :                            struct smbcli_state *cli)
     159             : {
     160             :         union smb_rename io;
     161             :         union smb_unlink io_un;
     162             :         NTSTATUS status;
     163           1 :         bool ret = true;
     164           1 :         int fnum = -1;
     165           1 :         const char *fname1 = BASEDIR "\\test1";
     166           1 :         const char *FNAME1 = BASEDIR "\\TEST1";
     167             :         union smb_fileinfo finfo;
     168             :         union smb_open op;
     169             : 
     170           1 :         torture_comment(tctx, "\nTesting OSX Rename\n");
     171           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     172           1 :         op.generic.level = RAW_OPEN_NTCREATEX;
     173           1 :         op.ntcreatex.in.root_fid.fnum = 0;
     174           1 :         op.ntcreatex.in.flags = 0;
     175           1 :         op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     176           1 :         op.ntcreatex.in.create_options = 0;
     177           1 :         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     178           1 :         op.ntcreatex.in.share_access =
     179             :                 NTCREATEX_SHARE_ACCESS_READ |
     180             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     181           1 :         op.ntcreatex.in.alloc_size = 0;
     182           1 :         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     183           1 :         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     184           1 :         op.ntcreatex.in.security_flags = 0;
     185           1 :         op.ntcreatex.in.fname = fname1;
     186             : 
     187           1 :         status = smb_raw_open(cli->tree, tctx, &op);
     188           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     189           1 :         fnum = op.ntcreatex.out.file.fnum;
     190             : 
     191           1 :         io.generic.level = RAW_RENAME_RENAME;
     192           1 :         io.rename.in.attrib = 0;
     193             : 
     194           1 :         smbcli_close(cli->tree, fnum);
     195             : 
     196             :         /* Rename by changing case. First check for the
     197             :          * existence of the file with the "newname".
     198             :          * If we find one and both the output and input are same case,
     199             :          * delete it. */
     200             : 
     201           1 :         torture_comment(tctx, "Checking os X rename (case changing)\n");
     202             : 
     203           1 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     204           1 :         finfo.all_info.in.file.path = FNAME1;
     205           1 :         torture_comment(tctx, "Looking for file %s \n",FNAME1);
     206           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     207             : 
     208           1 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
     209           1 :                 torture_comment(tctx, "Name of the file found %s \n", finfo.all_info.out.fname.s);
     210           1 :                 if (strcmp(finfo.all_info.out.fname.s, finfo.all_info.in.file.path) == 0) {
     211             :                         /* If file is found with the same case delete it */
     212           1 :                         torture_comment(tctx, "Deleting File %s \n", finfo.all_info.out.fname.s);
     213           1 :                         io_un.unlink.in.pattern = finfo.all_info.out.fname.s;
     214           1 :                         io_un.unlink.in.attrib = 0;
     215           1 :                         status = smb_raw_unlink(cli->tree, &io_un);
     216           1 :                         CHECK_STATUS(status, NT_STATUS_OK);
     217             :                 }
     218             :         }
     219             : 
     220           1 :         io.rename.in.pattern1 = fname1;
     221           1 :         io.rename.in.pattern2 = FNAME1;
     222           1 :         status = smb_raw_rename(cli->tree, &io);
     223           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     224             : 
     225           0 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     226           0 :         finfo.all_info.in.file.path = fname1;
     227           0 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     228           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     229           0 :         torture_comment(tctx, "File name after rename %s \n",finfo.all_info.out.fname.s);
     230             : 
     231           1 : done:
     232           1 :         smbcli_close(cli->tree, fnum);
     233           1 :         smb_raw_exit(cli->session);
     234           1 :         smbcli_deltree(cli->tree, BASEDIR);
     235           1 :         return ret;
     236             : }
     237             : 
     238             : /*
     239             :   test SMBntrename ops
     240             : */
     241           1 : static bool test_ntrename(struct torture_context *tctx, 
     242             :                                                   struct smbcli_state *cli)
     243             : {
     244             :         union smb_rename io;
     245             :         NTSTATUS status;
     246           1 :         bool ret = true;
     247             :         int fnum, i;
     248           1 :         const char *fname1 = BASEDIR "\\test1.txt";
     249           1 :         const char *fname2 = BASEDIR "\\test2.txt";
     250             :         union smb_fileinfo finfo;
     251             : 
     252           1 :         torture_comment(tctx, "Testing SMBntrename\n");
     253             : 
     254           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     255             : 
     256           1 :         torture_comment(tctx, "Trying simple rename\n");
     257             : 
     258           1 :         fnum = create_complex_file(cli, tctx, fname1);
     259             :         
     260           1 :         io.generic.level = RAW_RENAME_NTRENAME;
     261           1 :         io.ntrename.in.old_name = fname1;
     262           1 :         io.ntrename.in.new_name = fname2;
     263           1 :         io.ntrename.in.attrib = 0;
     264           1 :         io.ntrename.in.cluster_size = 0;
     265           1 :         io.ntrename.in.flags = RENAME_FLAG_RENAME;
     266             :         
     267           1 :         status = smb_raw_rename(cli->tree, &io);
     268           1 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     269             :         
     270           1 :         smbcli_close(cli->tree, fnum);
     271           1 :         status = smb_raw_rename(cli->tree, &io);
     272           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     273             : 
     274           1 :         torture_comment(tctx, "Trying self rename\n");
     275           1 :         io.ntrename.in.old_name = fname2;
     276           1 :         io.ntrename.in.new_name = fname2;
     277           1 :         status = smb_raw_rename(cli->tree, &io);
     278           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     279             : 
     280           1 :         io.ntrename.in.old_name = fname1;
     281           1 :         io.ntrename.in.new_name = fname1;
     282           1 :         status = smb_raw_rename(cli->tree, &io);
     283           1 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     284             : 
     285           1 :         torture_comment(tctx, "trying wildcard rename\n");
     286           1 :         io.ntrename.in.old_name = BASEDIR "\\*.txt";
     287           1 :         io.ntrename.in.new_name = fname1;
     288             :         
     289           1 :         status = smb_raw_rename(cli->tree, &io);
     290           1 :         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
     291             : 
     292           1 :         torture_comment(tctx, "Checking attrib handling\n");
     293           1 :         torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
     294           1 :         io.ntrename.in.old_name = fname2;
     295           1 :         io.ntrename.in.new_name = fname1;
     296           1 :         io.ntrename.in.attrib = 0;
     297           1 :         status = smb_raw_rename(cli->tree, &io);
     298           1 :         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
     299             : 
     300           1 :         io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
     301           1 :         status = smb_raw_rename(cli->tree, &io);
     302           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     303             : 
     304           1 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
     305             : 
     306           1 :         torture_comment(tctx, "Checking hard link\n");
     307           1 :         io.ntrename.in.old_name = fname1;
     308           1 :         io.ntrename.in.new_name = fname2;
     309           1 :         io.ntrename.in.attrib = 0;
     310           1 :         io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
     311           1 :         status = smb_raw_rename(cli->tree, &io);
     312           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     313             : 
     314           1 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
     315             : 
     316           1 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     317           1 :         finfo.generic.in.file.path = fname2;
     318           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     319           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     320           1 :         CHECK_VALUE(finfo.all_info.out.nlink, 2);
     321           1 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
     322             : 
     323           1 :         finfo.generic.in.file.path = fname1;
     324           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     325           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     326           1 :         CHECK_VALUE(finfo.all_info.out.nlink, 2);
     327           1 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
     328             : 
     329           1 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
     330             : 
     331           1 :         smbcli_unlink(cli->tree, fname2);
     332             : 
     333           1 :         finfo.generic.in.file.path = fname1;
     334           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     335           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     336           1 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     337           1 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
     338             : 
     339           1 :         torture_comment(tctx, "Checking copy\n");
     340           1 :         io.ntrename.in.old_name = fname1;
     341           1 :         io.ntrename.in.new_name = fname2;
     342           1 :         io.ntrename.in.attrib = 0;
     343           1 :         io.ntrename.in.flags = RENAME_FLAG_COPY;
     344           1 :         status = smb_raw_rename(cli->tree, &io);
     345           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     346             : 
     347           1 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     348           1 :         finfo.generic.in.file.path = fname1;
     349           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     350           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     351           1 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     352           1 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
     353             : 
     354           1 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     355           1 :         finfo.generic.in.file.path = fname2;
     356           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     357           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     358           1 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     359           1 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
     360             : 
     361           1 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
     362             : 
     363           1 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     364           1 :         finfo.generic.in.file.path = fname2;
     365           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     366           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     367           1 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     368           1 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
     369             : 
     370           1 :         finfo.generic.in.file.path = fname1;
     371           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     372           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     373           1 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     374           1 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
     375             : 
     376           1 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
     377             : 
     378           1 :         smbcli_unlink(cli->tree, fname2);
     379             : 
     380           1 :         finfo.generic.in.file.path = fname1;
     381           1 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     382           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     383           1 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     384             : 
     385           1 :         torture_comment(tctx, "Checking invalid flags\n");
     386           1 :         io.ntrename.in.old_name = fname1;
     387           1 :         io.ntrename.in.new_name = fname2;
     388           1 :         io.ntrename.in.attrib = 0;
     389           1 :         io.ntrename.in.flags = 0;
     390           1 :         status = smb_raw_rename(cli->tree, &io);
     391           1 :         if (TARGET_IS_WIN7(tctx)) {
     392           0 :                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     393             :         } else {
     394           1 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     395             :         }
     396             : 
     397           1 :         io.ntrename.in.flags = 300;
     398           1 :         status = smb_raw_rename(cli->tree, &io);
     399           1 :         if (TARGET_IS_WIN7(tctx)) {
     400           0 :                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     401             :         } else {
     402           1 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     403             :         }
     404             : 
     405           1 :         io.ntrename.in.flags = 0x106;
     406           1 :         status = smb_raw_rename(cli->tree, &io);
     407           1 :         if (TARGET_IS_WIN7(tctx)) {
     408           0 :                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     409             :         } else {
     410           1 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     411             :         }
     412             : 
     413           1 :         torture_comment(tctx, "Checking unknown field\n");
     414           1 :         io.ntrename.in.old_name = fname1;
     415           1 :         io.ntrename.in.new_name = fname2;
     416           1 :         io.ntrename.in.attrib = 0;
     417           1 :         io.ntrename.in.flags = RENAME_FLAG_RENAME;
     418           1 :         io.ntrename.in.cluster_size = 0xff;
     419           1 :         status = smb_raw_rename(cli->tree, &io);
     420           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     421             : 
     422           1 :         torture_comment(tctx, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
     423             : 
     424           1 :         io.ntrename.in.old_name = fname2;
     425           1 :         io.ntrename.in.new_name = fname1;
     426           1 :         io.ntrename.in.attrib = 0;
     427           1 :         io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
     428           1 :         io.ntrename.in.cluster_size = 1;
     429           1 :         status = smb_raw_rename(cli->tree, &io);
     430           1 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     431             : 
     432           1 :         io.ntrename.in.flags = RENAME_FLAG_COPY;
     433           1 :         status = smb_raw_rename(cli->tree, &io);
     434           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     435             : 
     436             : #if 0
     437             :         {
     438             :                 char buf[16384];
     439             :                 fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE);
     440             :                 memset(buf, 1, sizeof(buf));
     441             :                 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
     442             :                 smbcli_close(cli->tree, fnum);
     443             : 
     444             :                 fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE);
     445             :                 memset(buf, 1, sizeof(buf));
     446             :                 smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1);
     447             :                 smbcli_close(cli->tree, fnum);
     448             : 
     449             :                 torture_all_info(cli->tree, fname1);
     450             :                 torture_all_info(cli->tree, fname2);
     451             :         }
     452             :         
     453             : 
     454             :         io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
     455             :         status = smb_raw_rename(cli->tree, &io);
     456             :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     457             : 
     458             :         for (i=0;i<20000;i++) {
     459             :                 io.ntrename.in.cluster_size = i;
     460             :                 status = smb_raw_rename(cli->tree, &io);
     461             :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
     462             :                         torture_warning(tctx, "i=%d status=%s\n", i, nt_errstr(status));
     463             :                 }
     464             :         }
     465             : #endif
     466             : 
     467           1 :         torture_comment(tctx, "Checking other flags\n");
     468             : 
     469        4096 :         for (i=0;i<0xFFF;i++) {
     470        4095 :                 if (i == RENAME_FLAG_RENAME ||
     471        4093 :                     i == RENAME_FLAG_HARD_LINK ||
     472             :                     i == RENAME_FLAG_COPY) {
     473           3 :                         continue;
     474             :                 }
     475             : 
     476        4092 :                 io.ntrename.in.old_name = fname2;
     477        4092 :                 io.ntrename.in.new_name = fname1;
     478        4092 :                 io.ntrename.in.flags = i;
     479        4092 :                 io.ntrename.in.attrib = 0;
     480        4092 :                 io.ntrename.in.cluster_size = 0;
     481        4092 :                 status = smb_raw_rename(cli->tree, &io);
     482        4092 :                 if (TARGET_IS_WIN7(tctx)){
     483           0 :                         if (!NT_STATUS_EQUAL(status,
     484             :                                              NT_STATUS_INVALID_PARAMETER)) {
     485           0 :                                 torture_warning(tctx, "flags=0x%x status=%s\n",
     486             :                                                 i, nt_errstr(status));
     487             :                         }
     488             :                 } else {
     489        4092 :                         if (!NT_STATUS_EQUAL(status,
     490             :                                              NT_STATUS_ACCESS_DENIED)) {
     491           1 :                                 torture_warning(tctx, "flags=0x%x status=%s\n",
     492             :                                                 i, nt_errstr(status));
     493             :                         }
     494             :                 }
     495             :         }
     496             :         
     497           1 : done:
     498           1 :         smb_raw_exit(cli->session);
     499           1 :         smbcli_deltree(cli->tree, BASEDIR);
     500           1 :         return ret;
     501             : }
     502             : 
     503             : /*
     504             :   test dir rename.
     505             : */
     506           1 : static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli)
     507             : {
     508             :         union smb_open io;
     509             :         union smb_rename ren_io;
     510             :         NTSTATUS status;
     511           1 :         const char *dname1 = BASEDIR "\\dir_for_rename";
     512           1 :         const char *dname2 = BASEDIR "\\renamed_dir";
     513           1 :         const char *dname1_long = BASEDIR "\\dir_for_rename_long";
     514           1 :         const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
     515           1 :         const char *sname = BASEDIR "\\renamed_dir:a stream:$DATA";
     516           1 :         bool ret = true;
     517           1 :         int fnum = -1;
     518             : 
     519           1 :         torture_comment(tctx, "Checking rename on a directory containing an open file.\n");
     520             : 
     521           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     522             : 
     523             :         /* create a directory */
     524           1 :         smbcli_rmdir(cli->tree, dname1);
     525           1 :         smbcli_rmdir(cli->tree, dname2);
     526           1 :         smbcli_rmdir(cli->tree, dname1_long);
     527           1 :         smbcli_unlink(cli->tree, dname1);
     528           1 :         smbcli_unlink(cli->tree, dname2);
     529           1 :         smbcli_unlink(cli->tree, dname1_long);
     530             : 
     531           1 :         ZERO_STRUCT(io);
     532           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     533           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     534           1 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     535           1 :         io.ntcreatex.in.alloc_size = 0;
     536           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     537           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
     538           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     539           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     540           1 :         io.ntcreatex.in.fname = dname1;
     541           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     542           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     543             : 
     544           1 :         fnum = io.ntcreatex.out.file.fnum;
     545           1 :         smbcli_close(cli->tree, fnum);
     546             : 
     547             :         /* create the longname directory */
     548           1 :         io.ntcreatex.in.fname = dname1_long;
     549           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     550           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     551             : 
     552           1 :         fnum = io.ntcreatex.out.file.fnum;
     553           1 :         smbcli_close(cli->tree, fnum);
     554             : 
     555             :         /* Now create and hold open a file. */
     556           1 :         ZERO_STRUCT(io);
     557             : 
     558           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     559           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     560           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     561           1 :         io.ntcreatex.in.alloc_size = 0;
     562           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     563           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     564           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
     565           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     566           1 :         io.ntcreatex.in.create_options = 0;
     567           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     568           1 :         io.ntcreatex.in.security_flags = 0;
     569           1 :         io.ntcreatex.in.fname = fname;
     570             : 
     571             :         /* Create the file. */
     572             : 
     573           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     574           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     575           1 :         fnum = io.ntcreatex.out.file.fnum;
     576             : 
     577             :         /* Now try and rename the directory. */
     578             : 
     579           1 :         ZERO_STRUCT(ren_io);
     580           1 :         ren_io.generic.level = RAW_RENAME_RENAME;
     581           1 :         ren_io.rename.in.pattern1 = dname1;
     582           1 :         ren_io.rename.in.pattern2 = dname2;
     583           1 :         ren_io.rename.in.attrib = 0;
     584             :         
     585           1 :         status = smb_raw_rename(cli->tree, &ren_io);
     586           1 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     587             : 
     588             :         /* Close the file and try the rename. */
     589           0 :         smbcli_close(cli->tree, fnum);
     590             : 
     591           0 :         status = smb_raw_rename(cli->tree, &ren_io);
     592           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     593             : 
     594             :         /*
     595             :          * Now try just holding a second handle on the directory and holding
     596             :          * it open across a rename.  This should be allowed.
     597             :          */
     598           0 :         io.ntcreatex.in.fname = dname2;
     599           0 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     600             : 
     601           0 :         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
     602             :             SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
     603             : 
     604           0 :         status = smb_raw_open(cli->tree, tctx, &io);
     605           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     606           0 :         fnum = io.ntcreatex.out.file.fnum;
     607             : 
     608           0 :         ren_io.generic.level = RAW_RENAME_RENAME;
     609           0 :         ren_io.rename.in.pattern1 = dname2;
     610           0 :         ren_io.rename.in.pattern2 = dname1;
     611           0 :         ren_io.rename.in.attrib = 0;
     612             : 
     613           0 :         status = smb_raw_rename(cli->tree, &ren_io);
     614           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     615             : 
     616             :         /* close our handle to the directory. */
     617           0 :         smbcli_close(cli->tree, fnum);
     618             : 
     619             :         /* Open a handle on the long name, and then
     620             :          * try a rename. This would catch a regression
     621             :          * in bug #6781.
     622             :          */
     623           0 :         io.ntcreatex.in.fname = dname1_long;
     624           0 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     625             : 
     626           0 :         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
     627             :             SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
     628             : 
     629           0 :         status = smb_raw_open(cli->tree, tctx, &io);
     630           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     631           0 :         fnum = io.ntcreatex.out.file.fnum;
     632             : 
     633           0 :         ren_io.generic.level = RAW_RENAME_RENAME;
     634           0 :         ren_io.rename.in.pattern1 = dname1;
     635           0 :         ren_io.rename.in.pattern2 = dname2;
     636           0 :         ren_io.rename.in.attrib = 0;
     637             : 
     638           0 :         status = smb_raw_rename(cli->tree, &ren_io);
     639           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     640             : 
     641             :         /* close our handle to the longname directory. */
     642           0 :         smbcli_close(cli->tree, fnum);
     643             : 
     644             :         /*
     645             :          * Now try opening a stream on the directory and holding it open
     646             :          * across a rename.  This should be allowed.
     647             :          */
     648           0 :         io.ntcreatex.in.fname = sname;
     649             : 
     650           0 :         status = smb_raw_open(cli->tree, tctx, &io);
     651           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     652           0 :         fnum = io.ntcreatex.out.file.fnum;
     653             : 
     654           0 :         ren_io.generic.level = RAW_RENAME_RENAME;
     655           0 :         ren_io.rename.in.pattern1 = dname2;
     656           0 :         ren_io.rename.in.pattern2 = dname1;
     657           0 :         ren_io.rename.in.attrib = 0;
     658             : 
     659           0 :         status = smb_raw_rename(cli->tree, &ren_io);
     660           0 :         CHECK_STATUS(status, NT_STATUS_OK);
     661             : 
     662           1 : done:
     663             : 
     664           1 :         if (fnum != -1) {
     665           1 :                 smbcli_close(cli->tree, fnum);
     666             :         }
     667           1 :         smb_raw_exit(cli->session);
     668           1 :         smbcli_deltree(cli->tree, BASEDIR);
     669           1 :         return ret;
     670             : }
     671             : 
     672             : extern bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2);
     673             : extern bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1);
     674             : 
     675             : /* 
     676             :    basic testing of rename calls
     677             : */
     678         964 : struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx)
     679             : {
     680         964 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "rename");
     681             : 
     682         964 :         torture_suite_add_1smb_test(suite, "mv", test_mv);
     683             :         /* test_trans2rename and test_nttransrename are actually in torture/raw/oplock.c to
     684             :            use the handlers and macros there. */
     685         964 :         torture_suite_add_2smb_test(suite, "trans2rename", test_trans2rename);
     686         964 :         torture_suite_add_1smb_test(suite, "nttransrename", test_nttransrename);
     687         964 :         torture_suite_add_1smb_test(suite, "ntrename", test_ntrename);
     688         964 :         torture_suite_add_1smb_test(suite, "osxrename", test_osxrename);
     689         964 :         torture_suite_add_1smb_test(suite, "directory rename", test_dir_rename);
     690             : 
     691         964 :         return suite;
     692             : }

Generated by: LCOV version 1.13