LCOV - code coverage report
Current view: top level - source4/torture/smb2 - setinfo.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 174 208 83.7 %
Date: 2024-02-28 12:06:22 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    SMB2 setinfo individual test suite
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2005
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "system/time.h"
      24             : #include "libcli/smb2/smb2.h"
      25             : #include "libcli/smb2/smb2_calls.h"
      26             : 
      27             : #include "torture/torture.h"
      28             : #include "torture/smb2/proto.h"
      29             : 
      30             : #include "libcli/security/security.h"
      31             : #include "librpc/gen_ndr/ndr_security.h"
      32             : 
      33           5 : static bool find_returned_ea(union smb_fileinfo *finfo2,
      34             :                                 const char *eaname,
      35             :                                 const char *eavalue)
      36             : {
      37           0 :         unsigned int i;
      38           5 :         unsigned int num_eas = finfo2->all_eas.out.num_eas;
      39           5 :         struct ea_struct *eas = finfo2->all_eas.out.eas;
      40             : 
      41          12 :         for (i = 0; i < num_eas; i++) {
      42          10 :                 if (eas[i].name.s == NULL) {
      43           0 :                         continue;
      44             :                 }
      45             :                 /* Windows capitalizes returned EA names. */
      46          10 :                 if (strcasecmp_m(eas[i].name.s, eaname)) {
      47           7 :                         continue;
      48             :                 }
      49           3 :                 if (eavalue == NULL && eas[i].value.length == 0) {
      50             :                         /* Null value, found it ! */
      51           0 :                         return true;
      52             :                 }
      53           3 :                 if (eas[i].value.length == strlen(eavalue) &&
      54           3 :                                 memcmp(eas[i].value.data,
      55             :                                         eavalue,
      56             :                                         strlen(eavalue)) == 0) {
      57           3 :                         return true;
      58             :                 }
      59             :         }
      60           2 :         return false;
      61             : }
      62             : 
      63             : #define BASEDIR ""
      64             : 
      65             : #define FAIL_UNLESS(__cond)                                     \
      66             :         do {                                                    \
      67             :                 if (__cond) {} else {                           \
      68             :                         torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n",    \
      69             :                                __location__, #__cond);          \
      70             :                         ret = false; goto done;                 \
      71             :                 }                                               \
      72             :         } while(0)
      73             : 
      74             : /* basic testing of all SMB2 setinfo calls 
      75             :    for each call we test that it succeeds, and where possible test 
      76             :    for consistency between the calls. 
      77             : */
      78           5 : bool torture_smb2_setinfo(struct torture_context *tctx)
      79             : {
      80           0 :         struct smb2_tree *tree;
      81           5 :         bool ret = true;
      82           0 :         struct smb2_handle handle;
      83           0 :         char *fname;
      84           0 :         union smb_fileinfo finfo2;
      85           0 :         union smb_setfileinfo sfinfo;
      86           0 :         struct security_ace ace;
      87           0 :         struct security_descriptor *sd;
      88           0 :         struct dom_sid *test_sid;
      89           5 :         NTSTATUS status, status2=NT_STATUS_OK;
      90           0 :         const char *call_name;
      91           5 :         time_t basetime = (time(NULL) - 86400) & ~1;
      92           5 :         int n = time(NULL) % 100;
      93           0 :         struct ea_struct ea;
      94             :         
      95           5 :         ZERO_STRUCT(handle);
      96             :         
      97           5 :         fname = talloc_asprintf(tctx, BASEDIR "fnum_test_%d.txt", n);
      98             : 
      99           5 :         if (!torture_smb2_connection(tctx, &tree)) {
     100           0 :                 return false;
     101             :         }
     102             : 
     103             : #define RECREATE_FILE(fname) do { \
     104             :         smb2_util_close(tree, handle); \
     105             :         status = smb2_create_complex_file(tctx, tree, fname, &handle); \
     106             :         if (!NT_STATUS_IS_OK(status)) { \
     107             :                 torture_result(tctx, TORTURE_FAIL, "(%s) ERROR: open of %s failed (%s)\n", \
     108             :                        __location__, fname, nt_errstr(status)); \
     109             :                 ret = false; \
     110             :                 goto done; \
     111             :         }} while (0)
     112             : 
     113             : #define RECREATE_BOTH do { \
     114             :                 RECREATE_FILE(fname); \
     115             :         } while (0)
     116             : 
     117           5 :         RECREATE_BOTH;
     118             :         
     119             : #define CHECK_CALL(call, rightstatus) do { \
     120             :         call_name = #call; \
     121             :         sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
     122             :         sfinfo.generic.in.file.handle = handle; \
     123             :         status = smb2_setinfo_file(tree, &sfinfo); \
     124             :         if (!NT_STATUS_EQUAL(status, rightstatus)) { \
     125             :                 torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s (should be %s)\n", __location__, #call, \
     126             :                         nt_errstr(status), nt_errstr(rightstatus)); \
     127             :                 ret = false; \
     128             :                 goto done; \
     129             :         } \
     130             :         } while (0)
     131             : 
     132             : #define CHECK1(call) \
     133             :         do { if (NT_STATUS_IS_OK(status)) { \
     134             :                 finfo2.generic.level = RAW_FILEINFO_ ## call; \
     135             :                 finfo2.generic.in.file.handle = handle; \
     136             :                 status2 = smb2_getinfo_file(tree, tctx, &finfo2); \
     137             :                 if (!NT_STATUS_IS_OK(status2)) { \
     138             :                         torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__, #call, nt_errstr(status2)); \
     139             :                 ret = false; \
     140             :                 goto done; \
     141             :                 } \
     142             :         }} while (0)
     143             : 
     144             : #define CHECK_VALUE(call, stype, field, value) do { \
     145             :         CHECK1(call); \
     146             :         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
     147             :                 torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
     148             :                        call_name, #stype, #field, \
     149             :                        (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
     150             :                 torture_smb2_all_info(tctx, tree, handle); \
     151             :                 ret = false; \
     152             :                 goto done; \
     153             :         }} while (0)
     154             : 
     155             : #define CHECK_TIME(call, stype, field, value) do { \
     156             :         CHECK1(call); \
     157             :         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
     158             :                 torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
     159             :                         call_name, #stype, #field, \
     160             :                         (unsigned int)value, \
     161             :                         (unsigned int)nt_time_to_unix(finfo2.stype.out.field)); \
     162             :                 torture_warning(tctx, "\t%s", timestring(tctx, value)); \
     163             :                 torture_warning(tctx, "\t%s\n", nt_time_string(tctx, finfo2.stype.out.field)); \
     164             :                 torture_smb2_all_info(tctx, tree, handle); \
     165             :                 ret = false; \
     166             :                 goto done; \
     167             :         }} while (0)
     168             : 
     169             : #define CHECK_STATUS(status, correct) do { \
     170             :         if (!NT_STATUS_EQUAL(status, correct)) { \
     171             :                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
     172             :                        __location__, nt_errstr(status), nt_errstr(correct)); \
     173             :                 ret = false; \
     174             :                 goto done; \
     175             :         }} while (0)
     176             : 
     177           1 :         torture_smb2_all_info(tctx, tree, handle);
     178             :         
     179           1 :         torture_comment(tctx, "Test basic_information level\n");
     180           1 :         basetime += 86400;
     181           1 :         unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
     182           1 :         unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
     183           1 :         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
     184           1 :         unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
     185           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
     186           1 :         CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
     187           1 :         CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, create_time, basetime + 100);
     188           1 :         CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, access_time, basetime + 200);
     189           1 :         CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, write_time,  basetime + 300);
     190           1 :         CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, change_time, basetime + 400);
     191           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib,     FILE_ATTRIBUTE_READONLY);
     192             : 
     193           1 :         torture_comment(tctx, "a zero time means don't change\n");
     194           1 :         unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
     195           1 :         unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
     196           1 :         unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
     197           1 :         unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
     198           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
     199           1 :         CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
     200           1 :         CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, create_time, basetime + 100);
     201           1 :         CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, access_time, basetime + 200);
     202           1 :         CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, write_time,  basetime + 300);
     203           1 :         CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, change_time, basetime + 400);
     204           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib,     FILE_ATTRIBUTE_NORMAL);
     205             : 
     206           1 :         torture_comment(tctx, "change the attribute\n");
     207           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_HIDDEN;
     208           1 :         CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
     209           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);
     210             : 
     211           1 :         torture_comment(tctx, "zero attrib means don't change\n");
     212           1 :         sfinfo.basic_info.in.attrib = 0;
     213           1 :         CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
     214           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);
     215             : 
     216           1 :         torture_comment(tctx, "can't change a file to a directory\n");
     217           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
     218           1 :         CHECK_CALL(BASIC_INFORMATION, NT_STATUS_INVALID_PARAMETER);
     219             : 
     220           1 :         torture_comment(tctx, "restore attribute\n");
     221           1 :         sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
     222           1 :         CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
     223           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_NORMAL);
     224             : 
     225           1 :         torture_comment(tctx, "Test disposition_information level\n");
     226           1 :         sfinfo.disposition_info.in.delete_on_close = 1;
     227           1 :         CHECK_CALL(DISPOSITION_INFORMATION, NT_STATUS_OK);
     228           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, delete_pending, 1);
     229           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, nlink, 0);
     230             : 
     231           1 :         sfinfo.disposition_info.in.delete_on_close = 0;
     232           1 :         CHECK_CALL(DISPOSITION_INFORMATION, NT_STATUS_OK);
     233           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, delete_pending, 0);
     234           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, nlink, 1);
     235             : 
     236           1 :         torture_comment(tctx, "Test allocation_information level\n");
     237           1 :         sfinfo.allocation_info.in.alloc_size = 0;
     238           1 :         CHECK_CALL(ALLOCATION_INFORMATION, NT_STATUS_OK);
     239           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 0);
     240           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, alloc_size, 0);
     241             : 
     242           1 :         sfinfo.allocation_info.in.alloc_size = 4096;
     243           1 :         CHECK_CALL(ALLOCATION_INFORMATION, NT_STATUS_OK);
     244           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, alloc_size, 4096);
     245           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 0);
     246             : 
     247           1 :         torture_comment(tctx, "Test end_of_file_info level\n");
     248           1 :         sfinfo.end_of_file_info.in.size = 37;
     249           1 :         CHECK_CALL(END_OF_FILE_INFORMATION, NT_STATUS_OK);
     250           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 37);
     251             : 
     252           1 :         sfinfo.end_of_file_info.in.size = 7;
     253           1 :         CHECK_CALL(END_OF_FILE_INFORMATION, NT_STATUS_OK);
     254           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 7);
     255             : 
     256           1 :         torture_comment(tctx, "Test position_information level\n");
     257           1 :         sfinfo.position_information.in.position = 123456;
     258           1 :         CHECK_CALL(POSITION_INFORMATION, NT_STATUS_OK);
     259           1 :         CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
     260           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, position, 123456);
     261             : 
     262           1 :         torture_comment(tctx, "Test mode_information level\n");
     263           1 :         sfinfo.mode_information.in.mode = 2;
     264           1 :         CHECK_CALL(MODE_INFORMATION, NT_STATUS_OK);
     265           1 :         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
     266           1 :         CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, mode, 2);
     267             : 
     268           1 :         sfinfo.mode_information.in.mode = 1;
     269           1 :         CHECK_CALL(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
     270             : 
     271           1 :         sfinfo.mode_information.in.mode = 0;
     272           1 :         CHECK_CALL(MODE_INFORMATION, NT_STATUS_OK);
     273           1 :         CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);
     274             : 
     275           1 :         torture_comment(tctx, "Test sec_desc level\n");
     276           1 :         ZERO_STRUCT(finfo2);
     277           1 :         finfo2.query_secdesc.in.secinfo_flags =
     278             :                 SECINFO_OWNER |
     279             :                 SECINFO_GROUP |
     280             :                 SECINFO_DACL;
     281           1 :         CHECK1(SEC_DESC);
     282           1 :         sd = finfo2.query_secdesc.out.sd;
     283             : 
     284           1 :         test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
     285           1 :         ZERO_STRUCT(ace);
     286           1 :         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
     287           1 :         ace.flags = 0;
     288           1 :         ace.access_mask = SEC_STD_ALL;
     289           1 :         ace.trustee = *test_sid;
     290           1 :         status = security_descriptor_dacl_add(sd, &ace);
     291           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     292             : 
     293           1 :         torture_comment(tctx, "add a new ACE to the DACL\n");
     294             : 
     295           1 :         sfinfo.set_secdesc.in.secinfo_flags = finfo2.query_secdesc.in.secinfo_flags;
     296           1 :         sfinfo.set_secdesc.in.sd = sd;
     297           1 :         CHECK_CALL(SEC_DESC, NT_STATUS_OK);
     298           1 :         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, handle, sd));
     299             : 
     300           1 :         torture_comment(tctx, "remove it again\n");
     301             : 
     302           1 :         status = security_descriptor_dacl_del(sd, test_sid);
     303           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     304             : 
     305           1 :         sfinfo.set_secdesc.in.secinfo_flags = finfo2.query_secdesc.in.secinfo_flags;
     306           1 :         sfinfo.set_secdesc.in.sd = sd;
     307           1 :         CHECK_CALL(SEC_DESC, NT_STATUS_OK);
     308           1 :         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, handle, sd));
     309             : 
     310           1 :         torture_comment(tctx, "Check zero length EA's behavior\n");
     311             : 
     312             :         /* Set a new EA. */
     313           1 :         sfinfo.full_ea_information.in.eas.num_eas = 1;
     314           1 :         ea.flags = 0;
     315           1 :         ea.name.private_length = 6;
     316           1 :         ea.name.s = "NewEA";
     317           1 :         ea.value = data_blob_string_const("testme");
     318           1 :         sfinfo.full_ea_information.in.eas.eas = &ea;
     319           1 :         CHECK_CALL(FULL_EA_INFORMATION, NT_STATUS_OK);
     320             : 
     321             :         /* Does it still exist ? */
     322           1 :         finfo2.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
     323           1 :         finfo2.generic.in.file.handle = handle;
     324           1 :         finfo2.all_eas.in.continue_flags = 1;
     325           1 :         status2 = smb2_getinfo_file(tree, tctx, &finfo2);
     326           1 :         if (!NT_STATUS_IS_OK(status2)) {
     327           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__,
     328             :                         "SMB2_ALL_EAS", nt_errstr(status2));
     329           0 :                 ret = false;
     330           0 :                 goto done;
     331             :         }
     332             : 
     333             :         /* Note on Windows EA name is returned capitalized. */
     334           1 :         if (!find_returned_ea(&finfo2, "NewEA", "testme")) {
     335           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) Missing EA 'NewEA'\n", __location__);
     336           0 :                 ret = false;
     337             :         }
     338             : 
     339             :         /* Now zero it out (should delete it) */
     340           1 :         sfinfo.full_ea_information.in.eas.num_eas = 1;
     341           1 :         ea.flags = 0;
     342           1 :         ea.name.private_length = 6;
     343           1 :         ea.name.s = "NewEA";
     344           1 :         ea.value = data_blob_null;
     345           1 :         sfinfo.full_ea_information.in.eas.eas = &ea;
     346           1 :         CHECK_CALL(FULL_EA_INFORMATION, NT_STATUS_OK);
     347             : 
     348             :         /* Does it still exist ? */
     349           1 :         finfo2.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
     350           1 :         finfo2.generic.in.file.handle = handle;
     351           1 :         finfo2.all_eas.in.continue_flags = 1;
     352           1 :         status2 = smb2_getinfo_file(tree, tctx, &finfo2);
     353           1 :         if (!NT_STATUS_IS_OK(status2)) {
     354           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__,
     355             :                         "SMB2_ALL_EAS", nt_errstr(status2));
     356           0 :                 ret = false;
     357           0 :                 goto done;
     358             :         }
     359             : 
     360           1 :         if (find_returned_ea(&finfo2, "NewEA", NULL)) {
     361           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) EA 'NewEA' should be deleted\n", __location__);
     362           0 :                 ret = false;
     363             :         }
     364             : 
     365             :         /* Set a zero length EA. */
     366           1 :         sfinfo.full_ea_information.in.eas.num_eas = 1;
     367           1 :         ea.flags = 0;
     368           1 :         ea.name.private_length = 6;
     369           1 :         ea.name.s = "ZeroEA";
     370           1 :         ea.value = data_blob_null;
     371           1 :         sfinfo.full_ea_information.in.eas.eas = &ea;
     372           1 :         CHECK_CALL(FULL_EA_INFORMATION, NT_STATUS_OK);
     373             : 
     374             :         /* Does it still exist ? */
     375           1 :         finfo2.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
     376           1 :         finfo2.generic.in.file.handle = handle;
     377           1 :         finfo2.all_eas.in.continue_flags = 1;
     378           1 :         status2 = smb2_getinfo_file(tree, tctx, &finfo2);
     379           1 :         if (!NT_STATUS_IS_OK(status2)) {
     380           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__,
     381             :                         "SMB2_ALL_EAS", nt_errstr(status2));
     382           0 :                 ret = false;
     383           0 :                 goto done;
     384             :         }
     385             : 
     386             :         /* Over SMB2 ZeroEA should not exist. */
     387           1 :         if (!find_returned_ea(&finfo2, "EAONE", "VALUE1")) {
     388           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) Missing EA 'EAONE'\n", __location__);
     389           0 :                 ret = false;
     390             :         }
     391           1 :         if (!find_returned_ea(&finfo2, "SECONDEA", "ValueTwo")) {
     392           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) Missing EA 'SECONDEA'\n", __location__);
     393           0 :                 ret = false;
     394             :         }
     395           1 :         if (find_returned_ea(&finfo2, "ZeroEA", NULL)) {
     396           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) Found null EA 'ZeroEA'\n", __location__);
     397           0 :                 ret = false;
     398             :         }
     399             : 
     400           1 : done:
     401           5 :         status = smb2_util_close(tree, handle);
     402           5 :         if (NT_STATUS_IS_ERR(status)) {
     403           0 :                 torture_warning(tctx, "Failed to delete %s - %s\n", fname, nt_errstr(status));
     404             :         }
     405           5 :         smb2_util_unlink(tree, fname);
     406             : 
     407           5 :         return ret;
     408             : }
     409             : 
     410             : 

Generated by: LCOV version 1.14