2 Unix SMB/CIFS implementation.
4 test DOS extended attributes
6 Copyright (C) Andrew Tridgell 2004
7 Copyright (C) Guenter Kukkukk 2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "libcli/libcli.h"
27 #include "torture/util.h"
28 #include "torture/raw/proto.h"
30 #define BASEDIR "\\testeas"
32 #define CHECK_STATUS(status, correct) do { \
33 torture_assert_ntstatus_equal_goto(tctx, status, correct, ret, done, "Incorrect status"); \
36 static bool maxeadebug
; /* need that here, to allow no file delete in debug case */
38 static bool check_ea(struct smbcli_state
*cli
,
39 const char *fname
, const char *eaname
, const char *value
)
41 NTSTATUS status
= torture_check_ea(cli
, fname
, eaname
, value
);
42 return NT_STATUS_IS_OK(status
);
45 static char bad_ea_chars
[] = "\"*+,/:;<=>?[\\]|";
47 static bool test_eas(struct smbcli_state
*cli
, struct torture_context
*tctx
)
50 union smb_setfileinfo setfile
;
52 const char *fname
= BASEDIR
"\\ea.txt";
58 torture_comment(tctx
, "TESTING SETFILEINFO EA_SET\n");
60 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
61 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
62 io
.ntcreatex
.in
.flags
= 0;
63 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
64 io
.ntcreatex
.in
.create_options
= 0;
65 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
66 io
.ntcreatex
.in
.share_access
=
67 NTCREATEX_SHARE_ACCESS_READ
|
68 NTCREATEX_SHARE_ACCESS_WRITE
;
69 io
.ntcreatex
.in
.alloc_size
= 0;
70 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
71 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
72 io
.ntcreatex
.in
.security_flags
= 0;
73 io
.ntcreatex
.in
.fname
= fname
;
74 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
75 CHECK_STATUS(status
, NT_STATUS_OK
);
76 fnum
= io
.ntcreatex
.out
.file
.fnum
;
78 ret
&= check_ea(cli
, fname
, "EAONE", NULL
);
80 torture_comment(tctx
, "Adding first two EAs\n");
81 setfile
.generic
.level
= RAW_SFILEINFO_EA_SET
;
82 setfile
.generic
.in
.file
.fnum
= fnum
;
83 setfile
.ea_set
.in
.num_eas
= 2;
84 setfile
.ea_set
.in
.eas
= talloc_array(tctx
, struct ea_struct
, 2);
85 setfile
.ea_set
.in
.eas
[0].flags
= 0;
86 setfile
.ea_set
.in
.eas
[0].name
.s
= "EAONE";
87 setfile
.ea_set
.in
.eas
[0].value
= data_blob_string_const("VALUE1");
88 setfile
.ea_set
.in
.eas
[1].flags
= 0;
89 setfile
.ea_set
.in
.eas
[1].name
.s
= "SECONDEA";
90 setfile
.ea_set
.in
.eas
[1].value
= data_blob_string_const("ValueTwo");
92 status
= smb_raw_setfileinfo(cli
->tree
, &setfile
);
93 CHECK_STATUS(status
, NT_STATUS_OK
);
95 ret
&= check_ea(cli
, fname
, "EAONE", "VALUE1");
96 ret
&= check_ea(cli
, fname
, "SECONDEA", "ValueTwo");
98 torture_comment(tctx
, "Modifying 2nd EA\n");
99 setfile
.ea_set
.in
.num_eas
= 1;
100 setfile
.ea_set
.in
.eas
[0].name
.s
= "SECONDEA";
101 setfile
.ea_set
.in
.eas
[0].value
= data_blob_string_const(" Changed Value");
102 status
= smb_raw_setfileinfo(cli
->tree
, &setfile
);
103 CHECK_STATUS(status
, NT_STATUS_OK
);
105 ret
&= check_ea(cli
, fname
, "EAONE", "VALUE1");
106 ret
&= check_ea(cli
, fname
, "SECONDEA", " Changed Value");
108 torture_comment(tctx
, "Setting a NULL EA\n");
109 setfile
.ea_set
.in
.eas
[0].value
= data_blob(NULL
, 0);
110 setfile
.ea_set
.in
.eas
[0].name
.s
= "NULLEA";
111 status
= smb_raw_setfileinfo(cli
->tree
, &setfile
);
112 CHECK_STATUS(status
, NT_STATUS_OK
);
114 ret
&= check_ea(cli
, fname
, "EAONE", "VALUE1");
115 ret
&= check_ea(cli
, fname
, "SECONDEA", " Changed Value");
116 ret
&= check_ea(cli
, fname
, "NULLEA", NULL
);
118 torture_comment(tctx
, "Deleting first EA\n");
119 setfile
.ea_set
.in
.eas
[0].flags
= 0;
120 setfile
.ea_set
.in
.eas
[0].name
.s
= "EAONE";
121 setfile
.ea_set
.in
.eas
[0].value
= data_blob(NULL
, 0);
122 status
= smb_raw_setfileinfo(cli
->tree
, &setfile
);
123 CHECK_STATUS(status
, NT_STATUS_OK
);
125 ret
&= check_ea(cli
, fname
, "EAONE", NULL
);
126 ret
&= check_ea(cli
, fname
, "SECONDEA", " Changed Value");
128 torture_comment(tctx
, "Deleting second EA\n");
129 setfile
.ea_set
.in
.eas
[0].flags
= 0;
130 setfile
.ea_set
.in
.eas
[0].name
.s
= "SECONDEA";
131 setfile
.ea_set
.in
.eas
[0].value
= data_blob(NULL
, 0);
132 status
= smb_raw_setfileinfo(cli
->tree
, &setfile
);
133 CHECK_STATUS(status
, NT_STATUS_OK
);
135 ret
&= check_ea(cli
, fname
, "EAONE", NULL
);
136 ret
&= check_ea(cli
, fname
, "SECONDEA", NULL
);
138 /* Check EA name containing colon. All EA's set
139 must be ignored, not just the one with the bad
142 torture_comment(tctx
, "Adding bad EA name\n");
143 setfile
.generic
.level
= RAW_SFILEINFO_EA_SET
;
144 setfile
.generic
.in
.file
.fnum
= fnum
;
145 setfile
.ea_set
.in
.num_eas
= 3;
146 setfile
.ea_set
.in
.eas
= talloc_array(tctx
, struct ea_struct
, 3);
147 setfile
.ea_set
.in
.eas
[0].flags
= 0;
148 setfile
.ea_set
.in
.eas
[0].name
.s
= "EAONE";
149 setfile
.ea_set
.in
.eas
[0].value
= data_blob_string_const("VALUE1");
150 setfile
.ea_set
.in
.eas
[1].flags
= 0;
151 setfile
.ea_set
.in
.eas
[1].name
.s
= "SECOND:EA";
152 setfile
.ea_set
.in
.eas
[1].value
= data_blob_string_const("ValueTwo");
153 setfile
.ea_set
.in
.eas
[2].flags
= 0;
154 setfile
.ea_set
.in
.eas
[2].name
.s
= "THIRDEA";
155 setfile
.ea_set
.in
.eas
[2].value
= data_blob_string_const("ValueThree");
157 status
= smb_raw_setfileinfo(cli
->tree
, &setfile
);
158 CHECK_STATUS(status
, STATUS_INVALID_EA_NAME
);
160 ret
&= check_ea(cli
, fname
, "EAONE", NULL
);
161 ret
&= check_ea(cli
, fname
, "THIRDEA", NULL
);
163 setfile
.generic
.level
= RAW_SFILEINFO_EA_SET
;
164 setfile
.generic
.in
.file
.fnum
= fnum
;
165 setfile
.ea_set
.in
.num_eas
= 1;
166 setfile
.ea_set
.in
.eas
= talloc_array(tctx
, struct ea_struct
, 1);
167 setfile
.ea_set
.in
.eas
[0].flags
= 0;
168 strlcpy(bad_ea_name
, "TEST_X", sizeof(bad_ea_name
));
169 setfile
.ea_set
.in
.eas
[0].name
.s
= bad_ea_name
;
171 torture_comment(tctx
, "Testing bad EA name range.\n");
173 for (i
= 1; i
< 256; i
++) {
174 setfile
.ea_set
.in
.eas
[0].value
= data_blob_string_const("VALUE1");
175 bad_ea_name
[5] = (char)i
;
176 torture_comment(tctx
, "Testing bad EA name %d.\n", i
);
177 status
= smb_raw_setfileinfo(cli
->tree
, &setfile
);
178 if (i
< 32 || strchr(bad_ea_chars
, i
)) {
179 CHECK_STATUS(status
, STATUS_INVALID_EA_NAME
);
181 CHECK_STATUS(status
, NT_STATUS_OK
);
183 /* Now delete the EA we just set to make
184 sure we don't run out of room. */
185 setfile
.ea_set
.in
.eas
[0].value
= data_blob(NULL
, 0);
186 status
= smb_raw_setfileinfo(cli
->tree
, &setfile
);
187 CHECK_STATUS(status
, NT_STATUS_OK
);
192 smbcli_close(cli
->tree
, fnum
);
198 * Helper function to retrieve the max. ea size for one ea name
200 static int test_one_eamax(struct torture_context
*tctx
,
201 struct smbcli_state
*cli
, const int fnum
,
202 const char *eaname
, DATA_BLOB eablob
,
203 const int eastart
, const int eadebug
)
206 struct ea_struct eastruct
;
207 union smb_setfileinfo setfile
;
208 int i
, high
, low
, maxeasize
;
210 setfile
.generic
.level
= RAW_SFILEINFO_EA_SET
;
211 setfile
.generic
.in
.file
.fnum
= fnum
;
212 setfile
.ea_set
.in
.num_eas
= 1;
213 setfile
.ea_set
.in
.eas
= &eastruct
;
214 setfile
.ea_set
.in
.eas
->flags
= 0;
215 setfile
.ea_set
.in
.eas
->name
.s
= eaname
;
216 setfile
.ea_set
.in
.eas
->value
= eablob
;
218 maxeasize
= eablob
.length
;
225 torture_comment(tctx
, "Testing EA size: %d\n", i
);
227 setfile
.ea_set
.in
.eas
->value
.length
= i
;
229 status
= smb_raw_setfileinfo(cli
->tree
, &setfile
);
231 if (NT_STATUS_EQUAL(status
, NT_STATUS_OK
)) {
233 torture_comment(tctx
, "[%s] EA size %d succeeded! "
234 "(high=%d low=%d)\n",
235 eaname
, i
, high
, low
);
238 if (low
== maxeasize
) {
239 torture_comment(tctx
, "Max. EA size for \"%s\"=%d "
240 "[but could be possibly larger]\n",
244 if (high
- low
== 1 && high
!= maxeasize
) {
245 torture_comment(tctx
, "Max. EA size for \"%s\"=%d\n",
249 i
+= (high
- low
+ 1) / 2;
252 torture_comment(tctx
, "[%s] EA size %d failed! "
253 "(high=%d low=%d) [%s]\n",
254 eaname
, i
, high
, low
,
258 if (high
- low
<= 1) {
259 torture_comment(tctx
, "Max. EA size for \"%s\"=%d\n",
263 i
-= (high
- low
+ 1) / 2;
271 * Test for maximum ea size - more than one ea name is checked.
273 * Additional parameters can be passed, to allow further testing:
276 * maxeasize 65536 limit the max. size for a single EA name
277 * maxeanames 101 limit of the number of tested names
278 * maxeastart 1 this EA size is used to test for the 1st EA (atm)
279 * maxeadebug 0 if set true, further debug output is done - in addition
280 * the testfile is not deleted for further inspection!
282 * Set some/all of these options on the cmdline with:
283 * --option torture:maxeasize=1024 --option torture:maxeadebug=1 ...
286 static bool test_max_eas(struct smbcli_state
*cli
, struct torture_context
*tctx
)
290 const char *fname
= BASEDIR
"\\ea_max.txt";
295 int i
, j
, k
, last
, total
;
302 torture_comment(tctx
, "TESTING SETFILEINFO MAX. EA_SET\n");
304 maxeasize
= torture_setting_int(tctx
, "maxeasize", 65536);
305 maxeanames
= torture_setting_int(tctx
, "maxeanames", 101);
306 maxeastart
= torture_setting_int(tctx
, "maxeastart", 1);
307 maxeadebug
= torture_setting_int(tctx
, "maxeadebug", 0);
309 /* Do some sanity check on possibly passed parms */
310 if (maxeasize
<= 0) {
311 torture_comment(tctx
, "Invalid parameter 'maxeasize=%d'",maxeasize
);
314 if (maxeanames
<= 0) {
315 torture_comment(tctx
, "Invalid parameter 'maxeanames=%d'",maxeanames
);
318 if (maxeastart
<= 0) {
319 torture_comment(tctx
, "Invalid parameter 'maxeastart=%d'",maxeastart
);
322 if (maxeadebug
< 0) {
323 torture_comment(tctx
, "Invalid parameter 'maxeadebug=%d'",maxeadebug
);
327 torture_comment(tctx
, "\n\n");
330 if (maxeastart
> maxeasize
) {
331 maxeastart
= maxeasize
;
332 torture_comment(tctx
, "'maxeastart' outside range - corrected to %d\n",
335 torture_comment(tctx
, "MAXEA parms: maxeasize=%d maxeanames=%d maxeastart=%d"
336 " maxeadebug=%d\n", maxeasize
, maxeanames
, maxeastart
,
339 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
340 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
341 io
.ntcreatex
.in
.flags
= 0;
342 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
343 io
.ntcreatex
.in
.create_options
= 0;
344 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
345 io
.ntcreatex
.in
.share_access
=
346 NTCREATEX_SHARE_ACCESS_READ
|
347 NTCREATEX_SHARE_ACCESS_WRITE
;
348 io
.ntcreatex
.in
.alloc_size
= 0;
349 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
350 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
351 io
.ntcreatex
.in
.security_flags
= 0;
352 io
.ntcreatex
.in
.fname
= fname
;
353 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
354 CHECK_STATUS(status
, NT_STATUS_OK
);
355 fnum
= io
.ntcreatex
.out
.file
.fnum
;
357 eablob
= data_blob_talloc(tctx
, NULL
, maxeasize
);
358 if (eablob
.data
== NULL
) {
362 * Fill in some EA data - the offset could be easily checked
365 for (i
= 0, k
= 0; i
< eablob
.length
/ 4; i
++, k
+=4) {
366 eablob
.data
[k
] = k
& 0xff;
367 eablob
.data
[k
+1] = (k
>> 8) & 0xff;
368 eablob
.data
[k
+2] = (k
>> 16) & 0xff;
369 eablob
.data
[k
+3] = (k
>> 24) & 0xff;
372 i
= eablob
.length
% 4;
374 eablob
.data
[k
] = k
& 0xff;
376 eablob
.data
[k
+1] = (k
>> 8) & 0xff;
378 eablob
.data
[k
+2] = (k
>> 16) & 0xff;
383 * Filesystems might allow max. EAs data for different EA names.
384 * So more than one EA name should be checked.
389 for (i
= 0; i
< maxeanames
; i
++) {
390 if (eaname
!= NULL
) {
393 eaname
= talloc_asprintf(tctx
, "MAX%d", i
);
397 j
= test_one_eamax(tctx
, cli
, fnum
, eaname
, eablob
, last
, maxeadebug
);
405 torture_comment(tctx
, "Total EA size:%d\n", total
);
406 if (i
== maxeanames
) {
407 torture_comment(tctx
, "NOTE: More EAs could be available!\n");
413 smbcli_close(cli
->tree
, fnum
);
418 test using NTTRANS CREATE to create a file with an initial EA set
420 static bool test_nttrans_create(struct smbcli_state
*cli
, struct torture_context
*tctx
)
424 const char *fname
= BASEDIR
"\\ea2.txt";
425 const char *fname_bad
= BASEDIR
"\\ea2_bad.txt";
428 struct ea_struct eas
[3];
429 struct smb_ea_list ea_list
;
431 torture_comment(tctx
, "TESTING NTTRANS CREATE WITH EAS\n");
433 io
.generic
.level
= RAW_OPEN_NTTRANS_CREATE
;
434 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
435 io
.ntcreatex
.in
.flags
= 0;
436 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
437 io
.ntcreatex
.in
.create_options
= 0;
438 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
439 io
.ntcreatex
.in
.share_access
=
440 NTCREATEX_SHARE_ACCESS_READ
|
441 NTCREATEX_SHARE_ACCESS_WRITE
;
442 io
.ntcreatex
.in
.alloc_size
= 0;
443 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
444 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
445 io
.ntcreatex
.in
.security_flags
= 0;
446 io
.ntcreatex
.in
.fname
= fname
;
452 eas
[0].name
.s
= "1st EA";
453 eas
[0].value
= data_blob_string_const("Value One");
456 eas
[1].name
.s
= "2nd EA";
457 eas
[1].value
= data_blob_string_const("Second Value");
460 eas
[2].name
.s
= "and 3rd";
461 eas
[2].value
= data_blob_string_const("final value");
463 io
.ntcreatex
.in
.ea_list
= &ea_list
;
464 io
.ntcreatex
.in
.sec_desc
= NULL
;
466 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
467 CHECK_STATUS(status
, NT_STATUS_OK
);
468 fnum
= io
.ntcreatex
.out
.file
.fnum
;
470 ret
&= check_ea(cli
, fname
, "EAONE", NULL
);
471 ret
&= check_ea(cli
, fname
, "1st EA", "Value One");
472 ret
&= check_ea(cli
, fname
, "2nd EA", "Second Value");
473 ret
&= check_ea(cli
, fname
, "and 3rd", "final value");
475 smbcli_close(cli
->tree
, fnum
);
477 torture_comment(tctx
, "Trying to add EAs on non-create\n");
478 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
479 io
.ntcreatex
.in
.fname
= fname
;
483 eas
[0].name
.s
= "Fourth EA";
484 eas
[0].value
= data_blob_string_const("Value Four");
486 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
487 CHECK_STATUS(status
, NT_STATUS_OK
);
488 fnum
= io
.ntcreatex
.out
.file
.fnum
;
490 ret
&= check_ea(cli
, fname
, "1st EA", "Value One");
491 ret
&= check_ea(cli
, fname
, "2nd EA", "Second Value");
492 ret
&= check_ea(cli
, fname
, "and 3rd", "final value");
493 ret
&= check_ea(cli
, fname
, "Fourth EA", NULL
);
495 torture_comment(tctx
, "TESTING NTTRANS CREATE WITH BAD EA NAMES\n");
497 io
.generic
.level
= RAW_OPEN_NTTRANS_CREATE
;
498 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
499 io
.ntcreatex
.in
.flags
= 0;
500 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
501 io
.ntcreatex
.in
.create_options
= 0;
502 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
503 io
.ntcreatex
.in
.share_access
=
504 NTCREATEX_SHARE_ACCESS_READ
|
505 NTCREATEX_SHARE_ACCESS_WRITE
;
506 io
.ntcreatex
.in
.alloc_size
= 0;
507 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_CREATE
;
508 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
509 io
.ntcreatex
.in
.security_flags
= 0;
510 io
.ntcreatex
.in
.fname
= fname_bad
;
516 eas
[0].name
.s
= "1st EA";
517 eas
[0].value
= data_blob_string_const("Value One");
520 eas
[1].name
.s
= "2nd:BAD:EA";
521 eas
[1].value
= data_blob_string_const("Second Value");
524 eas
[2].name
.s
= "and 3rd";
525 eas
[2].value
= data_blob_string_const("final value");
527 io
.ntcreatex
.in
.ea_list
= &ea_list
;
528 io
.ntcreatex
.in
.sec_desc
= NULL
;
530 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
531 CHECK_STATUS(status
, STATUS_INVALID_EA_NAME
);
533 /* File must not exist. */
534 io
.generic
.level
= RAW_OPEN_NTCREATEX
;
535 io
.ntcreatex
.in
.root_fid
.fnum
= 0;
536 io
.ntcreatex
.in
.flags
= 0;
537 io
.ntcreatex
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
538 io
.ntcreatex
.in
.create_options
= 0;
539 io
.ntcreatex
.in
.file_attr
= FILE_ATTRIBUTE_NORMAL
;
540 io
.ntcreatex
.in
.share_access
=
541 NTCREATEX_SHARE_ACCESS_READ
|
542 NTCREATEX_SHARE_ACCESS_WRITE
;
543 io
.ntcreatex
.in
.alloc_size
= 0;
544 io
.ntcreatex
.in
.open_disposition
= NTCREATEX_DISP_OPEN
;
545 io
.ntcreatex
.in
.impersonation
= NTCREATEX_IMPERSONATION_ANONYMOUS
;
546 io
.ntcreatex
.in
.security_flags
= 0;
547 io
.ntcreatex
.in
.fname
= fname_bad
;
548 status
= smb_raw_open(cli
->tree
, tctx
, &io
);
549 CHECK_STATUS(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
552 smbcli_close(cli
->tree
, fnum
);
557 basic testing of EA calls
559 bool torture_raw_eas(struct torture_context
*torture
, struct smbcli_state
*cli
)
563 torture_assert(torture
, torture_setup_dir(cli
, BASEDIR
), "Failed to setup up test directory: " BASEDIR
);
565 ret
&= test_eas(cli
, torture
);
566 ret
&= test_nttrans_create(cli
, torture
);
568 smb_raw_exit(cli
->session
);
576 bool torture_max_eas(struct torture_context
*torture
)
578 struct smbcli_state
*cli
;
581 if (!torture_open_connection(&cli
, torture
, 0)) {
585 torture_assert(torture
, torture_setup_dir(cli
, BASEDIR
), "Failed to setup up test directory: " BASEDIR
);
587 ret
&= test_max_eas(cli
, torture
);
589 smb_raw_exit(cli
->session
);
591 /* in no ea debug case, all files are gone now */
592 smbcli_deltree(cli
->tree
, BASEDIR
);
595 torture_close_connection(cli
);