s3:SMB2-SESSION-RECONNECT: also expect NETWORK_NAME_DELETED is signing isn't used
[metze/samba/wip.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             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
539                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
540                 return false;
541         }
542
543         /* now grab the session key and try with signing */
544
545         status = smb2cli_session_update_session_key(cli2->smb2.session,
546                                                     ntlmssp->session_key,
547                                                     recv_iov);
548         if (!NT_STATUS_IS_OK(status)) {
549                 printf("smb2cli_session_update_session_key %s\n", nt_errstr(status));
550                 return false;
551         }
552
553         /* the tid seems to be irrelevant at this stage */
554
555         cli2->smb2.tid = cli1->smb2.tid;
556
557         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
558         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
559                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
560                 return false;
561         }
562
563         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
564                                fid_volatile, 0, 0, (const uint8_t *)hello);
565         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
566                 printf("smb2cli_write returned %s\n", nt_errstr(status));
567                 return false;
568         }
569
570         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
571                                fid_volatile, 2, 0,
572                                talloc_tos(), &result, &nread);
573         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
574                 printf("smb2cli_read returned %s\n", nt_errstr(status));
575                 return false;
576         }
577
578         status = smb2cli_create(cli2, "session-reconnect.txt",
579                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
580                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
581                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
582                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
583                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
584                         FILE_CREATE, /* create_disposition, */
585                         FILE_DELETE_ON_CLOSE, /* create_options, */
586                         NULL, /* smb2_create_blobs *blobs */
587                         &fid_persistent,
588                         &fid_volatile);
589         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
590                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
591                 return false;
592         }
593
594         /* now do a new tcon and test file calls again */
595
596         status = cli_tree_connect(cli2, share, "?????", "", 0);
597         if (!NT_STATUS_IS_OK(status)) {
598                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
599                 return false;
600         }
601
602         status = smb2cli_create(cli2, "session-reconnect.txt",
603                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
604                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
605                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
606                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
607                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
608                         FILE_CREATE, /* create_disposition, */
609                         FILE_DELETE_ON_CLOSE, /* create_options, */
610                         NULL, /* smb2_create_blobs *blobs */
611                         &fid_persistent,
612                         &fid_volatile);
613         if (!NT_STATUS_IS_OK(status)) {
614                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
615                 return false;
616         }
617
618         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
619                                fid_volatile, 0, 0, (const uint8_t *)hello);
620         if (!NT_STATUS_IS_OK(status)) {
621                 printf("smb2cli_write returned %s\n", nt_errstr(status));
622                 return false;
623         }
624
625         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
626         if (!NT_STATUS_IS_OK(status)) {
627                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
628                 return false;
629         }
630
631         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
632                                fid_volatile, 2, 0,
633                                talloc_tos(), &result, &nread);
634         if (!NT_STATUS_IS_OK(status)) {
635                 printf("smb2cli_read returned %s\n", nt_errstr(status));
636                 return false;
637         }
638
639         if (nread != strlen(hello)) {
640                 printf("smb2cli_read returned %d bytes, expected %d\n",
641                        (int)nread, (int)strlen(hello));
642                 return false;
643         }
644
645         if (memcmp(hello, result, nread) != 0) {
646                 printf("smb2cli_read returned '%s', expected '%s'\n",
647                        result, hello);
648                 return false;
649         }
650
651         return true;
652 }
653
654 bool run_smb2_tcon_dependence(int dummy)
655 {
656         struct cli_state *cli;
657         NTSTATUS status;
658         uint64_t fid_persistent, fid_volatile;
659         const char *hello = "Hello, world\n";
660         uint8_t *result;
661         uint32_t nread;
662
663         printf("Starting SMB2-TCON-DEPENDENCE\n");
664
665         if (!torture_init_connection(&cli)) {
666                 return false;
667         }
668         cli->smb2.pid = 0xFEFF;
669
670         status = smbXcli_negprot(cli->conn, cli->timeout,
671                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_24);
672         if (!NT_STATUS_IS_OK(status)) {
673                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
674                 return false;
675         }
676
677         status = cli_session_setup(cli, username,
678                                    password, strlen(password),
679                                    password, strlen(password),
680                                    workgroup);
681         if (!NT_STATUS_IS_OK(status)) {
682                 printf("cli_session_setup returned %s\n", nt_errstr(status));
683                 return false;
684         }
685
686         status = cli_tree_connect(cli, share, "?????", "", 0);
687         if (!NT_STATUS_IS_OK(status)) {
688                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
689                 return false;
690         }
691
692         status = smb2cli_create(cli, "tcon_depedence.txt",
693                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
694                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
695                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
696                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
697                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
698                         FILE_CREATE, /* create_disposition, */
699                         FILE_DELETE_ON_CLOSE, /* create_options, */
700                         NULL, /* smb2_create_blobs *blobs */
701                         &fid_persistent,
702                         &fid_volatile);
703         if (!NT_STATUS_IS_OK(status)) {
704                 printf("smb2cli_create on cli %s\n", nt_errstr(status));
705                 return false;
706         }
707
708         status = smb2cli_write(cli, strlen(hello), 0, fid_persistent,
709                                fid_volatile, 0, 0, (const uint8_t *)hello);
710         if (!NT_STATUS_IS_OK(status)) {
711                 printf("smb2cli_write returned %s\n", nt_errstr(status));
712                 return false;
713         }
714
715         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
716         if (!NT_STATUS_IS_OK(status)) {
717                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
718                 return false;
719         }
720
721         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
722                                fid_volatile, 2, 0,
723                                talloc_tos(), &result, &nread);
724         if (!NT_STATUS_IS_OK(status)) {
725                 printf("smb2cli_read returned %s\n", nt_errstr(status));
726                 return false;
727         }
728
729         if (nread != strlen(hello)) {
730                 printf("smb2cli_read returned %d bytes, expected %d\n",
731                        (int)nread, (int)strlen(hello));
732                 return false;
733         }
734
735         if (memcmp(hello, result, nread) != 0) {
736                 printf("smb2cli_read returned '%s', expected '%s'\n",
737                        result, hello);
738                 return false;
739         }
740
741         /* check behaviour with wrong tid... */
742
743         cli->smb2.tid++;
744
745         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
746                                fid_volatile, 2, 0,
747                                talloc_tos(), &result, &nread);
748         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
749                 printf("smb2cli_read returned %s\n", nt_errstr(status));
750                 return false;
751         }
752
753         cli->smb2.tid--;
754
755         return true;
756 }
757
758 bool run_smb2_multi_channel(int dummy)
759 {
760         struct cli_state *cli1;
761         struct cli_state *cli2;
762         NTSTATUS status;
763         bool ok;
764         uint64_t fid_persistent, fid_volatile;
765         struct tevent_context *ev;
766         struct tevent_req *subreq;
767         DATA_BLOB in_blob = data_blob_null;
768         DATA_BLOB out_blob;
769         struct ntlmssp_state *ntlmssp;
770         struct iovec *recv_iov;
771         const char *hello = "Hello, world\n";
772         uint8_t *result;
773         uint32_t nread;
774
775         printf("Starting SMB2-MULTI-CHANNEL\n");
776
777         if (!torture_init_connection(&cli1)) {
778                 return false;
779         }
780         cli1->smb2.pid = 0xFEFF;
781
782         if (!torture_init_connection(&cli2)) {
783                 return false;
784         }
785         cli2->smb2.pid = 0xFEFF;
786
787         status = smbXcli_negprot(cli1->conn, cli1->timeout,
788                                  PROTOCOL_SMB2_22, PROTOCOL_SMB2_24);
789         if (!NT_STATUS_IS_OK(status)) {
790                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
791                 return false;
792         }
793
794         status = smbXcli_negprot(cli2->conn, cli2->timeout,
795                                  PROTOCOL_SMB2_22, PROTOCOL_SMB2_24);
796         if (!NT_STATUS_IS_OK(status)) {
797                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
798                 return false;
799         }
800
801         status = cli_session_setup(cli1, username,
802                                    password, strlen(password),
803                                    password, strlen(password),
804                                    workgroup);
805         if (!NT_STATUS_IS_OK(status)) {
806                 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
807                 return false;
808         }
809
810         status = cli_tree_connect(cli1, share, "?????", "", 0);
811         if (!NT_STATUS_IS_OK(status)) {
812                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
813                 return false;
814         }
815
816         status = smb2cli_session_create_channel(cli2,
817                                                 cli1->smb2.session,
818                                                 cli2->conn,
819                                                 &cli2->smb2.session);
820         if (!NT_STATUS_IS_OK(status)) {
821                 printf("smb2cli_session_create_channel returned %s\n",
822                         nt_errstr(status));
823                 return false;
824         }
825
826         status = ntlmssp_client_start(talloc_tos(),
827                                       lp_netbios_name(),
828                                       lp_workgroup(),
829                                       lp_client_ntlmv2_auth(),
830                                       &ntlmssp);
831         if (!NT_STATUS_IS_OK(status)) {
832                 printf("ntlmssp_client_start returned %s\n", nt_errstr(status));
833                 return false;
834         }
835
836         ntlmssp_want_feature(ntlmssp,
837                              NTLMSSP_FEATURE_SESSION_KEY);
838         status = ntlmssp_set_username(ntlmssp, username);
839         if (!NT_STATUS_IS_OK(status)) {
840                 printf("ntlmssp_set_username returned %s\n", nt_errstr(status));
841                 return false;
842         }
843
844         status = ntlmssp_set_domain(ntlmssp, workgroup);
845         if (!NT_STATUS_IS_OK(status)) {
846                 printf("ntlmssp_set_domain returned %s\n", nt_errstr(status));
847                 return false;
848         }
849
850         status = ntlmssp_set_password(ntlmssp, password);
851         if (!NT_STATUS_IS_OK(status)) {
852                 printf("ntlmssp_set_password returned %s\n", nt_errstr(status));
853                 return false;
854         }
855
856         status = ntlmssp_update(ntlmssp, data_blob_null, &in_blob);
857         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
858                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
859                 return false;
860         }
861
862         ev = event_context_init(talloc_tos());
863         if (ev == NULL) {
864                 printf("event_context_init() returned NULL\n");
865                 return false;
866         }
867
868         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
869                                             cli2->conn,
870                                             cli2->timeout,
871                                             cli2->smb2.session,
872                                             0x01, /* in_flags */
873                                             SMB2_CAP_DFS, /* in_capabilities */
874                                             0, /* in_channel */
875                                             NULL, /* in_previous_session */
876                                             &in_blob); /* in_security_buffer */
877         if (subreq == NULL) {
878                 printf("smb2cli_session_setup_send() returned NULL\n");
879                 return false;
880         }
881
882         ok = tevent_req_poll(subreq, ev);
883         if (!ok) {
884                 printf("tevent_req_poll() returned false\n");
885                 return false;
886         }
887
888         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
889                                             NULL, &out_blob);
890         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
891                 printf("smb2cli_session_setup_recv returned %s\n",
892                         nt_errstr(status));
893                 return false;
894         }
895
896         status = ntlmssp_update(ntlmssp, out_blob, &in_blob);
897         if (!NT_STATUS_IS_OK(status)) {
898                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
899                 return false;
900         }
901
902         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
903                                             cli2->conn,
904                                             cli2->timeout,
905                                             cli2->smb2.session,
906                                             0x01, /* in_flags */
907                                             SMB2_CAP_DFS, /* in_capabilities */
908                                             0, /* in_channel */
909                                             NULL, /* in_previous_session */
910                                             &in_blob); /* in_security_buffer */
911         if (subreq == NULL) {
912                 printf("smb2cli_session_setup_send() returned NULL\n");
913                 return false;
914         }
915
916         ok = tevent_req_poll(subreq, ev);
917         if (!ok) {
918                 printf("tevent_req_poll() returned false\n");
919                 return false;
920         }
921
922         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
923                                             &recv_iov, &out_blob);
924         if (!NT_STATUS_IS_OK(status)) {
925                 printf("smb2cli_session_setup_recv returned %s\n",
926                         nt_errstr(status));
927                 return false;
928         }
929
930         status = smb2cli_session_update_session_key(cli2->smb2.session,
931                                                     ntlmssp->session_key,
932                                                     recv_iov);
933         if (!NT_STATUS_IS_OK(status)) {
934                 printf("smb2cli_session_update_session_key %s\n", nt_errstr(status));
935                 return false;
936         }
937
938         cli2->smb2.tid = cli1->smb2.tid;
939
940         status = smb2cli_create(cli2, "multi-channel.txt",
941                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
942                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
943                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
944                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
945                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
946                         FILE_CREATE, /* create_disposition, */
947                         FILE_DELETE_ON_CLOSE, /* create_options, */
948                         NULL, /* smb2_create_blobs *blobs */
949                         &fid_persistent,
950                         &fid_volatile);
951         if (!NT_STATUS_IS_OK(status)) {
952                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
953                 return false;
954         }
955
956         status = smb2cli_write(cli1, strlen(hello), 0, fid_persistent,
957                                fid_volatile, 0, 0, (const uint8_t *)hello);
958         if (!NT_STATUS_IS_OK(status)) {
959                 printf("smb2cli_write returned %s\n", nt_errstr(status));
960                 return false;
961         }
962
963         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
964         if (!NT_STATUS_IS_OK(status)) {
965                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
966                 return false;
967         }
968
969         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
970         if (!NT_STATUS_IS_OK(status)) {
971                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
972                 return false;
973         }
974
975         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
976                                fid_volatile, 2, 0,
977                                talloc_tos(), &result, &nread);
978         if (!NT_STATUS_IS_OK(status)) {
979                 printf("smb2cli_read returned %s\n", nt_errstr(status));
980                 return false;
981         }
982
983         if (nread != strlen(hello)) {
984                 printf("smb2cli_read returned %d bytes, expected %d\n",
985                        (int)nread, (int)strlen(hello));
986                 return false;
987         }
988
989         if (memcmp(hello, result, nread) != 0) {
990                 printf("smb2cli_read returned '%s', expected '%s'\n",
991                        result, hello);
992                 return false;
993         }
994
995         status = smb2cli_close(cli1, 0, fid_persistent, fid_volatile);
996         if (!NT_STATUS_IS_OK(status)) {
997                 printf("smb2cli_close returned %s\n", nt_errstr(status));
998                 return false;
999         }
1000
1001         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
1002         if (!NT_STATUS_IS_OK(status)) {
1003                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1004         }
1005
1006         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
1007         if (!NT_STATUS_IS_OK(status)) {
1008                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1009         }
1010
1011         return true;
1012 }
1013
1014 bool run_smb2_session_reauth(int dummy)
1015 {
1016         struct cli_state *cli;
1017         NTSTATUS status;
1018         bool ok;
1019         uint64_t fid_persistent, fid_volatile;
1020         struct tevent_context *ev;
1021         struct tevent_req *subreq;
1022         DATA_BLOB in_blob = data_blob_null;
1023         DATA_BLOB out_blob;
1024         struct ntlmssp_state *ntlmssp;
1025         struct iovec *recv_iov;
1026
1027         printf("Starting SMB2-SESSION_REAUTH\n");
1028
1029         if (!torture_init_connection(&cli)) {
1030                 return false;
1031         }
1032         cli->smb2.pid = 0xFEFF;
1033
1034         /*
1035          * PROTOCOL_SMB2_22 has a bug in win8pre0
1036          * it behaves like PROTOCOL_SMB2_02
1037          * and returns NT_STATUS_REQUEST_NOT_ACCEPTED,
1038          * while it allows it on PROTOCOL_SMB2_02.
1039          */
1040         status = smbXcli_negprot(cli->conn, cli->timeout,
1041                                  PROTOCOL_SMB2_10, PROTOCOL_SMB2_10);
1042         if (!NT_STATUS_IS_OK(status)) {
1043                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
1044                 return false;
1045         }
1046
1047         status = cli_session_setup(cli, username,
1048                                    password, strlen(password),
1049                                    password, strlen(password),
1050                                    workgroup);
1051         if (!NT_STATUS_IS_OK(status)) {
1052                 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
1053                 return false;
1054         }
1055
1056         status = cli_tree_connect(cli, share, "?????", "", 0);
1057         if (!NT_STATUS_IS_OK(status)) {
1058                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1059                 return false;
1060         }
1061
1062         status = smb2cli_create(cli, "session-reauth.txt",
1063                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1064                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1065                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1066                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1067                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1068                         FILE_CREATE, /* create_disposition, */
1069                         FILE_DELETE_ON_CLOSE, /* create_options, */
1070                         NULL, /* smb2_create_blobs *blobs */
1071                         &fid_persistent,
1072                         &fid_volatile);
1073         if (!NT_STATUS_IS_OK(status)) {
1074                 printf("smb2cli_create %s\n", nt_errstr(status));
1075                 return false;
1076         }
1077
1078         status = ntlmssp_client_start(talloc_tos(),
1079                                       lp_netbios_name(),
1080                                       lp_workgroup(),
1081                                       lp_client_ntlmv2_auth(),
1082                                       &ntlmssp);
1083         if (!NT_STATUS_IS_OK(status)) {
1084                 printf("ntlmssp_client_start returned %s\n", nt_errstr(status));
1085                 return false;
1086         }
1087
1088         ntlmssp_want_feature(ntlmssp,
1089                              NTLMSSP_FEATURE_SESSION_KEY);
1090         status = ntlmssp_set_username(ntlmssp, username);
1091         if (!NT_STATUS_IS_OK(status)) {
1092                 printf("ntlmssp_set_username returned %s\n", nt_errstr(status));
1093                 return false;
1094         }
1095
1096         status = ntlmssp_set_domain(ntlmssp, workgroup);
1097         if (!NT_STATUS_IS_OK(status)) {
1098                 printf("ntlmssp_set_domain returned %s\n", nt_errstr(status));
1099                 return false;
1100         }
1101
1102         status = ntlmssp_set_password(ntlmssp, password);
1103         if (!NT_STATUS_IS_OK(status)) {
1104                 printf("ntlmssp_set_password returned %s\n", nt_errstr(status));
1105                 return false;
1106         }
1107
1108         status = ntlmssp_update(ntlmssp, data_blob_null, &in_blob);
1109         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1110                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
1111                 return false;
1112         }
1113
1114         ev = event_context_init(talloc_tos());
1115         if (ev == NULL) {
1116                 printf("event_context_init() returned NULL\n");
1117                 return false;
1118         }
1119
1120         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1121                                             cli->conn,
1122                                             cli->timeout,
1123                                             cli->smb2.session,
1124                                             0x0, /* in_flags */
1125                                             SMB2_CAP_DFS, /* in_capabilities */
1126                                             0, /* in_channel */
1127                                             NULL, /* in_previous_session */
1128                                             &in_blob); /* in_security_buffer */
1129         if (subreq == NULL) {
1130                 printf("smb2cli_session_setup_send() returned NULL\n");
1131                 return false;
1132         }
1133
1134         ok = tevent_req_poll(subreq, ev);
1135         if (!ok) {
1136                 printf("tevent_req_poll() returned false\n");
1137                 return false;
1138         }
1139
1140         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1141                                             NULL, &out_blob);
1142         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1143                 printf("smb2cli_session_setup_recv returned %s\n",
1144                         nt_errstr(status));
1145                 return false;
1146         }
1147
1148         status = ntlmssp_update(ntlmssp, out_blob, &in_blob);
1149         if (!NT_STATUS_IS_OK(status)) {
1150                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
1151                 return false;
1152         }
1153
1154         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1155                                             cli->conn,
1156                                             cli->timeout,
1157                                             cli->smb2.session,
1158                                             0x0, /* in_flags */
1159                                             SMB2_CAP_DFS, /* in_capabilities */
1160                                             0, /* in_channel */
1161                                             NULL, /* in_previous_session */
1162                                             &in_blob); /* in_security_buffer */
1163         if (subreq == NULL) {
1164                 printf("smb2cli_session_setup_send() returned NULL\n");
1165                 return false;
1166         }
1167
1168         ok = tevent_req_poll(subreq, ev);
1169         if (!ok) {
1170                 printf("tevent_req_poll() returned false\n");
1171                 return false;
1172         }
1173
1174         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1175                                             &recv_iov, &out_blob);
1176         if (!NT_STATUS_IS_OK(status)) {
1177                 printf("smb2cli_session_setup_recv returned %s\n",
1178                         nt_errstr(status));
1179                 return false;
1180         }
1181
1182         status = smb2cli_session_update_session_key(cli->smb2.session,
1183                                                     ntlmssp->session_key,
1184                                                     recv_iov);
1185         if (!NT_STATUS_IS_OK(status)) {
1186                 printf("smb2cli_session_update_session_key %s\n", nt_errstr(status));
1187                 return false;
1188         }
1189
1190         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
1191         if (!NT_STATUS_IS_OK(status)) {
1192                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1193                 return false;
1194         }
1195
1196         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
1197         if (!NT_STATUS_IS_OK(status)) {
1198                 printf("smb2cli_close returned %s\n", nt_errstr(status));
1199                 return false;
1200         }
1201
1202         status = smb2cli_create(cli, "multi-channel.txt",
1203                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1204                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1205                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1206                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1207                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1208                         FILE_CREATE, /* create_disposition, */
1209                         FILE_DELETE_ON_CLOSE, /* create_options, */
1210                         NULL, /* smb2_create_blobs *blobs */
1211                         &fid_persistent,
1212                         &fid_volatile);
1213         if (!NT_STATUS_IS_OK(status)) {
1214                 printf("smb2cli_create %s\n", nt_errstr(status));
1215                 return false;
1216         }
1217
1218         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
1219         if (!NT_STATUS_IS_OK(status)) {
1220                 printf("smb2cli_close returned %s\n", nt_errstr(status));
1221                 return false;
1222         }
1223
1224         return true;
1225 }