s3:torture/test_smb2: also try PROTOCOL_SMB2_24
[mat/samba.git] / source3 / torture / test_smb2.c
1 /*
2    Unix SMB/CIFS implementation.
3    Initial test for the smb2 client lib
4    Copyright (C) Volker Lendecke 2011
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 "torture/proto.h"
22 #include "client.h"
23 #include "../libcli/smb/smbXcli_base.h"
24 #include "libsmb/smb2cli.h"
25 #include "libcli/security/security.h"
26 #include "libsmb/proto.h"
27 #include "../auth/ntlmssp/ntlmssp.h"
28
29 extern fstring host, workgroup, share, password, username, myname;
30
31 bool run_smb2_basic(int dummy)
32 {
33         struct cli_state *cli;
34         NTSTATUS status;
35         uint64_t fid_persistent, fid_volatile;
36         const char *hello = "Hello, world\n";
37         uint8_t *result;
38         uint32_t nread;
39         uint8_t *dir_data;
40         uint32_t dir_data_length;
41         uint32_t saved_tid = 0;
42         uint64_t saved_uid = 0;
43
44         printf("Starting SMB2-BASIC\n");
45
46         if (!torture_init_connection(&cli)) {
47                 return false;
48         }
49         cli->smb2.pid = 0xFEFF;
50
51         status = smbXcli_negprot(cli->conn, cli->timeout,
52                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
53         if (!NT_STATUS_IS_OK(status)) {
54                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
55                 return false;
56         }
57
58         status = cli_session_setup(cli, username,
59                                    password, strlen(password),
60                                    password, strlen(password),
61                                    workgroup);
62         if (!NT_STATUS_IS_OK(status)) {
63                 printf("cli_session_setup returned %s\n", nt_errstr(status));
64                 return false;
65         }
66
67         status = cli_tree_connect(cli, share, "?????", "", 0);
68         if (!NT_STATUS_IS_OK(status)) {
69                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
70                 return false;
71         }
72
73         status = smb2cli_create(cli, "smb2-basic.txt",
74                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
75                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
76                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
77                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
78                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
79                         FILE_CREATE, /* create_disposition, */
80                         FILE_DELETE_ON_CLOSE, /* create_options, */
81                         NULL, /* smb2_create_blobs *blobs */
82                         &fid_persistent,
83                         &fid_volatile);
84         if (!NT_STATUS_IS_OK(status)) {
85                 printf("smb2cli_create returned %s\n", nt_errstr(status));
86                 return false;
87         }
88
89         status = smb2cli_write(cli, strlen(hello), 0, fid_persistent,
90                                fid_volatile, 0, 0, (const uint8_t *)hello);
91         if (!NT_STATUS_IS_OK(status)) {
92                 printf("smb2cli_write returned %s\n", nt_errstr(status));
93                 return false;
94         }
95
96         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
97         if (!NT_STATUS_IS_OK(status)) {
98                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
99                 return false;
100         }
101
102         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
103                                fid_volatile, 2, 0,
104                                talloc_tos(), &result, &nread);
105         if (!NT_STATUS_IS_OK(status)) {
106                 printf("smb2cli_read returned %s\n", nt_errstr(status));
107                 return false;
108         }
109
110         if (nread != strlen(hello)) {
111                 printf("smb2cli_read returned %d bytes, expected %d\n",
112                        (int)nread, (int)strlen(hello));
113                 return false;
114         }
115
116         if (memcmp(hello, result, nread) != 0) {
117                 printf("smb2cli_read returned '%s', expected '%s'\n",
118                        result, hello);
119                 return false;
120         }
121
122         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
123         if (!NT_STATUS_IS_OK(status)) {
124                 printf("smb2cli_close returned %s\n", nt_errstr(status));
125                 return false;
126         }
127
128         status = smb2cli_create(cli, "",
129                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
130                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
131                         SEC_STD_SYNCHRONIZE|
132                         SEC_DIR_LIST|
133                         SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
134                         0, /* file_attributes, */
135                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
136                         FILE_OPEN, /* create_disposition, */
137                         FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
138                         NULL, /* smb2_create_blobs *blobs */
139                         &fid_persistent,
140                         &fid_volatile);
141         if (!NT_STATUS_IS_OK(status)) {
142                 printf("smb2cli_create returned %s\n", nt_errstr(status));
143                 return false;
144         }
145
146         status = smb2cli_query_directory(
147                 cli, 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
148                 talloc_tos(), &dir_data, &dir_data_length);
149
150         if (!NT_STATUS_IS_OK(status)) {
151                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
152                 return false;
153         }
154
155         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
156         if (!NT_STATUS_IS_OK(status)) {
157                 printf("smb2cli_close returned %s\n", nt_errstr(status));
158                 return false;
159         }
160
161         saved_tid = cli->smb2.tid;
162         status = smb2cli_tdis(cli);
163         if (!NT_STATUS_IS_OK(status)) {
164                 printf("smb2cli_tdis returned %s\n", nt_errstr(status));
165                 return false;
166         }
167         cli->smb2.tid = saved_tid;
168
169         status = smb2cli_tdis(cli);
170         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
171                 printf("2nd smb2cli_tdis returned %s\n", nt_errstr(status));
172                 return false;
173         }
174
175         saved_uid = smb2cli_session_current_id(cli->smb2.session);
176         status = smb2cli_logoff(cli);
177         if (!NT_STATUS_IS_OK(status)) {
178                 printf("smb2cli_logoff returned %s\n", nt_errstr(status));
179                 return false;
180         }
181
182         cli->smb2.session = smbXcli_session_create(cli, cli->conn);
183         if (cli->smb2.session == NULL) {
184                 printf("smbXcli_session_create() returned NULL\n");
185                 return false;
186         }
187
188         smb2cli_session_set_id_and_flags(cli->smb2.session, saved_uid, 0);
189
190         status = smb2cli_logoff(cli);
191         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
192                 printf("2nd smb2cli_logoff returned %s\n", nt_errstr(status));
193                 return false;
194         }
195
196         return true;
197 }
198
199 bool run_smb2_negprot(int dummy)
200 {
201         struct cli_state *cli;
202         NTSTATUS status;
203         enum protocol_types protocol;
204         const char *name = NULL;
205
206         printf("Starting SMB2-NEGPROT\n");
207
208         if (!torture_init_connection(&cli)) {
209                 return false;
210         }
211         cli->smb2.pid = 0xFEFF;
212
213         status = smbXcli_negprot(cli->conn, cli->timeout,
214                                  PROTOCOL_CORE, PROTOCOL_SMB2_24);
215         if (!NT_STATUS_IS_OK(status)) {
216                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
217                 return false;
218         }
219
220         protocol = smbXcli_conn_protocol(cli->conn);
221
222         switch (protocol) {
223         case PROTOCOL_SMB2_02:
224                 name = "SMB2_02";
225                 break;
226         case PROTOCOL_SMB2_10:
227                 name = "SMB2_10";
228                 break;
229         case PROTOCOL_SMB2_22:
230                 name = "SMB2_22";
231                 break;
232         case PROTOCOL_SMB2_24:
233                 name = "SMB2_24";
234                 break;
235         default:
236                 break;
237         }
238
239         if (name) {
240                 printf("Server supports %s\n", name);
241         } else {
242                 printf("Server DOES NOT support SMB2\n");
243                 return false;
244         }
245
246         status = smbXcli_negprot(cli->conn, cli->timeout,
247                                  protocol, protocol);
248         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET) &&
249             !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) &&
250             !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_ABORTED)) {
251                 printf("2nd smbXcli_negprot should disconnect - returned %s\n",
252                         nt_errstr(status));
253                 return false;
254         }
255
256         if (smbXcli_conn_is_connected(cli->conn)) {
257                 printf("2nd smbXcli_negprot should disconnect "
258                        "- still connected\n");
259                 return false;
260         }
261
262         return true;
263 }
264
265 bool run_smb2_session_reconnect(int dummy)
266 {
267         struct cli_state *cli1;
268         struct cli_state *cli2;
269         NTSTATUS status;
270         bool ok;
271         uint64_t fid_persistent, fid_volatile;
272         struct tevent_context *ev;
273         struct tevent_req *subreq;
274         DATA_BLOB in_blob = data_blob_null;
275         DATA_BLOB out_blob;
276         struct ntlmssp_state *ntlmssp;
277         struct iovec *recv_iov;
278         const char *hello = "Hello, world\n";
279         uint8_t *result;
280         uint32_t nread;
281
282         printf("Starting SMB2-SESSION-RECONNECT\n");
283
284         if (!torture_init_connection(&cli1)) {
285                 return false;
286         }
287         cli1->smb2.pid = 0xFEFF;
288
289         status = smbXcli_negprot(cli1->conn, cli1->timeout,
290                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_24);
291         if (!NT_STATUS_IS_OK(status)) {
292                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
293                 return false;
294         }
295
296         status = cli_session_setup(cli1, username,
297                                    password, strlen(password),
298                                    password, strlen(password),
299                                    workgroup);
300         if (!NT_STATUS_IS_OK(status)) {
301                 printf("cli_session_setup returned %s\n", nt_errstr(status));
302                 return false;
303         }
304
305         status = cli_tree_connect(cli1, share, "?????", "", 0);
306         if (!NT_STATUS_IS_OK(status)) {
307                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
308                 return false;
309         }
310
311         status = smb2cli_create(cli1, "session-reconnect.txt",
312                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
313                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
314                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
315                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
316                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
317                         FILE_CREATE, /* create_disposition, */
318                         FILE_DELETE_ON_CLOSE, /* create_options, */
319                         NULL, /* smb2_create_blobs *blobs */
320                         &fid_persistent,
321                         &fid_volatile);
322         if (!NT_STATUS_IS_OK(status)) {
323                 printf("smb2cli_create on cli1 %s\n", nt_errstr(status));
324                 return false;
325         }
326
327         status = smb2cli_write(cli1, strlen(hello), 0, fid_persistent,
328                                fid_volatile, 0, 0, (const uint8_t *)hello);
329         if (!NT_STATUS_IS_OK(status)) {
330                 printf("smb2cli_write returned %s\n", nt_errstr(status));
331                 return false;
332         }
333
334         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
335         if (!NT_STATUS_IS_OK(status)) {
336                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
337                 return false;
338         }
339
340         status = smb2cli_read(cli1, 0x10000, 0, fid_persistent,
341                                fid_volatile, 2, 0,
342                                talloc_tos(), &result, &nread);
343         if (!NT_STATUS_IS_OK(status)) {
344                 printf("smb2cli_read returned %s\n", nt_errstr(status));
345                 return false;
346         }
347
348         if (nread != strlen(hello)) {
349                 printf("smb2cli_read returned %d bytes, expected %d\n",
350                        (int)nread, (int)strlen(hello));
351                 return false;
352         }
353
354         if (memcmp(hello, result, nread) != 0) {
355                 printf("smb2cli_read returned '%s', expected '%s'\n",
356                        result, hello);
357                 return false;
358         }
359
360         /* prepare second session */
361
362         if (!torture_init_connection(&cli2)) {
363                 return false;
364         }
365         cli2->smb2.pid = 0xFEFF;
366
367         status = smbXcli_negprot(cli2->conn, cli2->timeout,
368                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_24);
369         if (!NT_STATUS_IS_OK(status)) {
370                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
371                 return false;
372         }
373
374         status = ntlmssp_client_start(talloc_tos(),
375                                       lp_netbios_name(),
376                                       lp_workgroup(),
377                                       lp_client_ntlmv2_auth(),
378                                       &ntlmssp);
379         if (!NT_STATUS_IS_OK(status)) {
380                 printf("ntlmssp_client_start returned %s\n", nt_errstr(status));
381                 return false;
382         }
383
384         ntlmssp_want_feature(ntlmssp,
385                              NTLMSSP_FEATURE_SESSION_KEY);
386         status = ntlmssp_set_username(ntlmssp, username);
387         if (!NT_STATUS_IS_OK(status)) {
388                 printf("ntlmssp_set_username returned %s\n", nt_errstr(status));
389                 return false;
390         }
391
392         status = ntlmssp_set_domain(ntlmssp, workgroup);
393         if (!NT_STATUS_IS_OK(status)) {
394                 printf("ntlmssp_set_domain returned %s\n", nt_errstr(status));
395                 return false;
396         }
397
398         status = ntlmssp_set_password(ntlmssp, password);
399         if (!NT_STATUS_IS_OK(status)) {
400                 printf("ntlmssp_set_password returned %s\n", nt_errstr(status));
401                 return false;
402         }
403
404         status = ntlmssp_update(ntlmssp, data_blob_null, &in_blob);
405         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
406                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
407                 return false;
408         }
409
410         cli2->smb2.session = smbXcli_session_create(cli2, cli2->conn);
411
412         ev = event_context_init(talloc_tos());
413         if (ev == NULL) {
414                 printf("event_context_init() returned NULL\n");
415                 return false;
416         }
417
418         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
419                                             cli2->conn,
420                                             cli2->timeout,
421                                             cli2->smb2.session,
422                                             0x0, /* in_flags */
423                                             SMB2_CAP_DFS, /* in_capabilities */
424                                             0, /* in_channel */
425                                             cli1->smb2.session, /* in_previous_session */
426                                             &in_blob); /* in_security_buffer */
427         if (subreq == NULL) {
428                 printf("smb2cli_session_setup_send() returned NULL\n");
429                 return false;
430         }
431
432         ok = tevent_req_poll(subreq, ev);
433         if (!ok) {
434                 printf("tevent_req_poll() returned false\n");
435                 return false;
436         }
437
438         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
439                                             NULL, &out_blob);
440         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
441                 printf("smb2cli_session_setup_recv returned %s\n",
442                         nt_errstr(status));
443                 return false;
444         }
445
446         status = ntlmssp_update(ntlmssp, out_blob, &in_blob);
447         if (!NT_STATUS_IS_OK(status)) {
448                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
449                 return false;
450         }
451
452         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
453                                             cli2->conn,
454                                             cli2->timeout,
455                                             cli2->smb2.session,
456                                             0x0, /* in_flags */
457                                             SMB2_CAP_DFS, /* in_capabilities */
458                                             0, /* in_channel */
459                                             cli1->smb2.session, /* in_previous_session */
460                                             &in_blob); /* in_security_buffer */
461         if (subreq == NULL) {
462                 printf("smb2cli_session_setup_send() returned NULL\n");
463                 return false;
464         }
465
466         ok = tevent_req_poll(subreq, ev);
467         if (!ok) {
468                 printf("tevent_req_poll() returned false\n");
469                 return false;
470         }
471
472         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
473                                             &recv_iov, &out_blob);
474         if (!NT_STATUS_IS_OK(status)) {
475                 printf("smb2cli_session_setup_recv returned %s\n",
476                         nt_errstr(status));
477                 return false;
478         }
479
480         status = smb2_signing_check_pdu(ntlmssp->session_key, recv_iov, 3);
481         if (!NT_STATUS_IS_OK(status)) {
482                 printf("check pdu returned %s\n", nt_errstr(status));
483                 return false;
484         }
485
486         /* check file operation on the old client */
487
488         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
489         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
490                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
491                 return false;
492         }
493
494         status = cli_tree_connect(cli1, share, "?????", "", 0);
495         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
496                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
497                 return false;
498         }
499
500         /*
501          * checking file operations without signing.
502          * on w2k8r2 at least, flush, read and write also work the same way,
503          * while create gives ACCESS_DENIED without signing
504          */
505         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
506         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
507                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
508                 return false;
509         }
510
511         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
512                                fid_volatile, 0, 0, (const uint8_t *)hello);
513         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
514                 printf("smb2cli_write returned %s\n", nt_errstr(status));
515                 return false;
516         }
517
518         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
519                                fid_volatile, 2, 0,
520                                talloc_tos(), &result, &nread);
521         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
522                 printf("smb2cli_read returned %s\n", nt_errstr(status));
523                 return false;
524         }
525
526         status = smb2cli_create(cli2, "session-reconnect.txt",
527                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
528                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
529                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
530                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
531                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
532                         FILE_CREATE, /* create_disposition, */
533                         FILE_DELETE_ON_CLOSE, /* create_options, */
534                         NULL, /* smb2_create_blobs *blobs */
535                         &fid_persistent,
536                         &fid_volatile);
537         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
538                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
539                 return false;
540         }
541
542         /* now grab the session key and try with signing */
543
544         status = smb2cli_session_update_session_key(cli2->smb2.session,
545                                                     ntlmssp->session_key,
546                                                     recv_iov);
547         if (!NT_STATUS_IS_OK(status)) {
548                 printf("smb2cli_session_update_session_key %s\n", nt_errstr(status));
549                 return false;
550         }
551
552         /* the tid seems to be irrelevant at this stage */
553
554         cli2->smb2.tid = cli1->smb2.tid;
555
556         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
557         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
558                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
559                 return false;
560         }
561
562         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
563                                fid_volatile, 0, 0, (const uint8_t *)hello);
564         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
565                 printf("smb2cli_write returned %s\n", nt_errstr(status));
566                 return false;
567         }
568
569         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
570                                fid_volatile, 2, 0,
571                                talloc_tos(), &result, &nread);
572         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
573                 printf("smb2cli_read returned %s\n", nt_errstr(status));
574                 return false;
575         }
576
577         status = smb2cli_create(cli2, "session-reconnect.txt",
578                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
579                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
580                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
581                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
582                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
583                         FILE_CREATE, /* create_disposition, */
584                         FILE_DELETE_ON_CLOSE, /* create_options, */
585                         NULL, /* smb2_create_blobs *blobs */
586                         &fid_persistent,
587                         &fid_volatile);
588         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
589                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
590                 return false;
591         }
592
593         /* now do a new tcon and test file calls again */
594
595         status = cli_tree_connect(cli2, share, "?????", "", 0);
596         if (!NT_STATUS_IS_OK(status)) {
597                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
598                 return false;
599         }
600
601         status = smb2cli_create(cli2, "session-reconnect.txt",
602                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
603                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
604                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
605                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
606                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
607                         FILE_CREATE, /* create_disposition, */
608                         FILE_DELETE_ON_CLOSE, /* create_options, */
609                         NULL, /* smb2_create_blobs *blobs */
610                         &fid_persistent,
611                         &fid_volatile);
612         if (!NT_STATUS_IS_OK(status)) {
613                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
614                 return false;
615         }
616
617         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
618                                fid_volatile, 0, 0, (const uint8_t *)hello);
619         if (!NT_STATUS_IS_OK(status)) {
620                 printf("smb2cli_write returned %s\n", nt_errstr(status));
621                 return false;
622         }
623
624         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
625         if (!NT_STATUS_IS_OK(status)) {
626                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
627                 return false;
628         }
629
630         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
631                                fid_volatile, 2, 0,
632                                talloc_tos(), &result, &nread);
633         if (!NT_STATUS_IS_OK(status)) {
634                 printf("smb2cli_read returned %s\n", nt_errstr(status));
635                 return false;
636         }
637
638         if (nread != strlen(hello)) {
639                 printf("smb2cli_read returned %d bytes, expected %d\n",
640                        (int)nread, (int)strlen(hello));
641                 return false;
642         }
643
644         if (memcmp(hello, result, nread) != 0) {
645                 printf("smb2cli_read returned '%s', expected '%s'\n",
646                        result, hello);
647                 return false;
648         }
649
650         return true;
651 }
652
653 bool run_smb2_tcon_dependence(int dummy)
654 {
655         struct cli_state *cli;
656         NTSTATUS status;
657         uint64_t fid_persistent, fid_volatile;
658         const char *hello = "Hello, world\n";
659         uint8_t *result;
660         uint32_t nread;
661
662         printf("Starting SMB2-TCON-DEPENDENCE\n");
663
664         if (!torture_init_connection(&cli)) {
665                 return false;
666         }
667         cli->smb2.pid = 0xFEFF;
668
669         status = smbXcli_negprot(cli->conn, cli->timeout,
670                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_24);
671         if (!NT_STATUS_IS_OK(status)) {
672                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
673                 return false;
674         }
675
676         status = cli_session_setup(cli, username,
677                                    password, strlen(password),
678                                    password, strlen(password),
679                                    workgroup);
680         if (!NT_STATUS_IS_OK(status)) {
681                 printf("cli_session_setup returned %s\n", nt_errstr(status));
682                 return false;
683         }
684
685         status = cli_tree_connect(cli, share, "?????", "", 0);
686         if (!NT_STATUS_IS_OK(status)) {
687                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
688                 return false;
689         }
690
691         status = smb2cli_create(cli, "tcon_depedence.txt",
692                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
693                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
694                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
695                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
696                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
697                         FILE_CREATE, /* create_disposition, */
698                         FILE_DELETE_ON_CLOSE, /* create_options, */
699                         NULL, /* smb2_create_blobs *blobs */
700                         &fid_persistent,
701                         &fid_volatile);
702         if (!NT_STATUS_IS_OK(status)) {
703                 printf("smb2cli_create on cli %s\n", nt_errstr(status));
704                 return false;
705         }
706
707         status = smb2cli_write(cli, strlen(hello), 0, fid_persistent,
708                                fid_volatile, 0, 0, (const uint8_t *)hello);
709         if (!NT_STATUS_IS_OK(status)) {
710                 printf("smb2cli_write returned %s\n", nt_errstr(status));
711                 return false;
712         }
713
714         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
715         if (!NT_STATUS_IS_OK(status)) {
716                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
717                 return false;
718         }
719
720         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
721                                fid_volatile, 2, 0,
722                                talloc_tos(), &result, &nread);
723         if (!NT_STATUS_IS_OK(status)) {
724                 printf("smb2cli_read returned %s\n", nt_errstr(status));
725                 return false;
726         }
727
728         if (nread != strlen(hello)) {
729                 printf("smb2cli_read returned %d bytes, expected %d\n",
730                        (int)nread, (int)strlen(hello));
731                 return false;
732         }
733
734         if (memcmp(hello, result, nread) != 0) {
735                 printf("smb2cli_read returned '%s', expected '%s'\n",
736                        result, hello);
737                 return false;
738         }
739
740         /* check behaviour with wrong tid... */
741
742         cli->smb2.tid++;
743
744         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
745                                fid_volatile, 2, 0,
746                                talloc_tos(), &result, &nread);
747         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
748                 printf("smb2cli_read returned %s\n", nt_errstr(status));
749                 return false;
750         }
751
752         cli->smb2.tid--;
753
754         return true;
755 }
756
757 bool run_smb2_multi_channel(int dummy)
758 {
759         struct cli_state *cli1;
760         struct cli_state *cli2;
761         NTSTATUS status;
762         bool ok;
763         uint64_t fid_persistent, fid_volatile;
764         struct tevent_context *ev;
765         struct tevent_req *subreq;
766         DATA_BLOB in_blob = data_blob_null;
767         DATA_BLOB out_blob;
768         struct ntlmssp_state *ntlmssp;
769         struct iovec *recv_iov;
770         const char *hello = "Hello, world\n";
771         uint8_t *result;
772         uint32_t nread;
773
774         printf("Starting SMB2-MULTI-CHANNEL\n");
775
776         if (!torture_init_connection(&cli1)) {
777                 return false;
778         }
779         cli1->smb2.pid = 0xFEFF;
780
781         if (!torture_init_connection(&cli2)) {
782                 return false;
783         }
784         cli2->smb2.pid = 0xFEFF;
785
786         status = smbXcli_negprot(cli1->conn, cli1->timeout,
787                                  PROTOCOL_SMB2_22, PROTOCOL_SMB2_24);
788         if (!NT_STATUS_IS_OK(status)) {
789                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
790                 return false;
791         }
792
793         status = smbXcli_negprot(cli2->conn, cli2->timeout,
794                                  PROTOCOL_SMB2_22, PROTOCOL_SMB2_24);
795         if (!NT_STATUS_IS_OK(status)) {
796                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
797                 return false;
798         }
799
800         status = cli_session_setup(cli1, username,
801                                    password, strlen(password),
802                                    password, strlen(password),
803                                    workgroup);
804         if (!NT_STATUS_IS_OK(status)) {
805                 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
806                 return false;
807         }
808
809         status = cli_tree_connect(cli1, share, "?????", "", 0);
810         if (!NT_STATUS_IS_OK(status)) {
811                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
812                 return false;
813         }
814
815         status = smb2cli_session_create_channel(cli2,
816                                                 cli1->smb2.session,
817                                                 cli2->conn,
818                                                 &cli2->smb2.session);
819         if (!NT_STATUS_IS_OK(status)) {
820                 printf("smb2cli_session_create_channel returned %s\n",
821                         nt_errstr(status));
822                 return false;
823         }
824
825         status = ntlmssp_client_start(talloc_tos(),
826                                       lp_netbios_name(),
827                                       lp_workgroup(),
828                                       lp_client_ntlmv2_auth(),
829                                       &ntlmssp);
830         if (!NT_STATUS_IS_OK(status)) {
831                 printf("ntlmssp_client_start returned %s\n", nt_errstr(status));
832                 return false;
833         }
834
835         ntlmssp_want_feature(ntlmssp,
836                              NTLMSSP_FEATURE_SESSION_KEY);
837         status = ntlmssp_set_username(ntlmssp, username);
838         if (!NT_STATUS_IS_OK(status)) {
839                 printf("ntlmssp_set_username returned %s\n", nt_errstr(status));
840                 return false;
841         }
842
843         status = ntlmssp_set_domain(ntlmssp, workgroup);
844         if (!NT_STATUS_IS_OK(status)) {
845                 printf("ntlmssp_set_domain returned %s\n", nt_errstr(status));
846                 return false;
847         }
848
849         status = ntlmssp_set_password(ntlmssp, password);
850         if (!NT_STATUS_IS_OK(status)) {
851                 printf("ntlmssp_set_password returned %s\n", nt_errstr(status));
852                 return false;
853         }
854
855         status = ntlmssp_update(ntlmssp, data_blob_null, &in_blob);
856         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
857                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
858                 return false;
859         }
860
861         ev = event_context_init(talloc_tos());
862         if (ev == NULL) {
863                 printf("event_context_init() returned NULL\n");
864                 return false;
865         }
866
867         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
868                                             cli2->conn,
869                                             cli2->timeout,
870                                             cli2->smb2.session,
871                                             0x01, /* in_flags */
872                                             SMB2_CAP_DFS, /* in_capabilities */
873                                             0, /* in_channel */
874                                             NULL, /* in_previous_session */
875                                             &in_blob); /* in_security_buffer */
876         if (subreq == NULL) {
877                 printf("smb2cli_session_setup_send() returned NULL\n");
878                 return false;
879         }
880
881         ok = tevent_req_poll(subreq, ev);
882         if (!ok) {
883                 printf("tevent_req_poll() returned false\n");
884                 return false;
885         }
886
887         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
888                                             NULL, &out_blob);
889         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
890                 printf("smb2cli_session_setup_recv returned %s\n",
891                         nt_errstr(status));
892                 return false;
893         }
894
895         status = ntlmssp_update(ntlmssp, out_blob, &in_blob);
896         if (!NT_STATUS_IS_OK(status)) {
897                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
898                 return false;
899         }
900
901         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
902                                             cli2->conn,
903                                             cli2->timeout,
904                                             cli2->smb2.session,
905                                             0x01, /* in_flags */
906                                             SMB2_CAP_DFS, /* in_capabilities */
907                                             0, /* in_channel */
908                                             NULL, /* in_previous_session */
909                                             &in_blob); /* in_security_buffer */
910         if (subreq == NULL) {
911                 printf("smb2cli_session_setup_send() returned NULL\n");
912                 return false;
913         }
914
915         ok = tevent_req_poll(subreq, ev);
916         if (!ok) {
917                 printf("tevent_req_poll() returned false\n");
918                 return false;
919         }
920
921         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
922                                             &recv_iov, &out_blob);
923         if (!NT_STATUS_IS_OK(status)) {
924                 printf("smb2cli_session_setup_recv returned %s\n",
925                         nt_errstr(status));
926                 return false;
927         }
928
929         status = smb2cli_session_update_session_key(cli2->smb2.session,
930                                                     ntlmssp->session_key,
931                                                     recv_iov);
932         if (!NT_STATUS_IS_OK(status)) {
933                 printf("smb2cli_session_update_session_key %s\n", nt_errstr(status));
934                 return false;
935         }
936
937         cli2->smb2.tid = cli1->smb2.tid;
938
939         status = smb2cli_create(cli2, "multi-channel.txt",
940                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
941                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
942                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
943                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
944                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
945                         FILE_CREATE, /* create_disposition, */
946                         FILE_DELETE_ON_CLOSE, /* create_options, */
947                         NULL, /* smb2_create_blobs *blobs */
948                         &fid_persistent,
949                         &fid_volatile);
950         if (!NT_STATUS_IS_OK(status)) {
951                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
952                 return false;
953         }
954
955         status = smb2cli_write(cli1, strlen(hello), 0, fid_persistent,
956                                fid_volatile, 0, 0, (const uint8_t *)hello);
957         if (!NT_STATUS_IS_OK(status)) {
958                 printf("smb2cli_write returned %s\n", nt_errstr(status));
959                 return false;
960         }
961
962         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
963         if (!NT_STATUS_IS_OK(status)) {
964                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
965                 return false;
966         }
967
968         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
969         if (!NT_STATUS_IS_OK(status)) {
970                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
971                 return false;
972         }
973
974         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
975                                fid_volatile, 2, 0,
976                                talloc_tos(), &result, &nread);
977         if (!NT_STATUS_IS_OK(status)) {
978                 printf("smb2cli_read returned %s\n", nt_errstr(status));
979                 return false;
980         }
981
982         if (nread != strlen(hello)) {
983                 printf("smb2cli_read returned %d bytes, expected %d\n",
984                        (int)nread, (int)strlen(hello));
985                 return false;
986         }
987
988         if (memcmp(hello, result, nread) != 0) {
989                 printf("smb2cli_read returned '%s', expected '%s'\n",
990                        result, hello);
991                 return false;
992         }
993
994         status = smb2cli_close(cli1, 0, fid_persistent, fid_volatile);
995         if (!NT_STATUS_IS_OK(status)) {
996                 printf("smb2cli_close returned %s\n", nt_errstr(status));
997                 return false;
998         }
999
1000         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
1001         if (!NT_STATUS_IS_OK(status)) {
1002                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1003         }
1004
1005         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
1006         if (!NT_STATUS_IS_OK(status)) {
1007                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1008         }
1009
1010         return true;
1011 }
1012
1013 bool run_smb2_session_reauth(int dummy)
1014 {
1015         struct cli_state *cli;
1016         NTSTATUS status;
1017         bool ok;
1018         uint64_t fid_persistent, fid_volatile;
1019         struct tevent_context *ev;
1020         struct tevent_req *subreq;
1021         DATA_BLOB in_blob = data_blob_null;
1022         DATA_BLOB out_blob;
1023         struct ntlmssp_state *ntlmssp;
1024         struct iovec *recv_iov;
1025
1026         printf("Starting SMB2-SESSION_REAUTH\n");
1027
1028         if (!torture_init_connection(&cli)) {
1029                 return false;
1030         }
1031         cli->smb2.pid = 0xFEFF;
1032
1033         /*
1034          * PROTOCOL_SMB2_22 has a bug in win8pre0
1035          * it behaves like PROTOCOL_SMB2_02
1036          * and returns NT_STATUS_REQUEST_NOT_ACCEPTED,
1037          * while it allows it on PROTOCOL_SMB2_02.
1038          */
1039         status = smbXcli_negprot(cli->conn, cli->timeout,
1040                                  PROTOCOL_SMB2_10, PROTOCOL_SMB2_10);
1041         if (!NT_STATUS_IS_OK(status)) {
1042                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
1043                 return false;
1044         }
1045
1046         status = cli_session_setup(cli, username,
1047                                    password, strlen(password),
1048                                    password, strlen(password),
1049                                    workgroup);
1050         if (!NT_STATUS_IS_OK(status)) {
1051                 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
1052                 return false;
1053         }
1054
1055         status = cli_tree_connect(cli, share, "?????", "", 0);
1056         if (!NT_STATUS_IS_OK(status)) {
1057                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1058                 return false;
1059         }
1060
1061         status = smb2cli_create(cli, "session-reauth.txt",
1062                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1063                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1064                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1065                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1066                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1067                         FILE_CREATE, /* create_disposition, */
1068                         FILE_DELETE_ON_CLOSE, /* create_options, */
1069                         NULL, /* smb2_create_blobs *blobs */
1070                         &fid_persistent,
1071                         &fid_volatile);
1072         if (!NT_STATUS_IS_OK(status)) {
1073                 printf("smb2cli_create %s\n", nt_errstr(status));
1074                 return false;
1075         }
1076
1077         status = ntlmssp_client_start(talloc_tos(),
1078                                       lp_netbios_name(),
1079                                       lp_workgroup(),
1080                                       lp_client_ntlmv2_auth(),
1081                                       &ntlmssp);
1082         if (!NT_STATUS_IS_OK(status)) {
1083                 printf("ntlmssp_client_start returned %s\n", nt_errstr(status));
1084                 return false;
1085         }
1086
1087         ntlmssp_want_feature(ntlmssp,
1088                              NTLMSSP_FEATURE_SESSION_KEY);
1089         status = ntlmssp_set_username(ntlmssp, username);
1090         if (!NT_STATUS_IS_OK(status)) {
1091                 printf("ntlmssp_set_username returned %s\n", nt_errstr(status));
1092                 return false;
1093         }
1094
1095         status = ntlmssp_set_domain(ntlmssp, workgroup);
1096         if (!NT_STATUS_IS_OK(status)) {
1097                 printf("ntlmssp_set_domain returned %s\n", nt_errstr(status));
1098                 return false;
1099         }
1100
1101         status = ntlmssp_set_password(ntlmssp, password);
1102         if (!NT_STATUS_IS_OK(status)) {
1103                 printf("ntlmssp_set_password returned %s\n", nt_errstr(status));
1104                 return false;
1105         }
1106
1107         status = ntlmssp_update(ntlmssp, data_blob_null, &in_blob);
1108         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1109                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
1110                 return false;
1111         }
1112
1113         ev = event_context_init(talloc_tos());
1114         if (ev == NULL) {
1115                 printf("event_context_init() returned NULL\n");
1116                 return false;
1117         }
1118
1119         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1120                                             cli->conn,
1121                                             cli->timeout,
1122                                             cli->smb2.session,
1123                                             0x0, /* in_flags */
1124                                             SMB2_CAP_DFS, /* in_capabilities */
1125                                             0, /* in_channel */
1126                                             NULL, /* in_previous_session */
1127                                             &in_blob); /* in_security_buffer */
1128         if (subreq == NULL) {
1129                 printf("smb2cli_session_setup_send() returned NULL\n");
1130                 return false;
1131         }
1132
1133         ok = tevent_req_poll(subreq, ev);
1134         if (!ok) {
1135                 printf("tevent_req_poll() returned false\n");
1136                 return false;
1137         }
1138
1139         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1140                                             NULL, &out_blob);
1141         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1142                 printf("smb2cli_session_setup_recv returned %s\n",
1143                         nt_errstr(status));
1144                 return false;
1145         }
1146
1147         status = ntlmssp_update(ntlmssp, out_blob, &in_blob);
1148         if (!NT_STATUS_IS_OK(status)) {
1149                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
1150                 return false;
1151         }
1152
1153         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1154                                             cli->conn,
1155                                             cli->timeout,
1156                                             cli->smb2.session,
1157                                             0x0, /* in_flags */
1158                                             SMB2_CAP_DFS, /* in_capabilities */
1159                                             0, /* in_channel */
1160                                             NULL, /* in_previous_session */
1161                                             &in_blob); /* in_security_buffer */
1162         if (subreq == NULL) {
1163                 printf("smb2cli_session_setup_send() returned NULL\n");
1164                 return false;
1165         }
1166
1167         ok = tevent_req_poll(subreq, ev);
1168         if (!ok) {
1169                 printf("tevent_req_poll() returned false\n");
1170                 return false;
1171         }
1172
1173         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1174                                             &recv_iov, &out_blob);
1175         if (!NT_STATUS_IS_OK(status)) {
1176                 printf("smb2cli_session_setup_recv returned %s\n",
1177                         nt_errstr(status));
1178                 return false;
1179         }
1180
1181         status = smb2cli_session_update_session_key(cli->smb2.session,
1182                                                     ntlmssp->session_key,
1183                                                     recv_iov);
1184         if (!NT_STATUS_IS_OK(status)) {
1185                 printf("smb2cli_session_update_session_key %s\n", nt_errstr(status));
1186                 return false;
1187         }
1188
1189         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
1190         if (!NT_STATUS_IS_OK(status)) {
1191                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1192                 return false;
1193         }
1194
1195         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
1196         if (!NT_STATUS_IS_OK(status)) {
1197                 printf("smb2cli_close returned %s\n", nt_errstr(status));
1198                 return false;
1199         }
1200
1201         status = smb2cli_create(cli, "multi-channel.txt",
1202                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1203                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1204                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1205                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1206                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1207                         FILE_CREATE, /* create_disposition, */
1208                         FILE_DELETE_ON_CLOSE, /* create_options, */
1209                         NULL, /* smb2_create_blobs *blobs */
1210                         &fid_persistent,
1211                         &fid_volatile);
1212         if (!NT_STATUS_IS_OK(status)) {
1213                 printf("smb2cli_create %s\n", nt_errstr(status));
1214                 return false;
1215         }
1216
1217         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
1218         if (!NT_STATUS_IS_OK(status)) {
1219                 printf("smb2cli_close returned %s\n", nt_errstr(status));
1220                 return false;
1221         }
1222
1223         return true;
1224 }