LCOV - code coverage report
Current view: top level - source4/torture/raw - setfileinfo.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 597 660 90.5 %
Date: 2024-02-28 12:06:22 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    RAW_SFILEINFO_* individual test suite
       4             :    Copyright (C) Andrew Tridgell 2003
       5             :    
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 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 "system/time.h"
      22             : #include "libcli/raw/libcliraw.h"
      23             : #include "libcli/libcli.h"
      24             : #include "torture/util.h"
      25             : #include "torture/raw/proto.h"
      26             : 
      27             : #define BASEDIR "\\testsfileinfo"
      28             : 
      29             : /* basic testing of all RAW_SFILEINFO_* calls 
      30             :    for each call we test that it succeeds, and where possible test 
      31             :    for consistency between the calls. 
      32             : */
      33             : static bool
      34           1 : torture_raw_sfileinfo_base(struct torture_context *torture, struct smbcli_state *cli)
      35             : {
      36           1 :         bool ret = true;
      37           1 :         int fnum = -1;
      38           0 :         char *fnum_fname;
      39           0 :         char *path_fname;
      40           0 :         char *path_fname_new;
      41           0 :         union smb_fileinfo finfo1, finfo2;
      42           0 :         union smb_setfileinfo sfinfo;
      43           0 :         NTSTATUS status, status2;
      44           0 :         const char *call_name;
      45           1 :         time_t basetime = (time(NULL) - 86400) & ~1;
      46           0 :         bool check_fnum;
      47           1 :         int n = time(NULL) % 100;
      48             :         
      49           1 :         path_fname = talloc_asprintf(torture, BASEDIR "\\fname_test_%d.txt", n);
      50           1 :         path_fname_new = talloc_asprintf(torture, BASEDIR "\\fname_test_new_%d.txt", n);
      51           1 :         fnum_fname = talloc_asprintf(torture, BASEDIR "\\fnum_test_%d.txt", n);
      52             : 
      53           1 :         torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
      54             : 
      55             : #define RECREATE_FILE(fname) do { \
      56             :         if (fnum != -1) smbcli_close(cli->tree, fnum); \
      57             :         fnum = create_complex_file(cli, torture, fname); \
      58             :         if (fnum == -1) { \
      59             :                 printf("(%s) ERROR: open of %s failed (%s)\n", \
      60             :                        __location__, fname, smbcli_errstr(cli->tree)); \
      61             :                 ret = false; \
      62             :                 goto done; \
      63             :         }} while (0)
      64             : 
      65             : #define RECREATE_BOTH do { \
      66             :                 RECREATE_FILE(path_fname); \
      67             :                 smbcli_close(cli->tree, fnum); \
      68             :                 RECREATE_FILE(fnum_fname); \
      69             :         } while (0)
      70             : 
      71           1 :         RECREATE_BOTH;
      72             :         
      73             : #define CHECK_CALL_FNUM(call, rightstatus) do { \
      74             :         check_fnum = true; \
      75             :         call_name = #call; \
      76             :         sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
      77             :         sfinfo.generic.in.file.fnum = fnum; \
      78             :         status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
      79             :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
      80             :                 torture_warning(torture, \
      81             :                         "(%s) %s - %s", __location__, #call, \
      82             :                         nt_errstr(status)); \
      83             :         } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
      84             :                 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
      85             :                         nt_errstr(status), nt_errstr(rightstatus)); \
      86             :                 ret = false; \
      87             :         } \
      88             :         finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
      89             :         finfo1.generic.in.file.fnum = fnum; \
      90             :         status2 = smb_raw_fileinfo(cli->tree, torture, &finfo1); \
      91             :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
      92             :                 torture_warning(torture, \
      93             :                         "(%s) %s - %s", __location__, #call, \
      94             :                         nt_errstr(status)); \
      95             :         } else if (!NT_STATUS_IS_OK(status2)) { \
      96             :                 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
      97             :                 ret = false; \
      98             :         }} while (0)
      99             : 
     100             : #define CHECK_CALL_PATH(call, rightstatus) do { \
     101             :         check_fnum = false; \
     102             :         call_name = #call; \
     103             :         sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
     104             :         sfinfo.generic.in.file.path = path_fname; \
     105             :         status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
     106             :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
     107             :                 sfinfo.generic.in.file.path = path_fname_new; \
     108             :                 status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
     109             :         } \
     110             :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
     111             :                 torture_warning(torture, \
     112             :                         "(%s) %s - %s", __location__, #call, \
     113             :                         nt_errstr(status)); \
     114             :         } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
     115             :                 printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
     116             :                         nt_errstr(status), nt_errstr(rightstatus)); \
     117             :                 ret = false; \
     118             :         } \
     119             :         finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
     120             :         finfo1.generic.in.file.path = path_fname; \
     121             :         status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
     122             :         if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
     123             :                 finfo1.generic.in.file.path = path_fname_new; \
     124             :                 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
     125             :         } \
     126             :         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
     127             :                 torture_warning(torture, \
     128             :                         "(%s) %s - %s", __location__, #call, \
     129             :                         nt_errstr(status)); \
     130             :         } else if (!NT_STATUS_IS_OK(status2)) { \
     131             :                 printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
     132             :                 ret = false; \
     133             :         }} while (0)
     134             : 
     135             : #define CHECK1(call) \
     136             :         do { if (NT_STATUS_IS_OK(status)) { \
     137             :                 finfo2.generic.level = RAW_FILEINFO_ ## call; \
     138             :                 if (check_fnum) { \
     139             :                         finfo2.generic.in.file.fnum = fnum; \
     140             :                         status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
     141             :                 } else { \
     142             :                         finfo2.generic.in.file.path = path_fname; \
     143             :                         status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
     144             :                         if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
     145             :                                 finfo2.generic.in.file.path = path_fname_new; \
     146             :                                 status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
     147             :                         } \
     148             :                 } \
     149             :                 if (!NT_STATUS_IS_OK(status2)) { \
     150             :                         printf("%s - %s\n", #call, nt_errstr(status2)); \
     151             :                         ret = false; \
     152             :                 } \
     153             :         }} while (0)
     154             : 
     155             : #define CHECK_VALUE(call, stype, field, value) do { \
     156             :         CHECK1(call); \
     157             :         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
     158             :                 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
     159             :                        call_name, #stype, #field, \
     160             :                        (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
     161             :                 dump_all_info(torture, &finfo1); \
     162             :                 ret = false; \
     163             :         }} while (0)
     164             : 
     165             : #define CHECK_TIME(call, stype, field, value) do { \
     166             :         CHECK1(call); \
     167             :         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
     168             :                 printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
     169             :                         call_name, #stype, #field, \
     170             :                         (unsigned int)value, \
     171             :                         (unsigned int)nt_time_to_unix(finfo2.stype.out.field)); \
     172             :                 printf("\t%s", timestring(torture, value)); \
     173             :                 printf("\t%s\n", nt_time_string(torture, finfo2.stype.out.field)); \
     174             :                 dump_all_info(torture, &finfo1); \
     175             :                 ret = false; \
     176             :         }} while (0)
     177             : 
     178             : #define CHECK_STR(call, stype, field, value) do { \
     179             :         CHECK1(call); \
     180             :         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \
     181             :                 printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \
     182             :                         call_name, #stype, #field, \
     183             :                         value, \
     184             :                         finfo2.stype.out.field); \
     185             :                 dump_all_info(torture, &finfo1); \
     186             :                 ret = false; \
     187             :         }} while (0)
     188             : 
     189             : #define CHECK_STATUS(status, correct) do { \
     190             :         if (!NT_STATUS_EQUAL(status, correct)) { \
     191             :                 printf("(%s) Incorrect status %s - should be %s\n", \
     192             :                        __location__, nt_errstr(status), nt_errstr(correct)); \
     193             :                 ret = false; \
     194             :                 goto done; \
     195             :         }} while (0)
     196             : 
     197             :         
     198           1 :         printf("Test setattr\n");
     199           1 :         sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY;
     200           1 :         sfinfo.setattr.in.write_time = basetime;
     201           2 :         CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
     202           2 :         CHECK_VALUE  (ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
     203           2 :         CHECK_TIME   (ALL_INFO, all_info, write_time, basetime);
     204             : 
     205           1 :         printf("setting to NORMAL doesn't do anything\n");
     206           1 :         sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_NORMAL;
     207           1 :         sfinfo.setattr.in.write_time = 0;
     208           2 :         CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
     209           2 :         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
     210           2 :         CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
     211             : 
     212           1 :         printf("a zero write_time means don't change\n");
     213           1 :         sfinfo.setattr.in.attrib = 0;
     214           1 :         sfinfo.setattr.in.write_time = 0;
     215           2 :         CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
     216           2 :         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
     217           2 :         CHECK_TIME (ALL_INFO, all_info, write_time, basetime);
     218             : 
     219           1 :         printf("Test setattre\n");
     220           1 :         sfinfo.setattre.in.create_time = basetime + 20;
     221           1 :         sfinfo.setattre.in.access_time = basetime + 30;
     222           1 :         sfinfo.setattre.in.write_time  = basetime + 40;
     223           2 :         CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
     224           1 :         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
     225           1 :         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
     226           1 :         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 40);
     227             : 
     228           1 :         sfinfo.setattre.in.create_time = 0;
     229           1 :         sfinfo.setattre.in.access_time = 0;
     230           1 :         sfinfo.setattre.in.write_time  = 0;
     231           2 :         CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
     232           1 :         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
     233           1 :         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
     234           1 :         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 40);
     235             : 
     236           1 :         printf("Test standard level\n");
     237           1 :         sfinfo.standard.in.create_time = basetime + 100;
     238           1 :         sfinfo.standard.in.access_time = basetime + 200;
     239           1 :         sfinfo.standard.in.write_time  = basetime + 300;
     240           2 :         CHECK_CALL_FNUM(STANDARD, NT_STATUS_OK);
     241           1 :         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
     242           1 :         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
     243           1 :         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
     244             : 
     245           1 :         printf("Test basic_info level\n");
     246           1 :         basetime += 86400;
     247           1 :         unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
     248           1 :         unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
     249           1 :         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
     250           1 :         unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
     251           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
     252           2 :         CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
     253           1 :         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
     254           1 :         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
     255           1 :         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
     256           1 :         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
     257           1 :         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
     258             : 
     259           1 :         printf("a zero time means don't change\n");
     260           1 :         unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
     261           1 :         unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
     262           1 :         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
     263           1 :         unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
     264           1 :         sfinfo.basic_info.in.attrib = 0;
     265           2 :         CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
     266           1 :         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
     267           1 :         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
     268           1 :         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
     269           1 :         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
     270           1 :         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
     271             : 
     272           1 :         printf("Test basic_information level\n");
     273           1 :         basetime += 86400;
     274           1 :         unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
     275           1 :         unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
     276           1 :         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
     277           1 :         unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
     278           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
     279           2 :         CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
     280           1 :         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
     281           1 :         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
     282           1 :         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
     283           1 :         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
     284           1 :         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
     285             : 
     286           2 :         CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
     287           2 :         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
     288           2 :         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
     289           2 :         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
     290           2 :         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
     291           2 :         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
     292             : 
     293           1 :         torture_comment(torture, "try to change a file to a directory\n");
     294           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
     295           2 :         CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_INVALID_PARAMETER);
     296             : 
     297           1 :         printf("a zero time means don't change\n");
     298           1 :         unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
     299           1 :         unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
     300           1 :         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
     301           1 :         unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
     302           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
     303           2 :         CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
     304           1 :         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
     305           1 :         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
     306           1 :         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
     307           1 :         CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
     308           1 :         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
     309             : 
     310           2 :         CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
     311           2 :         CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
     312           2 :         CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
     313           2 :         CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
     314             : 
     315             :         /* interesting - w2k3 leaves change_time as current time for 0 change time
     316             :            in setpathinfo
     317             :           CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
     318             :         */
     319           2 :         CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
     320             : 
     321           1 :         printf("Test disposition_info level\n");
     322           1 :         sfinfo.disposition_info.in.delete_on_close = 1;
     323           2 :         CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
     324           1 :         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
     325           1 :         CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
     326             : 
     327           1 :         sfinfo.disposition_info.in.delete_on_close = 0;
     328           2 :         CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
     329           1 :         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
     330           1 :         CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
     331             : 
     332           1 :         printf("Test disposition_information level\n");
     333           1 :         sfinfo.disposition_info.in.delete_on_close = 1;
     334           2 :         CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
     335           1 :         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
     336           1 :         CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
     337             : 
     338             :         /* this would delete the file! */
     339             :         /*
     340             :           CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
     341             :           CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
     342             :           CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
     343             :         */
     344             : 
     345           1 :         sfinfo.disposition_info.in.delete_on_close = 0;
     346           2 :         CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
     347           1 :         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
     348           1 :         CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
     349             : 
     350           2 :         CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
     351           2 :         CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
     352           2 :         CHECK_VALUE(ALL_INFO, all_info, nlink, 1);
     353             : 
     354           1 :         printf("Test allocation_info level\n");
     355           1 :         sfinfo.allocation_info.in.alloc_size = 0;
     356           2 :         CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
     357           1 :         CHECK_VALUE(ALL_INFO, all_info, size, 0);
     358           1 :         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
     359             : 
     360           1 :         sfinfo.allocation_info.in.alloc_size = 4096;
     361           2 :         CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
     362           1 :         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
     363           1 :         CHECK_VALUE(ALL_INFO, all_info, size, 0);
     364             : 
     365           1 :         RECREATE_BOTH;
     366           1 :         sfinfo.allocation_info.in.alloc_size = 0;
     367           2 :         CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
     368           1 :         CHECK_VALUE(ALL_INFO, all_info, size, 0);
     369           1 :         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
     370             : 
     371           2 :         CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
     372           2 :         CHECK_VALUE(ALL_INFO, all_info, size, 0);
     373           2 :         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
     374             : 
     375           1 :         sfinfo.allocation_info.in.alloc_size = 4096;
     376           2 :         CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
     377           1 :         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
     378           1 :         CHECK_VALUE(ALL_INFO, all_info, size, 0);
     379             : 
     380             :         /* setting the allocation size up via setpathinfo seems
     381             :            to be broken in w2k3 */
     382           2 :         CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
     383           2 :         CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
     384           2 :         CHECK_VALUE(ALL_INFO, all_info, size, 0);
     385             : 
     386           1 :         printf("Test end_of_file_info level\n");
     387           1 :         sfinfo.end_of_file_info.in.size = 37;
     388           2 :         CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
     389           1 :         CHECK_VALUE(ALL_INFO, all_info, size, 37);
     390             : 
     391           1 :         sfinfo.end_of_file_info.in.size = 7;
     392           2 :         CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
     393           1 :         CHECK_VALUE(ALL_INFO, all_info, size, 7);
     394             : 
     395           1 :         sfinfo.end_of_file_info.in.size = 37;
     396           2 :         CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
     397           1 :         CHECK_VALUE(ALL_INFO, all_info, size, 37);
     398             : 
     399           2 :         CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
     400           2 :         CHECK_VALUE(ALL_INFO, all_info, size, 37);
     401             : 
     402           1 :         sfinfo.end_of_file_info.in.size = 7;
     403           2 :         CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
     404           1 :         CHECK_VALUE(ALL_INFO, all_info, size, 7);
     405             : 
     406           2 :         CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
     407           2 :         CHECK_VALUE(ALL_INFO, all_info, size, 7);
     408             : 
     409           1 :         printf("Test position_information level\n");
     410           1 :         sfinfo.position_information.in.position = 123456;
     411           2 :         CHECK_CALL_FNUM(POSITION_INFORMATION, NT_STATUS_OK);
     412           1 :         CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
     413             : 
     414           2 :         CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
     415           2 :         CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);
     416             : 
     417           1 :         printf("Test mode_information level\n");
     418           1 :         sfinfo.mode_information.in.mode = 2;
     419           2 :         CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
     420           1 :         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
     421             : 
     422           2 :         CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
     423           2 :         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
     424             : 
     425           1 :         sfinfo.mode_information.in.mode = 1;
     426           2 :         CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
     427           2 :         CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
     428             : 
     429           1 :         sfinfo.mode_information.in.mode = 0;
     430           2 :         CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
     431           1 :         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
     432             : 
     433           2 :         CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
     434           2 :         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
     435             : 
     436             : #if 0
     437             :         printf("Test unix_basic level\n");
     438             :         CHECK_CALL_FNUM(UNIX_BASIC, NT_STATUS_OK);
     439             :         CHECK_CALL_PATH(UNIX_BASIC, NT_STATUS_OK);
     440             : 
     441             :         printf("Test unix_link level\n");
     442             :         CHECK_CALL_FNUM(UNIX_LINK, NT_STATUS_OK);
     443             :         CHECK_CALL_PATH(UNIX_LINK, NT_STATUS_OK);
     444             : #endif
     445             : 
     446           1 : done:
     447           1 :         smb_raw_exit(cli->session);
     448           1 :         smbcli_close(cli->tree, fnum);
     449           1 :         if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
     450           0 :                 printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
     451             :         }
     452           1 :         if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
     453           0 :                 printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
     454             :         }
     455             : 
     456           1 :         return ret;
     457             : }
     458             : 
     459             : /*
     460             :  * basic testing of all RAW_SFILEINFO_RENAME call
     461             :  */
     462             : static bool
     463           5 : torture_raw_sfileinfo_rename(struct torture_context *torture,
     464             :     struct smbcli_state *cli)
     465             : {
     466           5 :         bool ret = true;
     467           5 :         int fnum_saved, d_fnum, fnum2, fnum = -1;
     468           0 :         char *fnum_fname;
     469           0 :         char *fnum_fname_new;
     470           0 :         char *path_fname;
     471           0 :         char *path_fname_new;
     472           0 :         char *path_dname;
     473           0 :         char *path_dname_new;
     474           0 :         char *saved_name;
     475           0 :         char *saved_name_new;
     476           0 :         union smb_fileinfo finfo1, finfo2;
     477           0 :         union smb_setfileinfo sfinfo;
     478           0 :         NTSTATUS status, status2;
     479           0 :         const char *call_name;
     480           0 :         bool check_fnum;
     481           5 :         int n = time(NULL) % 100;
     482             : 
     483           5 :         path_fname = talloc_asprintf(torture, BASEDIR "\\fname_test_%d.txt", n);
     484           5 :         path_fname_new = talloc_asprintf(torture, BASEDIR "\\fname_test_new_%d.txt", n);
     485           5 :         fnum_fname = talloc_asprintf(torture, BASEDIR "\\fnum_test_%d.txt", n);
     486           5 :         fnum_fname_new = talloc_asprintf(torture, BASEDIR "\\fnum_test_new_%d.txt", n);
     487           5 :         path_dname = talloc_asprintf(torture, BASEDIR "\\dname_test_%d", n);
     488           5 :         path_dname_new = talloc_asprintf(torture, BASEDIR "\\dname_test_new_%d", n);
     489             : 
     490           5 :         torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     491             : 
     492           5 :         RECREATE_BOTH;
     493             : 
     494           5 :         ZERO_STRUCT(sfinfo);
     495             : 
     496           5 :         smbcli_close(cli->tree, create_complex_file(cli, torture, fnum_fname_new));
     497           5 :         smbcli_close(cli->tree, create_complex_file(cli, torture, path_fname_new));
     498             : 
     499           5 :         sfinfo.rename_information.in.overwrite = 0;
     500           5 :         sfinfo.rename_information.in.root_fid  = 0;
     501           5 :         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
     502          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
     503             : 
     504           5 :         sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
     505          10 :         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);
     506             : 
     507           5 :         sfinfo.rename_information.in.new_name  = fnum_fname_new;
     508           5 :         sfinfo.rename_information.in.overwrite = 1;
     509           5 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED);
     510             : 
     511           5 :         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
     512           5 :         sfinfo.rename_information.in.overwrite = 1;
     513          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
     514           5 :         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
     515             : 
     516           5 :         printf("Trying rename with dest file open\n");
     517           5 :         fnum2 = create_complex_file(cli, torture, fnum_fname);
     518           5 :         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
     519           5 :         sfinfo.rename_information.in.overwrite = 1;
     520          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
     521           5 :         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
     522             : 
     523           5 :         fnum_saved = fnum;
     524           5 :         fnum = fnum2;
     525           5 :         sfinfo.disposition_info.in.delete_on_close = 1;
     526          10 :         CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
     527           5 :         fnum = fnum_saved;
     528             : 
     529           5 :         printf("Trying rename with dest file open and delete_on_close\n");
     530           5 :         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
     531           5 :         sfinfo.rename_information.in.overwrite = 1;
     532          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
     533             : 
     534           5 :         smbcli_close(cli->tree, fnum2);
     535          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
     536           5 :         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
     537             : 
     538           5 :         printf("Trying rename with source file open twice\n");
     539           5 :         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
     540           5 :         sfinfo.rename_information.in.overwrite = 1;
     541          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
     542           5 :         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
     543             : 
     544           5 :         fnum2 = create_complex_file(cli, torture, fnum_fname);
     545           5 :         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
     546           5 :         sfinfo.rename_information.in.overwrite = 0;
     547          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
     548           5 :         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
     549           5 :         smbcli_close(cli->tree, fnum2);
     550             : 
     551           5 :         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
     552           5 :         sfinfo.rename_information.in.overwrite = 0;
     553          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
     554           5 :         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
     555             : 
     556           5 :         sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
     557           5 :         sfinfo.rename_information.in.overwrite = 1;
     558          10 :         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
     559          10 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
     560             : 
     561           5 :         sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
     562          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
     563           5 :         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
     564             : 
     565           5 :         sfinfo.rename_information.in.new_name  = path_fname+strlen(BASEDIR)+1;
     566          10 :         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
     567          10 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
     568             : 
     569           5 :         printf("Trying rename with a root fid\n");
     570           5 :         status = create_directory_handle(cli->tree, BASEDIR, &d_fnum);
     571           5 :         CHECK_STATUS(status, NT_STATUS_OK);
     572           5 :         sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
     573           5 :         sfinfo.rename_information.in.root_fid = d_fnum;
     574          10 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
     575           5 :         CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
     576           5 :         smbcli_close(cli->tree, d_fnum);
     577             : 
     578           5 :         printf("Trying rename directory\n");
     579           5 :         if (!torture_setup_dir(cli, path_dname)) {
     580           0 :                 ret = false;
     581           0 :                 goto done;
     582             :         }
     583           5 :         saved_name = path_fname;
     584           5 :         saved_name_new = path_fname_new;
     585           5 :         path_fname = path_dname;
     586           5 :         path_fname_new = path_dname_new;
     587           5 :         sfinfo.rename_information.in.new_name  = path_dname_new+strlen(BASEDIR)+1;
     588           5 :         sfinfo.rename_information.in.overwrite = 0;
     589           5 :         sfinfo.rename_information.in.root_fid  = 0;
     590          10 :         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
     591          10 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
     592           5 :         path_fname = saved_name;
     593           5 :         path_fname_new = saved_name_new;
     594             : 
     595           5 :         if (torture_setting_bool(torture, "samba3", false)) {
     596           4 :                 printf("SKIP: Trying rename directory with a handle\n");
     597           4 :                 printf("SKIP: Trying rename by path while a handle is open\n");
     598           4 :                 printf("SKIP: Trying rename directory by path while a handle is open\n");
     599           4 :                 goto done;
     600             :         }
     601             : 
     602           1 :         printf("Trying rename directory with a handle\n");
     603           1 :         status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
     604           1 :         fnum_saved = fnum;
     605           1 :         fnum = d_fnum;
     606           1 :         saved_name = fnum_fname;
     607           1 :         saved_name_new = fnum_fname_new;
     608           1 :         fnum_fname = path_dname;
     609           1 :         fnum_fname_new = path_dname_new;
     610           1 :         sfinfo.rename_information.in.new_name  = path_dname+strlen(BASEDIR)+1;
     611           1 :         sfinfo.rename_information.in.overwrite = 0;
     612           1 :         sfinfo.rename_information.in.root_fid  = 0;
     613           2 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
     614           1 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
     615           1 :         smbcli_close(cli->tree, d_fnum);
     616           1 :         fnum = fnum_saved;
     617           1 :         fnum_fname = saved_name;
     618           1 :         fnum_fname_new = saved_name_new;
     619             : 
     620           1 :         printf("Trying rename by path while a handle is open\n");
     621           1 :         fnum_saved = fnum;
     622           1 :         fnum = create_complex_file(cli, torture, path_fname);
     623           1 :         sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
     624           1 :         sfinfo.rename_information.in.overwrite = 0;
     625           1 :         sfinfo.rename_information.in.root_fid  = 0;
     626           2 :         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
     627           2 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
     628             :         /* check that the handle returns the same name */
     629           1 :         check_fnum = true;
     630           1 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
     631             :         /* rename it back on the handle */
     632           1 :         sfinfo.rename_information.in.new_name  = path_fname+strlen(BASEDIR)+1;
     633           2 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
     634           1 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
     635           1 :         check_fnum = false;
     636           2 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
     637           1 :         smbcli_close(cli->tree, fnum);
     638           1 :         fnum = fnum_saved;
     639             : 
     640           1 :         printf("Trying rename directory by path while a handle is open\n");
     641           1 :         status = create_directory_handle(cli->tree, path_dname, &d_fnum);
     642           1 :         fnum_saved = fnum;
     643           1 :         fnum = d_fnum;
     644           1 :         saved_name = path_fname;
     645           1 :         saved_name_new = path_fname_new;
     646           1 :         path_fname = path_dname;
     647           1 :         path_fname_new = path_dname_new;
     648           1 :         sfinfo.rename_information.in.new_name  = path_dname_new+strlen(BASEDIR)+1;
     649           1 :         sfinfo.rename_information.in.overwrite = 0;
     650           1 :         sfinfo.rename_information.in.root_fid  = 0;
     651           2 :         CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
     652           2 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
     653           1 :         path_fname = saved_name;
     654           1 :         path_fname_new = saved_name_new;
     655           1 :         saved_name = fnum_fname;
     656           1 :         saved_name_new = fnum_fname_new;
     657           1 :         fnum_fname = path_dname;
     658           1 :         fnum_fname_new = path_dname_new;
     659             :         /* check that the handle returns the same name */
     660           1 :         check_fnum = true;
     661           1 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
     662             :         /* rename it back on the handle */
     663           1 :         sfinfo.rename_information.in.new_name  = path_dname+strlen(BASEDIR)+1;
     664           2 :         CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
     665           1 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
     666           1 :         fnum_fname = saved_name;
     667           1 :         fnum_fname_new = saved_name_new;
     668           1 :         saved_name = path_fname;
     669           1 :         saved_name_new = path_fname_new;
     670           1 :         path_fname = path_dname;
     671           1 :         path_fname_new = path_dname_new;
     672           1 :         check_fnum = false;
     673           2 :         CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
     674           1 :         smbcli_close(cli->tree, d_fnum);
     675           1 :         fnum = fnum_saved;
     676           1 :         path_fname = saved_name;
     677           1 :         path_fname_new = saved_name_new;
     678             : 
     679           5 : done:
     680           5 :         smb_raw_exit(cli->session);
     681           5 :         smbcli_deltree(cli->tree, BASEDIR);
     682           5 :         return ret;
     683             : }
     684             : 
     685             : /* 
     686             :    look for the w2k3 setpathinfo STANDARD bug
     687             : */
     688           5 : static bool torture_raw_sfileinfo_bug(struct torture_context *torture,
     689             :     struct smbcli_state *cli)
     690             : {
     691           5 :         const char *fname = "\\bug3.txt";
     692           0 :         union smb_setfileinfo sfinfo;
     693           0 :         NTSTATUS status;
     694           0 :         int fnum;
     695             : 
     696           5 :         if (!torture_setting_bool(torture, "dangerous", false))
     697           5 :                 torture_skip(torture, 
     698             :                         "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n");
     699             : 
     700           0 :         fnum = create_complex_file(cli, torture, fname);
     701           0 :         smbcli_close(cli->tree, fnum);
     702             : 
     703           0 :         sfinfo.generic.level = RAW_SFILEINFO_STANDARD;
     704           0 :         sfinfo.generic.in.file.path = fname;
     705             : 
     706           0 :         sfinfo.standard.in.create_time = 0;
     707           0 :         sfinfo.standard.in.access_time = 0;
     708           0 :         sfinfo.standard.in.write_time  = 0;
     709             : 
     710           0 :         status = smb_raw_setpathinfo(cli->tree, &sfinfo);
     711           0 :         printf("%s - %s\n", fname, nt_errstr(status));
     712             : 
     713           0 :         printf("now try and delete %s\n", fname);
     714             : 
     715           0 :         return true;
     716             : }
     717             : 
     718             : /**
     719             :  * Test both the snia cifs RAW_SFILEINFO_END_OF_FILE_INFO and the undocumented
     720             :  * pass-through RAW_SFILEINFO_END_OF_FILE_INFORMATION in the context of
     721             :  * trans2setpathinfo.
     722             :  */
     723             : static bool
     724           5 : torture_raw_sfileinfo_eof(struct torture_context *tctx,
     725             :     struct smbcli_state *cli1, struct smbcli_state *cli2)
     726             : {
     727           5 :         const char *fname = BASEDIR "\\test_sfileinfo_end_of_file.dat";
     728           0 :         NTSTATUS status;
     729           5 :         bool ret = true;
     730           0 :         union smb_open io;
     731           0 :         union smb_setfileinfo sfi;
     732           0 :         union smb_fileinfo qfi;
     733           5 :         uint16_t fnum = 0;
     734             : 
     735           5 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     736           0 :                 return false;
     737             :         }
     738             : 
     739             :         /* cleanup */
     740           5 :         smbcli_unlink(cli1->tree, fname);
     741             : 
     742           5 :         io.generic.level = RAW_OPEN_NTCREATEX;
     743           5 :         io.ntcreatex.in.root_fid.fnum = 0;
     744           5 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     745           5 :         io.ntcreatex.in.alloc_size = 0;
     746           5 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     747           5 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     748           5 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
     749           5 :         io.ntcreatex.in.create_options = 0;
     750           5 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     751           5 :         io.ntcreatex.in.security_flags = 0;
     752           5 :         io.ntcreatex.in.fname = fname;
     753           5 :         io.ntcreatex.in.flags = 0;
     754             : 
     755             :         /* Open the file sharing none. */
     756           5 :         status = smb_raw_open(cli1->tree, tctx, &io);
     757           5 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
     758             :             done, "Status should be OK");
     759           5 :         fnum = io.ntcreatex.out.file.fnum;
     760             : 
     761             :         /* Try to sfileinfo to extend the file. */
     762           5 :         ZERO_STRUCT(sfi);
     763           5 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
     764           5 :         sfi.generic.in.file.path = fname;
     765           5 :         sfi.end_of_file_info.in.size = 100;
     766           5 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
     767             : 
     768             :         /* There should be share mode contention in this case. */
     769           5 :         torture_assert_ntstatus_equal_goto(tctx, status,
     770             :             NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
     771             :             "SHARING_VIOLATION");
     772             : 
     773             :         /* Make sure the size is still 0. */
     774           5 :         ZERO_STRUCT(qfi);
     775           5 :         qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
     776           5 :         qfi.generic.in.file.path = fname;
     777           5 :         status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
     778           5 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
     779             :             done, "Status should be OK");
     780             : 
     781           5 :         torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 0,
     782             :             "alloc_size should be 0 since the setpathinfo failed.");
     783             : 
     784             :         /* Try again with the pass through instead of documented version. */
     785           5 :         ZERO_STRUCT(sfi);
     786           5 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
     787           5 :         sfi.generic.in.file.path = fname;
     788           5 :         sfi.end_of_file_info.in.size = 100;
     789           5 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
     790             : 
     791             :         /*
     792             :          * Looks like a windows bug:
     793             :          * http://lists.samba.org/archive/cifs-protocol/2009-November/001130.html
     794             :          */
     795           5 :         if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
     796             :                 /* It succeeds! This is just weird! */
     797           0 :                 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
     798             :                     ret, done, "Status should be OK");
     799             : 
     800             :                 /* Verify that the file was actually extended to 100. */
     801           0 :                 ZERO_STRUCT(qfi);
     802           0 :                 qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
     803           0 :                 qfi.generic.in.file.path = fname;
     804           0 :                 status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
     805           0 :                 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
     806             :                     ret, done, "Status should be OK");
     807             : 
     808           0 :                 torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 100,
     809             :                     "alloc_size should be 100 since the setpathinfo "
     810             :                     "succeeded.");
     811             :         } else {
     812           5 :                 torture_assert_ntstatus_equal_goto(tctx, status,
     813             :                     NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
     814             :                     "SHARING_VIOLATION");
     815             :         }
     816             : 
     817             :         /* close the first file. */
     818           5 :         smbcli_close(cli1->tree, fnum);
     819           5 :         fnum = 0;
     820             : 
     821             :         /* Try to sfileinfo to extend the file again (non-pass-through). */
     822           5 :         ZERO_STRUCT(sfi);
     823           5 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
     824           5 :         sfi.generic.in.file.path = fname;
     825           5 :         sfi.end_of_file_info.in.size = 200;
     826           5 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
     827             : 
     828             :         /* This should cause the client to return invalid level. */
     829           5 :         if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
     830             :                 /*
     831             :                  * Windows sends back an invalid packet that smbclient sees
     832             :                  * and returns INTERNAL_ERROR.
     833             :                  */
     834           0 :                 torture_assert_ntstatus_equal_goto(tctx, status,
     835             :                     NT_STATUS_INTERNAL_ERROR, ret, done, "Status should be "
     836             :                     "INTERNAL_ERROR");
     837             :         } else {
     838           5 :                 torture_assert_ntstatus_equal_goto(tctx, status,
     839             :                     NT_STATUS_INVALID_LEVEL, ret, done, "Status should be "
     840             :                     "INVALID_LEVEL");
     841             :         }
     842             : 
     843             :         /* Try to extend the file now with the passthrough level. */
     844           4 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
     845           4 :         status = smb_raw_setpathinfo(cli2->tree, &sfi);
     846           4 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
     847             :             done, "Status should be OK");
     848             : 
     849             :         /* Verify that the file was actually extended to 200. */
     850           4 :         ZERO_STRUCT(qfi);
     851           4 :         qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
     852           4 :         qfi.generic.in.file.path = fname;
     853           4 :         status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
     854             : 
     855           4 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
     856             :             done, "Status should be OK");
     857           4 :         torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 200,
     858             :             "alloc_size should be 200 since the setpathinfo succeeded.");
     859             : 
     860             :         /* Open the file so end of file can be set by handle. */
     861           4 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE;
     862           4 :         status = smb_raw_open(cli1->tree, tctx, &io);
     863           4 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
     864             :             done, "Status should be OK");
     865           4 :         fnum = io.ntcreatex.out.file.fnum;
     866             : 
     867             :         /* Try sfileinfo to extend the file by handle (non-pass-through). */
     868           4 :         ZERO_STRUCT(sfi);
     869           4 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
     870           4 :         sfi.generic.in.file.fnum = fnum;
     871           4 :         sfi.end_of_file_info.in.size = 300;
     872           4 :         status = smb_raw_setfileinfo(cli1->tree, &sfi);
     873           4 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
     874             :             done, "Status should be OK");
     875             : 
     876             :         /* Verify that the file was actually extended to 300. */
     877           4 :         ZERO_STRUCT(qfi);
     878           4 :         qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
     879           4 :         qfi.generic.in.file.path = fname;
     880           4 :         status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
     881           4 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
     882             :             done, "Status should be OK");
     883           4 :         torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 300,
     884             :             "alloc_size should be 300 since the setpathinfo succeeded.");
     885             : 
     886             :         /* Try sfileinfo to extend the file by handle (pass-through). */
     887           4 :         ZERO_STRUCT(sfi);
     888           4 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
     889           4 :         sfi.generic.in.file.fnum = fnum;
     890           4 :         sfi.end_of_file_info.in.size = 400;
     891           4 :         status = smb_raw_setfileinfo(cli1->tree, &sfi);
     892           4 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
     893             :             done, "Status should be OK");
     894             : 
     895             :         /* Verify that the file was actually extended to 300. */
     896           4 :         ZERO_STRUCT(qfi);
     897           4 :         qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
     898           4 :         qfi.generic.in.file.path = fname;
     899           4 :         status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
     900           4 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
     901             :             done, "Status should be OK");
     902           4 :         torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 400,
     903             :             "alloc_size should be 400 since the setpathinfo succeeded.");
     904           4 :  done:
     905           5 :         if (fnum > 0) {
     906           4 :                 smbcli_close(cli1->tree, fnum);
     907           4 :                 fnum = 0;
     908             :         }
     909             : 
     910           5 :         smb_raw_exit(cli1->session);
     911           5 :         smb_raw_exit(cli2->session);
     912           5 :         smbcli_deltree(cli1->tree, BASEDIR);
     913           5 :         return ret;
     914             : }
     915             : 
     916             : static bool
     917           1 : torture_raw_sfileinfo_eof_access(struct torture_context *tctx,
     918             :     struct smbcli_state *cli1, struct smbcli_state *cli2)
     919             : {
     920           1 :         const char *fname = BASEDIR "\\test_exclusive3.dat";
     921           0 :         NTSTATUS status, expected_status;
     922           1 :         bool ret = true;
     923           0 :         union smb_open io;
     924           0 :         union smb_setfileinfo sfi;
     925           1 :         uint16_t fnum=0;
     926           1 :         uint32_t access_mask = 0;
     927             : 
     928           1 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     929           0 :                 return false;
     930             :         }
     931             : 
     932             :         /* cleanup */
     933           1 :         smbcli_unlink(cli1->tree, fname);
     934             : 
     935             :         /*
     936             :          * base ntcreatex parms
     937             :          */
     938           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     939           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     940           1 :         io.ntcreatex.in.alloc_size = 0;
     941           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     942           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     943           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     944           1 :         io.ntcreatex.in.create_options = 0;
     945           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     946           1 :         io.ntcreatex.in.security_flags = 0;
     947           1 :         io.ntcreatex.in.fname = fname;
     948           1 :         io.ntcreatex.in.flags = 0;
     949             : 
     950             : 
     951         512 :         for (access_mask = 1; access_mask <= 0x00001FF; access_mask++) {
     952         511 :                 io.ntcreatex.in.access_mask = access_mask;
     953             : 
     954         511 :                 status = smb_raw_open(cli1->tree, tctx, &io);
     955         511 :                 if (!NT_STATUS_IS_OK(status)) {
     956           0 :                         continue;
     957             :                 }
     958             : 
     959         511 :                 fnum = io.ntcreatex.out.file.fnum;
     960             : 
     961         511 :                 ZERO_STRUCT(sfi);
     962         511 :                 sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
     963         511 :                 sfi.generic.in.file.fnum = fnum;
     964         511 :                 sfi.end_of_file_info.in.size = 100;
     965             : 
     966         511 :                 status = smb_raw_setfileinfo(cli1->tree, &sfi);
     967             : 
     968         511 :                 expected_status = (access_mask & SEC_FILE_WRITE_DATA) ?
     969           0 :                     NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
     970             : 
     971         511 :                 if (!NT_STATUS_EQUAL(expected_status, status)) {
     972           0 :                         torture_comment(tctx, "0x%x wrong\n", access_mask);
     973             :                 }
     974             : 
     975         511 :                 torture_assert_ntstatus_equal_goto(tctx, status,
     976             :                     expected_status, ret, done, "Status Wrong");
     977             : 
     978         511 :                 smbcli_close(cli1->tree, fnum);
     979             :         }
     980             : 
     981           1 : done:
     982           1 :         smb_raw_exit(cli1->session);
     983           1 :         smb_raw_exit(cli2->session);
     984           1 :         smbcli_deltree(cli1->tree, BASEDIR);
     985           1 :         return ret;
     986             : }
     987             : 
     988             : static bool
     989           1 : torture_raw_sfileinfo_archive(struct torture_context *tctx,
     990             :     struct smbcli_state *cli)
     991             : {
     992           1 :         const char *fname = BASEDIR "\\test_archive.dat";
     993           0 :         NTSTATUS status;
     994           1 :         bool ret = true;
     995           0 :         union smb_open io;
     996           0 :         union smb_setfileinfo sfinfo;
     997           0 :         union smb_fileinfo finfo;
     998           1 :         uint16_t fnum=0;
     999             : 
    1000           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1001             : 
    1002             :         /* cleanup */
    1003           1 :         smbcli_unlink(cli->tree, fname);
    1004             : 
    1005             :         /*
    1006             :          * create a normal file, verify archive bit
    1007             :          */
    1008           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1009           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1010           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1011           1 :         io.ntcreatex.in.alloc_size = 0;
    1012           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1013           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1014           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1015           1 :         io.ntcreatex.in.create_options = 0;
    1016           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1017           1 :         io.ntcreatex.in.security_flags = 0;
    1018           1 :         io.ntcreatex.in.fname = fname;
    1019           1 :         io.ntcreatex.in.flags = 0;
    1020           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1021           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1022             :             ret, done, "open failed");
    1023           1 :         fnum = io.ntcreatex.out.file.fnum;
    1024             : 
    1025           1 :         torture_assert_int_equal(tctx,
    1026             :             io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
    1027             :             FILE_ATTRIBUTE_ARCHIVE,
    1028             :             "archive bit not set");
    1029             : 
    1030             :         /*
    1031             :          * try to turn off archive bit
    1032             :          */
    1033           1 :         ZERO_STRUCT(sfinfo);
    1034           1 :         sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
    1035           1 :         sfinfo.generic.in.file.fnum = fnum;
    1036           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
    1037           1 :         status = smb_raw_setfileinfo(cli->tree, &sfinfo);
    1038           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1039             :             ret, done, "setfileinfo failed");
    1040             : 
    1041           1 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    1042           1 :         finfo.generic.in.file.fnum = fnum;
    1043           1 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    1044           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1045             :             ret, done, "fileinfo failed");
    1046             : 
    1047           1 :         torture_assert_int_equal(tctx,
    1048             :             finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
    1049             :             FILE_ATTRIBUTE_NORMAL,
    1050             :             "archive bit set");
    1051             : 
    1052           1 :         status = smbcli_close(cli->tree, fnum);
    1053           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1054             :             ret, done, "close failed");
    1055             : 
    1056           1 :         status = smbcli_unlink(cli->tree, fname);
    1057           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1058             :             ret, done, "unlink failed");
    1059             : 
    1060             :         /*
    1061             :          * create a directory, verify no archive bit
    1062             :          */
    1063           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1064           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1065           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_DIR_ALL;
    1066           1 :         io.ntcreatex.in.alloc_size = 0;
    1067           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1068           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1069           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1070           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1071           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1072           1 :         io.ntcreatex.in.security_flags = 0;
    1073           1 :         io.ntcreatex.in.fname = fname;
    1074           1 :         io.ntcreatex.in.flags = 0;
    1075           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1076           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1077             :             ret, done, "directory open failed");
    1078           1 :         fnum = io.ntcreatex.out.file.fnum;
    1079             : 
    1080           1 :         torture_assert_int_equal(tctx,
    1081             :             io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
    1082             :             FILE_ATTRIBUTE_DIRECTORY,
    1083             :             "archive bit set");
    1084             : 
    1085             :         /*
    1086             :          * verify you can turn on archive bit
    1087             :          */
    1088           1 :         sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
    1089           1 :         sfinfo.generic.in.file.fnum = fnum;
    1090           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE;
    1091           1 :         status = smb_raw_setfileinfo(cli->tree, &sfinfo);
    1092           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1093             :             ret, done, "setfileinfo failed");
    1094             : 
    1095           1 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    1096           1 :         finfo.generic.in.file.fnum = fnum;
    1097           1 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    1098           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1099             :             ret, done, "fileinfo failed");
    1100             : 
    1101           1 :         torture_assert_int_equal(tctx,
    1102             :             finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
    1103             :             FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE,
    1104             :             "archive bit not set");
    1105             : 
    1106             :         /*
    1107             :          * and try to turn it back off
    1108             :          */
    1109           1 :         sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
    1110           1 :         sfinfo.generic.in.file.fnum = fnum;
    1111           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
    1112           1 :         status = smb_raw_setfileinfo(cli->tree, &sfinfo);
    1113           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1114             :             ret, done, "setfileinfo failed");
    1115             : 
    1116           1 :         finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    1117           1 :         finfo.generic.in.file.fnum = fnum;
    1118           1 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    1119           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1120             :             ret, done, "fileinfo failed");
    1121             : 
    1122           1 :         torture_assert_int_equal(tctx,
    1123             :             finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
    1124             :             FILE_ATTRIBUTE_DIRECTORY,
    1125             :             "archive bit set");
    1126             : 
    1127           1 :         status = smbcli_close(cli->tree, fnum);
    1128           1 :         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
    1129             :             ret, done, "close failed");
    1130             : 
    1131           1 : done:
    1132           1 :         smbcli_close(cli->tree, fnum);
    1133           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1134           1 :         return ret;
    1135             : }
    1136             : 
    1137        2379 : struct torture_suite *torture_raw_sfileinfo(TALLOC_CTX *mem_ctx)
    1138             : {
    1139        2379 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "sfileinfo");
    1140             : 
    1141        2379 :         torture_suite_add_1smb_test(suite, "base", torture_raw_sfileinfo_base);
    1142        2379 :         torture_suite_add_1smb_test(suite, "rename", torture_raw_sfileinfo_rename);
    1143        2379 :         torture_suite_add_1smb_test(suite, "bug", torture_raw_sfileinfo_bug);
    1144        2379 :         torture_suite_add_2smb_test(suite, "end-of-file",
    1145             :             torture_raw_sfileinfo_eof);
    1146        2379 :         torture_suite_add_2smb_test(suite, "end-of-file-access",
    1147             :             torture_raw_sfileinfo_eof_access);
    1148        2379 :         torture_suite_add_1smb_test(suite, "archive",
    1149             :                                                                 torture_raw_sfileinfo_archive);
    1150             : 
    1151        2379 :         return suite;
    1152             : }

Generated by: LCOV version 1.14