LCOV - code coverage report
Current view: top level - source4/torture/raw - rename.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 415 420 98.8 %
Date: 2023-11-21 12:31:41 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           6 : static bool test_mv(struct torture_context *tctx, 
      48             :                                         struct smbcli_state *cli)
      49             : {
      50           1 :         union smb_rename io;
      51           1 :         NTSTATUS status;
      52           6 :         bool ret = true;
      53           6 :         int fnum = -1;
      54           6 :         const char *fname1 = BASEDIR "\\test1.txt";
      55           6 :         const char *fname2 = BASEDIR "\\test2.txt";
      56           6 :         const char *Fname1 = BASEDIR "\\Test1.txt";
      57           1 :         union smb_fileinfo finfo;
      58           1 :         union smb_open op;
      59             : 
      60           6 :         torture_comment(tctx, "Testing SMBmv\n");
      61             : 
      62           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
      63             : 
      64           6 :         torture_comment(tctx, "Trying simple rename\n");
      65             : 
      66           6 :         op.generic.level = RAW_OPEN_NTCREATEX;
      67           6 :         op.ntcreatex.in.root_fid.fnum = 0;
      68           6 :         op.ntcreatex.in.flags = 0;
      69           6 :         op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
      70           6 :         op.ntcreatex.in.create_options = 0;
      71           6 :         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
      72           6 :         op.ntcreatex.in.share_access = 
      73             :                 NTCREATEX_SHARE_ACCESS_READ | 
      74             :                 NTCREATEX_SHARE_ACCESS_WRITE;
      75           6 :         op.ntcreatex.in.alloc_size = 0;
      76           6 :         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
      77           6 :         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
      78           6 :         op.ntcreatex.in.security_flags = 0;
      79           6 :         op.ntcreatex.in.fname = fname1;
      80             : 
      81           6 :         status = smb_raw_open(cli->tree, tctx, &op);
      82           6 :         CHECK_STATUS(status, NT_STATUS_OK);
      83           6 :         fnum = op.ntcreatex.out.file.fnum;
      84             : 
      85           6 :         io.generic.level = RAW_RENAME_RENAME;
      86           6 :         io.rename.in.pattern1 = fname1;
      87           6 :         io.rename.in.pattern2 = fname2;
      88           6 :         io.rename.in.attrib = 0;
      89             :         
      90           6 :         torture_comment(tctx, "trying rename while first file open\n");
      91           6 :         status = smb_raw_rename(cli->tree, &io);
      92           6 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
      93             : 
      94           6 :         smbcli_close(cli->tree, fnum);
      95             : 
      96           6 :         op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
      97           6 :         op.ntcreatex.in.share_access = 
      98             :                 NTCREATEX_SHARE_ACCESS_DELETE | 
      99             :                 NTCREATEX_SHARE_ACCESS_READ |
     100             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     101           6 :         status = smb_raw_open(cli->tree, tctx, &op);
     102           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     103           6 :         fnum = op.ntcreatex.out.file.fnum;
     104             : 
     105           6 :         torture_comment(tctx, "trying rename while first file open with SHARE_ACCESS_DELETE\n");
     106           6 :         status = smb_raw_rename(cli->tree, &io);
     107           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     108             : 
     109           6 :         io.rename.in.pattern1 = fname2;
     110           6 :         io.rename.in.pattern2 = fname1;
     111           6 :         status = smb_raw_rename(cli->tree, &io);
     112           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     113             : 
     114           6 :         torture_comment(tctx, "Trying case-changing rename\n");
     115           6 :         io.rename.in.pattern1 = fname1;
     116           6 :         io.rename.in.pattern2 = Fname1;
     117           6 :         status = smb_raw_rename(cli->tree, &io);
     118           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     119             : 
     120           6 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     121           6 :         finfo.all_info.in.file.path = fname1;
     122           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     123           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     124           6 :         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           6 :         io.rename.in.pattern1 = fname1;
     131           6 :         io.rename.in.pattern2 = fname2;
     132             : 
     133           6 :         torture_comment(tctx, "trying rename while not open\n");
     134           6 :         smb_raw_exit(cli->session);
     135           6 :         status = smb_raw_rename(cli->tree, &io);
     136           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     137             :         
     138           6 :         torture_comment(tctx, "Trying self rename\n");
     139           6 :         io.rename.in.pattern1 = fname2;
     140           6 :         io.rename.in.pattern2 = fname2;
     141           6 :         status = smb_raw_rename(cli->tree, &io);
     142           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     143             : 
     144           6 :         io.rename.in.pattern1 = fname1;
     145           6 :         io.rename.in.pattern2 = fname1;
     146           6 :         status = smb_raw_rename(cli->tree, &io);
     147           6 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     148             : 
     149           6 : done:
     150           6 :         smbcli_close(cli->tree, fnum);
     151           6 :         smb_raw_exit(cli->session);
     152           6 :         smbcli_deltree(cli->tree, BASEDIR);
     153           6 :         return ret;
     154             : }
     155             : 
     156             : 
     157           6 : static bool test_osxrename(struct torture_context *tctx,
     158             :                            struct smbcli_state *cli)
     159             : {
     160           1 :         union smb_rename io;
     161           1 :         union smb_unlink io_un;
     162           1 :         NTSTATUS status;
     163           6 :         bool ret = true;
     164           6 :         int fnum = -1;
     165           6 :         const char *fname1 = BASEDIR "\\test1";
     166           6 :         const char *FNAME1 = BASEDIR "\\TEST1";
     167           1 :         union smb_fileinfo finfo;
     168           1 :         union smb_open op;
     169             : 
     170           6 :         torture_comment(tctx, "\nTesting OSX Rename\n");
     171           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     172           6 :         op.generic.level = RAW_OPEN_NTCREATEX;
     173           6 :         op.ntcreatex.in.root_fid.fnum = 0;
     174           6 :         op.ntcreatex.in.flags = 0;
     175           6 :         op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     176           6 :         op.ntcreatex.in.create_options = 0;
     177           6 :         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     178           6 :         op.ntcreatex.in.share_access =
     179             :                 NTCREATEX_SHARE_ACCESS_READ |
     180             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     181           6 :         op.ntcreatex.in.alloc_size = 0;
     182           6 :         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     183           6 :         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     184           6 :         op.ntcreatex.in.security_flags = 0;
     185           6 :         op.ntcreatex.in.fname = fname1;
     186             : 
     187           6 :         status = smb_raw_open(cli->tree, tctx, &op);
     188           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     189           6 :         fnum = op.ntcreatex.out.file.fnum;
     190             : 
     191           6 :         io.generic.level = RAW_RENAME_RENAME;
     192           6 :         io.rename.in.attrib = 0;
     193             : 
     194           6 :         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           6 :         torture_comment(tctx, "Checking os X rename (case changing)\n");
     202             : 
     203           6 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     204           6 :         finfo.all_info.in.file.path = FNAME1;
     205           6 :         torture_comment(tctx, "Looking for file %s \n",FNAME1);
     206           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     207             : 
     208           6 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
     209           6 :                 torture_comment(tctx, "Name of the file found %s \n", finfo.all_info.out.fname.s);
     210           6 :                 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           6 :         io.rename.in.pattern1 = fname1;
     221           6 :         io.rename.in.pattern2 = FNAME1;
     222           6 :         status = smb_raw_rename(cli->tree, &io);
     223           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     224             : 
     225           5 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     226           5 :         finfo.all_info.in.file.path = fname1;
     227           5 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     228           5 :         CHECK_STATUS(status, NT_STATUS_OK);
     229           5 :         torture_comment(tctx, "File name after rename %s \n",finfo.all_info.out.fname.s);
     230             : 
     231           6 : done:
     232           6 :         smbcli_close(cli->tree, fnum);
     233           6 :         smb_raw_exit(cli->session);
     234           6 :         smbcli_deltree(cli->tree, BASEDIR);
     235           6 :         return ret;
     236             : }
     237             : 
     238             : /*
     239             :   test SMBntrename ops
     240             : */
     241           6 : static bool test_ntrename(struct torture_context *tctx, 
     242             :                                                   struct smbcli_state *cli)
     243             : {
     244           1 :         union smb_rename io;
     245           1 :         NTSTATUS status;
     246           6 :         bool ret = true;
     247           1 :         int fnum, i;
     248           6 :         const char *fname1 = BASEDIR "\\test1.txt";
     249           6 :         const char *fname2 = BASEDIR "\\test2.txt";
     250           1 :         union smb_fileinfo finfo;
     251             : 
     252           6 :         torture_comment(tctx, "Testing SMBntrename\n");
     253             : 
     254           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     255             : 
     256           6 :         torture_comment(tctx, "Trying simple rename\n");
     257             : 
     258           6 :         fnum = create_complex_file(cli, tctx, fname1);
     259             :         
     260           6 :         io.generic.level = RAW_RENAME_NTRENAME;
     261           6 :         io.ntrename.in.old_name = fname1;
     262           6 :         io.ntrename.in.new_name = fname2;
     263           6 :         io.ntrename.in.attrib = 0;
     264           6 :         io.ntrename.in.cluster_size = 0;
     265           6 :         io.ntrename.in.flags = RENAME_FLAG_RENAME;
     266             :         
     267           6 :         status = smb_raw_rename(cli->tree, &io);
     268           6 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     269             :         
     270           6 :         smbcli_close(cli->tree, fnum);
     271           6 :         status = smb_raw_rename(cli->tree, &io);
     272           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     273             : 
     274           6 :         torture_comment(tctx, "Trying self rename\n");
     275           6 :         io.ntrename.in.old_name = fname2;
     276           6 :         io.ntrename.in.new_name = fname2;
     277           6 :         status = smb_raw_rename(cli->tree, &io);
     278           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     279             : 
     280           6 :         io.ntrename.in.old_name = fname1;
     281           6 :         io.ntrename.in.new_name = fname1;
     282           6 :         status = smb_raw_rename(cli->tree, &io);
     283           6 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     284             : 
     285           6 :         torture_comment(tctx, "trying wildcard rename\n");
     286           6 :         io.ntrename.in.old_name = BASEDIR "\\*.txt";
     287           6 :         io.ntrename.in.new_name = fname1;
     288             :         
     289           6 :         status = smb_raw_rename(cli->tree, &io);
     290           6 :         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
     291             : 
     292           6 :         torture_comment(tctx, "Checking attrib handling\n");
     293           6 :         torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
     294           6 :         io.ntrename.in.old_name = fname2;
     295           6 :         io.ntrename.in.new_name = fname1;
     296           6 :         io.ntrename.in.attrib = 0;
     297           6 :         status = smb_raw_rename(cli->tree, &io);
     298           6 :         CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);
     299             : 
     300           6 :         io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
     301           6 :         status = smb_raw_rename(cli->tree, &io);
     302           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     303             : 
     304           6 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
     305             : 
     306           6 :         torture_comment(tctx, "Checking hard link\n");
     307           6 :         io.ntrename.in.old_name = fname1;
     308           6 :         io.ntrename.in.new_name = fname2;
     309           6 :         io.ntrename.in.attrib = 0;
     310           6 :         io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
     311           6 :         status = smb_raw_rename(cli->tree, &io);
     312           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     313             : 
     314           6 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
     315             : 
     316           6 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     317           6 :         finfo.generic.in.file.path = fname2;
     318           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     319           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     320           6 :         CHECK_VALUE(finfo.all_info.out.nlink, 2);
     321           6 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
     322             : 
     323           6 :         finfo.generic.in.file.path = fname1;
     324           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     325           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     326           6 :         CHECK_VALUE(finfo.all_info.out.nlink, 2);
     327           6 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
     328             : 
     329           6 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
     330             : 
     331           6 :         smbcli_unlink(cli->tree, fname2);
     332             : 
     333           6 :         finfo.generic.in.file.path = fname1;
     334           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     335           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     336           6 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     337           6 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
     338             : 
     339           6 :         torture_comment(tctx, "Checking copy\n");
     340           6 :         io.ntrename.in.old_name = fname1;
     341           6 :         io.ntrename.in.new_name = fname2;
     342           6 :         io.ntrename.in.attrib = 0;
     343           6 :         io.ntrename.in.flags = RENAME_FLAG_COPY;
     344           6 :         status = smb_raw_rename(cli->tree, &io);
     345           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     346             : 
     347           6 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     348           6 :         finfo.generic.in.file.path = fname1;
     349           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     350           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     351           6 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     352           6 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
     353             : 
     354           6 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     355           6 :         finfo.generic.in.file.path = fname2;
     356           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     357           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     358           6 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     359           6 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
     360             : 
     361           6 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);
     362             : 
     363           6 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
     364           6 :         finfo.generic.in.file.path = fname2;
     365           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     366           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     367           6 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     368           6 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);
     369             : 
     370           6 :         finfo.generic.in.file.path = fname1;
     371           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     372           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     373           6 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     374           6 :         CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);
     375             : 
     376           6 :         torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);
     377             : 
     378           6 :         smbcli_unlink(cli->tree, fname2);
     379             : 
     380           6 :         finfo.generic.in.file.path = fname1;
     381           6 :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
     382           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     383           6 :         CHECK_VALUE(finfo.all_info.out.nlink, 1);
     384             : 
     385           6 :         torture_comment(tctx, "Checking invalid flags\n");
     386           6 :         io.ntrename.in.old_name = fname1;
     387           6 :         io.ntrename.in.new_name = fname2;
     388           6 :         io.ntrename.in.attrib = 0;
     389           6 :         io.ntrename.in.flags = 0;
     390           6 :         status = smb_raw_rename(cli->tree, &io);
     391           6 :         if (TARGET_IS_WIN7(tctx)) {
     392           0 :                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     393             :         } else {
     394           6 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     395             :         }
     396             : 
     397           6 :         io.ntrename.in.flags = 300;
     398           6 :         status = smb_raw_rename(cli->tree, &io);
     399           6 :         if (TARGET_IS_WIN7(tctx)) {
     400           0 :                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     401             :         } else {
     402           6 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     403             :         }
     404             : 
     405           6 :         io.ntrename.in.flags = 0x106;
     406           6 :         status = smb_raw_rename(cli->tree, &io);
     407           6 :         if (TARGET_IS_WIN7(tctx)) {
     408           0 :                 CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     409             :         } else {
     410           6 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     411             :         }
     412             : 
     413           6 :         torture_comment(tctx, "Checking unknown field\n");
     414           6 :         io.ntrename.in.old_name = fname1;
     415           6 :         io.ntrename.in.new_name = fname2;
     416           6 :         io.ntrename.in.attrib = 0;
     417           6 :         io.ntrename.in.flags = RENAME_FLAG_RENAME;
     418           6 :         io.ntrename.in.cluster_size = 0xff;
     419           6 :         status = smb_raw_rename(cli->tree, &io);
     420           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     421             : 
     422           6 :         torture_comment(tctx, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");
     423             : 
     424           6 :         io.ntrename.in.old_name = fname2;
     425           6 :         io.ntrename.in.new_name = fname1;
     426           6 :         io.ntrename.in.attrib = 0;
     427           6 :         io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
     428           6 :         io.ntrename.in.cluster_size = 1;
     429           6 :         status = smb_raw_rename(cli->tree, &io);
     430           6 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     431             : 
     432           6 :         io.ntrename.in.flags = RENAME_FLAG_COPY;
     433           6 :         status = smb_raw_rename(cli->tree, &io);
     434           6 :         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           6 :         torture_comment(tctx, "Checking other flags\n");
     468             : 
     469       24577 :         for (i=0;i<0xFFF;i++) {
     470       24573 :                 if (i == RENAME_FLAG_RENAME ||
     471       24560 :                     i == RENAME_FLAG_HARD_LINK ||
     472             :                     i == RENAME_FLAG_COPY) {
     473          18 :                         continue;
     474             :                 }
     475             : 
     476       24552 :                 io.ntrename.in.old_name = fname2;
     477       24552 :                 io.ntrename.in.new_name = fname1;
     478       24552 :                 io.ntrename.in.flags = i;
     479       24552 :                 io.ntrename.in.attrib = 0;
     480       24552 :                 io.ntrename.in.cluster_size = 0;
     481       24552 :                 status = smb_raw_rename(cli->tree, &io);
     482       24552 :                 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       24552 :                         if (!NT_STATUS_EQUAL(status,
     490             :                                              NT_STATUS_ACCESS_DENIED)) {
     491           6 :                                 torture_warning(tctx, "flags=0x%x status=%s\n",
     492             :                                                 i, nt_errstr(status));
     493             :                         }
     494             :                 }
     495             :         }
     496             :         
     497           6 : done:
     498           6 :         smb_raw_exit(cli->session);
     499           6 :         smbcli_deltree(cli->tree, BASEDIR);
     500           6 :         return ret;
     501             : }
     502             : 
     503             : /*
     504             :   test dir rename.
     505             : */
     506           6 : static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli)
     507             : {
     508           1 :         union smb_open io;
     509           1 :         union smb_rename ren_io;
     510           1 :         NTSTATUS status;
     511           6 :         const char *dname1 = BASEDIR "\\dir_for_rename";
     512           6 :         const char *dname2 = BASEDIR "\\renamed_dir";
     513           6 :         const char *dname1_long = BASEDIR "\\dir_for_rename_long";
     514           6 :         const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
     515           6 :         const char *sname = BASEDIR "\\renamed_dir:a stream:$DATA";
     516           6 :         bool ret = true;
     517           6 :         int fnum = -1;
     518             : 
     519           6 :         torture_comment(tctx, "Checking rename on a directory containing an open file.\n");
     520             : 
     521           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     522             : 
     523             :         /* create a directory */
     524           6 :         smbcli_rmdir(cli->tree, dname1);
     525           6 :         smbcli_rmdir(cli->tree, dname2);
     526           6 :         smbcli_rmdir(cli->tree, dname1_long);
     527           6 :         smbcli_unlink(cli->tree, dname1);
     528           6 :         smbcli_unlink(cli->tree, dname2);
     529           6 :         smbcli_unlink(cli->tree, dname1_long);
     530             : 
     531           6 :         ZERO_STRUCT(io);
     532           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
     533           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     534           6 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     535           6 :         io.ntcreatex.in.alloc_size = 0;
     536           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     537           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
     538           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     539           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     540           6 :         io.ntcreatex.in.fname = dname1;
     541           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     542           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     543             : 
     544           6 :         fnum = io.ntcreatex.out.file.fnum;
     545           6 :         smbcli_close(cli->tree, fnum);
     546             : 
     547             :         /* create the longname directory */
     548           6 :         io.ntcreatex.in.fname = dname1_long;
     549           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     550           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     551             : 
     552           6 :         fnum = io.ntcreatex.out.file.fnum;
     553           6 :         smbcli_close(cli->tree, fnum);
     554             : 
     555             :         /* Now create and hold open a file. */
     556           6 :         ZERO_STRUCT(io);
     557             : 
     558           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
     559           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     560           6 :         io.ntcreatex.in.root_fid.fnum = 0;
     561           6 :         io.ntcreatex.in.alloc_size = 0;
     562           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     563           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     564           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
     565           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     566           6 :         io.ntcreatex.in.create_options = 0;
     567           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     568           6 :         io.ntcreatex.in.security_flags = 0;
     569           6 :         io.ntcreatex.in.fname = fname;
     570             : 
     571             :         /* Create the file. */
     572             : 
     573           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     574           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     575           6 :         fnum = io.ntcreatex.out.file.fnum;
     576             : 
     577             :         /* Now try and rename the directory. */
     578             : 
     579           6 :         ZERO_STRUCT(ren_io);
     580           6 :         ren_io.generic.level = RAW_RENAME_RENAME;
     581           6 :         ren_io.rename.in.pattern1 = dname1;
     582           6 :         ren_io.rename.in.pattern2 = dname2;
     583           6 :         ren_io.rename.in.attrib = 0;
     584             :         
     585           6 :         status = smb_raw_rename(cli->tree, &ren_io);
     586           6 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     587             : 
     588             :         /* Close the file and try the rename. */
     589           5 :         smbcli_close(cli->tree, fnum);
     590             : 
     591           5 :         status = smb_raw_rename(cli->tree, &ren_io);
     592           5 :         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           5 :         io.ntcreatex.in.fname = dname2;
     599           5 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     600             : 
     601           5 :         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
     602             :             SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
     603             : 
     604           5 :         status = smb_raw_open(cli->tree, tctx, &io);
     605           5 :         CHECK_STATUS(status, NT_STATUS_OK);
     606           5 :         fnum = io.ntcreatex.out.file.fnum;
     607             : 
     608           5 :         ren_io.generic.level = RAW_RENAME_RENAME;
     609           5 :         ren_io.rename.in.pattern1 = dname2;
     610           5 :         ren_io.rename.in.pattern2 = dname1;
     611           5 :         ren_io.rename.in.attrib = 0;
     612             : 
     613           5 :         status = smb_raw_rename(cli->tree, &ren_io);
     614           5 :         CHECK_STATUS(status, NT_STATUS_OK);
     615             : 
     616             :         /* close our handle to the directory. */
     617           5 :         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           5 :         io.ntcreatex.in.fname = dname1_long;
     624           5 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     625             : 
     626           5 :         io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
     627             :             SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
     628             : 
     629           5 :         status = smb_raw_open(cli->tree, tctx, &io);
     630           5 :         CHECK_STATUS(status, NT_STATUS_OK);
     631           5 :         fnum = io.ntcreatex.out.file.fnum;
     632             : 
     633           5 :         ren_io.generic.level = RAW_RENAME_RENAME;
     634           5 :         ren_io.rename.in.pattern1 = dname1;
     635           5 :         ren_io.rename.in.pattern2 = dname2;
     636           5 :         ren_io.rename.in.attrib = 0;
     637             : 
     638           5 :         status = smb_raw_rename(cli->tree, &ren_io);
     639           5 :         CHECK_STATUS(status, NT_STATUS_OK);
     640             : 
     641             :         /* close our handle to the longname directory. */
     642           5 :         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           5 :         io.ntcreatex.in.fname = sname;
     649             : 
     650           5 :         status = smb_raw_open(cli->tree, tctx, &io);
     651           5 :         CHECK_STATUS(status, NT_STATUS_OK);
     652           5 :         fnum = io.ntcreatex.out.file.fnum;
     653             : 
     654           5 :         ren_io.generic.level = RAW_RENAME_RENAME;
     655           5 :         ren_io.rename.in.pattern1 = dname2;
     656           5 :         ren_io.rename.in.pattern2 = dname1;
     657           5 :         ren_io.rename.in.attrib = 0;
     658             : 
     659           5 :         status = smb_raw_rename(cli->tree, &ren_io);
     660           5 :         CHECK_STATUS(status, NT_STATUS_OK);
     661             : 
     662           6 : done:
     663             : 
     664           5 :         if (fnum != -1) {
     665           6 :                 smbcli_close(cli->tree, fnum);
     666             :         }
     667           6 :         smb_raw_exit(cli->session);
     668           6 :         smbcli_deltree(cli->tree, BASEDIR);
     669           6 :         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        2358 : struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx)
     679             : {
     680        2358 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "rename");
     681             : 
     682        2358 :         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        2358 :         torture_suite_add_2smb_test(suite, "trans2rename", test_trans2rename);
     686        2358 :         torture_suite_add_1smb_test(suite, "nttransrename", test_nttransrename);
     687        2358 :         torture_suite_add_1smb_test(suite, "ntrename", test_ntrename);
     688        2358 :         torture_suite_add_1smb_test(suite, "osxrename", test_osxrename);
     689        2358 :         torture_suite_add_1smb_test(suite, "directory rename", test_dir_rename);
     690             : 
     691        2358 :         return suite;
     692             : }

Generated by: LCOV version 1.14