s3: Fix bug #9085.
[Samba.git] / source4 / torture / raw / chkpath.c
bloba39993489bbe229c8658d50d477044fe754bda3a
1 /*
2 Unix SMB/CIFS implementation.
3 chkpath individual test suite
4 Copyright (C) Andrew Tridgell 2003
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.
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.
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/>.
20 #include "includes.h"
21 #include "system/locale.h"
22 #include "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
28 #define BASEDIR "\\rawchkpath"
30 #define CHECK_STATUS(status, correct, dos_correct) do { \
31 if (!NT_STATUS_EQUAL(status, correct) && !NT_STATUS_EQUAL(status, dos_correct)) { \
32 printf("(%d) Incorrect status %s - should be %s\n", \
33 __LINE__, nt_errstr(status), nt_errstr(correct)); \
34 ret = false; \
35 goto done; \
36 }} while (0)
39 static NTSTATUS single_search(struct smbcli_state *cli,
40 TALLOC_CTX *mem_ctx, const char *pattern)
42 union smb_search_first io;
43 NTSTATUS status;
45 io.t2ffirst.level = RAW_SEARCH_TRANS2;
46 io.t2ffirst.data_level = RAW_SEARCH_DATA_STANDARD;
47 io.t2ffirst.in.search_attrib = 0;
48 io.t2ffirst.in.max_count = 1;
49 io.t2ffirst.in.flags = FLAG_TRANS2_FIND_CLOSE;
50 io.t2ffirst.in.storage_type = 0;
51 io.t2ffirst.in.pattern = pattern;
53 status = smb_raw_search_first(cli->tree, mem_ctx,
54 &io, NULL, NULL);
56 return status;
59 static bool test_path_ex(struct smbcli_state *cli, struct torture_context *tctx,
60 const char *path, const char *path_expected,
61 NTSTATUS expected, NTSTATUS dos_expected)
63 union smb_chkpath io;
64 union smb_fileinfo finfo;
65 NTSTATUS status;
67 io.chkpath.in.path = path;
68 status = smb_raw_chkpath(cli->tree, &io);
69 if (!NT_STATUS_EQUAL(status, expected) && !NT_STATUS_EQUAL(status, dos_expected)) {
70 printf("FAILED %-30s chkpath %s should be %s or %s\n",
71 path, nt_errstr(status), nt_errstr(expected), nt_errstr(dos_expected));
72 return false;
73 } else {
74 printf("%-30s chkpath correct (%s)\n", path, nt_errstr(status));
77 if (NT_STATUS_EQUAL(expected, NT_STATUS_NOT_A_DIRECTORY)) {
78 expected = NT_STATUS_OK;
81 ZERO_STRUCT(finfo);
82 finfo.generic.level = RAW_FILEINFO_NAME_INFO;
83 finfo.generic.in.file.path = path;
84 status = smb_raw_pathinfo(cli->tree, cli, &finfo);
85 if (!NT_STATUS_EQUAL(status, expected) && !NT_STATUS_EQUAL(status, dos_expected)) {
86 printf("FAILED: %-30s pathinfo %s should be %s or %s\n",
87 path, nt_errstr(status), nt_errstr(expected), nt_errstr(dos_expected));
88 return false;
91 if (!NT_STATUS_IS_OK(status)) {
92 printf("%-30s chkpath correct (%s)\n", path, nt_errstr(status));
93 return true;
96 if (path_expected &&
97 (!finfo.name_info.out.fname.s ||
98 strcmp(finfo.name_info.out.fname.s, path_expected) != 0)) {
99 if (tctx && torture_setting_bool(tctx, "samba4", false)) {
100 printf("IGNORE: %-30s => %-20s should be %s\n",
101 path, finfo.name_info.out.fname.s, path_expected);
102 return true;
104 printf("FAILED: %-30s => %-20s should be %s\n",
105 path, finfo.name_info.out.fname.s, path_expected);
106 return false;
108 printf("%-30s => %-20s correct\n",
109 path, finfo.name_info.out.fname.s);
111 return true;
114 static bool test_path(struct smbcli_state *cli, const char *path,
115 NTSTATUS expected, NTSTATUS dos_expected)
117 return test_path_ex(cli, NULL, path, path, expected, dos_expected);
120 static bool test_chkpath(struct smbcli_state *cli, struct torture_context *tctx)
122 union smb_chkpath io;
123 NTSTATUS status;
124 bool ret = true;
125 int fnum = -1;
126 int fnum1 = -1;
128 io.chkpath.in.path = BASEDIR;
130 status = smb_raw_chkpath(cli->tree, &io);
131 CHECK_STATUS(status, NT_STATUS_OK, NT_STATUS_OK);
133 ret &= test_path(cli, BASEDIR "\\nodir", NT_STATUS_OBJECT_NAME_NOT_FOUND, NT_STATUS_DOS(ERRDOS,ERRbadpath));
135 fnum = create_complex_file(cli, tctx, BASEDIR "\\test.txt..");
136 if (fnum == -1) {
137 printf("failed to open test.txt - %s\n", smbcli_errstr(cli->tree));
138 ret = false;
139 goto done;
142 ret &= test_path(cli, BASEDIR "\\test.txt..", NT_STATUS_NOT_A_DIRECTORY, NT_STATUS_DOS(ERRDOS,ERRbadpath));
144 if (!torture_set_file_attribute(cli->tree, BASEDIR, FILE_ATTRIBUTE_HIDDEN)) {
145 printf("failed to set basedir hidden\n");
146 ret = false;
147 goto done;
150 ret &= test_path_ex(cli, tctx, BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
151 ret &= test_path_ex(cli, tctx, ((const char *)BASEDIR) + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
152 ret &= test_path_ex(cli, tctx, ((const char *)BASEDIR"\\\\") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
153 ret &= test_path_ex(cli, tctx, ((const char *)BASEDIR"\\foo\\..") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
154 ret &= test_path_ex(cli, tctx, ((const char *)BASEDIR"\\f\\o\\o\\..\\..\\..") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
155 ret &= test_path_ex(cli, tctx, ((const char *)BASEDIR"\\foo\\\\..\\\\") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
156 ret &= test_path_ex(cli, tctx, BASEDIR"\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
157 ret &= test_path_ex(cli, tctx, BASEDIR"\\\\..\\"BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
158 ret &= test_path_ex(cli, tctx, BASEDIR"\\\\\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
159 ret &= test_path_ex(cli, tctx, "\\\\\\\\"BASEDIR"\\\\\\\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
160 ret &= test_path_ex(cli, tctx, "\\\\\\\\"BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
161 ret &= test_path_ex(cli, tctx, BASEDIR "\\foo\\..\\test.txt..", BASEDIR "\\test.txt..",
162 NT_STATUS_NOT_A_DIRECTORY, NT_STATUS_DOS(ERRDOS,ERRbadpath));
163 ret &= test_path_ex(cli, tctx, "", "\\", NT_STATUS_OK, NT_STATUS_OK);
164 ret &= test_path(cli, ".", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
165 ret &= test_path(cli, ".\\", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
166 ret &= test_path(cli, "\\\\\\.\\", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
167 ret &= test_path(cli, ".\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND, NT_STATUS_DOS(ERRDOS,ERRbadpath));
168 ret &= test_path(cli, "." BASEDIR, NT_STATUS_OBJECT_PATH_NOT_FOUND, NT_STATUS_DOS(ERRDOS,ERRbadpath));
169 ret &= test_path(cli, BASEDIR "\\.", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
170 ret &= test_path(cli, BASEDIR "\\.\\test.txt..", NT_STATUS_OBJECT_PATH_NOT_FOUND, NT_STATUS_DOS(ERRDOS,ERRbadpath));
171 ret &= test_path(cli, ".\\.\\", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
172 ret &= test_path(cli, ".\\.\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
173 ret &= test_path(cli, ".\\.\\.aaaaa", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
174 ret &= test_path(cli, "\\.\\", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
175 ret &= test_path(cli, "\\.\\\\", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
176 ret &= test_path(cli, "\\.\\\\\\\\\\\\", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
178 /* Note that the two following paths are identical but
179 give different NT status returns for chkpth and findfirst. */
181 printf("testing findfirst on %s\n", "\\.\\\\\\\\\\\\.");
182 status = single_search(cli, tctx, "\\.\\\\\\\\\\\\.");
183 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRinvalidname));
185 ret &= test_path(cli, "\\.\\\\\\\\\\\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
187 /* We expect this open to fail with the same error code as the chkpath below. */
188 printf("testing Open on %s\n", "\\.\\\\\\\\\\\\.");
189 /* findfirst seems to fail with a different error. */
190 fnum1 = smbcli_nt_create_full(cli->tree, "\\.\\\\\\\\\\\\.",
191 0, SEC_RIGHTS_FILE_ALL,
192 FILE_ATTRIBUTE_NORMAL,
193 NTCREATEX_SHARE_ACCESS_DELETE|
194 NTCREATEX_SHARE_ACCESS_READ|
195 NTCREATEX_SHARE_ACCESS_WRITE,
196 NTCREATEX_DISP_OVERWRITE_IF,
197 0, 0);
198 status = smbcli_nt_error(cli->tree);
199 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
202 ret &= test_path(cli, "\\.\\\\xxx", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
203 ret &= test_path(cli, "..\\..\\..", NT_STATUS_OBJECT_PATH_SYNTAX_BAD,NT_STATUS_DOS(ERRDOS,ERRinvalidpath));
204 ret &= test_path(cli, "\\..", NT_STATUS_OBJECT_PATH_SYNTAX_BAD,NT_STATUS_DOS(ERRDOS,ERRinvalidpath));
205 ret &= test_path(cli, "\\.\\\\\\\\\\\\xxx", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
206 ret &= test_path(cli, BASEDIR"\\.\\", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
207 ret &= test_path(cli, BASEDIR"\\.\\\\", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
208 ret &= test_path(cli, BASEDIR"\\.\\nt", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
209 ret &= test_path(cli, BASEDIR"\\.\\.\\nt", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
210 ret &= test_path(cli, BASEDIR"\\nt", NT_STATUS_OK, NT_STATUS_OK);
211 ret &= test_path(cli, BASEDIR".\\foo", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
212 ret &= test_path(cli, BASEDIR"xx\\foo", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
213 ret &= test_path(cli, ".\\", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
214 ret &= test_path(cli, ".\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
215 ret &= test_path(cli, ".\\.\\.\\.\\foo\\.\\.\\", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
216 ret &= test_path(cli, BASEDIR".\\.\\.\\.\\foo\\.\\.\\", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
217 ret &= test_path(cli, BASEDIR".\\.\\.\\.\\foo\\..\\.\\", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
218 ret &= test_path(cli, BASEDIR".", NT_STATUS_OBJECT_NAME_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
219 ret &= test_path(cli, "\\", NT_STATUS_OK,NT_STATUS_OK);
220 ret &= test_path(cli, "\\.", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
221 ret &= test_path(cli, "\\..\\", NT_STATUS_OBJECT_PATH_SYNTAX_BAD,NT_STATUS_DOS(ERRDOS,ERRinvalidpath));
222 ret &= test_path(cli, "\\..", NT_STATUS_OBJECT_PATH_SYNTAX_BAD,NT_STATUS_DOS(ERRDOS,ERRinvalidpath));
223 ret &= test_path(cli, BASEDIR "\\.", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
224 ret &= test_path_ex(cli, tctx, BASEDIR "\\..", "\\", NT_STATUS_OK,NT_STATUS_OK);
225 ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb600", NT_STATUS_OBJECT_NAME_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
226 ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb6.exe", NT_STATUS_NOT_A_DIRECTORY,NT_STATUS_DOS(ERRDOS,ERRbadpath));
228 /* We expect this open to fail with the same error code as the chkpath below. */
229 printf("testing Open on %s\n", BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
230 /* findfirst seems to fail with a different error. */
231 fnum1 = smbcli_nt_create_full(cli->tree, BASEDIR".\\.\\.\\.\\foo\\..\\.\\",
232 0, SEC_RIGHTS_FILE_ALL,
233 FILE_ATTRIBUTE_NORMAL,
234 NTCREATEX_SHARE_ACCESS_DELETE|
235 NTCREATEX_SHARE_ACCESS_READ|
236 NTCREATEX_SHARE_ACCESS_WRITE,
237 NTCREATEX_DISP_OVERWRITE_IF,
238 0, 0);
239 status = smbcli_nt_error(cli->tree);
240 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
242 printf("testing findfirst on %s\n", BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
243 status = single_search(cli, tctx, BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
244 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
246 /* We expect this open to fail with the same error code as the chkpath below. */
247 /* findfirst seems to fail with a different error. */
248 printf("testing Open on %s\n", BASEDIR "\\nt\\V S\\VB98\\vb6.exe\\3");
249 fnum1 = smbcli_nt_create_full(cli->tree, BASEDIR "\\nt\\V S\\VB98\\vb6.exe\\3",
250 0, SEC_RIGHTS_FILE_ALL,
251 FILE_ATTRIBUTE_NORMAL,
252 NTCREATEX_SHARE_ACCESS_DELETE|
253 NTCREATEX_SHARE_ACCESS_READ|
254 NTCREATEX_SHARE_ACCESS_WRITE,
255 NTCREATEX_DISP_OVERWRITE_IF,
256 0, 0);
257 status = smbcli_nt_error(cli->tree);
258 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
260 ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb6.exe\\3", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
261 ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb6.exe\\3\\foo", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
262 ret &= test_path(cli, BASEDIR "\\nt\\3\\foo", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
263 ret &= test_path(cli, BASEDIR "\\nt\\V S\\*\\vb6.exe\\3", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
264 ret &= test_path(cli, BASEDIR "\\nt\\V S\\*\\*\\vb6.exe\\3", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
266 done:
267 smbcli_close(cli->tree, fnum);
268 return ret;
271 static bool test_chkpath_names(struct smbcli_state *cli, struct torture_context *tctx)
273 union smb_chkpath io;
274 union smb_fileinfo finfo;
275 NTSTATUS status;
276 bool ret = true;
277 uint8_t i;
280 * we don't test characters >= 0x80 yet,
281 * as somehow our client libraries can't do that
283 for (i=0x01; i <= 0x7F; i++) {
285 * it's important that we test the last character
286 * because of the error code with ':' 0x3A
287 * and servers without stream support
289 char *path = talloc_asprintf(tctx, "%s\\File0x%02X%c",
290 BASEDIR, i, i);
291 NTSTATUS expected;
292 NTSTATUS expected_dos1;
293 NTSTATUS expected_dos2;
295 expected = NT_STATUS_OBJECT_NAME_NOT_FOUND;
296 expected_dos1 = NT_STATUS_DOS(ERRDOS,ERRbadpath);
297 expected_dos2 = NT_STATUS_DOS(ERRDOS,ERRbadfile);
299 switch (i) {
300 case '"':/*0x22*/
301 case '*':/*0x2A*/
302 case '/':/*0x2F*/
303 case ':':/*0x3A*/
304 case '<':/*0x3C*/
305 case '>':/*0x3E*/
306 case '?':/*0x3F*/
307 case '|':/*0x7C*/
308 if (i == '/' &&
309 torture_setting_bool(tctx, "samba3", false)) {
310 /* samba 3 handles '/' as '\\' */
311 break;
313 expected = NT_STATUS_OBJECT_NAME_INVALID;
314 expected_dos1 = NT_STATUS_DOS(ERRDOS,ERRbadpath);
315 expected_dos2 = NT_STATUS_DOS(ERRDOS,ERRinvalidname);
316 break;
317 default:
318 if (i <= 0x1F) {
319 expected = NT_STATUS_OBJECT_NAME_INVALID;
320 expected_dos1 = NT_STATUS_DOS(ERRDOS,ERRbadpath);
321 expected_dos2 = NT_STATUS_DOS(ERRDOS,ERRinvalidname);
323 break;
326 printf("Checking File0x%02X%c%s expected[%s|%s|%s]\n",
327 i, isprint(i)?(char)i:' ',
328 isprint(i)?"":"(not printable)",
329 nt_errstr(expected),
330 nt_errstr(expected_dos1),
331 nt_errstr(expected_dos2));
333 io.chkpath.in.path = path;
334 status = smb_raw_chkpath(cli->tree, &io);
335 CHECK_STATUS(status, expected, expected_dos1);
337 ZERO_STRUCT(finfo);
338 finfo.generic.level = RAW_FILEINFO_NAME_INFO;
339 finfo.generic.in.file.path = path;
340 status = smb_raw_pathinfo(cli->tree, cli, &finfo);
341 CHECK_STATUS(status, expected, expected_dos2);
343 talloc_free(path);
346 done:
347 return ret;
351 basic testing of chkpath calls
353 bool torture_raw_chkpath(struct torture_context *torture,
354 struct smbcli_state *cli)
356 bool ret = true;
357 int fnum;
359 if (!torture_setup_dir(cli, BASEDIR)) {
360 return false;
363 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR "\\nt"))) {
364 printf("Failed to create " BASEDIR " - %s\n", smbcli_errstr(cli->tree));
365 return false;
368 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR "\\nt\\V S"))) {
369 printf("Failed to create " BASEDIR " - %s\n", smbcli_errstr(cli->tree));
370 return false;
373 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR "\\nt\\V S\\VB98"))) {
374 printf("Failed to create " BASEDIR " - %s\n", smbcli_errstr(cli->tree));
375 return false;
378 fnum = create_complex_file(cli, torture, BASEDIR "\\nt\\V S\\VB98\\vb6.exe");
379 if (fnum == -1) {
380 printf("failed to open \\nt\\V S\\VB98\\vb6.exe - %s\n", smbcli_errstr(cli->tree));
381 ret = false;
382 goto done;
385 ret &= test_chkpath(cli, torture);
386 ret &= test_chkpath_names(cli, torture);
388 done:
390 smb_raw_exit(cli->session);
391 smbcli_deltree(cli->tree, BASEDIR);
393 return ret;